spree_core 4.2.0.beta → 4.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/app/finders/spree/addresses/find.rb +17 -0
  3. data/app/helpers/spree/base_helper.rb +37 -11
  4. data/app/helpers/spree/mail_helper.rb +12 -7
  5. data/app/helpers/spree/products_helper.rb +2 -1
  6. data/app/mailers/spree/base_mailer.rb +1 -1
  7. data/app/models/concerns/spree/user_payment_source.rb +1 -1
  8. data/app/models/spree/address.rb +13 -1
  9. data/app/models/spree/app_dependencies.rb +7 -1
  10. data/app/models/spree/credit_card.rb +5 -0
  11. data/app/models/spree/line_item.rb +2 -1
  12. data/app/models/spree/order.rb +7 -2
  13. data/app/models/spree/order/payments.rb +10 -2
  14. data/app/models/spree/preferences/store.rb +1 -1
  15. data/app/models/spree/promotion.rb +6 -0
  16. data/app/models/spree/promotion_handler/promotion_duplicator.rb +9 -3
  17. data/app/models/spree/store.rb +3 -0
  18. data/app/presenters/spree/variant_presenter.rb +2 -1
  19. data/app/services/spree/account/addresses/base.rb +39 -0
  20. data/app/services/spree/account/addresses/create.rb +18 -0
  21. data/app/services/spree/account/addresses/update.rb +18 -0
  22. data/app/services/spree/checkout/update.rb +13 -2
  23. data/config/locales/en.yml +11 -4
  24. data/db/default/spree/countries.rb +10 -4
  25. data/db/default/spree/states.rb +42 -5
  26. data/db/default/spree/stores.rb +17 -13
  27. data/db/default/spree/zones.rb +1 -1
  28. data/db/migrate/20200610113542_add_label_to_spree_addresses.rb +5 -0
  29. data/db/migrate/20201013084504_add_seo_robots_to_spree_stores.rb +5 -0
  30. data/lib/spree/core.rb +1 -0
  31. data/lib/spree/core/controller_helpers/order.rb +9 -4
  32. data/lib/spree/core/version.rb +1 -1
  33. data/lib/spree/permitted_attributes.rb +2 -2
  34. data/spree_core.gemspec +1 -0
  35. metadata +28 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd3e3f16eb808f16f592360085f02f1382ee4ddd6ee0903c3eb8a8079e5d8bad
4
- data.tar.gz: 8567b7555de6f0f578d6277e6943af11b68329e5e17a77d13c7e66085e7fe09f
3
+ metadata.gz: 9aaaa7166983682cd10080012ae8c4b54c89808552125eed36bce0345c2ed023
4
+ data.tar.gz: b330046bd7a2af73be37cfedc5bae1a591c22e0344d62d1672d5ba84d0cf6f84
5
5
  SHA512:
6
- metadata.gz: 113900d45a999bb7aa47209797e8ab47a5ed6f40caa445242952eac3a604cc43bc658fec8fb86dc148743032f71341d97331cd7d6d7b77d84df36ffc979f122b
7
- data.tar.gz: a175395cbe157f6ca1704ab5bdacbbf5c9abbee4bdae89f19363c06fc7a1fe06610fab87347342ecddd297d3bf22bf9354116340e8e408270a4f968a78883a0e
6
+ metadata.gz: f2faa906d370fd03cb6e477b00e9e52c5a658e051df9cf02d6f19a62f1480a99785e038e3ade796c92b2a8dc1cec4c820602e68dcc3615142c9cfe1a191f33bb
7
+ data.tar.gz: 578828b9e6649880bfd6f1029adc1f0b5563ef5c68cda14d5ff1e3237ccc057953f0b30c4cad0984eff273417701c5303f6efe6ef3f13b19dd4cec4bc67358e2
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ module Addresses
3
+ class Find
4
+ def initialize(scope:, params:)
5
+ @scope = scope
6
+ end
7
+
8
+ def execute
9
+ scope
10
+ end
11
+
12
+ private
13
+
14
+ attr_reader :scope
15
+ end
16
+ end
17
+ end
@@ -57,8 +57,33 @@ module Spree
57
57
  end
58
58
  end
59
59
 
60
+ def object
61
+ instance_variable_get('@' + controller_name.singularize)
62
+ end
63
+
64
+ def og_meta_data
65
+ og_meta = {}
66
+
67
+ if object.is_a? Spree::Product
68
+ image = default_image_for_product_or_variant(object)
69
+ og_meta['og:image'] = main_app.url_for(image.attachment) if image&.attachment
70
+
71
+ og_meta['og:url'] = spree.url_for(object) if frontend_available? # url_for product needed
72
+ og_meta['og:type'] = object.class.name.demodulize.downcase
73
+ og_meta['og:title'] = object.name
74
+ og_meta['og:description'] = object.description
75
+
76
+ price = object.price_in(current_currency)
77
+ if price
78
+ og_meta['product:price:amount'] = price.amount
79
+ og_meta['product:price:currency'] = current_currency
80
+ end
81
+ end
82
+
83
+ og_meta
84
+ end
85
+
60
86
  def meta_data
61
- object = instance_variable_get('@' + controller_name.singularize)
62
87
  meta = {}
63
88
 
64
89
  if object.is_a? ApplicationRecord
@@ -82,16 +107,10 @@ module Spree
82
107
  meta
83
108
  end
84
109
 
85
- def meta_image_url_path
86
- object = instance_variable_get('@' + controller_name.singularize)
87
- return unless object.is_a?(Spree::Product)
88
-
89
- image = default_image_for_product_or_variant(object)
90
- image&.attachment.present? ? main_app.url_for(image.attachment) : asset_path(Spree::Config[:logo])
91
- end
92
-
93
- def meta_image_data_tag
94
- tag('meta', property: 'og:image', content: meta_image_url_path) if meta_image_url_path
110
+ def og_meta_data_tags
111
+ og_meta_data.map do |property, content|
112
+ tag('meta', property: property, content: content) unless property.nil? || content.nil?
113
+ end.join("\n")
95
114
  end
96
115
 
97
116
  def meta_data_tags
@@ -189,5 +208,12 @@ module Spree
189
208
  style if style.in? Spree::Image.styles.with_indifferent_access
190
209
  end
191
210
  end
211
+
212
+ def meta_robots
213
+ return unless current_store.respond_to?(:seo_robots)
214
+ return if current_store.seo_robots.blank?
215
+
216
+ tag('meta', name: 'robots', content: current_store.seo_robots)
217
+ end
192
218
  end
193
219
  end
@@ -11,14 +11,19 @@ module Spree
11
11
  order.name || Spree.t('customer')
12
12
  end
13
13
 
14
+ def store_logo
15
+ @order&.store&.mailer_logo || @order&.store&.logo || current_store.mailer_logo || current_store.logo
16
+ end
17
+
18
+ def default_logo
19
+ Spree::Config.mailer_logo || Spree::Config.logo
20
+ end
21
+
14
22
  def logo_path
15
- if current_store.present? && current_store.logo.attached? && current_store.logo.variable?
16
- main_app.url_for(current_store.logo.variant(resize: '244x104>'))
17
- elsif current_store.present? && current_store.logo.attached? && current_store.logo.image?
18
- main_app.url_for(current_store.logo)
19
- else
20
- Spree::Config.mailer_logo || Spree::Config.logo
21
- end
23
+ return default_logo unless store_logo.attached?
24
+ return main_app.url_for(store_logo.variant(resize: '244x104>')) if store_logo.variable?
25
+
26
+ return main_app.url_for(store_logo) if store_logo.image?
22
27
  end
23
28
  end
24
29
  end
@@ -110,7 +110,8 @@ module Spree
110
110
  variants: @variants,
111
111
  is_product_available_in_currency: is_product_available_in_currency,
112
112
  current_currency: current_currency,
113
- current_price_options: current_price_options
113
+ current_price_options: current_price_options,
114
+ current_store: current_store
114
115
  ).call.to_json
115
116
  end
116
117
 
@@ -8,7 +8,7 @@ module Spree
8
8
  helper_method :current_store
9
9
 
10
10
  def from_address
11
- current_store.mail_from_address
11
+ @order&.store&.mail_from_address || current_store.mail_from_address
12
12
  end
13
13
 
14
14
  def money(amount, currency = nil)
@@ -9,7 +9,7 @@ module Spree
9
9
  end
10
10
 
11
11
  def payment_sources
12
- credit_cards.with_payment_profile
12
+ credit_cards.with_payment_profile.not_expired
13
13
  end
14
14
 
15
15
  def drop_payment_source(source)
@@ -10,10 +10,16 @@ module Spree
10
10
  'TO', 'TV', 'UG', 'AE', 'VU', 'YE', 'ZW'
11
11
  ].freeze
12
12
 
13
+ # The required states listed below match those used by PayPal and Shopify.
14
+ STATES_REQUIRED = [
15
+ 'AU', 'AE', 'BR', 'CA', 'CN', 'ES', 'HK', 'IE', 'IN',
16
+ 'IT', 'MY', 'MX', 'NZ', 'PT', 'RO', 'TH', 'US', 'ZA'
17
+ ].freeze
18
+
13
19
  # we're not freezing this on purpose so developers can extend and manage
14
20
  # those attributes depending of the logic of their applications
15
21
  ADDRESS_FIELDS = %w(firstname lastname company address1 address2 city state zipcode country phone)
16
- EXCLUDED_KEYS_FOR_COMPARISION = %w(id updated_at created_at deleted_at user_id)
22
+ EXCLUDED_KEYS_FOR_COMPARISION = %w(id updated_at created_at deleted_at label user_id)
17
23
 
18
24
  belongs_to :country, class_name: 'Spree::Country'
19
25
  belongs_to :state, class_name: 'Spree::State', optional: true
@@ -31,6 +37,12 @@ module Spree
31
37
 
32
38
  validate :state_validate, :postal_code_validate
33
39
 
40
+ validates :label, uniqueness: { conditions: -> { where(deleted_at: nil) },
41
+ scope: :user_id,
42
+ case_sensitive: false,
43
+ allow_blank: true,
44
+ allow_nil: true }
45
+
34
46
  delegate :name, :iso3, :iso, :iso_name, to: :country, prefix: true
35
47
  delegate :abbr, to: :state, prefix: true, allow_nil: true
36
48
 
@@ -11,7 +11,8 @@ module Spree
11
11
  :checkout_remove_store_credit_service, :checkout_get_shipping_rates_service,
12
12
  :coupon_handler, :country_finder, :current_order_finder, :credit_card_finder,
13
13
  :completed_order_finder, :order_sorter, :cart_compare_line_items_service, :collection_paginator, :products_sorter,
14
- :products_finder, :taxon_finder, :line_item_by_variant_finder, :cart_estimate_shipping_rates_service
14
+ :products_finder, :taxon_finder, :line_item_by_variant_finder, :cart_estimate_shipping_rates_service,
15
+ :account_create_address_service, :account_update_address_service, :address_finder
15
16
  ].freeze
16
17
 
17
18
  attr_accessor *INJECTION_POINTS
@@ -59,9 +60,14 @@ module Spree
59
60
  # coupons
60
61
  # TODO: we should split this service into 2 seperate - Add and Remove
61
62
  @coupon_handler = 'Spree::PromotionHandler::Coupon'
63
+
64
+ # account
65
+ @account_create_address_service = 'Spree::Account::Addresses::Create'
66
+ @account_update_address_service = 'Spree::Account::Addresses::Update'
62
67
  end
63
68
 
64
69
  def set_default_finders
70
+ @address_finder = 'Spree::Addresses::Find'
65
71
  @country_finder = 'Spree::Countries::Find'
66
72
  @current_order_finder = 'Spree::Orders::FindCurrent'
67
73
  @completed_order_finder = 'Spree::Orders::FindComplete'
@@ -37,6 +37,11 @@ module Spree
37
37
 
38
38
  scope :with_payment_profile, -> { where.not(gateway_customer_profile_id: nil) }
39
39
  scope :default, -> { where(default: true) }
40
+ scope :not_expired, lambda {
41
+ where('CAST(spree_credit_cards.year AS DECIMAL) > ?', Time.current.year).
42
+ or(where('CAST(spree_credit_cards.year AS DECIMAL) = ?', Time.current.year).
43
+ where('CAST(spree_credit_cards.month AS DECIMAL) >= ?', Time.current.month))
44
+ }
40
45
 
41
46
  # needed for some of the ActiveMerchant gateways (eg. SagePay)
42
47
  alias_attribute :brand, :cc_type
@@ -75,7 +75,8 @@ module Spree
75
75
 
76
76
  extend DisplayMoney
77
77
  money_methods :amount, :subtotal, :discounted_amount, :final_amount, :total, :price,
78
- :adjustment_total, :additional_tax_total, :promo_total, :included_tax_total
78
+ :adjustment_total, :additional_tax_total, :promo_total, :included_tax_total,
79
+ :pre_tax_amount
79
80
 
80
81
  alias single_money display_price
81
82
  alias single_display_amount display_price
@@ -22,7 +22,7 @@ module Spree
22
22
  money_methods :outstanding_balance, :item_total, :adjustment_total,
23
23
  :included_tax_total, :additional_tax_total, :tax_total,
24
24
  :shipment_total, :promo_total, :total,
25
- :cart_promo_total
25
+ :cart_promo_total, :pre_tax_item_amount, :pre_tax_total
26
26
 
27
27
  alias display_ship_total display_shipment_total
28
28
  alias_attribute :ship_total, :shipment_total
@@ -174,7 +174,12 @@ module Spree
174
174
 
175
175
  # Sum of all line item amounts pre-tax
176
176
  def pre_tax_item_amount
177
- line_items.to_a.sum(&:pre_tax_amount)
177
+ line_items.sum(:pre_tax_amount)
178
+ end
179
+
180
+ # Sum of all line item and shipment pre-tax
181
+ def pre_tax_total
182
+ pre_tax_item_amount + shipments.sum(:pre_tax_amount)
178
183
  end
179
184
 
180
185
  def shipping_discount
@@ -32,7 +32,7 @@ module Spree
32
32
  end
33
33
 
34
34
  def pending_payments
35
- payments.select(&:pending?)
35
+ payments.pending
36
36
  end
37
37
 
38
38
  def unprocessed_payments
@@ -52,7 +52,7 @@ module Spree
52
52
 
53
53
  payment.public_send(method)
54
54
 
55
- if payment.completed? && payment_total != total
55
+ if payment.completed? && payment_total != total_without_pending_store_credits
56
56
  self.payment_total += payment.amount
57
57
  end
58
58
  end
@@ -60,6 +60,14 @@ module Spree
60
60
  result = !!Spree::Config[:allow_checkout_on_gateway_error]
61
61
  errors.add(:base, e.message) && (return result)
62
62
  end
63
+
64
+ # Pending store credits are not added to `self.payment_total`.
65
+ # It can cause a situation where the amount of the credit card payment reduced with store credits
66
+ # may be added twice to `self.payment_total` causing wrong `order.outstanding_balance`
67
+ # calculations and thus an incorrect payment state.
68
+ def total_without_pending_store_credits
69
+ total - payments.map { |p| p.amount if p.source.is_a?(Spree::StoreCredit) && p.pending? }.sum(&:to_f)
70
+ end
63
71
  end
64
72
  end
65
73
  end
@@ -6,7 +6,7 @@
6
6
 
7
7
  require 'singleton'
8
8
 
9
- DB_EXCEPTIONS = if defined? PG
9
+ DB_EXCEPTIONS ||= if defined? PG
10
10
  [PG::ConnectionBad, ActiveRecord::NoDatabaseError]
11
11
  elsif defined? Mysql2
12
12
  [Mysql2::Error::ConnectionError, ActiveRecord::NoDatabaseError]
@@ -28,6 +28,8 @@ module Spree
28
28
 
29
29
  before_save :normalize_blank_values
30
30
 
31
+ before_validation :normalize_code
32
+
31
33
  scope :coupons, -> { where.not(code: nil) }
32
34
  scope :advertised, -> { where(advertise: true) }
33
35
  scope :applied, lambda {
@@ -227,6 +229,10 @@ module Spree
227
229
  end
228
230
  end
229
231
 
232
+ def normalize_code
233
+ self.code = code.strip if code.present?
234
+ end
235
+
230
236
  def match_all?
231
237
  match_policy == 'all'
232
238
  end
@@ -1,15 +1,16 @@
1
1
  module Spree
2
2
  module PromotionHandler
3
3
  class PromotionDuplicator
4
- def initialize(promotion)
4
+ def initialize(promotion, random_string: nil)
5
5
  @promotion = promotion
6
+ @random_string = random_string || generate_random_string(4)
6
7
  end
7
8
 
8
9
  def duplicate
9
10
  @new_promotion = @promotion.dup
10
- @new_promotion.path = "#{@promotion.path}_new"
11
+ @new_promotion.path = "#{@promotion.path}_#{@random_string}"
11
12
  @new_promotion.name = "New #{@promotion.name}"
12
- @new_promotion.code = "#{@promotion.code}_new"
13
+ @new_promotion.code = "#{@promotion.code}_#{@random_string}"
13
14
 
14
15
  ActiveRecord::Base.transaction do
15
16
  @new_promotion.save
@@ -33,6 +34,11 @@ module Spree
33
34
  end
34
35
  end
35
36
 
37
+ def generate_random_string(number)
38
+ charset = Array('A'..'Z') + Array('a'..'z')
39
+ Array.new(number) { charset.sample }.join
40
+ end
41
+
36
42
  def copy_actions
37
43
  @promotion.promotion_actions.each do |action|
38
44
  new_action = action.dup
@@ -18,6 +18,9 @@ module Spree
18
18
  end
19
19
 
20
20
  has_one_attached :logo
21
+ has_one_attached :mailer_logo
22
+
23
+ validates :mailer_logo, content_type: ['image/png', 'image/jpg', 'image/jpeg']
21
24
 
22
25
  before_save :ensure_default_exists_and_is_unique
23
26
  before_destroy :validate_not_default
@@ -3,13 +3,14 @@ module Spree
3
3
  include Rails.application.routes.url_helpers
4
4
  include Spree::BaseHelper
5
5
 
6
- attr_reader :current_currency, :current_price_options
6
+ attr_reader :current_currency, :current_price_options, :current_store
7
7
 
8
8
  def initialize(opts = {})
9
9
  @variants = opts[:variants]
10
10
  @is_product_available_in_currency = opts[:is_product_available_in_currency]
11
11
  @current_currency = opts[:current_currency]
12
12
  @current_price_options = opts[:current_price_options]
13
+ @current_store = opts[:current_store]
13
14
  end
14
15
 
15
16
  def call
@@ -0,0 +1,39 @@
1
+ module Spree
2
+ module Account
3
+ module Addresses
4
+ class Base
5
+ prepend Spree::ServiceModule::Base
6
+
7
+ private
8
+
9
+ attr_accessor :country
10
+
11
+ def fill_country_and_state_ids(params)
12
+ replace_country_iso_with_id(params)
13
+ fill_state_id(params)
14
+ end
15
+
16
+ def replace_country_iso_with_id(params)
17
+ iso = params[:country_iso]
18
+ return params unless iso.present?
19
+
20
+ country = Spree::Country.by_iso(iso)
21
+ params[:country_id] = country&.id
22
+ params.delete(:country_iso)
23
+ params
24
+ end
25
+
26
+ def fill_state_id(params)
27
+ state_name = params[:state_name]
28
+ return params unless state_name.present?
29
+
30
+ country ||= Spree::Country.find(params[:country_id]) if params[:country_id].present?
31
+ return params unless country
32
+
33
+ params[:state_id] = country.states.find_by(name: state_name)&.id
34
+ params
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module Account
3
+ module Addresses
4
+ class Create < ::Spree::Account::Addresses::Base
5
+ def call(user:, address_params:)
6
+ fill_country_and_state_ids(address_params)
7
+
8
+ address = user.addresses.new(address_params)
9
+ if address.save
10
+ success(address)
11
+ else
12
+ failure(address)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module Account
3
+ module Addresses
4
+ class Update < ::Spree::Account::Addresses::Base
5
+ def call(address:, address_params:)
6
+ address_params[:country_id] ||= address.country_id
7
+ fill_country_and_state_ids(address_params)
8
+
9
+ if address.update(address_params)
10
+ success(address)
11
+ else
12
+ failure(address)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -4,8 +4,12 @@ module Spree
4
4
  prepend Spree::ServiceModule::Base
5
5
 
6
6
  def call(order:, params:, permitted_attributes:, request_env:)
7
- params = replace_country_iso_with_id(params, 'ship') if address_with_country_iso_present?(params, 'ship')
8
- params = replace_country_iso_with_id(params, 'bill') if address_with_country_iso_present?(params, 'bill')
7
+ ship_changed = address_with_country_iso_present?(params, 'ship')
8
+ bill_changed = address_with_country_iso_present?(params, 'bill')
9
+ params = replace_country_iso_with_id(params, 'ship') if ship_changed
10
+ params = replace_country_iso_with_id(params, 'bill') if bill_changed
11
+ order.state = 'address' if (ship_changed || bill_changed) && order.has_checkout_step?('address')
12
+ order.state = 'delivery' if selected_shipping_rate_present?(params) && order.has_checkout_step?('delivery')
9
13
  return success(order) if order.update_from_params(params, permitted_attributes, request_env)
10
14
 
11
15
  failure(order)
@@ -20,6 +24,13 @@ module Spree
20
24
  true
21
25
  end
22
26
 
27
+ def selected_shipping_rate_present?(params)
28
+ shipments_attributes = params.dig(:order, :shipments_attributes)
29
+ return false unless shipments_attributes
30
+
31
+ shipments_attributes.any? { |s| s.dig(:selected_shipping_rate_id) }
32
+ end
33
+
23
34
  def replace_country_iso_with_id(params, address_kind = 'ship')
24
35
  country_id = Spree::Country.by_iso(params[:order]["#{address_kind}_address_attributes"].fetch(:country_iso))&.id
25
36
 
@@ -13,6 +13,7 @@ en:
13
13
  activerecord:
14
14
  attributes:
15
15
  spree/address:
16
+ label: Address name
16
17
  address1: Address
17
18
  address2: Address (contd.)
18
19
  city: City
@@ -502,10 +503,14 @@ en:
502
503
  address_book:
503
504
  other_address: "Other address"
504
505
  add_new_shipping_address: "Add new address"
505
- new_shipping_address: "New Address"
506
- edit_shipping_address: "Edit Address"
506
+ label: Address Name
507
+ address_name_label: Address Name
508
+ address_name_placeholder: Give this address a unique name (Work, Home, etc.)
509
+ new_address: "New Address"
510
+ edit_address: "Edit Address"
511
+ remove_address: Remove Address
507
512
  no_shipping_addresses_on_file: "No addresses on file"
508
- shipping_addresses: "Addresses"
513
+ addresses: "Addresses"
509
514
  successfully_created: "Address has been successfully created."
510
515
  successfully_removed: "Address has been successfully removed."
511
516
  successfully_saved: "Saved successfully"
@@ -945,6 +950,7 @@ en:
945
950
  fields: Fields
946
951
  language: Language
947
952
  country: Country
953
+ default_country: Default Country
948
954
  localization_settings: Localization Settings
949
955
  only_incomplete: Only incomplete
950
956
  only_complete: Only complete
@@ -1036,6 +1042,7 @@ en:
1036
1042
  make_refund: Make refund
1037
1043
  make_sure_the_above_reimbursement_amount_is_correct: Make sure the above reimbursement amount is correct
1038
1044
  mail_from_address: Mail from address
1045
+ mailer_logo: Mailer logo (JPG or PNG images only)
1039
1046
  manage_promotion_categories: Manage Promotion Categories
1040
1047
  manual_intervention_required: Manual intervention required
1041
1048
  manage_variants: Manage Variants
@@ -1637,7 +1644,7 @@ en:
1637
1644
  stock_transfer:
1638
1645
  errors:
1639
1646
  must_have_variant: You must add at least one variant.
1640
- variants_unavailable: "Some variants are not available on %{stock}"
1647
+ variants_unavailable: "Some variants are not available on %{stock}"
1641
1648
  stock_transfers: Stock Transfers
1642
1649
  stop: Stop
1643
1650
  store: Store
@@ -1,18 +1,24 @@
1
1
  require 'carmen'
2
2
 
3
+ EXCLUDED_COUNTRIES = ['AQ', 'AX', 'GS', 'UM', 'HM', 'IO', 'EH', 'BV', 'TF'].freeze
4
+
3
5
  Carmen::Country.all.each do |country|
6
+ # Skip the creation of some territories, uninhabited islands and the Antarctic.
7
+ next if EXCLUDED_COUNTRIES.include?(country.alpha_2_code)
8
+
4
9
  Spree::Country.where(
5
10
  name: country.name,
6
11
  iso3: country.alpha_3_code,
7
12
  iso: country.alpha_2_code,
8
13
  iso_name: country.name.upcase,
9
- numcode: country.numeric_code,
10
- states_required: country.subregions?
14
+ numcode: country.numeric_code
11
15
  ).first_or_create
12
16
  end
13
17
 
14
18
  Spree::Config[:default_country_id] = Spree::Country.find_by(iso: 'US').id
15
19
 
16
- # find countries that do not use postal codes (by iso) and set 'zipcode_required' to false for them.
17
-
20
+ # Find countries that do not use postal codes (by iso) and set 'zipcode_required' to false for them.
18
21
  Spree::Country.where(iso: Spree::Address::NO_ZIPCODE_ISO_CODES).update_all(zipcode_required: false)
22
+
23
+ # Find all countries that require a state (province) at checkout and set 'states_required' to true.
24
+ Spree::Country.where(iso: Spree::Address::STATES_REQUIRED).update_all(states_required: true)
@@ -1,12 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ EXCLUDED_US_STATES = ['UM', 'AS', 'MP', 'VI', 'PR', 'GU'].freeze
4
+ EXCLUDED_CN_STATES = ['HK', 'MO', 'TW'].freeze
5
+
6
+ def state_level(country, subregion)
7
+ country.states.where(
8
+ name: subregion.name,
9
+ abbr: subregion.code
10
+ ).first_or_create
11
+ end
12
+
13
+ def province_level(country, subregion)
14
+ subregion.subregions.each do |province|
15
+ country.states.where(
16
+ name: province.name,
17
+ abbr: province.code
18
+ ).first_or_create
19
+ end
20
+ end
21
+
1
22
  Spree::Country.where(states_required: true).each do |country|
2
23
  carmen_country = Carmen::Country.named(country.name)
3
24
  next unless carmen_country
4
25
 
5
26
  carmen_country.subregions.each do |subregion|
6
- country.states.where(
7
- name: subregion.name,
8
- abbr: subregion.code,
9
- country_id: country.id
10
- ).first_or_create
27
+ if carmen_country.alpha_2_code == 'US'
28
+ # Produces 50 states, one postal district (Washington DC)
29
+ # and 3 APO's as you would expect to see on any good U.S. states list.
30
+ next if EXCLUDED_US_STATES.include?(subregion.code)
31
+
32
+ state_level(country, subregion)
33
+ elsif carmen_country.alpha_2_code == 'CA' || carmen_country.alpha_2_code == 'MX'
34
+ # Force Canada and Mexico to use state-level data import from Carmen Gem
35
+ # else we pull in a subset of provinces that are not common at checkout.
36
+ state_level(country, subregion)
37
+ elsif carmen_country.alpha_2_code == 'CN'
38
+ # Removes 3 "States" from that list that are also listed as Countries,
39
+ # Hong Kong, Taiwan and Macao
40
+ next if EXCLUDED_CN_STATES.include?(subregion.code)
41
+
42
+ state_level(country, subregion)
43
+ elsif subregion.subregions?
44
+ province_level(country, subregion)
45
+ else
46
+ state_level(country, subregion)
47
+ end
11
48
  end
12
49
  end
@@ -1,16 +1,20 @@
1
- # Possibly already created by a migration.
2
- unless Spree::Store.default.persisted?
1
+ default_store = Spree::Store.default
2
+
3
+ if default_store.persisted?
4
+ default_store.update!(default_country_id: Spree::Config[:default_country_id])
5
+ else
3
6
  Spree::Store.new do |s|
4
- s.name = 'Spree Demo Site'
5
- s.code = 'spree'
6
- s.url = Rails.application.routes.default_url_options[:host] || 'demo.spreecommerce.org'
7
- s.mail_from_address = 'no-reply@example.com'
8
- s.customer_support_email = 'support@example.com'
9
- s.default_currency = 'USD'
10
- s.seo_title = 'Spree Commerce Demo Shop'
11
- s.meta_description = 'This is the new Spree UX DEMO | OVERVIEW: http://bit.ly/new-spree-ux | DOCS: http://bit.ly/spree-ux-customization-docs | CONTACT: https://spreecommerce.org/contact/'
12
- s.facebook = 'spreecommerce'
13
- s.twitter = 'spreecommerce'
14
- s.instagram = 'spreecommerce'
7
+ s.name = 'Spree Demo Site'
8
+ s.code = 'spree'
9
+ s.url = Rails.application.routes.default_url_options[:host] || 'demo.spreecommerce.org'
10
+ s.mail_from_address = 'no-reply@example.com'
11
+ s.customer_support_email = 'support@example.com'
12
+ s.default_currency = 'USD'
13
+ s.default_country_id = Spree::Config[:default_country_id]
14
+ s.seo_title = 'Spree Commerce Demo Shop'
15
+ s.meta_description = 'This is the new Spree UX DEMO | OVERVIEW: http://bit.ly/new-spree-ux | DOCS: http://bit.ly/spree-ux-customization-docs | CONTACT: https://spreecommerce.org/contact/'
16
+ s.facebook = 'spreecommerce'
17
+ s.twitter = 'spreecommerce'
18
+ s.instagram = 'spreecommerce'
15
19
  end.save!
16
20
  end
@@ -16,7 +16,7 @@ end
16
16
  middle_east.zone_members.where(zoneable: Spree::Country.find_by!(iso: name)).first_or_create!
17
17
  end
18
18
 
19
- %w(AF AM AZ BH BD BT BN KH CN CX CC IO GE HK IN ID IR IQ IL JP JO KZ KW KG LA LB MO MY MV MN MM NP
19
+ %w(AF AM AZ BH BD BT BN KH CN CX CC GE HK IN ID IR IQ IL JP JO KZ KW KG LA LB MO MY MV MN MM NP
20
20
  KP OM PK PS PH QA SA SG KR LK SY TW TJ TH TR TM AE UZ VN YE).each do |name|
21
21
  asia.zone_members.where(zoneable: Spree::Country.find_by!(iso: name)).first_or_create!
22
22
  end
@@ -0,0 +1,5 @@
1
+ class AddLabelToSpreeAddresses < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_column :spree_addresses, :label, :string unless column_exists?(:spree_addresses, :label)
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddSeoRobotsToSpreeStores < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_column :spree_stores, :seo_robots, :string unless column_exists?(:spree_stores, :seo_robots)
4
+ end
5
+ end
@@ -13,6 +13,7 @@ require 'premailer/rails'
13
13
  require 'ransack'
14
14
  require 'responders'
15
15
  require 'state_machines-activerecord'
16
+ require 'active_storage_validations'
16
17
 
17
18
  # This is required because ActiveModel::Validations#invalid? conflicts with the
18
19
  # invalid state of a Payment. In the future this should be removed.
@@ -52,10 +52,15 @@ module Spree
52
52
  end
53
53
 
54
54
  def set_current_order
55
- if try_spree_current_user && current_order
56
- try_spree_current_user.orders.incomplete.where('id != ?', current_order.id).each do |order|
57
- current_order.merge!(order, try_spree_current_user)
58
- end
55
+ return unless try_spree_current_user && current_order
56
+
57
+ orders_scope = try_spree_current_user.orders.
58
+ incomplete.
59
+ where.not(id: current_order.id).
60
+ where(store_id: current_store.id)
61
+
62
+ orders_scope.each do |order|
63
+ current_order.merge!(order, try_spree_current_user)
59
64
  end
60
65
  end
61
66
 
@@ -1,5 +1,5 @@
1
1
  module Spree
2
2
  def self.version
3
- '4.2.0.beta'
3
+ '4.2.0.rc1'
4
4
  end
5
5
  end
@@ -33,7 +33,7 @@ module Spree
33
33
  :id, :firstname, :lastname, :first_name, :last_name,
34
34
  :address1, :address2, :city, :country_iso, :country_id, :state_id,
35
35
  :zipcode, :phone, :state_name, :alternative_phone, :company,
36
- :user_id, :deleted_at,
36
+ :user_id, :deleted_at, :label,
37
37
  country: [:iso, :name, :iso3, :iso_name],
38
38
  state: [:name, :abbr]
39
39
  ]
@@ -101,7 +101,7 @@ module Spree
101
101
  :customer_support_email, :facebook, :twitter, :instagram,
102
102
  :description, :address, :contact_email, :contact_phone,
103
103
  :default_locale, :default_country_id, :supported_currencies,
104
- :new_order_notifications_email]
104
+ :new_order_notifications_email, :mailer_logo]
105
105
 
106
106
  @@store_credit_attributes = %i[amount currency category_id memo]
107
107
 
@@ -50,6 +50,7 @@ Gem::Specification.new do |s|
50
50
  s.add_dependency 'sprockets-rails'
51
51
  s.add_dependency 'mini_magick', '>= 4.9.4', '< 4.11.0'
52
52
  s.add_dependency 'image_processing', '~> 1.2'
53
+ s.add_dependency 'active_storage_validations', '~> 0.9'
53
54
 
54
55
  s.add_development_dependency 'email_spec', '~> 2.2'
55
56
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.0.beta
4
+ version: 4.2.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Schofield
8
8
  - Spark Solutions
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-09-07 00:00:00.000000000 Z
12
+ date: 2020-10-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemerchant
@@ -377,6 +377,20 @@ dependencies:
377
377
  - - "~>"
378
378
  - !ruby/object:Gem::Version
379
379
  version: '1.2'
380
+ - !ruby/object:Gem::Dependency
381
+ name: active_storage_validations
382
+ requirement: !ruby/object:Gem::Requirement
383
+ requirements:
384
+ - - "~>"
385
+ - !ruby/object:Gem::Version
386
+ version: '0.9'
387
+ type: :runtime
388
+ prerelease: false
389
+ version_requirements: !ruby/object:Gem::Requirement
390
+ requirements:
391
+ - - "~>"
392
+ - !ruby/object:Gem::Version
393
+ version: '0.9'
380
394
  - !ruby/object:Gem::Dependency
381
395
  name: email_spec
382
396
  requirement: !ruby/object:Gem::Requirement
@@ -407,6 +421,7 @@ files:
407
421
  - app/assets/images/noimage/small.png
408
422
  - app/assets/javascripts/spree.js
409
423
  - app/controllers/spree/base_controller.rb
424
+ - app/finders/spree/addresses/find.rb
410
425
  - app/finders/spree/countries/find.rb
411
426
  - app/finders/spree/credit_cards/find.rb
412
427
  - app/finders/spree/line_items/find_by_variant.rb
@@ -620,6 +635,9 @@ files:
620
635
  - app/presenters/spree/variant_presenter.rb
621
636
  - app/presenters/spree/variants/option_types_presenter.rb
622
637
  - app/presenters/spree/variants/options_presenter.rb
638
+ - app/services/spree/account/addresses/base.rb
639
+ - app/services/spree/account/addresses/create.rb
640
+ - app/services/spree/account/addresses/update.rb
623
641
  - app/services/spree/cart/add_item.rb
624
642
  - app/services/spree/cart/create.rb
625
643
  - app/services/spree/cart/estimate_shipping_rates.rb
@@ -956,7 +974,9 @@ files:
956
974
  - db/migrate/20200513154939_add_show_property_to_spree_product_properties.rb
957
975
  - db/migrate/20200607161221_add_store_owner_order_notification_delivered_to_spree_orders.rb
958
976
  - db/migrate/20200607161222_add_new_order_notifications_email_to_spree_stores.rb
977
+ - db/migrate/20200610113542_add_label_to_spree_addresses.rb
959
978
  - db/migrate/20200826075557_add_unique_index_on_taxon_id_and_product_id_to_spree_products_taxons.rb
979
+ - db/migrate/20201013084504_add_seo_robots_to_spree_stores.rb
960
980
  - db/seeds.rb
961
981
  - lib/friendly_id/slug_rails5_patch.rb
962
982
  - lib/generators/spree/custom_user/custom_user_generator.rb
@@ -1108,10 +1128,10 @@ licenses:
1108
1128
  - BSD-3-Clause
1109
1129
  metadata:
1110
1130
  bug_tracker_uri: https://github.com/spree/spree/issues
1111
- changelog_uri: https://github.com/spree/spree/releases/tag/v4.2.0.beta
1131
+ changelog_uri: https://github.com/spree/spree/releases/tag/v4.2.0.rc1
1112
1132
  documentation_uri: https://guides.spreecommerce.org/
1113
- source_code_uri: https://github.com/spree/spree/tree/v4.2.0.beta
1114
- post_install_message:
1133
+ source_code_uri: https://github.com/spree/spree/tree/v4.2.0.rc1
1134
+ post_install_message:
1115
1135
  rdoc_options: []
1116
1136
  require_paths:
1117
1137
  - lib
@@ -1126,8 +1146,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1126
1146
  - !ruby/object:Gem::Version
1127
1147
  version: 1.8.23
1128
1148
  requirements: []
1129
- rubygems_version: 3.1.2
1130
- signing_key:
1149
+ rubygems_version: 3.1.4
1150
+ signing_key:
1131
1151
  specification_version: 4
1132
1152
  summary: The bare bones necessary for Spree.
1133
1153
  test_files: []