Class: Spree::Address

Inherits:
Object
  • Object
show all
Includes:
Metadata, Metafields, Security::Addresses
Defined in:
app/models/spree/address.rb

Constant Summary collapse

STATES_REQUIRED =

The required states listed below match those used by PayPal and Shopify.

[
  'AU', 'AE', 'BR', 'CA', 'CN', 'ES', 'HK', 'IE', 'IN',
  'IT', 'MY', 'MX', 'NZ', 'PT', 'RO', 'TH', 'US', 'ZA'
].freeze
ADDRESS_FIELDS =

we’re not freezing this on purpose so developers can extend and manage those attributes depending of the logic of their applications

%w(firstname lastname company address1 address2 city state zipcode country phone)
EXCLUDED_KEYS_FOR_COMPARISON =
%w(id updated_at created_at deleted_at label user_id public_metadata private_metadata)

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Metadata

#metadata, #metadata=, #public_metadata=

Class Method Details

.required_fieldsObject



102
103
104
105
106
# File 'app/models/spree/address.rb', line 102

def self.required_fields
  Spree::Address.validators.map do |v|
    v.is_a?(ActiveModel::Validations::PresenceValidator) ? v.attributes : []
  end.flatten
end

Instance Method Details

#==(other) ⇒ Object



163
164
165
166
167
# File 'app/models/spree/address.rb', line 163

def ==(other)
  return false unless other&.respond_to?(:value_attributes)

  value_attributes == other.value_attributes
end

#address_validatorsObject



76
77
78
79
80
# File 'app/models/spree/address.rb', line 76

def address_validators
  Spree.validators.addresses.each do |validator|
    validates_with validator
  end
end

#async_geocodeObject



242
243
244
# File 'app/models/spree/address.rb', line 242

def async_geocode
  Spree::Addresses::GeocodeAddressJob.perform_later(id) if should_geocode?
end

#can_be_deleted?Boolean

Returns:



222
223
224
# File 'app/models/spree/address.rb', line 222

def can_be_deleted?
  shipments.empty? && Order.complete.where('bill_address_id = ? OR ship_address_id = ?', id, id).none?
end

#checkObject



226
227
228
229
230
# File 'app/models/spree/address.rb', line 226

def check
  attrs = attributes.except('id', 'updated_at', 'created_at')
  the_same_address = user&.addresses&.find_by(attrs)
  the_same_address || self
end

#cloneObject



159
160
161
# File 'app/models/spree/address.rb', line 159

def clone
  self.class.new(value_attributes)
end

#country_iso=(value) ⇒ Object

Writer methods for API convenience - these set country/state from ISO/abbr codes The reader methods (country_iso, state_abbr) are delegates to country.iso and state.abbr



91
92
93
# File 'app/models/spree/address.rb', line 91

def country_iso=(value)
  @country_iso_input = value
end

#destroyObject



232
233
234
235
236
237
238
239
240
# File 'app/models/spree/address.rb', line 232

def destroy
  assign_new_default_address_to_user

  if can_be_deleted?
    super
  else
    update_column :deleted_at, Time.current
  end
end

#editable?Boolean

Returns:



218
219
220
# File 'app/models/spree/address.rb', line 218

def editable?
  new_record? || Order.complete.where('bill_address_id = ? OR ship_address_id = ?', id, id).none?
end

#empty?Boolean

Returns:



173
174
175
# File 'app/models/spree/address.rb', line 173

def empty?
  attributes.except('id', 'created_at', 'updated_at', 'country_id').all? { |_, v| v.nil? }
end

#full_nameObject

first_name / last_name aliases are defined via alias_attribute above



132
133
134
# File 'app/models/spree/address.rb', line 132

def full_name
  "#{firstname} #{lastname}".strip
end

#gateway_hashObject Also known as: active_merchant_hash

Generates an address hash for payment gateway options



178
179
180
181
182
183
184
185
186
187
188
189
# File 'app/models/spree/address.rb', line 178

def gateway_hash
  {
    name: full_name,
    address1: address1,
    address2: address2,
    city: city,
    state: state_text,
    zip: zipcode,
    country: country.try(:iso),
    phone: phone
  }
end

#geocoder_addressObject



246
247
248
# File 'app/models/spree/address.rb', line 246

def geocoder_address
  @geocoder_address ||= [street, city, state_text, country.to_s].compact.map(&:strip).join(', ')
end

#is_default_billing?Boolean Also known as: is_default_billing

In 6.0 these become real columns on Address, replacing User#bill_address_id / ship_address_id. For now they delegate to the User FK so the API shape is stable.

Returns:



120
121
122
# File 'app/models/spree/address.rb', line 120

def is_default_billing?
  user.present? && id == user.bill_address_id
end

#is_default_shipping?Boolean Also known as: is_default_shipping

Returns:



125
126
127
# File 'app/models/spree/address.rb', line 125

def is_default_shipping?
  user.present? && id == user.ship_address_id
end

#require_company?Boolean

Returns:



206
207
208
# File 'app/models/spree/address.rb', line 206

def require_company?
  false
end

#require_name?Boolean

Returns:



202
203
204
# File 'app/models/spree/address.rb', line 202

def require_name?
  !quick_checkout
end

#require_phone?Boolean

Returns:



192
193
194
195
196
# File 'app/models/spree/address.rb', line 192

def require_phone?
  # We want to collect phone number for quick checkout but not to validate it
  # as it's not available before payment by browser.
  !quick_checkout && Spree::Config[:address_requires_phone]
end

#require_street?Boolean

Returns:



210
211
212
# File 'app/models/spree/address.rb', line 210

def require_street?
  !quick_checkout
end

#require_zipcode?Boolean

Returns:



198
199
200
# File 'app/models/spree/address.rb', line 198

def require_zipcode?
  !quick_checkout && (country ? country.zipcode_required? : true)
end

#show_company_address_field?Boolean

Returns:



214
215
216
# File 'app/models/spree/address.rb', line 214

def show_company_address_field?
  Spree::Store.current.prefers_company_field_enabled?
end

#state_abbr=(value) ⇒ Object



95
96
97
# File 'app/models/spree/address.rb', line 95

def state_abbr=(value)
  @state_abbr_input = value
end

#state_name_textObject



140
141
142
# File 'app/models/spree/address.rb', line 140

def state_name_text
  state_name.present? ? state_name : state&.name
end

#state_textObject



136
137
138
# File 'app/models/spree/address.rb', line 136

def state_text
  state.try(:abbr) || state.try(:name) || state_name
end

#streetObject



144
145
146
# File 'app/models/spree/address.rb', line 144

def street
  [address1, address2].join(' ')
end

#to_sObject



148
149
150
151
152
153
154
155
156
157
# File 'app/models/spree/address.rb', line 148

def to_s
  [
    full_name,
    company,
    address1,
    address2,
    "#{city}, #{state_text} #{zipcode}",
    country.to_s
  ].reject(&:blank?).map { |attribute| ERB::Util.html_escape(attribute) }.join('<br/>')
end

#user_default_billing?Boolean

Returns:



108
109
110
111
# File 'app/models/spree/address.rb', line 108

def user_default_billing?
  Spree::Deprecation.warn('Spree::Address#user_default_billing? is deprecated and will be removed in Spree 6.0. Use #is_default_billing? instead.')
  is_default_billing?
end

#user_default_shipping?Boolean

Returns:



113
114
115
116
# File 'app/models/spree/address.rb', line 113

def user_default_shipping?
  Spree::Deprecation.warn('Spree::Address#user_default_shipping? is deprecated and will be removed in Spree 6.0. Use #is_default_shipping? instead.')
  is_default_shipping?
end

#value_attributesObject



169
170
171
# File 'app/models/spree/address.rb', line 169

def value_attributes
  attributes.except(*EXCLUDED_KEYS_FOR_COMPARISON)
end