spree_core 4.0.9 → 4.1.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/spree.js +0 -1
  3. data/app/finders/spree/products/find.rb +19 -6
  4. data/app/finders/spree/variants/option_types_finder.rb +21 -0
  5. data/app/finders/spree/variants/visible_finder.rb +22 -0
  6. data/app/helpers/spree/base_helper.rb +48 -18
  7. data/app/helpers/spree/products_helper.rb +76 -8
  8. data/app/models/concerns/spree/user_methods.rb +2 -2
  9. data/app/models/spree/app_dependencies.rb +1 -7
  10. data/app/models/spree/credit_card.rb +4 -5
  11. data/app/models/spree/image/configuration/active_storage.rb +9 -1
  12. data/app/models/spree/image.rb +52 -3
  13. data/app/models/spree/line_item.rb +1 -2
  14. data/app/models/spree/option_type.rb +4 -0
  15. data/app/models/spree/order/address_book.rb +20 -7
  16. data/app/models/spree/order/store_credit.rb +0 -8
  17. data/app/models/spree/order.rb +12 -12
  18. data/app/models/spree/payment_method.rb +8 -0
  19. data/app/models/spree/preferences/preferable.rb +1 -1
  20. data/app/models/spree/product.rb +7 -6
  21. data/app/models/spree/promotion/actions/create_item_adjustments.rb +1 -1
  22. data/app/models/spree/promotion_handler/coupon.rb +2 -1
  23. data/app/models/spree/return_item/eligibility_validator/base_validator.rb +1 -1
  24. data/app/models/spree/store.rb +2 -1
  25. data/app/models/spree/taxon.rb +2 -6
  26. data/app/models/spree/variant.rb +2 -14
  27. data/app/models/spree/zone.rb +6 -3
  28. data/app/presenters/spree/product_summary_presenter.rb +26 -0
  29. data/app/presenters/spree/variant_presenter.rb +69 -0
  30. data/app/presenters/spree/variants/option_types_presenter.rb +74 -0
  31. data/app/presenters/spree/variants/options_presenter.rb +49 -0
  32. data/app/services/spree/checkout/get_shipping_rates.rb +10 -7
  33. data/app/services/spree/checkout/update.rb +2 -13
  34. data/config/locales/en.yml +156 -14
  35. data/db/default/spree/stores.rb +8 -3
  36. data/db/migrate/20140309033438_create_store_from_preferences.rb +8 -4
  37. data/db/migrate/20191005121504_add_store_id_to_payment_methods.rb +7 -0
  38. data/db/migrate/20191016134113_add_deafult_value_for_store_default_currency.rb +5 -0
  39. data/db/migrate/20200102141311_add_social_to_spree_stores.rb +7 -0
  40. data/lib/generators/spree/dummy/dummy_generator.rb +3 -1
  41. data/lib/generators/spree/dummy/templates/initializers/bullet.rb +5 -0
  42. data/lib/generators/spree/install/install_generator.rb +13 -5
  43. data/lib/generators/spree/install/templates/config/initializers/spree.rb +0 -1
  44. data/lib/generators/spree/install/templates/config/initializers/spree_storefront.rb +1 -0
  45. data/lib/generators/spree/install/templates/config/spree_storefront.yml +67 -0
  46. data/lib/spree/core/controller_helpers/order.rb +12 -6
  47. data/lib/spree/core/controller_helpers/store.rb +2 -2
  48. data/lib/spree/core/search/base.rb +59 -22
  49. data/lib/spree/core/version.rb +1 -3
  50. data/lib/spree/core.rb +0 -1
  51. data/lib/spree/money.rb +8 -1
  52. data/lib/spree/permitted_attributes.rb +3 -2
  53. data/lib/spree/testing_support/capybara_ext.rb +0 -52
  54. data/lib/spree/testing_support/common_rake.rb +1 -1
  55. data/lib/spree/testing_support/factories/store_factory.rb +3 -0
  56. data/lib/spree/testing_support/order_walkthrough.rb +7 -3
  57. data/spree_core.gemspec +9 -15
  58. metadata +49 -35
  59. data/app/finders/spree/addresses/find.rb +0 -17
  60. data/app/models/spree/order_contents.rb +0 -31
  61. data/app/services/spree/account/addresses/base.rb +0 -39
  62. data/app/services/spree/account/addresses/create.rb +0 -18
  63. data/app/services/spree/account/addresses/update.rb +0 -18
  64. data/lib/spree/database_type_utilities.rb +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a03a9b9613b892110e4ddbf70e4f8e3da2cd83bf5636d29eb49e486f3fb4657
4
- data.tar.gz: c07761960b024e5c87fee995ba330be9c702622be01ca07b9fe7c0315d92a48f
3
+ metadata.gz: db73357d472e46822ad95d6ee2071b01413e2f1ab743177f7cfc8845c6830092
4
+ data.tar.gz: 83c396103e3809183ac12c21f72e4831cb2c10d1089232bdecd58395459a961b
5
5
  SHA512:
6
- metadata.gz: a4d24118216bd79b613f96692b37d09289298de88da7b895d9345645fe6a23bb34862d889e3812dcd27570d8791e9584c11c8fe25bf76484100e7d175533d041
7
- data.tar.gz: 6be12d08fad71b54fe85fa83c0c86efd8e99ba5203fccb992bf8dd51b7d974c598f0e28a00afd249c9037d0f24d16583f4e1aa3290d30df00f49a9be2c7bff53
6
+ metadata.gz: f57f8d0b1bee1cb0b0d77b7aa82ac8f62d89a783e07dbd1e5f2a8a6d780eaf8de46ccf5e898420d423fe1d133ce2645615cd4611580ca92008d006c059667e1a
7
+ data.tar.gz: 7e3aee2e5bcc514a78dcc8da3cfb5b35635f691fc2fe9ac68002c9cd208bc96b5df4f784da4612cf1ad409dea467e0a5c29cc13e156e25aa7baeb5d72f367f47
@@ -2,7 +2,6 @@
2
2
  function Spree () {}
3
3
 
4
4
  Spree.ready = function (callback) {
5
- jQuery(callback)
6
5
  return jQuery(document).on('page:load turbolinks:load', function () {
7
6
  return callback(jQuery)
8
7
  })
@@ -112,17 +112,30 @@ module Spree
112
112
  def by_options(products)
113
113
  return products unless options?
114
114
 
115
- products.where(
116
- id: options.map do |key, value|
117
- products.with_option_value(key, value).ids
118
- end.flatten.compact.uniq
119
- )
115
+ options.map do |key, value|
116
+ products.with_option_value(key, value)
117
+ end.inject(:&)
120
118
  end
121
119
 
122
120
  def by_option_value_ids(products)
123
121
  return products unless option_value_ids?
124
122
 
125
- products.joins(variants: :option_values).distinct.where(spree_option_values: { id: option_value_ids })
123
+ product_ids = Spree::Product.
124
+ joins(variants: :option_values).
125
+ where(spree_option_values: { id: option_value_ids }).
126
+ group("#{Spree::Product.table_name}.id, #{Spree::Variant.table_name}.id").
127
+ having('COUNT(spree_option_values.option_type_id) = ?', option_types_count(option_value_ids)).
128
+ distinct.
129
+ ids
130
+
131
+ products.where(id: product_ids)
132
+ end
133
+
134
+ def option_types_count(option_value_ids)
135
+ Spree::OptionValue.
136
+ where(id: option_value_ids).
137
+ distinct.
138
+ count(:option_type_id)
126
139
  end
127
140
 
128
141
  def ordered(products)
@@ -0,0 +1,21 @@
1
+ module Spree
2
+ module Variants
3
+ class OptionTypesFinder
4
+ COLOR_TYPE = 'color'.freeze
5
+
6
+ def initialize(variant_ids:)
7
+ @variant_ids = variant_ids
8
+ end
9
+
10
+ def execute
11
+ Spree::OptionType.includes(option_values: :variants).where(spree_variants: { id: variant_ids }).
12
+ reorder('spree_option_types.position ASC, spree_option_values.position ASC').
13
+ partition { |option_type| option_type.name.downcase == COLOR_TYPE }.flatten
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :variant_ids
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ module Spree
2
+ module Variants
3
+ class VisibleFinder
4
+ def initialize(scope:, current_currency:)
5
+ @scope = scope
6
+ @current_currency = current_currency
7
+ end
8
+
9
+ def execute
10
+ Spree::Variant.where(id: active_variants).joins(:option_values).order('spree_option_values.position ASC')
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :scope, :current_currency
16
+
17
+ def active_variants
18
+ scope.active(current_currency).unscope(:order)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -32,8 +32,12 @@ module Spree
32
32
  end
33
33
  end
34
34
 
35
- def logo(image_path = Spree::Config[:logo])
36
- link_to image_tag(image_path), spree.respond_to?(:root_path) ? spree.root_path : main_app.root_path
35
+ def logo(image_path = Spree::Config[:logo], options = {})
36
+ path = spree.respond_to?(:root_path) ? spree.root_path : main_app.root_path
37
+
38
+ link_to path, 'aria-label': current_store.name, method: options[:method] do
39
+ image_tag image_path, alt: current_store.name, title: current_store.name
40
+ end
37
41
  end
38
42
 
39
43
  def meta_data
@@ -50,15 +54,32 @@ module Spree
50
54
  end
51
55
 
52
56
  if meta[:keywords].blank? || meta[:description].blank?
53
- meta.reverse_merge!(keywords: current_store.meta_keywords,
54
- description: current_store.meta_description)
57
+ if object && object[:name].present?
58
+ meta.reverse_merge!(keywords: [object.name, current_store.meta_keywords].reject(&:blank?).join(', '),
59
+ description: [object.name, current_store.meta_description].reject(&:blank?).join(', '))
60
+ else
61
+ meta.reverse_merge!(keywords: (current_store.meta_keywords || current_store.seo_title),
62
+ description: (current_store.meta_description || current_store.seo_title))
63
+ end
55
64
  end
56
65
  meta
57
66
  end
58
67
 
68
+ def meta_image_url_path
69
+ object = instance_variable_get('@' + controller_name.singularize)
70
+ return unless object.is_a?(Spree::Product)
71
+
72
+ image = default_image_for_product_or_variant(object)
73
+ image&.attachment.present? ? main_app.url_for(image.attachment) : asset_path(Spree::Config[:logo])
74
+ end
75
+
76
+ def meta_image_data_tag
77
+ tag('meta', property: 'og:image', content: meta_image_url_path) if meta_image_url_path
78
+ end
79
+
59
80
  def meta_data_tags
60
81
  meta_data.map do |name, content|
61
- tag('meta', name: name, content: content)
82
+ tag('meta', name: name, content: content) unless name.nil? || content.nil?
62
83
  end.join("\n")
63
84
  end
64
85
 
@@ -75,14 +96,30 @@ module Spree
75
96
  [I18n.l(time.to_date, format: :long), time.strftime('%l:%M %p')].join(' ')
76
97
  end
77
98
 
78
- def seo_url(taxon)
79
- spree.nested_taxons_path(taxon.permalink)
99
+ def seo_url(taxon, options = nil)
100
+ spree.nested_taxons_path(taxon.permalink, options)
80
101
  end
81
102
 
82
103
  def frontend_available?
83
104
  Spree::Core::Engine.frontend_available?
84
105
  end
85
106
 
107
+ def default_image_for_product_or_variant(product_or_variant)
108
+ if product_or_variant.images.empty?
109
+ if product_or_variant.is_a?(Spree::Product) && product_or_variant.variant_images.any?
110
+ product_or_variant.variant_images.first
111
+ elsif product_or_variant.is_a?(Spree::Variant) && product_or_variant.product.variant_images.any?
112
+ product_or_variant.product.variant_images.first
113
+ end
114
+ else
115
+ product_or_variant.images.first
116
+ end
117
+ end
118
+
119
+ def base_cache_key
120
+ [I18n.locale, current_currency]
121
+ end
122
+
86
123
  private
87
124
 
88
125
  def create_product_image_tag(image, product, options, style)
@@ -94,18 +131,11 @@ module Spree
94
131
  self.class.send :define_method, "#{style}_image" do |product, *options|
95
132
  options = options.first || {}
96
133
  options[:alt] ||= product.name
97
- if product.images.empty?
98
- if !product.is_a?(Spree::Variant) && !product.variant_images.empty?
99
- create_product_image_tag(product.variant_images.first, product, options, style)
100
- else
101
- if product.is_a?(Variant) && !product.product.variant_images.empty?
102
- create_product_image_tag(product.product.variant_images.first, product, options, style)
103
- else
104
- image_tag "noimage/#{style}.png", options
105
- end
106
- end
134
+ image_path = default_image_for_product_or_variant(product)
135
+ if image_path.present?
136
+ create_product_image_tag image_path, product, options, style
107
137
  else
108
- create_product_image_tag(product.images.first, product, options, style)
138
+ image_tag "noimage/#{style}.png", options
109
139
  end
110
140
  end
111
141
  end
@@ -1,5 +1,7 @@
1
1
  module Spree
2
2
  module ProductsHelper
3
+ include BaseHelper
4
+
3
5
  # returns the formatted price for the specified variant as a full price or a difference depending on configuration
4
6
  def variant_price(variant)
5
7
  if Spree::Config[:show_variant_full_price]
@@ -29,6 +31,14 @@ module Spree
29
31
  end
30
32
  end
31
33
 
34
+ def default_variant(variants)
35
+ variants_option_types_presenter(variants).default_variant || variants.find(&:is_master)
36
+ end
37
+
38
+ def used_variants_options(variants)
39
+ variants_option_types_presenter(variants).options
40
+ end
41
+
32
42
  # converts line breaks in product description into <p> tags (for html display purposes)
33
43
  def product_description(product)
34
44
  description = if Spree::Config[:show_raw_product_description]
@@ -47,15 +57,27 @@ module Spree
47
57
  end
48
58
  end
49
59
 
50
- def cache_key_for_products
51
- count = @products.count
52
- max_updated_at = (@products.maximum(:updated_at) || Date.today).to_s(:number)
53
- products_cache_keys = "spree/products/all-#{params[:page]}-#{max_updated_at}-#{count}"
54
- (common_product_cache_keys + [products_cache_keys]).compact.join('/')
60
+ def cache_key_for_products(products = @products, additional_cache_key = nil)
61
+ count = products.count
62
+ max_updated_at = (products.maximum(:updated_at) || Date.today).to_s(:number)
63
+ products_cache_keys = "spree/products/all-#{params[:page]}-#{params[:sort_by]}-#{max_updated_at}-#{count}-#{@taxon&.id}"
64
+ (common_product_cache_keys + [products_cache_keys] + [additional_cache_key]).compact.join('/')
55
65
  end
56
66
 
57
67
  def cache_key_for_product(product = @product)
58
- (common_product_cache_keys + [product.cache_key_with_version, product.possible_promotions]).compact.join('/')
68
+ cache_key_elements = common_product_cache_keys
69
+ cache_key_elements += [
70
+ product.cache_key_with_version,
71
+ product.possible_promotions
72
+ ]
73
+
74
+ cache_key_elements.compact.join('/')
75
+ end
76
+
77
+ def limit_descritpion(string)
78
+ return string if string.length <= 450
79
+
80
+ string.slice(0..449) + '...'
59
81
  end
60
82
 
61
83
  def available_status(product) # will return a human readable string
@@ -71,16 +93,62 @@ module Spree
71
93
  end
72
94
  end
73
95
 
74
- private
96
+ def product_images(product, variants)
97
+ variants = if product.variants_and_option_values(current_currency).any?
98
+ variants.reject(&:is_master)
99
+ else
100
+ variants
101
+ end
102
+
103
+ variants.map(&:images).flatten
104
+ end
105
+
106
+ def product_variants_matrix(is_product_available_in_currency)
107
+ Spree::VariantPresenter.new(
108
+ variants: @variants,
109
+ is_product_available_in_currency: is_product_available_in_currency,
110
+ current_currency: current_currency,
111
+ current_price_options: current_price_options
112
+ ).call.to_json
113
+ end
114
+
115
+ def related_products
116
+ return [] unless @product.respond_to?(:has_related_products?) && @product.has_related_products?(:related_products)
117
+
118
+ @_related_products ||= @product.
119
+ related_products.
120
+ includes(
121
+ :tax_category,
122
+ master: [
123
+ :prices,
124
+ images: { attachment_attachment: :blob },
125
+ ]
126
+ ).
127
+ limit(Spree::Config[:products_per_page])
128
+ end
129
+
130
+ def product_available_in_currency?(product)
131
+ !(product.price_in(current_currency).amount.nil? || product.price_in(current_currency).amount.zero?)
132
+ end
75
133
 
76
134
  def common_product_cache_keys
77
- [I18n.locale, current_currency] + price_options_cache_key
135
+ base_cache_key + price_options_cache_key
78
136
  end
79
137
 
138
+ private
139
+
80
140
  def price_options_cache_key
81
141
  current_price_options.sort.map(&:last).map do |value|
82
142
  value.try(:cache_key) || value
83
143
  end
84
144
  end
145
+
146
+ def variants_option_types_presenter(variants)
147
+ @_variants_option_types_presenter ||= begin
148
+ option_types = Spree::Variants::OptionTypesFinder.new(variant_ids: variants.map(&:id)).execute
149
+
150
+ Spree::Variants::OptionTypesPresenter.new(option_types)
151
+ end
152
+ end
85
153
  end
86
154
  end
@@ -47,9 +47,9 @@ module Spree
47
47
  spree_roles.any? { |role| role.name == role_in_question.to_s }
48
48
  end
49
49
 
50
- def last_incomplete_spree_order(store)
50
+ def last_incomplete_spree_order(store, options = {})
51
51
  orders.where(store: store).incomplete.
52
- includes(line_items: [variant: [:images, :option_values, :product]]).
52
+ includes(options[:includes]).
53
53
  order('created_at DESC').
54
54
  first
55
55
  end
@@ -11,8 +11,7 @@ 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,
15
- :account_create_address_service, :account_update_address_service, :address_finder
14
+ :products_finder, :taxon_finder, :line_item_by_variant_finder, :cart_estimate_shipping_rates_service
16
15
  ].freeze
17
16
 
18
17
  attr_accessor *INJECTION_POINTS
@@ -60,14 +59,9 @@ module Spree
60
59
  # coupons
61
60
  # TODO: we should split this service into 2 seperate - Add and Remove
62
61
  @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'
67
62
  end
68
63
 
69
64
  def set_default_finders
70
- @address_finder = 'Spree::Addresses::Find'
71
65
  @country_finder = 'Spree::Countries::Find'
72
66
  @current_order_finder = 'Spree::Orders::FindCurrent'
73
67
  @completed_order_finder = 'Spree::Orders::FindComplete'
@@ -24,9 +24,10 @@ module Spree
24
24
  attribute :month, ActiveRecord::Type::Integer.new
25
25
  attribute :year, ActiveRecord::Type::Integer.new
26
26
 
27
- attr_reader :number, :verification_value
27
+ attr_reader :number
28
28
  attr_accessor :encrypted_data,
29
29
  :imported,
30
+ :verification_value,
30
31
  :manual_entry
31
32
 
32
33
  with_options if: :require_card_numbers?, on: :create do
@@ -100,11 +101,9 @@ module Spree
100
101
  end
101
102
  end
102
103
 
103
- def verification_value=(value)
104
- @verification_value = value.to_s.gsub(/\s/, '')
105
- end
106
-
107
104
  def set_last_digits
105
+ number.to_s.gsub!(/\s/, '')
106
+ verification_value.to_s.gsub!(/\s/, '')
108
107
  self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
109
108
  end
110
109
 
@@ -15,7 +15,15 @@ module Spree
15
15
  mini: '48x48>',
16
16
  small: '100x100>',
17
17
  product: '240x240>',
18
- large: '600x600>'
18
+ pdp_thumbnail: '160x200>',
19
+ plp_and_carousel: '448x600>',
20
+ plp_and_carousel_xs: '254x340>',
21
+ plp_and_carousel_sm: '350x468>',
22
+ plp_and_carousel_md: '222x297>',
23
+ plp_and_carousel_lg: '278x371>',
24
+ large: '600x600>',
25
+ plp: '278x371>',
26
+ zoomed: '650x870>'
19
27
  }
20
28
  end
21
29
 
@@ -2,7 +2,7 @@ module Spree
2
2
  class Image < Asset
3
3
  include Configuration::ActiveStorage
4
4
  include Rails.application.routes.url_helpers
5
-
5
+
6
6
  # In Rails 5.x class constants are being undefined/redefined during the code reloading process
7
7
  # in a rails development environment, after which the actual ruby objects stored in those class constants
8
8
  # are no longer equal (subclass == self) what causes error ActiveRecord::SubclassNotFound
@@ -12,14 +12,63 @@ module Spree
12
12
 
13
13
  def styles
14
14
  self.class.styles.map do |_, size|
15
- width, height = size[/(\d+)x(\d+)/].split('x')
15
+ width, height = size.chop.split('x')
16
16
 
17
17
  {
18
- url: polymorphic_path(attachment.variant(resize: size), only_path: true),
18
+ url: polymorphic_path(attachment.variant(combine_options: {
19
+ gravity: 'center',
20
+ resize: size,
21
+ extent: size,
22
+ background: 'snow2',
23
+ quality: 80
24
+ }), only_path: true),
19
25
  width: width,
20
26
  height: height
21
27
  }
22
28
  end
23
29
  end
30
+
31
+ def style(name)
32
+ size = self.class.styles[name]
33
+ return unless size
34
+
35
+ width, height = size.chop.split('x')
36
+
37
+ {
38
+ url: polymorphic_path(attachment.variant(combine_options: {
39
+ gravity: 'center',
40
+ resize: size,
41
+ extent: size,
42
+ background: 'snow2',
43
+ quality: 80
44
+ }), only_path: true),
45
+ size: size,
46
+ width: width,
47
+ height: height
48
+ }
49
+ end
50
+
51
+ def style_dimensions(name)
52
+ size = self.class.styles[name]
53
+ width, height = size.chop.split('x')
54
+
55
+ {
56
+ width: width,
57
+ height: height
58
+ }
59
+ end
60
+
61
+ def plp_url
62
+ size = self.class.styles[:plp_and_carousel]
63
+ variant = attachment.variant(
64
+ gravity: 'center',
65
+ resize: size,
66
+ extent: size,
67
+ background: 'snow2',
68
+ quality: 80
69
+ )
70
+
71
+ polymorphic_path(variant, only_path: true)
72
+ end
24
73
  end
25
74
  end
@@ -59,8 +59,7 @@ module Spree
59
59
 
60
60
  extend DisplayMoney
61
61
  money_methods :amount, :subtotal, :discounted_amount, :final_amount, :total, :price,
62
- :adjustment_total, :additional_tax_total, :promo_total, :included_tax_total,
63
- :pre_tax_amount
62
+ :adjustment_total, :additional_tax_total, :promo_total, :included_tax_total
64
63
 
65
64
  alias single_money display_price
66
65
  alias single_display_amount display_price
@@ -23,6 +23,10 @@ module Spree
23
23
 
24
24
  after_touch :touch_all_products
25
25
 
26
+ def filter_param
27
+ presentation.titleize.delete(' ').downcase
28
+ end
29
+
26
30
  private
27
31
 
28
32
  def touch_all_products
@@ -55,18 +55,31 @@ module Spree
55
55
  def update_or_create_address(attributes = {})
56
56
  return if attributes.blank?
57
57
 
58
- attributes.transform_values! { |v| v == '' ? nil : v }
58
+ attributes = attributes.select { |_k, v| v.present? }
59
59
 
60
- default_address_scope = user ? user.addresses : ::Spree::Address
61
- default_address = default_address_scope.find_by(id: attributes[:id])
60
+ if user
61
+ address = user.addresses.build(attributes.except(:id)).check
62
+ return address if address.id
63
+ end
64
+
65
+ if attributes[:id]
66
+ address = Spree::Address.find(attributes[:id])
67
+ attributes.delete(:id)
62
68
 
63
- if default_address&.editable?
64
- default_address.update(attributes)
69
+ if address&.editable?
70
+ address.update(attributes)
71
+ return address
72
+ else
73
+ attributes.delete(:id)
74
+ end
75
+ end
65
76
 
66
- return default_address
77
+ unless attributes[:id]
78
+ address = Spree::Address.new(attributes)
79
+ address.save
67
80
  end
68
81
 
69
- ::Spree::Address.find_or_create_by(attributes.except(:id, :updated_at, :created_at))
82
+ address
70
83
  end
71
84
  end
72
85
  end
@@ -1,14 +1,6 @@
1
1
  module Spree
2
2
  class Order < Spree::Base
3
3
  module StoreCredit
4
- def add_store_credit_payments(amount = nil)
5
- Spree::Dependencies.checkout_add_store_credit_service.constantize.call(order: self, amount: amount)
6
- end
7
-
8
- def remove_store_credit_payments
9
- Spree::Dependencies.checkout_remove_store_credit_service.constantize.call(order: self)
10
- end
11
-
12
4
  def covered_by_store_credit?
13
5
  return false unless user
14
6
 
@@ -21,8 +21,7 @@ module Spree
21
21
  extend Spree::DisplayMoney
22
22
  money_methods :outstanding_balance, :item_total, :adjustment_total,
23
23
  :included_tax_total, :additional_tax_total, :tax_total,
24
- :shipment_total, :promo_total, :total,
25
- :cart_promo_total, :pre_tax_item_amount, :pre_tax_total
24
+ :shipment_total, :promo_total, :total
26
25
 
27
26
  alias display_ship_total display_shipment_total
28
27
  alias_attribute :ship_total, :shipment_total
@@ -174,12 +173,7 @@ module Spree
174
173
 
175
174
  # Sum of all line item amounts pre-tax
176
175
  def pre_tax_item_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)
176
+ line_items.to_a.sum(&:pre_tax_amount)
183
177
  end
184
178
 
185
179
  def shipping_discount
@@ -375,8 +369,8 @@ module Spree
375
369
  payment_state == 'paid' || payment_state == 'credit_owed'
376
370
  end
377
371
 
378
- def available_payment_methods
379
- @available_payment_methods ||= collect_payment_methods
372
+ def available_payment_methods(store = nil)
373
+ @available_payment_methods ||= collect_payment_methods(store)
380
374
  end
381
375
 
382
376
  def insufficient_stock_lines
@@ -631,6 +625,12 @@ module Spree
631
625
  all_adjustments.eligible.nonzero.promotion.map { |a| a.source.promotion_id }.uniq
632
626
  end
633
627
 
628
+ def valid_coupon_promotions
629
+ promotions.
630
+ where(id: valid_promotion_ids).
631
+ coupons
632
+ end
633
+
634
634
  private
635
635
 
636
636
  def link_by_email
@@ -689,8 +689,8 @@ module Spree
689
689
  self.token ||= generate_token
690
690
  end
691
691
 
692
- def collect_payment_methods
693
- PaymentMethod.available_on_front_end.select { |pm| pm.available_for_order?(self) }
692
+ def collect_payment_methods(store = nil)
693
+ PaymentMethod.available_on_front_end.select { |pm| pm.available_for_order?(self) && pm.available_for_store?(store) }
694
694
  end
695
695
 
696
696
  def credit_card_nil_payment?(attributes)
@@ -12,6 +12,8 @@ module Spree
12
12
 
13
13
  validates :name, presence: true
14
14
 
15
+ belongs_to :store
16
+
15
17
  with_options dependent: :restrict_with_error do
16
18
  has_many :payments, class_name: 'Spree::Payment', inverse_of: :payment_method
17
19
  has_many :credit_cards, class_name: 'Spree::CreditCard'
@@ -75,5 +77,11 @@ module Spree
75
77
  def available_for_order?(_order)
76
78
  true
77
79
  end
80
+
81
+ def available_for_store?(store)
82
+ return true if store.blank? || store_id.blank?
83
+
84
+ store_id == store.id
85
+ end
78
86
  end
79
87
  end
@@ -100,7 +100,7 @@ module Spree::Preferences::Preferable
100
100
  if value.is_a?(FalseClass) ||
101
101
  value.nil? ||
102
102
  value == 0 ||
103
- value&.to_s =~ /^(f|false|0)$/i ||
103
+ value =~ /^(f|false|0)$/i ||
104
104
  (value.respond_to?(:empty?) && value.empty?)
105
105
  false
106
106
  else