Class: Address
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Address
- Includes:
- Comparable, Models::Auditable, Models::LiquidMethods, PgSearch::Model
- Defined in:
- app/models/address.rb
Overview
== Schema Information
Table name: addresses
Database name: primary
id :integer not null, primary key
address_text :text
address_text_tsvector :tsvector
address_type :string(255)
city :string(255)
company_name_override :string(255)
country_iso3 :string(3)
county_code :string(255)
county_name :string(255)
description :string(255)
disable_address_correction :boolean
has_loading_dock :boolean
is_construction_site :boolean
is_placeholder :boolean default(FALSE), not null
is_residential :boolean default(TRUE), not null
is_store_mailing_address :boolean default(FALSE)
is_trade_show :boolean
is_warehouse :boolean default(FALSE)
jde_number :integer
lat :float
limited_access :boolean
lng :float
normalized_address :string
override_all_address_validation :boolean
person_name_override :string(255)
recipients_tsv :tsvector
region :string
require_signature_by_default :boolean default(FALSE), not null
requires_appointment :boolean
requires_inside_delivery :boolean
requires_liftgate :boolean
series_geocoded :boolean
service_area_mile_radius :integer
smartfit_available_updated_at :datetime default(2012-03-28 20:35:14.000000000 CDT -05:00), not null
state_code :string(20)
street1 :string(255)
street2 :string(255)
street3 :string(35)
supported_carriers :string(255) is an Array
supports_third_party_shipping :boolean
timezone_name :string
verified :boolean default(FALSE)
verified_for_shipping :boolean
zip :string(255)
created_at :datetime
updated_at :datetime
creator_id :integer
party_id :integer
updater_id :integer
Indexes
addresses_jde_number_index (jde_number)
addresses_party_id_index (party_id)
index_addresses_on_address_text_tsvector (address_text_tsvector) USING gin
index_addresses_on_country_iso3 (country_iso3)
index_addresses_on_county_code (county_code)
index_addresses_on_county_name (county_name)
index_addresses_on_lat_and_lng (lat,lng)
index_addresses_on_recipients_tsv (recipients_tsv) USING gin
index_addresses_on_state_code (state_code)
index_addresses_street1_like (street1)
index_addresses_zip_like (zip)
tsearch_city_idx (to_tsvector('english'::regconfig, (city)::text)) USING gin
tsearch_zip_idx (to_tsvector('english'::regconfig, (zip)::text)) USING gin
Foreign Keys
addresses_party_id_fk (party_id => parties.id) ON DELETE => nullify
fk_addresses_country_iso3 (country_iso3 => countries.iso3)
Defined Under Namespace
Classes: Creator, LineAbbreviator, NormalizedAddress, RecalculateShipping, Updater
Constant Summary collapse
- PO_BOX_REGEXP =
Po box regexp.
/[p|P]\s*[o|O]\s*[b|B]\s*[o|O]\s*[x|X]\s*[a-zA-Z0-9]*|\b[P|p]+(OST|ost|o|O)?\.?\s*[O|o0]+(ffice|FFICE)?\.?\s*[B|b][O|o0]?[X|x]+\.?\s+\#?(\d+)*(\D+)*\b|[c|C]\s*[p|P]\s*[0-9]/- MAX_STREET_FIELD_LENGTH =
Maximum street field length.
35- ADDRESS_FIELDS_FOR_GEOCODING =
Address fields for geocoding.
%w[street1 street2 street3 city state_code country_iso3 zip].freeze
- ADDRESS_FIELDS_TO_RECALCULATE_SHIPPING_FOR =
Address fields to recalculate shipping for.
(ADDRESS_FIELDS_FOR_GEOCODING + %w[is_residential require_signature_by_default]).freeze
- FREIGHT_FIELDS =
Recognised freight fields.
%w[has_loading_dock requires_liftgate requires_inside_delivery is_construction_site limited_access requires_appointment].freeze
Constants included from Models::Auditable
Models::Auditable::ALWAYS_IGNORED
Constants included from Models::Schedulable
Models::Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
-
#admin_mode ⇒ Object
Returns the value of attribute admin_mode.
-
#autocorrect_message ⇒ Object
Returns the value of attribute autocorrect_message.
-
#check_for_duplicates ⇒ Object
Returns the value of attribute check_for_duplicates.
-
#city ⇒ Object
readonly
Validates street1, city, country iso3.
-
#country_iso3 ⇒ Object
readonly
Validates street1, city, country iso3.
-
#do_not_accept_legacy_verified ⇒ Object
Returns the value of attribute do_not_accept_legacy_verified.
-
#require_carrier_validation ⇒ Object
Returns the value of attribute require_carrier_validation.
-
#set_default_billing_address ⇒ Object
Returns the value of attribute set_default_billing_address.
-
#set_default_mailing_address ⇒ Object
Returns the value of attribute set_default_mailing_address.
-
#set_default_shipping_address ⇒ Object
Returns the value of attribute set_default_shipping_address.
-
#skip_carrier_validation ⇒ Object
Returns the value of attribute skip_carrier_validation.
-
#state_code ⇒ Object
readonly
Validates state code, requires states or provinces.
-
#street1 ⇒ Object
readonly
Validates street1, city, country iso3.
-
#street2 ⇒ Object
readonly
Validates street1, street2, street3.
-
#street3 ⇒ Object
readonly
Validates street1, street2, street3.
-
#suggested_addresses ⇒ Object
Returns the value of attribute suggested_addresses.
-
#validate_with_carrier ⇒ Object
Returns the value of attribute validate_with_carrier.
Belongs to collapse
-
#country ⇒ Country
The country this record belongs to.
-
#party ⇒ Party?
The party this record belongs to.
-
#postal_code ⇒ PostalCode?
The postal code this record belongs to.
-
#state ⇒ State?
The state this record belongs to.
Methods included from Models::Auditable
Has one collapse
-
#billing_customer ⇒ Customer
Billing customer.
-
#locator_record ⇒ LocatorRecord
Locator record.
-
#mailing_customer ⇒ Customer
Mailing customer.
-
#mailing_store ⇒ Store
Mailing store.
-
#shipping_customer ⇒ Customer
Shipping customer.
-
#warehouse_store ⇒ Store
Warehouse store.
Has many collapse
-
#billing_credit_memos ⇒ ActiveRecord::Relation<CreditMemo>
Billing credit memos.
-
#billing_invoices ⇒ ActiveRecord::Relation<Invoice>
Billing invoices.
-
#billing_orders ⇒ ActiveRecord::Relation<Order>
Billing orders.
-
#mail_activities ⇒ ActiveRecord::Relation<MailActivity>
Mail activities.
-
#returned_rmas ⇒ ActiveRecord::Relation<Rma>
Returned rmas.
-
#service_jobs ⇒ ActiveRecord::Relation<ServiceJob>
Service jobs.
-
#shipping_account_numbers ⇒ ActiveRecord::Relation<ShippingAccountNumber>
Shipping account numbers.
-
#shipping_credit_memos ⇒ ActiveRecord::Relation<CreditMemo>
Shipping credit memos.
-
#shipping_invoices ⇒ ActiveRecord::Relation<Invoice>
Shipping invoices.
-
#shipping_orders ⇒ ActiveRecord::Relation<Order>
Shipping orders.
-
#shipping_quotes ⇒ ActiveRecord::Relation<Quote>
Shipping quotes.
-
#support_cases ⇒ ActiveRecord::Relation<SupportCase>
Support cases.
Class Method Summary collapse
-
.address_type_options ⇒ Object
Address type options.
-
.canada ⇒ ActiveRecord::Relation<Address>
A relation of Addresses that are canada.
-
.clear_geocoder_cache ⇒ Object
Clear geocoder cache.
-
.geocode_address_string(address_string) ⇒ Object
Geocode address string.
-
.is_warehouse ⇒ ActiveRecord::Relation<Address>
A relation of Addresses that are is warehouse.
-
.linked_to_party_or_order ⇒ ActiveRecord::Relation<Address>
A relation of Addresses that are linked to party or order.
-
.placeholder_address(country = 'USA') ⇒ Object
Placeholder address.
-
.populate_region ⇒ Object
Populates the region field based on the country and state code.
-
.usa ⇒ ActiveRecord::Relation<Address>
A relation of Addresses that are usa.
-
.warehouse_addresses ⇒ ActiveRecord::Relation<Address>
A relation of Addresses that are warehouse addresses.
Instance Method Summary collapse
-
#==(other) ⇒ Object
==.
-
#address_dropdown_format ⇒ Object
Address dropdown format.
-
#address_element_changed? ⇒ Boolean
Whether the record address element changed.
-
#address_element_changed_for_geocoding? ⇒ Boolean
Whether the record address element changed for geocoding.
-
#address_for_comparison ⇒ Object
Address for comparison.
-
#address_for_geocoder ⇒ Object
Address for geocoder.
-
#archiveable? ⇒ Boolean
Whether the record archiveable.
-
#belongs_to?(customer) ⇒ Boolean
INSTANCE METHODS.
-
#carrier_validation(autosave = false) ⇒ Object
Carrier validation.
-
#check_for_location_change ⇒ Object
Check for location change.
-
#company_name ⇒ Object
Company name.
-
#company_name=(value) ⇒ Object
Sets the company name.
-
#correct_to!(candidate, reason: nil) ⇒ Boolean
Applies a provider-verified AddressValidation::Candidate and persists it, skipping carrier re-validation (the candidate is already verified).
-
#correct_zip ⇒ Object
Correct zip.
-
#country_iso ⇒ Object
Country iso.
-
#country_iso=(val) ⇒ Object
Accessors when iso 2 character form is used.
-
#country_printable_name(locale: I18n.locale) ⇒ Object
Saves us a db call in 99.99% of cases.
-
#credit_line ⇒ Object
Credit line.
-
#data_hash ⇒ Object
Data hash.
-
#default_billing ⇒ Object
Default billing.
-
#default_billing=(new_value) ⇒ Object
Sets the default billing.
-
#default_mailing ⇒ Object
Default mailing.
-
#default_mailing=(new_value) ⇒ Object
Sets the default mailing.
-
#default_shipping ⇒ Object
Default shipping.
-
#default_shipping=(new_value) ⇒ Object
Sets the default shipping.
-
#dependents ⇒ Object
Dependents.
-
#destroy_or_unlink ⇒ Object
Destroy or unlink.
-
#determine_address_type ⇒ Object
Determine address type.
-
#distance_from(target_lat, target_lng) ⇒ Object
Distance from.
-
#do_not_save_if_warehouse ⇒ Object
Do not save if warehouse.
-
#editing_locked? ⇒ Boolean
Whether the record editing locked.
-
#external_validation_with_carrier(force = false) ⇒ Object
External validation with carrier.
-
#first_duplicate ⇒ Object
First duplicate.
-
#format_for_bread_billing ⇒ Object
Format for bread billing.
-
#format_for_bread_shipping ⇒ Object
Format for bread shipping.
-
#format_for_forte(use_iso = false) ⇒ Object
Format for forte.
-
#format_for_payment_gateway(use_iso = false) ⇒ Object
Format for payment gateway.
-
#format_for_paypal_api_invoice ⇒ Object
Format for paypal api invoice.
-
#format_for_paypal_invoice ⇒ Object
Format for paypal invoice.
-
#format_for_paypal_payment_gateway(use_iso = false) ⇒ Object
Format for paypal payment gateway.
-
#freight_fields_text ⇒ Object
Returns a string summarizing the freight fields set on the address.
-
#freight_fields_validation ⇒ Object
Freight fields validation.
-
#full_address(include_recipient = true, sep = '.', attn_override_flag = nil, hide_country = false, hide_street_2 = false) ⇒ Object
Full address.
-
#full_address_for_web ⇒ Object
Full address for web.
-
#geocode_me ⇒ Object
Geocodes the address by searching using Geocoder and sets the latitude, longitude and normalized address attributes on the model.
-
#has_freight_fields_defined? ⇒ Boolean
(also: #is_valid_for_freight?)
Whether the record has freight fields defined.
-
#has_postal_codes? ⇒ Boolean
Whether the record has postal codes.
-
#has_states_or_provinces? ⇒ Boolean
Whether the record has states or provinces.
-
#in_canada? ⇒ Boolean
Whether the record in canada.
-
#in_usa? ⇒ Boolean
Whether the record in usa.
-
#inherited_company_name ⇒ Object
Inherited company name.
-
#inherited_person_name ⇒ Object
Inherited person name.
-
#is_amazon? ⇒ Boolean
Whether the record is amazon.
-
#is_for_customer? ⇒ Boolean
Whether the record is for customer.
-
#is_for_supplier? ⇒ Boolean
Whether the record is for supplier.
-
#is_warehouse_and_disabled? ⇒ Boolean
Whether the record is warehouse and disabled.
-
#is_warehouse_by_distance? ⇒ Boolean
Whether the record is warehouse by distance.
-
#iso3166_country ⇒ Object
Iso3166 country.
-
#localized_address_format_array(include_recipient: true, with_country: true, attention_name: nil, attention_prepend: nil, name: nil, locale: I18n.locale) ⇒ Object
Returns an array of address lines formatted according to the address format for the country.
-
#lookup_timezone(store_timezone = false) ⇒ Object
Looks up the timezone using google api.
-
#name_and_address ⇒ Object
Name and address.
-
#north_america? ⇒ Boolean
Whether the record north america.
-
#not_a_po_box?(carrier = nil) ⇒ Boolean
Whether the record not a po box.
-
#ok_to_delete? ⇒ Boolean
Whether the record ok to delete.
-
#one_time_only ⇒ Object
One time only.
-
#person_name ⇒ Object
Person name.
-
#person_name=(value) ⇒ Object
Sets the person name.
-
#po_box? ⇒ Boolean
An address is defined as a PO box if all its address components matches the PO box regexp Ex.
-
#po_box_carriers ⇒ Object
Po box carriers.
-
#postal_carrier ⇒ Object
Postal carrier.
-
#postal_compact ⇒ Object
Postal compact.
-
#recalc_tax_on_open_orders ⇒ Object
Recalc tax on open orders.
-
#recipient ⇒ Object
Recipient.
-
#render_to(options = {}) ⇒ void
Renders each line of the address to the given block.
-
#requires_states_or_provinces? ⇒ Boolean
Whether the record requires states or provinces.
-
#same_as(address) ⇒ Object
Same as.
-
#search_text ⇒ Object
Search text.
-
#set_freight_field_defaults ⇒ Object
Set freight field defaults.
-
#state_codes_list ⇒ Object
State codes list.
-
#state_present_and_has_states_or_provinces? ⇒ Boolean
Whether the record state present and has states or provinces.
-
#states_for_select ⇒ Object
States for select.
-
#temporary? ⇒ Boolean
Whether the record temporary.
-
#text_block(with_recipient = false, with_country = false, phone = nil) ⇒ Object
Text block.
-
#timezone ⇒ Object
Returns a timezone object or look it up and store.
-
#timezones_for_select ⇒ Object
Timezones for select.
-
#to_array(include_recipient: true, with_country: true, attention_name: nil, attention_prepend: nil, name: nil, upcase: false, phone: nil, email: nil, address_type: false, extra_data: nil, locale: I18n.locale) ⇒ Object
Returns an array of address lines formatted according to the options passed in.
-
#to_s(params = {}) ⇒ String
String representation of the record.
-
#unlink ⇒ Object
Unlink.
-
#update_party_timezone ⇒ Object
Update party timezone.
-
#via_json ⇒ Object
Via json.
-
#via_json=(x) ⇒ Object
Sets the via json.
-
#via_xml ⇒ Object
Via xml.
-
#via_xml=(x) ⇒ Object
Sets the via xml.
-
#zip_5 ⇒ Object
Zip 5.
-
#zip_compact ⇒ Object
Zip compact.
-
#zip_state_consistent? ⇒ Boolean?
Cheap, offline check that the ZIP and state agree, using the PostalCode cache (self-healing) for the US and the FSA first-letter map for Canada.
Methods included from Models::Auditable
#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record
Methods inherited from ApplicationRecord
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
Methods included from Models::Schedulable
Methods included from Models::AfterCommittable
Methods included from Models::EventPublishable
Instance Attribute Details
#admin_mode ⇒ Object
Returns the value of attribute admin_mode.
99 100 101 |
# File 'app/models/address.rb', line 99 def admin_mode @admin_mode end |
#autocorrect_message ⇒ Object
Returns the value of attribute autocorrect_message.
99 100 101 |
# File 'app/models/address.rb', line 99 def @autocorrect_message end |
#check_for_duplicates ⇒ Object
Returns the value of attribute check_for_duplicates.
99 100 101 |
# File 'app/models/address.rb', line 99 def check_for_duplicates @check_for_duplicates end |
#city ⇒ Object (readonly)
Validates street1, city, country iso3.
Validations:
155 |
# File 'app/models/address.rb', line 155 validates :street1, :city, :country_iso3, presence: true |
#country_iso3 ⇒ Object (readonly)
Validates street1, city, country iso3.
Validations:
155 |
# File 'app/models/address.rb', line 155 validates :street1, :city, :country_iso3, presence: true |
#do_not_accept_legacy_verified ⇒ Object
Returns the value of attribute do_not_accept_legacy_verified.
99 100 101 |
# File 'app/models/address.rb', line 99 def do_not_accept_legacy_verified @do_not_accept_legacy_verified end |
#require_carrier_validation ⇒ Object
Returns the value of attribute require_carrier_validation.
99 100 101 |
# File 'app/models/address.rb', line 99 def require_carrier_validation @require_carrier_validation end |
#set_default_billing_address ⇒ Object
Returns the value of attribute set_default_billing_address.
99 100 101 |
# File 'app/models/address.rb', line 99 def set_default_billing_address @set_default_billing_address end |
#set_default_mailing_address ⇒ Object
Returns the value of attribute set_default_mailing_address.
99 100 101 |
# File 'app/models/address.rb', line 99 def set_default_mailing_address @set_default_mailing_address end |
#set_default_shipping_address ⇒ Object
Returns the value of attribute set_default_shipping_address.
99 100 101 |
# File 'app/models/address.rb', line 99 def set_default_shipping_address @set_default_shipping_address end |
#skip_carrier_validation ⇒ Object
Returns the value of attribute skip_carrier_validation.
99 100 101 |
# File 'app/models/address.rb', line 99 def skip_carrier_validation @skip_carrier_validation end |
#state_code ⇒ Object (readonly)
Validates state code, requires states or provinces.
Validations:
157 |
# File 'app/models/address.rb', line 157 validates :state_code, presence: { if: :requires_states_or_provinces? } |
#street1 ⇒ Object (readonly)
Validates street1, city, country iso3.
Validations:
- Presence
- Length ({ maximum: MAX_STREET_FIELD_LENGTH, too_long: "is too long (maximum is #{MAX_STREET_FIELD_LENGTH} characters, you may need to DISABLE address correction)" })
155 |
# File 'app/models/address.rb', line 155 validates :street1, :city, :country_iso3, presence: true |
#street2 ⇒ Object (readonly)
Validates street1, street2, street3.
Validations:
- Length ({ maximum: MAX_STREET_FIELD_LENGTH, too_long: "is too long (maximum is #{MAX_STREET_FIELD_LENGTH} characters, you may need to DISABLE address correction)" })
162 163 |
# File 'app/models/address.rb', line 162 validates :street1, :street2, :street3, length: { maximum: MAX_STREET_FIELD_LENGTH, too_long: "is too long (maximum is #{MAX_STREET_FIELD_LENGTH} characters, you may need to DISABLE address correction)" } |
#street3 ⇒ Object (readonly)
Validates street1, street2, street3.
Validations:
- Length ({ maximum: MAX_STREET_FIELD_LENGTH, too_long: "is too long (maximum is #{MAX_STREET_FIELD_LENGTH} characters, you may need to DISABLE address correction)" })
162 163 |
# File 'app/models/address.rb', line 162 validates :street1, :street2, :street3, length: { maximum: MAX_STREET_FIELD_LENGTH, too_long: "is too long (maximum is #{MAX_STREET_FIELD_LENGTH} characters, you may need to DISABLE address correction)" } |
#suggested_addresses ⇒ Object
Returns the value of attribute suggested_addresses.
99 100 101 |
# File 'app/models/address.rb', line 99 def suggested_addresses @suggested_addresses end |
#validate_with_carrier ⇒ Object
Returns the value of attribute validate_with_carrier.
99 100 101 |
# File 'app/models/address.rb', line 99 def validate_with_carrier @validate_with_carrier end |
Class Method Details
.address_type_options ⇒ Object
Address type options.
283 284 285 286 287 288 |
# File 'app/models/address.rb', line 283 def self. [['Residential', 'residential'], ['Commercial Building with Receiving Dock', 'commercial_building_with_receiving_dock'], ['Commercial Building without Receiving Dock', 'commercial_building_without_receiving_dock'], ['Construction Site/Limited Access', 'construction_site']] end |
.canada ⇒ ActiveRecord::Relation<Address>
A relation of Addresses that are canada. Active Record Scope
187 |
# File 'app/models/address.rb', line 187 scope :canada, -> { where(country_iso3: 'CAN') } |
.clear_geocoder_cache ⇒ Object
Clear geocoder cache.
222 223 224 225 |
# File 'app/models/address.rb', line 222 def self.clear_geocoder_cache # Queue all our locator address for geocoding Geocoder::Lookup.get(:google).cache.expire(:all) end |
.geocode_address_string(address_string) ⇒ Object
Geocode address string.
922 923 924 925 926 927 928 929 |
# File 'app/models/address.rb', line 922 def self.geocode_address_string(address_string) # aargh deal with &&^%^&% new Geocoder issue where it return no results when space is skipped in Canadian postal codes address_string = "#{address_string[0..2]} #{address_string[3..5]}" if address_string && (address_string.length == 6) results = Geocoder.search(address_string) return unless (geo = results.first) [geo.latitude, geo.longitude] end |
.is_warehouse ⇒ ActiveRecord::Relation<Address>
A relation of Addresses that are is warehouse. Active Record Scope
185 |
# File 'app/models/address.rb', line 185 scope :is_warehouse, -> { where(is_warehouse: true) } |
.linked_to_party_or_order ⇒ ActiveRecord::Relation<Address>
A relation of Addresses that are linked to party or order. Active Record Scope
188 189 190 191 192 193 194 195 196 |
# File 'app/models/address.rb', line 188 scope :linked_to_party_or_order, -> { where(%{exists(select 1 from parties where addresses.party_id is not null and parties.id = addresses.party_id and parties.type IN ('Customer','Contact')) OR exists(select 1 from orders where orders.shipping_address_id = addresses.id) }) } |
.placeholder_address(country = 'USA') ⇒ Object
Placeholder address.
273 274 275 |
# File 'app/models/address.rb', line 273 def self.placeholder_address(country = 'USA') Address.find_by(is_placeholder: true, country_iso3: country) end |
.populate_region ⇒ Object
Populates the region field based on the country and state code.
1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 |
# File 'app/models/address.rb', line 1388 def self.populate_region Address.transaction do %w[US CA].each do |iso| ic = ISO3166::Country[iso] ic.subdivisions.each do |state_code, sub| n = sub.name Address.where(country_iso3: ic.alpha3, state_code: state_code, region: nil).update_all(region: n) end end # Now for the stragglers Address.where(region: nil).where.not(country_iso3: nil).where.not(state_code: nil).find_each do |a| next unless (ic = a.iso3166_country) next unless (sub = ic.find_subdivision_by_name(a.state_code)) a.update_columns(region: sub.name, state_code: sub.code) end end end |
.usa ⇒ ActiveRecord::Relation<Address>
A relation of Addresses that are usa. Active Record Scope
186 |
# File 'app/models/address.rb', line 186 scope :usa, -> { where(country_iso3: 'USA') } |
.warehouse_addresses ⇒ ActiveRecord::Relation<Address>
A relation of Addresses that are warehouse addresses. Active Record Scope
184 |
# File 'app/models/address.rb', line 184 scope :warehouse_addresses, -> { where(is_warehouse: true) } |
Instance Method Details
#==(other) ⇒ Object
==.
416 417 418 419 420 |
# File 'app/models/address.rb', line 416 def ==(other) return false unless other.is_a?(Address) same_as(other) end |
#address_dropdown_format ⇒ Object
Address dropdown format.
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 |
# File 'app/models/address.rb', line 546 def address_dropdown_format address = [] address << street1.presence address << street2.presence address << street3.presence address << city.presence address << "#{state_code} #{zip}" address << country_iso3 address = address.uniq.compact if Party.where(mailing_address_id: id).present? { id: id, text: "#{address.join(', ')} ---> (MAILING)" } elsif Party.where(billing_address_id: id).present? { id: id, text: "#{address.join(', ')} ---> (BILLING)" } elsif Party.where(shipping_address_id: id).present? { id: id, text: "#{address.join(', ')} ---> (SHIPPING)" } else { id: id, text: "#{address.join(', ')} ---> (OTHER)" } end end |
#address_element_changed? ⇒ Boolean
Returns whether the record address element changed.
1148 1149 1150 |
# File 'app/models/address.rb', line 1148 def address_element_changed? (ADDRESS_FIELDS_TO_RECALCULATE_SHIPPING_FOR + FREIGHT_FIELDS).any? { |f| changes[f] || saved_changes[f] } end |
#address_element_changed_for_geocoding? ⇒ Boolean
Returns whether the record address element changed for geocoding.
1153 1154 1155 |
# File 'app/models/address.rb', line 1153 def address_element_changed_for_geocoding? ADDRESS_FIELDS_FOR_GEOCODING.any? { |f| changes[f] || saved_changes[f] } end |
#address_for_comparison ⇒ Object
Address for comparison.
575 576 577 578 |
# File 'app/models/address.rb', line 575 def address_for_comparison # here we can sometimes get Null, NULL, null, etc. from some services for an address field, also replace common abbreviations with a standard set to_array(upcase: true, include_recipient: :overrides) end |
#address_for_geocoder ⇒ Object
Address for geocoder.
568 569 570 571 572 |
# File 'app/models/address.rb', line 568 def address_for_geocoder addr = [street1, street2, city, state&.name || state_code, zip, country&.name] addr = addr.map(&:to_s).map(&:squish).filter_map(&:presence) addr.join(',') end |
#archiveable? ⇒ Boolean
Returns whether the record archiveable.
1203 1204 1205 |
# File 'app/models/address.rb', line 1203 def archiveable? billing_customer.nil? && shipping_customer.nil? && mailing_customer.nil? end |
#belongs_to?(customer) ⇒ Boolean
INSTANCE METHODS
333 334 335 336 |
# File 'app/models/address.rb', line 333 def belongs_to?(customer) (party_id == customer.id) || shipping_orders.find { |o| o.customer_id == customer.id } end |
#billing_credit_memos ⇒ ActiveRecord::Relation<CreditMemo>
Billing credit memos.
134 |
# File 'app/models/address.rb', line 134 has_many :billing_credit_memos, class_name: 'CreditMemo', foreign_key: :billing_address_id |
#billing_customer ⇒ Customer
Billing customer.
114 |
# File 'app/models/address.rb', line 114 has_one :billing_customer, class_name: 'Customer', dependent: :nullify, foreign_key: :billing_address_id, inverse_of: :billing_address |
#billing_invoices ⇒ ActiveRecord::Relation<Invoice>
Billing invoices.
130 |
# File 'app/models/address.rb', line 130 has_many :billing_invoices, class_name: 'Invoice', foreign_key: :billing_address_id |
#billing_orders ⇒ ActiveRecord::Relation<Order>
Billing orders.
126 |
# File 'app/models/address.rb', line 126 has_many :billing_orders, class_name: 'Order', foreign_key: :billing_address_id |
#carrier_validation(autosave = false) ⇒ Object
Carrier validation.
1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 |
# File 'app/models/address.rb', line 1112 def carrier_validation(autosave = false) # puts "!!!!!!!!!!!!!carrier_validation" return false, errors_to_s, [] if errors.any? if is_warehouse || override_all_address_validation return true, (is_warehouse ? 'Address is warehouse' : 'Address is marked override all validation'), [] end require 'wy_shipping' result = WyShipping.valid_address?(self) logger.info "External Validation with Carrier result #{result[:valid_address]}:#{result[:status_message]}." ErrorReporting.error("Carrier validation params missing. 'valid_address' not present. Result params: #{result}") if result[:valid_address].nil? res = result[:valid_address] if res == true && is_residential == true && # be conservative here and tend to residential unless all suggested addressed say address_residential_indicator 'no' result[:suggested_address_hashes].all? do |ah| ah['address_residential_indicator'] == 'no' end res = true self.is_residential = false self. = 'Address was AUTOCORRECTED, from residential to commercial.' logger.info 'Adjusting address marking it residential false because carrier says so.' elsif res == true && is_residential == false && # be conservative here and tend to residential if any suggested addressed say address_residential_indicator 'yes' result[:suggested_address_hashes].any? do |ah| ah['address_residential_indicator'] == 'yes' end res = true self.is_residential = true self. = 'Address was AUTOCORRECTED, from commercial to residential.' logger.info "External Validation with Carrier result #{result[:valid_address]}:#{result[:status_message]}." logger.info 'Adjusting address marking it residential true because carrier says so.' end self.verified_for_shipping = res save if verified_for_shipping && autosave [res, result[:status_message], result[:suggested_address_hashes] || []] end |
#check_for_location_change ⇒ Object
Check for location change.
318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'app/models/address.rb', line 318 def check_for_location_change return unless party && lat && lng && (saved_change_to_lat? || saved_change_to_lng?) Rails.configuration.event_store.publish( Events::LocationChanged.new(data: { party_id: party.id, latitude: lat, longitude: lng }), stream_name: "Party-#{party.id}" ) end |
#company_name ⇒ Object
Company name.
1192 1193 1194 |
# File 'app/models/address.rb', line 1192 def company_name company_name_override.presence || inherited_company_name end |
#company_name=(value) ⇒ Object
Sets the company name.
1198 1199 1200 |
# File 'app/models/address.rb', line 1198 def company_name=(value) self.company_name_override = value unless inherited_company_name && value =~ /inherited_company_name/i end |
#correct_to!(candidate, reason: nil) ⇒ Boolean
Applies a provider-verified AddressValidation::Candidate and persists it,
skipping carrier re-validation (the candidate is already verified). Audited
via PaperTrail. Mirrors the autocorrect formatting used by
#external_validation_with_carrier.
259 260 261 262 263 264 265 266 267 268 269 |
# File 'app/models/address.rb', line 259 def correct_to!(candidate, reason: nil) self.street1 = I18n.transliterate(candidate.street1.to_s).upcase.presence || street1 self.city = I18n.transliterate(candidate.city.to_s).upcase.presence || city self.state_code = candidate.state_code.presence || state_code self.zip = candidate.zip.presence || zip self.is_residential = candidate.residential unless candidate.residential.nil? self.verified_for_shipping = true self.skip_carrier_validation = true self. = reason if reason save! end |
#correct_zip ⇒ Object
Correct zip.
228 229 230 |
# File 'app/models/address.rb', line 228 def correct_zip ValidatesZipcode.valid?(zip, country_iso) if has_postal_codes? end |
#country ⇒ Country
Returns the country this record belongs to.
108 |
# File 'app/models/address.rb', line 108 belongs_to :country, foreign_key: 'country_iso3', primary_key: 'iso3' |
#country_iso ⇒ Object
Country iso.
379 380 381 |
# File 'app/models/address.rb', line 379 def country_iso iso3166_country&.alpha2 end |
#country_iso=(val) ⇒ Object
Accessors when iso 2 character form is used
374 375 376 |
# File 'app/models/address.rb', line 374 def country_iso=(val) self.country_iso3 = ISO3166::Country[val]&.alpha3 end |
#country_printable_name(locale: I18n.locale) ⇒ Object
Saves us a db call in 99.99% of cases
874 875 876 877 |
# File 'app/models/address.rb', line 874 def country_printable_name(locale: I18n.locale) lang = locale.to_s.first(2).downcase iso3166_country.translation(lang) end |
#credit_line ⇒ Object
Credit line.
463 464 465 |
# File 'app/models/address.rb', line 463 def credit_line party&.has_terms? ? party.available_credit.to_i : 0 end |
#data_hash ⇒ Object
Data hash.
339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'app/models/address.rb', line 339 def data_hash hsh = { street1: street1, city: city, state: state&.name || state_code, zip: zip, country: country.iso } # only add street2 if it's present, otherwise you'll end up with a 'NULL' string hsh[:street2] = street2 if street2.present? hsh end |
#default_billing ⇒ Object
Default billing.
491 492 493 |
# File 'app/models/address.rb', line 491 def default_billing party && party.id.present? && (party.billing_address_id == id) end |
#default_billing=(new_value) ⇒ Object
Sets the default billing.
498 499 500 |
# File 'app/models/address.rb', line 498 def default_billing=(new_value) self.set_default_billing_address = true if new_value.to_b end |
#default_mailing ⇒ Object
Default mailing.
468 469 470 |
# File 'app/models/address.rb', line 468 def default_mailing party&.id.present? && (party.mailing_address_id == id) end |
#default_mailing=(new_value) ⇒ Object
Sets the default mailing.
486 487 488 |
# File 'app/models/address.rb', line 486 def default_mailing=(new_value) self.set_default_mailing_address = true if new_value.to_b end |
#default_shipping ⇒ Object
Default shipping.
503 504 505 |
# File 'app/models/address.rb', line 503 def default_shipping party && party.id.present? && (party.shipping_address_id == id) end |
#default_shipping=(new_value) ⇒ Object
Sets the default shipping.
510 511 512 |
# File 'app/models/address.rb', line 510 def default_shipping=(new_value) self.set_default_shipping_address = true if new_value.to_b end |
#dependents ⇒ Object
Dependents.
690 691 692 693 694 695 696 697 698 699 700 701 702 |
# File 'app/models/address.rb', line 690 def dependents deps = [] deps += shipping_orders deps << billing_customer deps += shipping_quotes deps += shipping_account_numbers deps += mail_activities deps += billing_invoices deps += shipping_invoices deps += billing_credit_memos deps += shipping_credit_memos deps.uniq.compact end |
#destroy_or_unlink ⇒ Object
Destroy or unlink.
1208 1209 1210 1211 1212 1213 1214 |
# File 'app/models/address.rb', line 1208 def destroy_or_unlink if ok_to_delete? destroy else unlink end end |
#determine_address_type ⇒ Object
Determine address type.
291 292 293 294 295 296 297 298 299 300 301 302 303 |
# File 'app/models/address.rb', line 291 def determine_address_type return unless persisted? if is_residential 'residential' elsif is_construction_site 'construction_site' elsif has_loading_dock 'commercial_building_with_receiving_dock' elsif requires_liftgate 'commercial_building_without_receiving_dock' end end |
#distance_from(target_lat, target_lng) ⇒ Object
Distance from.
410 411 412 |
# File 'app/models/address.rb', line 410 def distance_from(target_lat, target_lng) Geocoder::Calculations.distance_between([lat, lng], [target_lat, target_lng]) end |
#do_not_save_if_warehouse ⇒ Object
Do not save if warehouse.
951 952 953 954 955 |
# File 'app/models/address.rb', line 951 def do_not_save_if_warehouse return unless is_warehouse? && changed? && !admin_mode.to_b errors.add(:is_warehouse, 'Warehouse addresses cannot be modified outside of admin console.') end |
#editing_locked? ⇒ Boolean
Returns whether the record editing locked.
384 385 386 |
# File 'app/models/address.rb', line 384 def editing_locked? shipping_orders.any?(&:editing_locked?) || support_cases.any?(&:editing_locked?) end |
#external_validation_with_carrier(force = false) ⇒ Object
External validation with carrier.
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 |
# File 'app/models/address.rb', line 1001 def external_validation_with_carrier(force = false) return false if errors.present? # Don't bother hitting the server if we have other errors self.require_carrier_validation = require_carrier_validation.to_b # Make sure we interpret all flavors to boolean # Not checking for address change to justify this expensive validation causes horrendous performance *any* time this address is verified - CB11/4 self.verified_for_shipping = false if address_element_changed? || disable_address_correction_changed? || override_all_address_validation_changed? return true if override_all_address_validation || (!do_not_accept_legacy_verified && verified) || (disable_address_correction || (!require_carrier_validation && !force)) return true if verified_for_shipping logger.info "External Validation with Carrier called for #{id}. require_carrier_validation(#{require_carrier_validation}), previous verified_for_shipping(#{verified_for_shipping})" matches = Address.where(street1: street1) .where(street2: street2) .where(city: city) .where(state_code: state_code) .where(zip: zip) .where(country_iso3: country_iso3) .where(verified_for_shipping: true) .where.not(id: id).limit(1) if matches.present? logger.info 'Address External Validation with Carrier: Found matching address in system' self.verified_for_shipping = true return true end res, , suggested_address_hashes = carrier_validation if res && (suggested_address_hashes&.length == 1) && ((a = suggested_address_hashes.first)[:address].to_s.length > 1) && (a[:address].to_s.length <= MAX_STREET_FIELD_LENGTH) # One address, auto fix old_address = to_s(include_recipient: false, with_country: false, address_type: true) a = suggested_address_hashes.first self.street1 = I18n.transliterate(a[:address].to_s).upcase self.street2 = a[:address2] || street2 # here nil means use what was entered since we don't validate apartments, suites etc self.street3 = a[:address3] || street3 # here nil means use what was entered since we don't validate apartments, suites etc self.city = I18n.transliterate(a[:city].to_s).upcase self.state_code = a[:state] self.zip = a[:zip] self.is_residential = a[:is_residential].present? # If null or false it will be false, otherwise true self.verified_for_shipping = true # self.disable_address_correction = true unless changed? self. = "Address was AUTOCORRECTED, FROM: #{old_address}, TO: #{to_s(include_recipient: false, with_country: false, address_type: true)}." end elsif suggested_address_hashes&.length&.> 1 self.suggested_addresses = suggested_address_hashes.map do |a| # This will do two things, first remove the address validation attributes that are not understood by address and convert all symbols to strings for merging into the attributes new_addr_attr = {} new_addr_attr['street1'] = I18n.transliterate(a[:address].to_s).upcase new_addr_attr['street2'] = a[:address2] || street2 # here nil means use what was entered since we don't validate apartments, suites etc new_addr_attr['street3'] = a[:address3] || street3 # here nil means use what was entered since we don't validate apartments, suites etc new_addr_attr['city'] = I18n.transliterate(a[:city].to_s).upcase new_addr_attr['state_code'] = a[:state] new_addr_attr['zip'] = a[:zip] new_addr_attr['is_residential'] = a[:is_residential].present? new_addr = dup new_addr.attributes = new_addr.attributes.merge(new_addr_attr) new_addr.id = id # Because if this is used it will replace it, the dup/cloning doesn't copy this attribute. new_addr.verified_for_shipping = true # No need to double validate this address if it gets selected # new_addr.disable_address_correction = true new_addr.check_for_duplicates = true # will need to verify this is not a duplicate new_addr end end self.verified_for_shipping = res unless res errors.add(:base, "We could not validate your address. Please check that your address is correct. If you want to skip validation, please check the 'Disable Address Correction' checkbox when editing the address. #{}") end res end |
#first_duplicate ⇒ Object
First duplicate.
1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 |
# File 'app/models/address.rb', line 1255 def first_duplicate dupe_id = nil if party_id Address.where(party_id: party_id).where.not(id: id.to_i).find_each do |a| logger.info "Address - Comparing #{id} with address id #{a.id}" if a == self dupe_id = a.id break end end end dupe_id end |
#format_for_bread_billing ⇒ Object
Format for bread billing.
671 672 673 674 675 676 677 678 679 680 681 682 |
# File 'app/models/address.rb', line 671 def format_for_bread_billing names = (person_name || company_name).split { fullName: person_name || company_name, firstName: names.first, lastName: names.last, address: street1, address2: street2, city: city, state: state_code, zip: zip, email: party&.email } end |
#format_for_bread_shipping ⇒ Object
Format for bread shipping.
658 659 660 661 662 663 664 665 666 667 668 |
# File 'app/models/address.rb', line 658 def format_for_bread_shipping names = (person_name || company_name).split { fullName: person_name || company_name, firstName: names.first, lastName: names.last, address: street1, address2: street2, city: city, state: state_code, zip: zip } end |
#format_for_forte(use_iso = false) ⇒ Object
Format for forte.
622 623 624 625 626 627 628 629 630 631 632 633 634 635 |
# File 'app/models/address.rb', line 622 def format_for_forte(use_iso = false) names = (person_name || company_name).split { name: person_name || company_name, first_name: names.first, last_name: names.last, company_name: company_name || person_name, address1: street1, address2: street2, city: city, state: state_code, zip: zip, country: (use_iso ? country.iso : country.iso3), shipping_address_type: is_residential? ? 'residential' : 'commercial' } end |
#format_for_payment_gateway(use_iso = false) ⇒ Object
Format for payment gateway.
596 597 598 599 600 601 602 603 604 605 |
# File 'app/models/address.rb', line 596 def format_for_payment_gateway(use_iso = false) { name: person_name || company_name, address1: street1, address2: street2, city: city, state: state&.name || state_code, zip: zip, phone: party&.phone, country: (use_iso ? country.iso : country.iso3) } end |
#format_for_paypal_api_invoice ⇒ Object
Format for paypal api invoice.
648 649 650 651 652 653 654 655 |
# File 'app/models/address.rb', line 648 def format_for_paypal_api_invoice { line1: street1, line2: street2, city: city, state: state_code, postal_code: zip, country_code: country.iso } end |
#format_for_paypal_invoice ⇒ Object
Format for paypal invoice.
638 639 640 641 642 643 644 645 |
# File 'app/models/address.rb', line 638 def format_for_paypal_invoice { line1: street1, line2: street2, city: city, state: state_code, postalCode: zip, countryCode: country.iso } end |
#format_for_paypal_payment_gateway(use_iso = false) ⇒ Object
Format for paypal payment gateway.
609 610 611 612 613 614 615 616 617 618 |
# File 'app/models/address.rb', line 609 def format_for_paypal_payment_gateway(use_iso = false) { name: person_name || company_name, address1: street1, address2: street2, city: city, state: state_code, zip: zip, phone: party&.phone, country: (use_iso ? country.iso : country.iso3) } end |
#freight_fields_text ⇒ Object
Returns a string summarizing the freight fields set on the address.
Joins freight field values like 'requires liftgate', 'limited access'
into a comma-separated string. Handles defaults like require signature.
856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 |
# File 'app/models/address.rb', line 856 def freight_fields_text freight_fields_text = nil freight_fields_text_arr = [] freight_fields_text_arr << 'require signature by default' if require_signature_by_default? if has_freight_fields_defined? freight_fields_text_arr << 'has loading dock' if has_loading_dock? freight_fields_text_arr << 'requires inside delivery' if requires_inside_delivery? freight_fields_text_arr << 'requires lift-gate' if requires_liftgate? freight_fields_text_arr << 'is construction site' if is_construction_site? freight_fields_text_arr << 'limited_access' if limited_access? freight_fields_text_arr << 'requires appointment' if requires_appointment? freight_fields_text = freight_fields_text_arr.join(', ') end freight_fields_text end |
#freight_fields_validation ⇒ Object
Freight fields validation.
958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 |
# File 'app/models/address.rb', line 958 def freight_fields_validation return false if errors.present? # Don't bother hitting the server if we have other errors logger.info "freight_fields_validation called for #{id}. previous verified_for_shipping (#{verified_for_shipping})" # Not checking for address change to justify this expensive validation causes horrendous performance *any* time this address is verified - CB11/4 self.verified_for_shipping = false if address_element_changed? || override_all_address_validation_changed? return true if override_all_address_validation return true if verified_for_shipping logger.info "freight_fields_validation called for #{id}. verified_for_shipping (#{verified_for_shipping})" res = true if is_residential && (has_loading_dock || is_trade_show) res = false errors.add(:is_residential, "Residential addresses generally speaking can't have loading docks. If this is *really* the case then please check the 'override all address validation' checkbox.") end if is_construction_site && requires_inside_delivery res = false errors.add(:is_construction_site, "Construction sites (ie unbuilt yet) generally speaking can't require inside delivery. If this is *really* the case then please check the 'override all address validation' checkbox.") end if has_loading_dock && requires_liftgate res = false errors.add(:has_loading_dock, "Addresses generally speaking don't usually both have loading docks and require a liftgate. If this is *really* the case then please check the 'override all address validation' checkbox.") end res end |
#full_address(include_recipient = true, sep = '.', attn_override_flag = nil, hide_country = false, hide_street_2 = false) ⇒ Object
Full address.
530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
# File 'app/models/address.rb', line 530 def full_address(include_recipient = true, sep = '.', attn_override_flag = nil, hide_country = false, hide_street_2 = false) addr = [] if include_recipient addr << company_name.presence addr << (attn_override_flag || person_name.presence) end addr << street1.presence addr << street2.presence unless hide_street_2 addr << street3.presence addr << "#{city}, #{state_code} #{zip}" addr << country unless country_iso3 == 'USA' || hide_country addr = addr.uniq.compact addr.join(sep) end |
#full_address_for_web ⇒ Object
Full address for web.
520 521 522 |
# File 'app/models/address.rb', line 520 def full_address_for_web full_address(false, '<br>') end |
#geocode_me ⇒ Object
Geocodes the address by searching using Geocoder
and sets the latitude, longitude and normalized address
attributes on the model. Handles errors from the Geocoder gem.
934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 |
# File 'app/models/address.rb', line 934 def geocode_me results = Geocoder.search(address_for_geocoder) geo = results.first if geo logger.info "Geocoded address #{id} with lat:#{geo.latitude}, lng: #{geo.longitude}" self.lat = geo.latitude self.lng = geo.longitude na = [company_name_override.presence, person_name_override.presence, geo.formatted_address].compact.uniq.join(', ') self.normalized_address = na else logger.info "Geocoding failed on address #{id}, #{address_for_geocoder}" end rescue StandardError => e @logger.error " Geocoder error from address(id=#{id}) geocode_me, #{e} skipping" end |
#has_freight_fields_defined? ⇒ Boolean Also known as: is_valid_for_freight?
Returns whether the record has freight fields defined.
994 995 996 |
# File 'app/models/address.rb', line 994 def has_freight_fields_defined? FREIGHT_FIELDS.all? { |ff| !send(ff).nil? } end |
#has_postal_codes? ⇒ Boolean
Returns whether the record has postal codes.
731 732 733 |
# File 'app/models/address.rb', line 731 def has_postal_codes? iso3166_country&.postal_code end |
#has_states_or_provinces? ⇒ Boolean
Returns whether the record has states or provinces.
721 722 723 |
# File 'app/models/address.rb', line 721 def has_states_or_provinces? iso3166_country.subdivisions.present? end |
#in_canada? ⇒ Boolean
Returns whether the record in canada.
443 444 445 |
# File 'app/models/address.rb', line 443 def in_canada? country_iso3 == 'CAN' end |
#in_usa? ⇒ Boolean
Returns whether the record in usa.
448 449 450 |
# File 'app/models/address.rb', line 448 def in_usa? country_iso3 == 'USA' end |
#inherited_company_name ⇒ Object
Inherited company name.
1183 1184 1185 1186 1187 1188 1189 |
# File 'app/models/address.rb', line 1183 def inherited_company_name return unless party return if party.has_guest_name? return party.full_name if party.is_a?(Supplier) || party.is_a?(GroupAssociation) || party&.is_organization? party.customer.full_name if party.customer&.is_organization? end |
#inherited_person_name ⇒ Object
Inherited person name.
1158 1159 1160 1161 1162 1163 1164 |
# File 'app/models/address.rb', line 1158 def inherited_person_name return unless party return if party.has_guest_name? return unless party.is_person? party.full_name end |
#is_amazon? ⇒ Boolean
Returns whether the record is amazon.
278 279 280 |
# File 'app/models/address.rb', line 278 def is_amazon? company_name_override&.match?(/amazon/i) end |
#is_for_customer? ⇒ Boolean
Returns whether the record is for customer.
705 706 707 708 |
# File 'app/models/address.rb', line 705 def is_for_customer? # handle one time shipping address party.nil? is true party.nil? || party.instance_of?(Customer) || party.instance_of?(Supplier) end |
#is_for_supplier? ⇒ Boolean
Returns whether the record is for supplier.
711 712 713 |
# File 'app/models/address.rb', line 711 def is_for_supplier? party.instance_of?(Supplier) end |
#is_warehouse_and_disabled? ⇒ Boolean
Returns whether the record is warehouse and disabled.
1275 1276 1277 1278 1279 1280 1281 1282 |
# File 'app/models/address.rb', line 1275 def is_warehouse_and_disabled? res = false if is_warehouse? res = true if WAREHOUSE_PICKUP_DISABLED_US && country_iso3 == 'USA' res = true if WAREHOUSE_PICKUP_DISABLED_CA && country_iso3 == 'CAN' end res end |
#is_warehouse_by_distance? ⇒ Boolean
Returns whether the record is warehouse by distance.
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 |
# File 'app/models/address.rb', line 1285 def is_warehouse_by_distance? res = false if is_warehouse? res = true # trivial case else # find distance because there are like 86 instances of addresses that correspond to 300 Granton (aka CA warehouse) us_warehouse_address = Store.find(1).warehouse_address ca_warehouse_address = Store.find(2).warehouse_address distance_us = distance_from(us_warehouse_address.lat, us_warehouse_address.lng) distance_ca = distance_from(ca_warehouse_address.lat, ca_warehouse_address.lng) res = true if distance_us < 0.1 || distance_ca < 0.1 end res end |
#iso3166_country ⇒ Object
Iso3166 country.
479 480 481 |
# File 'app/models/address.rb', line 479 def iso3166_country ISO3166::Country.find_country_by_alpha3(country_iso3) end |
#localized_address_format_array(include_recipient: true, with_country: true, attention_name: nil, attention_prepend: nil, name: nil, locale: I18n.locale) ⇒ Object
Returns an array of address lines formatted according to the address format
for the country. Allows customizing included fields like recipient name,
street, city, etc.
755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 |
# File 'app/models/address.rb', line 755 def localized_address_format_array(include_recipient: true, with_country: true, attention_name: nil, attention_prepend: nil, name: nil, locale: I18n.locale) lang = locale.to_s.first(2).downcase address_format = iso3166_country&.address_format&.presence # Fallback to US format when iso3166 is not present address_format ||= "{{recipient}}\n{{street}}\n{{city}} {{region_short}} {{postalcode}}\n{{country}}" liquid_template = Liquid::ParseEnvironment.parse(address_format) recipient_names = [] if include_recipient == :overrides recipient_names << company_name_override recipient_names << person_name_override elsif include_recipient if company_name.present? name = attention_name || person_name name = "#{attention_prepend} #{name}" if name.present? && attention_prepend.present? recipient_names << company_name recipient_names << name else name = attention_name || name || person_name recipient_names << name end end = {} [:recipient] = recipient_names.filter_map(&:presence).uniq.join("\n") [:street] = [street1.presence, street2.presence, street3.presence].compact.join("\n") [:city] = city [:region] = region || state_code [:region_short] = state_code [:postalcode] = zip [:country] = with_country && iso3166_country ? iso3166_country.translation(lang) : '' address_text = Liquid::Renderer.render(liquid_template, , "Address(#{id})#localized_address_format_array") # Now split on new lines and remove empty lines address_text.split("\n").compact_blank end |
#locator_record ⇒ LocatorRecord
Locator record.
120 |
# File 'app/models/address.rb', line 120 has_one :locator_record, dependent: :destroy, inverse_of: :address |
#lookup_timezone(store_timezone = false) ⇒ Object
Looks up the timezone using google api. This requires lat / lng to be set
If the timezone returned is valid (sometime the api returns junk) then
the timezone object is returned. Pass true to store_timezone to record the timezone
upon lookup when missing without a callback
393 394 395 396 397 398 399 400 401 402 403 404 405 |
# File 'app/models/address.rb', line 393 def lookup_timezone(store_timezone = false) return unless lat && lng tz = begin Timezone.lookup(lat, lng) rescue StandardError nil end return unless PartyRecordTimezone.valid_timezone?(tz) update_column(:timezone_name, tz.name) if timezone_name != tz.name && store_timezone tz end |
#mail_activities ⇒ ActiveRecord::Relation<MailActivity>
Mail activities.
142 |
# File 'app/models/address.rb', line 142 has_many :mail_activities, class_name: 'MailActivity' |
#mailing_customer ⇒ Customer
Mailing customer.
118 |
# File 'app/models/address.rb', line 118 has_one :mailing_customer, class_name: 'Customer', dependent: :nullify, foreign_key: :mailing_address_id, inverse_of: :mailing_address |
#mailing_store ⇒ Store
Mailing store.
124 |
# File 'app/models/address.rb', line 124 has_one :mailing_store, class_name: 'Store', foreign_key: :mailing_address_id |
#name_and_address ⇒ Object
Name and address.
473 474 475 476 |
# File 'app/models/address.rb', line 473 def name_and_address [party.full_name, street1, street2, city, "#{state_code} #{zip}", iso3166_country.common_name].compact.uniq.join(', ') end |
#north_america? ⇒ Boolean
Returns whether the record north america.
736 737 738 |
# File 'app/models/address.rb', line 736 def north_america? %w[USA CAN MEX].include?(country_iso3) end |
#not_a_po_box?(carrier = nil) ⇒ Boolean
Returns whether the record not a po box.
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 |
# File 'app/models/address.rb', line 1075 def not_a_po_box?(carrier = nil) Rails.logger.debug { "not_a_po_box? carrier: #{carrier || 'nil'}" } carrier_is_not_postal = false carrier_is_not_postal = true if carrier && PO_BOX_CARRIERS.exclude?(carrier) && carrier.to_s.downcase.exclude?('post') && carrier.to_s.downcase.exclude?('usps') nil_carrier_and_we_do_not_support_postal_carrier = false nil_carrier_and_we_do_not_support_postal_carrier = true if carrier.nil? && (SUPPORTED_SHIPPING_CARRIERS[country_iso3.to_sym] || []).exclude?(postal_carrier) Rails.logger.debug { "not_a_po_box? carrier_is_not_postal: #{carrier_is_not_postal}" } Rails.logger.debug { "not_a_po_box? nil_carrier_and_we_do_not_support_postal_carrier: #{nil_carrier_and_we_do_not_support_postal_carrier}" } Rails.logger.debug { "not_a_po_box? po_box?: #{po_box?}" } if po_box? && (carrier_is_not_postal || nil_carrier_and_we_do_not_support_postal_carrier) errors.add(:base, "We can't ship to PO boxes unless the carrier is one of #{PO_BOX_CARRIERS.join(', ')}") false else true end end |
#ok_to_delete? ⇒ Boolean
Returns whether the record ok to delete.
685 686 687 |
# File 'app/models/address.rb', line 685 def ok_to_delete? dependents.empty? end |
#one_time_only ⇒ Object
One time only.
423 424 425 |
# File 'app/models/address.rb', line 423 def one_time_only party_id.nil? && !is_warehouse end |
#party ⇒ Party?
Returns the party this record belongs to.
106 |
# File 'app/models/address.rb', line 106 belongs_to :party, inverse_of: :addresses, optional: true |
#person_name ⇒ Object
Person name.
1167 1168 1169 |
# File 'app/models/address.rb', line 1167 def person_name person_name_override.presence || inherited_person_name end |
#person_name=(value) ⇒ Object
Sets the person name.
1174 1175 1176 1177 1178 1179 1180 |
# File 'app/models/address.rb', line 1174 def person_name=(value) self.person_name_override = if value.nil? || (inherited_person_name && value.casecmp?(inherited_person_name)) nil else value end end |
#po_box? ⇒ Boolean
An address is defined as a PO box if all its address components matches the PO box regexp
Ex. if address 1 is 123 main st and address 2 is PO BOX 10 it is not considered a PO box
but if address 1 is PO BOX 10 and there's no other street address then it is considered a PO Box
1095 1096 1097 |
# File 'app/models/address.rb', line 1095 def po_box? [street1, street2, street3].filter_map(&:presence).all? { |s| s =~ PO_BOX_REGEXP } end |
#po_box_carriers ⇒ Object
Po box carriers.
1100 1101 1102 |
# File 'app/models/address.rb', line 1100 def po_box_carriers PO_BOX_CARRIERS_BY_COUNTRY[country_iso3.to_sym] end |
#postal_carrier ⇒ Object
Postal carrier.
1105 1106 1107 1108 |
# File 'app/models/address.rb', line 1105 def postal_carrier postal_carriers = { USA: 'USPS', CAN: 'Canadapost' } postal_carriers[country_iso3.to_sym] end |
#postal_code ⇒ PostalCode?
Returns the postal code this record belongs to.
112 |
# File 'app/models/address.rb', line 112 belongs_to :postal_code, foreign_key: :zip, primary_key: :code, optional: true |
#postal_compact ⇒ Object
Postal compact.
438 439 440 |
# File 'app/models/address.rb', line 438 def postal_compact zip.to_s.scan(/\w/).join.first(6) end |
#recalc_tax_on_open_orders ⇒ Object
Recalc tax on open orders.
306 307 308 |
# File 'app/models/address.rb', line 306 def recalc_tax_on_open_orders shipping_orders.so_only.open_for_tax_update.each(&:refresh_tax_rate) end |
#recipient ⇒ Object
Recipient.
515 516 517 |
# File 'app/models/address.rb', line 515 def recipient company_name.presence || person_name end |
#render_to(options = {}) ⇒ void
This method returns an undefined value.
Renders each line of the address to the given block.
916 917 918 |
# File 'app/models/address.rb', line 916 def render_to( = {}, &) to_array(**).each(&) end |
#requires_states_or_provinces? ⇒ Boolean
Returns whether the record requires states or provinces.
716 717 718 |
# File 'app/models/address.rb', line 716 def requires_states_or_provinces? %w[USA CAN].include?(country_iso3) end |
#returned_rmas ⇒ ActiveRecord::Relation<Rma>
Returned rmas.
146 |
# File 'app/models/address.rb', line 146 has_many :returned_rmas, class_name: 'Rma', foreign_key: :return_shipping_address_id |
#same_as(address) ⇒ Object
Same as.
582 583 584 585 586 587 588 589 590 591 592 |
# File 'app/models/address.rb', line 582 def same_as(address) # Possible you're just giving me the same address so i'll just match on id if address.persisted? && persisted? address.id == id # If our address was normalized by geocoder, we will use that form to compare elsif address.normalized_address.present? && normalized_address.present? address.normalized_address == normalized_address else # Use native fields address_for_comparison == address.address_for_comparison end end |
#search_text ⇒ Object
Search text.
1270 1271 1272 |
# File 'app/models/address.rb', line 1270 def search_text to_array.join(' ') end |
#service_jobs ⇒ ActiveRecord::Relation<ServiceJob>
Service jobs.
148 |
# File 'app/models/address.rb', line 148 has_many :service_jobs, -> { order(:created_at) }, inverse_of: :address |
#set_freight_field_defaults ⇒ Object
Set freight field defaults.
880 881 882 883 884 885 886 887 |
# File 'app/models/address.rb', line 880 def set_freight_field_defaults self.has_loading_dock ||= false self.requires_liftgate ||= true self.requires_inside_delivery ||= false self.is_construction_site ||= false self.limited_access ||= false self.requires_appointment ||= true end |
#shipping_account_numbers ⇒ ActiveRecord::Relation<ShippingAccountNumber>
Shipping account numbers.
144 |
# File 'app/models/address.rb', line 144 has_many :shipping_account_numbers |
#shipping_credit_memos ⇒ ActiveRecord::Relation<CreditMemo>
Shipping credit memos.
136 |
# File 'app/models/address.rb', line 136 has_many :shipping_credit_memos, class_name: 'CreditMemo', foreign_key: :shipping_address_id |
#shipping_customer ⇒ Customer
Shipping customer.
116 |
# File 'app/models/address.rb', line 116 has_one :shipping_customer, class_name: 'Customer', dependent: :nullify, foreign_key: :shipping_address_id, inverse_of: :shipping_address |
#shipping_invoices ⇒ ActiveRecord::Relation<Invoice>
Shipping invoices.
132 |
# File 'app/models/address.rb', line 132 has_many :shipping_invoices, class_name: 'Invoice', foreign_key: :shipping_address_id |
#shipping_orders ⇒ ActiveRecord::Relation<Order>
Shipping orders.
128 |
# File 'app/models/address.rb', line 128 has_many :shipping_orders, class_name: 'Order', foreign_key: :shipping_address_id |
#shipping_quotes ⇒ ActiveRecord::Relation<Quote>
Shipping quotes.
138 |
# File 'app/models/address.rb', line 138 has_many :shipping_quotes, class_name: 'Quote', foreign_key: :shipping_address_id |
#state ⇒ State?
Returns the state this record belongs to.
110 |
# File 'app/models/address.rb', line 110 belongs_to :state, foreign_key: 'state_code', primary_key: 'code', optional: true |
#state_codes_list ⇒ Object
State codes list.
458 459 460 |
# File 'app/models/address.rb', line 458 def state_codes_list iso3166_country.subdivisions.keys end |
#state_present_and_has_states_or_provinces? ⇒ Boolean
Returns whether the record state present and has states or provinces.
726 727 728 |
# File 'app/models/address.rb', line 726 def state_present_and_has_states_or_provinces? state_code.present? && iso3166_country && has_states_or_provinces? end |
#states_for_select ⇒ Object
States for select.
453 454 455 |
# File 'app/models/address.rb', line 453 def states_for_select State.states_for_select(countries_iso: country_iso3) end |
#support_cases ⇒ ActiveRecord::Relation<SupportCase>
Support cases.
140 |
# File 'app/models/address.rb', line 140 has_many :support_cases, class_name: 'SupportCase', foreign_key: :service_address_id |
#temporary? ⇒ Boolean
Returns whether the record temporary.
353 354 355 |
# File 'app/models/address.rb', line 353 def temporary? street1 == 'Unknown' end |
#text_block(with_recipient = false, with_country = false, phone = nil) ⇒ Object
Text block.
893 894 895 896 897 898 899 |
# File 'app/models/address.rb', line 893 def text_block(with_recipient = false, with_country = false, phone = nil) = {} [:include_recipient] = with_recipient [:with_country] = with_country [:phone] = phone to_array().join("\n") end |
#timezone ⇒ Object
Returns a timezone object or look it up and store
363 364 365 366 367 368 369 370 |
# File 'app/models/address.rb', line 363 def timezone tz = begin ActiveSupport::TimeZone.find_tzinfo(timezone_name) rescue TZInfo::InvalidTimezoneIdentifier ErrorReporting.warning("Invalid timezone #{timezone_name} for address id #{id}") end tz || lookup_timezone(:store) end |
#timezones_for_select ⇒ Object
Timezones for select.
358 359 360 |
# File 'app/models/address.rb', line 358 def timezones_for_select iso3166_country.timezones.zone_identifiers end |
#to_array(include_recipient: true, with_country: true, attention_name: nil, attention_prepend: nil, name: nil, upcase: false, phone: nil, email: nil, address_type: false, extra_data: nil, locale: I18n.locale) ⇒ Object
Returns an array of address lines formatted according to the options passed in.
Allows customizing included fields like recipient name, street, city, etc.
Also includes phone, email, address type, and extra data if specified.
Can upcase the fields.
locale - The locale to use for translations (default: I18n.locale)
include_recipient - Whether to include the recipient name
with_country - Whether to include the country
attention_name - Custom attention name to use
attention_prepend - String to prepend to attention name
name - Custom recipient name to use
upcase - Whether to upcase the fields
phone - Phone number to include
email - Email to include
address_type - Whether to include the address type
extra_data - Extra data to append
Returns an array of address lines, based on the country formatting rules.
824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 |
# File 'app/models/address.rb', line 824 def to_array(include_recipient: true, with_country: true, attention_name: nil, attention_prepend: nil, name: nil, upcase: false, phone: nil, email: nil, address_type: false, extra_data: nil, locale: I18n.locale) a = localized_address_format_array(include_recipient:, with_country:, attention_name:, attention_prepend:, name:, locale:) a << "Phone: #{phone}" if phone.present? a << "E-mail: #{email}" if email.present? if address_type a << (is_residential? ? "(Residential #{freight_fields_text})" : "(Commercial #{freight_fields_text})") a << "Freight Ready?: #{is_valid_for_freight? ? '✔ Yes' : 'X No'}" end a << extra_data res = a.map(&:to_s).map(&:squish).map(&:presence).uniq.compact res = res.map(&:upcase) if upcase.to_b res.uniq end |
#to_s(params = {}) ⇒ String
Returns string representation of the record.
742 743 744 |
# File 'app/models/address.rb', line 742 def to_s(params = {}) to_array(**params).join(', ') end |
#unlink ⇒ Object
Unlink.
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 |
# File 'app/models/address.rb', line 1217 def unlink party_id return unless party Address.transaction do party.update_attribute!(:shipping_address_id, nil) if self == party.shipping_address party.update_attribute!(:mailing_address_id, nil) if self == party.mailing_address raise 'Cannot remove address from customer as it is used as the main billing address.' if self == party.billing_address update_attribute(:party_id, nil) end end |
#update_party_timezone ⇒ Object
Update party timezone.
311 312 313 314 315 |
# File 'app/models/address.rb', line 311 def update_party_timezone return unless party && saved_change_to_timezone_name? PartyRecordTimezone.new.process_party_and_associations(party) end |
#via_json ⇒ Object
Via json.
1231 1232 1233 |
# File 'app/models/address.rb', line 1231 def via_json to_json end |
#via_json=(x) ⇒ Object
Sets the via json.
1238 1239 1240 |
# File 'app/models/address.rb', line 1238 def via_json=(x) from_json x end |
#via_xml ⇒ Object
Via xml.
1243 1244 1245 |
# File 'app/models/address.rb', line 1243 def via_xml to_xml end |
#via_xml=(x) ⇒ Object
Sets the via xml.
1250 1251 1252 |
# File 'app/models/address.rb', line 1250 def via_xml=(x) from_xml x end |
#warehouse_store ⇒ Store
Warehouse store.
122 |
# File 'app/models/address.rb', line 122 has_one :warehouse_store, class_name: 'Store', foreign_key: :warehouse_address_id |
#zip_5 ⇒ Object
Zip 5.
428 429 430 |
# File 'app/models/address.rb', line 428 def zip_5 zip.to_s.first(5) end |
#zip_compact ⇒ Object
Zip compact.
433 434 435 |
# File 'app/models/address.rb', line 433 def zip_compact in_usa? ? zip_5 : postal_compact end |
#zip_state_consistent? ⇒ Boolean?
Cheap, offline check that the ZIP and state agree, using the
PostalCode cache (self-healing) for the US and the FSA first-letter map
for Canada. This is a signal, not an authority: only full-address
verification (AddressValidation) can say which field is wrong. Used to
decide whether to spend a verification call (e.g. before a TaxJar submit —
AppSignal #6094, a VT ZIP saved with state FL).
241 242 243 244 245 246 247 248 249 |
# File 'app/models/address.rb', line 241 def zip_state_consistent? return nil if zip.blank? || state_code.blank? return nil unless %w[USA CAN].include?(country_iso3) canonical = PostalCode.state_for(zip, country_iso3: country_iso3) return nil if canonical.blank? canonical.casecmp?(state_code.to_s) end |