Skip to content

Commit d3b5b8a

Browse files
committed
Add city criteria to newsletter segments
Allow filtering newsletter segment members by their city (exact match). This enables targeting members in specific locations for newsletters. - Add city column to newsletter_segments table - Add by_city filter method in Newsletter::Segment model - Add city select input in segment admin form (after depot) - Extract member_cities_collection helper to share between member filter and segment form - Add translations for all supported languages
1 parent 5020781 commit d3b5b8a

File tree

8 files changed

+49
-4
lines changed

8 files changed

+49
-4
lines changed

app/admin/member.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@
2525
as: :select,
2626
collection: -> { admin_depots_collection },
2727
if: proc { params[:scope] != "inactive" && feature?("shop") }
28-
filter :city, as: :select, collection: -> {
29-
Member.pluck(:city).uniq.map(&:presence).compact.sort
30-
}
28+
filter :city, as: :select, collection: -> { member_cities_collection }
3129
filter :country_code, as: :select, collection: -> {
3230
country_codes = Member.pluck(:country_code).uniq.map(&:presence).compact.sort
3331
countries_collection(country_codes)

app/admin/newsletter/segment.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@
5353
for: Depot,
5454
label: Depot.model_name.human(count: 2),
5555
hint: t("formtastic.hints.newsletter/segment.depot_ids")
56+
f.input :city,
57+
as: :select,
58+
collection: member_cities_collection,
59+
include_blank: true,
60+
hint: t("formtastic.hints.newsletter/segment.city")
5661
if DeliveryCycle.kept.many?
5762
f.input :delivery_cycle_ids,
5863
collection: admin_delivery_cycles_collection,
@@ -93,6 +98,7 @@
9398
:coming_deliveries_in_days,
9499
:billing_year_division,
95100
:membership_ids,
101+
:city,
96102
*I18n.available_locales.map { |l| "title_#{l}" },
97103
basket_size_ids: [],
98104
basket_complement_ids: [],

app/helpers/admin_helper.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ def cycles_option_for_select(cycles)
4646
}
4747
end
4848

49+
def member_cities_collection
50+
Member.pluck(:city).uniq.map(&:presence).compact.sort
51+
end
52+
4953
def grouped_by_date(relation, past: :last)
5054
if fy_year = params.dig(:q, :during_year)
5155
relation = relation.during_year(fy_year)

app/models/newsletter/segment.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def members
5050
members = by_billing_year_division(members)
5151
members = by_coming_deliveries_in_days(members)
5252
members = by_membership_ids(members)
53+
members = by_city(members)
5354
members.uniq
5455
end
5556

@@ -117,5 +118,11 @@ def by_membership_ids(members)
117118

118119
members.where(memberships: { id: self[:membership_ids] })
119120
end
121+
122+
def by_city(members)
123+
return members unless city?
124+
125+
members.where(city: city)
126+
end
120127
end
121128
end

config/locales/formtastic.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,12 @@ _:
721721
_de: Unterscheidet aktive Mitglieder anhand des Zeitraums, in dem sie ihre Rechnungen erhalten.
722722
_it: Permette di differenziare i soci attivi in base all'intervallo di pagamento del loro abbonamento.
723723
_nl: Onderscheidt actieve leden op basis van de periode waarin zij hun rekeningen ontvangen.
724+
city:
725+
_en: Filters active members by their city (exact match).
726+
_fr: Permet de filtrer les membres actifs par leur ville (correspondance exacte).
727+
_de: Filtert aktive Mitglieder nach ihrer Stadt (exakte Übereinstimmung).
728+
_it: Filtra i soci attivi per la loro città (corrispondenza esatta).
729+
_nl: Filtert actieve leden op hun stad (exacte overeenkomst).
724730
coming_deliveries_in_days:
725731
_en: Differentiates active members based on the date of their next basket delivery.
726732
_fr: Permet de différencier les membres actifs par la date de leur prochaine livraison de panier.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
class AddCityToNewsletterSegments < ActiveRecord::Migration[8.1]
4+
def change
5+
add_column :newsletter_segments, :city, :string
6+
end
7+
end

db/schema.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[8.1].define(version: 2026_01_04_091700) do
13+
ActiveRecord::Schema[8.1].define(version: 2026_01_06_203500) do
1414
create_table "absences", force: :cascade do |t|
1515
t.datetime "created_at"
1616
t.date "ended_on"
@@ -675,6 +675,7 @@
675675
t.json "basket_complement_ids", default: [], null: false
676676
t.json "basket_size_ids", default: [], null: false
677677
t.integer "billing_year_division"
678+
t.string "city"
678679
t.integer "coming_deliveries_in_days"
679680
t.datetime "created_at", null: false
680681
t.json "delivery_cycle_ids", default: [], null: false

test/models/newsletter/segment_test.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,20 @@ class Newsletter::SegmentTest < ActiveSupport::TestCase
115115
segment = Newsletter::Segment.create!(membership_ids: "")
116116
assert_equal [ members(:anna), members(:john), members(:bob), members(:jane) ], segment.members
117117
end
118+
119+
test "segment by city" do
120+
travel_to "2024-01-01"
121+
122+
members(:john).update!(city: "Zurich")
123+
members(:anna).update!(city: "Zurich")
124+
125+
segment = Newsletter::Segment.create!(city: "Zurich")
126+
assert_equal [ members(:anna), members(:john) ], segment.members
127+
128+
segment = Newsletter::Segment.create!(city: "City")
129+
assert_equal [ members(:bob), members(:jane) ], segment.members
130+
131+
segment = Newsletter::Segment.create!(city: nil)
132+
assert_equal [ members(:anna), members(:john), members(:bob), members(:jane) ], segment.members
133+
end
118134
end

0 commit comments

Comments
 (0)