Module: Models::PartyAddresses
- Extended by:
- ActiveSupport::Concern
- Included in:
- Party
- Defined in:
- app/concerns/models/party_addresses.rb
Overview
Address delegation, catalog/store helpers, and visit-derived location fields.
== Country / locale / timezone resolution chain
These three derived attributes have multi-level overrides that depend on the
concrete Party subclass and which underlying store/customer is reachable:
countryParty (first address) -> Customer (+ catalog store fallback) ->
Contact (+ customer catalog fallback)localeParty (I18n.locale) -> Customer (catalog-derived) ->
Contact (customer.locale)timezoneParty (timezone_name column) -> Contact (+ customer.timezone fallback)
Customer overrides are in Models::CustomerDisplay; Contact overrides are in
Models::ContactDisplay. The Party-level methods here serve as the bottom of the chain
and the default for any Party that is neither a Customer nor a Contact.
Instance Method Summary collapse
-
#addresses_options_for_select ⇒ Array<Array(String, Integer)>
Builds [label, value] pairs of full address and id for select helpers.
-
#can_change_country? ⇒ Boolean
Whether the party's country may be changed: bots without an id, guests, and lead-qualification parties without a main address.
-
#catalog_country ⇒ Country?
Country of this party's catalog (or the associated customer's catalog).
-
#catalog_country_iso ⇒ String?
ISO code of the catalog's country.
-
#catalog_country_iso3 ⇒ String?
ISO3 code of the catalog's country.
-
#city ⇒ String?
City from the first address, falling back to the most recent visit's geolocated city.
-
#country ⇒ Country?
Country of the first address.
-
#country_iso ⇒ String?
ISO code of the party's country.
-
#country_iso3 ⇒ String?
ISO3 code of the party's country.
-
#first_address ⇒ Address?
Returns the party's first address, or nil when the addresses association is unreachable.
-
#flag ⇒ String?
Flag code ('us' or 'ca') for this party's catalog, falling back to the associated customer's catalog and then the US catalog.
-
#location_name ⇒ String?
"City, ST" summary of the main address, when one exists.
-
#most_recent_visit ⇒ Visit?
The party's most recent visit, memoized.
-
#new_address ⇒ Address
Builds a new unsaved address for this party, defaulting country to the store's country, copying defaults from the first existing address, and setting the residential flag from the homeowner status.
-
#store ⇒ Store?
Store backing this party's catalog, or nil when the catalog is unreachable.
-
#street1 ⇒ String?
First address street line 1.
-
#street2 ⇒ String?
First address street line 2.
-
#street3 ⇒ String?
First address street line 3.
-
#timezone ⇒ ActiveSupport::TimeZone?
Timezone from the party's timezone_name column.
-
#unique_addresses(include_address_id = nil) ⇒ Array<Address>
Returns the party's addresses deduplicated by full address value, ordered by street1.
-
#visit_data(attribute) ⇒ Object?
Reads an attribute off the most recent visit.
-
#visit_location ⇒ String?
Location summary geolocated from the most recent visit.
-
#zip ⇒ String?
Zip/postal code from the first address, falling back to the most recent visit's geolocated postal code.
Instance Method Details
#addresses_options_for_select ⇒ Array<Array(String, Integer)>
Builds [label, value] pairs of full address and id for select helpers.
58 59 60 |
# File 'app/concerns/models/party_addresses.rb', line 58 def addresses.map { |add| [add.full_address(true, ', '), add.id] } end |
#can_change_country? ⇒ Boolean
Whether the party's country may be changed: bots without an id,
guests, and lead-qualification parties without a main address.
202 203 204 |
# File 'app/concerns/models/party_addresses.rb', line 202 def can_change_country? bot_id.blank? || state == 'guest' || (state == 'lead_qualify' && main_address.nil?) end |
#catalog_country ⇒ Country?
Country of this party's catalog (or the associated customer's
catalog).
125 126 127 128 |
# File 'app/concerns/models/party_addresses.rb', line 125 def catalog_country cat = catalog || try(:customer)&.catalog cat&.country end |
#catalog_country_iso ⇒ String?
Returns ISO code of the catalog's country.
136 137 138 |
# File 'app/concerns/models/party_addresses.rb', line 136 def catalog_country_iso catalog_country&.iso end |
#catalog_country_iso3 ⇒ String?
Returns ISO3 code of the catalog's country.
131 132 133 |
# File 'app/concerns/models/party_addresses.rb', line 131 def catalog_country_iso3 catalog_country&.iso3 end |
#city ⇒ String?
City from the first address, falling back to the most recent visit's
geolocated city.
76 77 78 |
# File 'app/concerns/models/party_addresses.rb', line 76 def city first_address&.city || visit_data(:city) end |
#country ⇒ Country?
Country of the first address. Bottom of the country resolution chain
described in the module header.
107 108 109 |
# File 'app/concerns/models/party_addresses.rb', line 107 def country first_address&.country end |
#country_iso ⇒ String?
Returns ISO code of the party's country.
117 118 119 |
# File 'app/concerns/models/party_addresses.rb', line 117 def country_iso country&.iso end |
#country_iso3 ⇒ String?
Returns ISO3 code of the party's country.
112 113 114 |
# File 'app/concerns/models/party_addresses.rb', line 112 def country_iso3 country&.iso3 end |
#first_address ⇒ Address?
Returns the party's first address, or nil when the addresses
association is unreachable.
66 67 68 69 70 |
# File 'app/concerns/models/party_addresses.rb', line 66 def first_address addresses.first rescue StandardError nil end |
#flag ⇒ String?
Flag code ('us' or 'ca') for this party's catalog, falling back to
the associated customer's catalog and then the US catalog.
183 184 185 186 |
# File 'app/concerns/models/party_addresses.rb', line 183 def flag cat = catalog || try(:customer)&.catalog || Catalog.us_catalog { 1 => 'us', 2 => 'ca' }[cat.store_id] end |
#location_name ⇒ String?
"City, ST" summary of the main address, when one exists.
153 154 155 |
# File 'app/concerns/models/party_addresses.rb', line 153 def location_name (addr = main_address) ? "#{addr.city}, #{addr.state_code}" : nil end |
#most_recent_visit ⇒ Visit?
The party's most recent visit, memoized.
167 168 169 |
# File 'app/concerns/models/party_addresses.rb', line 167 def most_recent_visit @most_recent_visit ||= visits.order(started_at: :desc).first end |
#new_address ⇒ Address
Builds a new unsaved address for this party, defaulting country to the
store's country, copying defaults from the first existing address, and
setting the residential flag from the homeowner status.
29 30 31 32 33 34 35 36 |
# File 'app/concerns/models/party_addresses.rb', line 29 def new_address addr = Address.new addr.party = self addr.country = store.country copy_first_address_defaults!(addr) addr.is_residential = is_homeowner? addr end |
#store ⇒ Store?
Store backing this party's catalog, or nil when the catalog is
unreachable.
192 193 194 195 196 |
# File 'app/concerns/models/party_addresses.rb', line 192 def store catalog.store rescue StandardError nil end |
#street1 ⇒ String?
Returns first address street line 1.
89 90 91 |
# File 'app/concerns/models/party_addresses.rb', line 89 def street1 first_address&.street1 end |
#street2 ⇒ String?
Returns first address street line 2.
94 95 96 |
# File 'app/concerns/models/party_addresses.rb', line 94 def street2 first_address&.street2 end |
#street3 ⇒ String?
Returns first address street line 3.
99 100 101 |
# File 'app/concerns/models/party_addresses.rb', line 99 def street3 first_address&.street3 end |
#timezone ⇒ ActiveSupport::TimeZone?
Timezone from the party's timezone_name column. Reports a warning to
AppSignal when the name is not a valid TZInfo identifier.
144 145 146 147 148 |
# File 'app/concerns/models/party_addresses.rb', line 144 def timezone ActiveSupport::TimeZone.find_tzinfo(timezone_name) rescue TZInfo::InvalidTimezoneIdentifier ErrorReporting.warning("Invalid timezone #{timezone_name} for party id #{id}") end |
#unique_addresses(include_address_id = nil) ⇒ Array<Address>
Returns the party's addresses deduplicated by full address value,
ordered by street1.
44 45 46 47 48 49 50 51 52 53 |
# File 'app/concerns/models/party_addresses.rb', line 44 def unique_addresses(include_address_id = nil) all_addresses = addresses.order(:street1) res = [] all_addresses.each do |address| (res << address) && next if address.id == include_address_id res << address unless res.any?(address) end res end |
#visit_data(attribute) ⇒ Object?
Reads an attribute off the most recent visit.
175 176 177 |
# File 'app/concerns/models/party_addresses.rb', line 175 def visit_data(attribute) most_recent_visit.try(attribute.to_sym) end |
#visit_location ⇒ String?
Location summary geolocated from the most recent visit.
160 161 162 |
# File 'app/concerns/models/party_addresses.rb', line 160 def visit_location most_recent_visit&.location_summary end |
#zip ⇒ String?
Zip/postal code from the first address, falling back to the most
recent visit's geolocated postal code.
84 85 86 |
# File 'app/concerns/models/party_addresses.rb', line 84 def zip first_address&.zip_compact || visit_data(:postal_code) end |