spree_core 4.1.10 → 4.2.0.rc2
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.
- checksums.yaml +4 -4
- data/app/controllers/spree/base_controller.rb +1 -0
- data/app/helpers/spree/base_helper.rb +61 -14
- data/app/helpers/spree/mail_helper.rb +29 -0
- data/app/helpers/spree/products_helper.rb +2 -1
- data/app/mailers/spree/base_mailer.rb +17 -3
- data/app/mailers/spree/order_mailer.rb +11 -2
- data/app/mailers/spree/reimbursement_mailer.rb +4 -2
- data/app/mailers/spree/shipment_mailer.rb +4 -2
- data/app/models/concerns/spree/default_price.rb +2 -1
- data/app/models/concerns/spree/user_methods.rb +11 -5
- data/app/models/concerns/spree/user_payment_source.rb +1 -1
- data/app/models/spree/address.rb +13 -1
- data/app/models/spree/adjustment.rb +1 -0
- data/app/models/spree/app_configuration.rb +4 -0
- data/app/models/spree/credit_card.rb +5 -0
- data/app/models/spree/line_item.rb +12 -2
- data/app/models/spree/log_entry.rb +1 -1
- data/app/models/spree/option_type.rb +7 -1
- data/app/models/spree/order.rb +33 -7
- data/app/models/spree/order/address_book.rb +7 -20
- data/app/models/spree/order/payments.rb +10 -2
- data/app/models/spree/preferences/store.rb +1 -1
- data/app/models/spree/price.rb +26 -2
- data/app/models/spree/product.rb +17 -7
- data/app/models/spree/promotion.rb +10 -15
- data/app/models/spree/promotion_handler/coupon.rb +2 -3
- data/app/models/spree/promotion_handler/promotion_duplicator.rb +9 -3
- data/app/models/spree/reimbursement.rb +2 -0
- data/app/models/spree/shipment.rb +2 -5
- data/app/models/spree/stock_location.rb +13 -2
- data/app/models/spree/store.rb +27 -2
- data/app/models/spree/variant.rb +15 -2
- data/app/models/spree/zone.rb +4 -0
- data/app/presenters/spree/variant_presenter.rb +9 -1
- data/app/presenters/spree/variants/option_types_presenter.rb +1 -0
- data/app/views/layouts/spree/base_mailer.html.erb +45 -40
- data/app/views/spree/order_mailer/cancel_email.html.erb +19 -25
- data/app/views/spree/order_mailer/cancel_email.text.erb +24 -2
- data/app/views/spree/order_mailer/confirm_email.html.erb +18 -65
- data/app/views/spree/order_mailer/confirm_email.text.erb +2 -1
- data/app/views/spree/order_mailer/store_owner_notification_email.html.erb +23 -0
- data/app/views/spree/order_mailer/store_owner_notification_email.text.erb +38 -0
- data/app/views/spree/reimbursement_mailer/reimbursement_email.html.erb +53 -58
- data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +3 -1
- data/app/views/spree/shared/_base_mailer_footer.html.erb +6 -14
- data/app/views/spree/shared/_base_mailer_header.html.erb +12 -32
- data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +293 -625
- data/app/views/spree/shared/_purchased_items_table.html.erb +60 -0
- data/app/views/spree/shared/purchased_items_table/_adjustment.html.erb +13 -0
- data/app/views/spree/shared/purchased_items_table/_line_item.html.erb +27 -0
- data/app/views/spree/shared/purchased_items_table/_subtotal.html.erb +13 -0
- data/app/views/spree/shared/purchased_items_table/_total.html.erb +13 -0
- data/app/views/spree/shipment_mailer/shipped_email.html.erb +31 -36
- data/app/views/spree/shipment_mailer/shipped_email.text.erb +2 -1
- data/config/initializers/assets.rb +1 -0
- data/config/locales/en.yml +125 -16
- data/db/default/spree/countries.rb +10 -4
- data/db/default/spree/states.rb +42 -5
- data/db/default/spree/stores.rb +17 -12
- data/db/default/spree/zones.rb +1 -1
- data/db/migrate/20140309033438_create_store_from_preferences.rb +1 -1
- data/db/migrate/20191017121054_add_supported_currencies_to_store.rb +10 -0
- data/db/migrate/20200102141311_add_social_to_spree_stores.rb +3 -0
- data/db/migrate/20200308210757_add_default_locale_to_spree_store.rb +7 -0
- data/db/migrate/20200310145140_add_customer_support_email_to_spree_store.rb +7 -0
- data/db/migrate/20200421095017_add_compare_at_amount_to_spree_prices.rb +7 -0
- data/db/migrate/20200423123001_add_default_country_id_to_spree_store.rb +9 -0
- data/db/migrate/20200430072209_add_footer_fields_to_spree_stores.rb +8 -0
- data/db/migrate/20200513154939_add_show_property_to_spree_product_properties.rb +5 -0
- data/db/migrate/20200607161221_add_store_owner_order_notification_delivered_to_spree_orders.rb +7 -0
- data/db/migrate/20200607161222_add_new_order_notifications_email_to_spree_stores.rb +7 -0
- data/db/migrate/20200610113542_add_label_to_spree_addresses.rb +5 -0
- data/db/migrate/20200826075557_add_unique_index_on_taxon_id_and_product_id_to_spree_products_taxons.rb +5 -0
- data/db/migrate/20201006110150_add_checkout_zone_field_to_store.rb +12 -0
- data/db/migrate/20201012091259_add_filterable_column_to_spree_option_types.rb +6 -0
- data/db/migrate/20201013084504_add_seo_robots_to_spree_stores.rb +5 -0
- data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/backend/all.js +0 -2
- data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -2
- data/lib/generators/spree/mailers_preview/mailers_preview_generator.rb +23 -0
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/order_preview.rb +13 -0
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/reimbursement_preview.rb +5 -0
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/shipment_preview.rb +5 -0
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/user_preview.rb +11 -0
- data/lib/spree/core.rb +2 -0
- data/lib/spree/core/controller_helpers/common.rb +1 -0
- data/lib/spree/core/controller_helpers/currency_helpers.rb +15 -0
- data/lib/spree/core/controller_helpers/order.rb +9 -4
- data/lib/spree/core/controller_helpers/store.rb +12 -1
- data/lib/spree/core/importer/order.rb +9 -9
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/permitted_attributes.rb +8 -5
- data/lib/spree/testing_support/authorization_helpers.rb +7 -4
- data/lib/spree/testing_support/factories/promotion_factory.rb +29 -17
- data/lib/spree/testing_support/factories/store_factory.rb +11 -8
- data/lib/spree/testing_support/factories/zone_factory.rb +1 -1
- data/lib/spree/testing_support/i18n.rb +1 -1
- data/spree_core.gemspec +6 -5
- data/vendor/assets/javascripts/cleave.js +1669 -0
- metadata +57 -16
- data/app/views/spree/order_mailer/_adjustment.html.erb +0 -8
- data/app/views/spree/order_mailer/_subtotal.html.erb +0 -8
- data/app/views/spree/order_mailer/_total.html.erb +0 -8
@@ -19,12 +19,18 @@ module Spree
|
|
19
19
|
|
20
20
|
default_scope { order(:position) }
|
21
21
|
|
22
|
+
scope :filterable, -> { where(filterable: true) }
|
23
|
+
|
22
24
|
accepts_nested_attributes_for :option_values, reject_if: ->(ov) { ov[:name].blank? || ov[:presentation].blank? }, allow_destroy: true
|
23
25
|
|
24
26
|
after_touch :touch_all_products
|
25
27
|
|
26
28
|
def filter_param
|
27
|
-
|
29
|
+
name.titleize.delete(' ').downcase
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.color
|
33
|
+
find_by(name: 'color')
|
28
34
|
end
|
29
35
|
|
30
36
|
private
|
data/app/models/spree/order.rb
CHANGED
@@ -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.
|
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
|
@@ -297,15 +302,15 @@ module Spree
|
|
297
302
|
def outstanding_balance
|
298
303
|
if canceled?
|
299
304
|
-1 * payment_total
|
300
|
-
elsif refunds.exists?
|
301
|
-
# If refund has happened add it back to total to prevent balance_due payment state
|
302
|
-
# See: https://github.com/spree/spree/issues/6229 & https://github.com/spree/spree/issues/8136
|
303
|
-
total - (payment_total + refunds.sum(:amount))
|
304
305
|
else
|
305
|
-
total - payment_total
|
306
|
+
total - (payment_total + reimbursement_paid_total)
|
306
307
|
end
|
307
308
|
end
|
308
309
|
|
310
|
+
def reimbursement_paid_total
|
311
|
+
reimbursements.sum(&:paid_amount)
|
312
|
+
end
|
313
|
+
|
309
314
|
def outstanding_balance?
|
310
315
|
outstanding_balance != 0
|
311
316
|
end
|
@@ -351,6 +356,8 @@ module Spree
|
|
351
356
|
|
352
357
|
deliver_order_confirmation_email unless confirmation_delivered?
|
353
358
|
|
359
|
+
deliver_store_owner_order_notification_email if deliver_store_owner_order_notification_email?
|
360
|
+
|
354
361
|
consider_risk
|
355
362
|
end
|
356
363
|
|
@@ -641,6 +648,13 @@ module Spree
|
|
641
648
|
sum(:amount)
|
642
649
|
end
|
643
650
|
|
651
|
+
def has_free_shipping?
|
652
|
+
shipment_adjustments.
|
653
|
+
joins(:promotion_action).
|
654
|
+
where(spree_adjustments: { eligible: true, source_type: 'Spree::PromotionAction' },
|
655
|
+
spree_promotion_actions: { type: 'Spree::Promotion::Actions::FreeShipping' }).exists?
|
656
|
+
end
|
657
|
+
|
644
658
|
private
|
645
659
|
|
646
660
|
def link_by_email
|
@@ -706,5 +720,17 @@ module Spree
|
|
706
720
|
def credit_card_nil_payment?(attributes)
|
707
721
|
payments.store_credits.present? && attributes[:amount].to_f.zero?
|
708
722
|
end
|
723
|
+
|
724
|
+
# Returns true if:
|
725
|
+
# 1. an email address is set for new order notifications AND
|
726
|
+
# 2. no notification for this order has been sent yet.
|
727
|
+
def deliver_store_owner_order_notification_email?
|
728
|
+
store.new_order_notifications_email.present? && !store_owner_notification_delivered?
|
729
|
+
end
|
730
|
+
|
731
|
+
def deliver_store_owner_order_notification_email
|
732
|
+
OrderMailer.store_owner_notification_email(id).deliver_later
|
733
|
+
update_column(:store_owner_notification_delivered, true)
|
734
|
+
end
|
709
735
|
end
|
710
736
|
end
|
@@ -55,31 +55,18 @@ module Spree
|
|
55
55
|
def update_or_create_address(attributes = {})
|
56
56
|
return if attributes.blank?
|
57
57
|
|
58
|
-
attributes
|
58
|
+
attributes.transform_values! { |v| v == '' ? nil : v }
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
return address if address.id
|
63
|
-
end
|
64
|
-
|
65
|
-
if attributes[:id]
|
66
|
-
address = Spree::Address.find(attributes[:id])
|
67
|
-
attributes.delete(:id)
|
60
|
+
default_address_scope = user ? user.addresses : ::Spree::Address
|
61
|
+
default_address = default_address_scope.find_by(id: attributes[:id])
|
68
62
|
|
69
|
-
|
70
|
-
|
71
|
-
return address
|
72
|
-
else
|
73
|
-
attributes.delete(:id)
|
74
|
-
end
|
75
|
-
end
|
63
|
+
if default_address&.editable?
|
64
|
+
default_address.update(attributes)
|
76
65
|
|
77
|
-
|
78
|
-
address = Spree::Address.new(attributes)
|
79
|
-
address.save
|
66
|
+
return default_address
|
80
67
|
end
|
81
68
|
|
82
|
-
|
69
|
+
::Spree::Address.find_or_create_by(attributes.except(:id, :updated_at, :created_at))
|
83
70
|
end
|
84
71
|
end
|
85
72
|
end
|
@@ -32,7 +32,7 @@ module Spree
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def pending_payments
|
35
|
-
payments.
|
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 !=
|
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
|
data/app/models/spree/price.rb
CHANGED
@@ -15,10 +15,16 @@ module Spree
|
|
15
15
|
less_than_or_equal_to: MAXIMUM_AMOUNT
|
16
16
|
}
|
17
17
|
|
18
|
+
validates :compare_at_amount, allow_nil: true, numericality: {
|
19
|
+
greater_than_or_equal_to: 0,
|
20
|
+
less_than_or_equal_to: MAXIMUM_AMOUNT
|
21
|
+
}
|
22
|
+
|
18
23
|
extend DisplayMoney
|
19
|
-
money_methods :amount, :price
|
24
|
+
money_methods :amount, :price, :compare_at_amount
|
25
|
+
alias display_compare_at_price display_compare_at_amount
|
20
26
|
|
21
|
-
self.whitelisted_ransackable_attributes = ['amount']
|
27
|
+
self.whitelisted_ransackable_attributes = ['amount', 'compare_at_amount']
|
22
28
|
|
23
29
|
def money
|
24
30
|
Spree::Money.new(amount || 0, currency: currency)
|
@@ -28,17 +34,35 @@ module Spree
|
|
28
34
|
self[:amount] = Spree::LocalizedNumber.parse(amount)
|
29
35
|
end
|
30
36
|
|
37
|
+
def compare_at_money
|
38
|
+
Spree::Money.new(compare_at_amount || 0, currency: currency)
|
39
|
+
end
|
40
|
+
|
41
|
+
def compare_at_amount=(compare_at_amount)
|
42
|
+
self[:compare_at_amount] = Spree::LocalizedNumber.parse(compare_at_amount)
|
43
|
+
end
|
44
|
+
|
31
45
|
alias_attribute :price, :amount
|
46
|
+
alias_attribute :compare_at_price, :compare_at_amount
|
32
47
|
|
33
48
|
def price_including_vat_for(price_options)
|
34
49
|
options = price_options.merge(tax_category: variant.tax_category)
|
35
50
|
gross_amount(price, options)
|
36
51
|
end
|
37
52
|
|
53
|
+
def compare_at_price_including_vat_for(price_options)
|
54
|
+
options = price_options.merge(tax_category: variant.tax_category)
|
55
|
+
gross_amount(compare_at_price, options)
|
56
|
+
end
|
57
|
+
|
38
58
|
def display_price_including_vat_for(price_options)
|
39
59
|
Spree::Money.new(price_including_vat_for(price_options), currency: currency)
|
40
60
|
end
|
41
61
|
|
62
|
+
def display_compare_at_price_including_vat_for(price_options)
|
63
|
+
Spree::Money.new(compare_at_price_including_vat_for(price_options), currency: currency)
|
64
|
+
end
|
65
|
+
|
42
66
|
# Remove variant default_scope `deleted_at: nil`
|
43
67
|
def variant
|
44
68
|
Spree::Variant.unscoped { super }
|
data/app/models/spree/product.rb
CHANGED
@@ -113,17 +113,17 @@ module Spree
|
|
113
113
|
|
114
114
|
self.whitelisted_ransackable_associations = %w[taxons stores variants_including_master master variants]
|
115
115
|
self.whitelisted_ransackable_attributes = %w[description name slug discontinue_on]
|
116
|
-
self.whitelisted_ransackable_scopes = %w[not_discontinued]
|
116
|
+
self.whitelisted_ransackable_scopes = %w[not_discontinued search_by_name]
|
117
117
|
|
118
118
|
[
|
119
119
|
:sku, :price, :currency, :weight, :height, :width, :depth, :is_master,
|
120
|
-
:cost_currency, :price_in, :amount_in, :cost_price
|
120
|
+
:cost_currency, :price_in, :amount_in, :cost_price, :compare_at_price
|
121
121
|
].each do |method_name|
|
122
122
|
delegate method_name, :"#{method_name}=", to: :find_or_build_master
|
123
123
|
end
|
124
124
|
|
125
125
|
delegate :display_amount, :display_price, :has_default_price?,
|
126
|
-
:images, to: :find_or_build_master
|
126
|
+
:display_compare_at_price, :images, to: :find_or_build_master
|
127
127
|
|
128
128
|
alias master_images images
|
129
129
|
|
@@ -160,10 +160,8 @@ module Spree
|
|
160
160
|
#
|
161
161
|
# @return [Spree::Variant]
|
162
162
|
def default_variant
|
163
|
-
|
164
|
-
|
165
|
-
Rails.cache.fetch("spree/default-variant/#{cache_key_with_version}/#{track_inventory}") do
|
166
|
-
if track_inventory && variants.in_stock_or_backorderable.any?
|
163
|
+
Rails.cache.fetch(default_variant_cache_key) do
|
164
|
+
if Spree::Config[:track_inventory_levels] && variants.in_stock_or_backorderable.any?
|
167
165
|
variants.in_stock_or_backorderable.first
|
168
166
|
else
|
169
167
|
has_variants? ? variants.first : master
|
@@ -252,6 +250,14 @@ module Spree
|
|
252
250
|
where conditions.inject(:or)
|
253
251
|
end
|
254
252
|
|
253
|
+
def self.search_by_name(query)
|
254
|
+
if defined?(SpreeGlobalize)
|
255
|
+
joins(:translations).order(:name).where("LOWER(#{Product::Translation.table_name}.name) LIKE LOWER(:query)", query: "%#{query}%").distinct
|
256
|
+
else
|
257
|
+
where("LOWER(#{Product.table_name}.name) LIKE LOWER(:query)", query: "%#{query}%")
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
255
261
|
# Suitable for displaying only variants that has at least one option value.
|
256
262
|
# There may be scenarios where an option type is removed and along with it
|
257
263
|
# all option values. At that point all variants associated with only those
|
@@ -344,6 +350,10 @@ module Spree
|
|
344
350
|
save
|
345
351
|
end
|
346
352
|
|
353
|
+
def default_variant_cache_key
|
354
|
+
"spree/default-variant/#{cache_key_with_version}/#{Spree::Config[:track_inventory_levels]}"
|
355
|
+
end
|
356
|
+
|
347
357
|
def ensure_master
|
348
358
|
return unless new_record?
|
349
359
|
|
@@ -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 {
|
@@ -192,21 +194,10 @@ module Spree
|
|
192
194
|
end
|
193
195
|
|
194
196
|
def used_by?(user, excluded_orders = [])
|
195
|
-
|
196
|
-
:
|
197
|
-
:
|
198
|
-
:
|
199
|
-
].any? do |adjustment_type|
|
200
|
-
user.orders.complete.joins(adjustment_type).where(
|
201
|
-
spree_adjustments: {
|
202
|
-
source_type: 'Spree::PromotionAction',
|
203
|
-
source_id: actions.map(&:id),
|
204
|
-
eligible: true
|
205
|
-
}
|
206
|
-
).where.not(
|
207
|
-
id: excluded_orders.map(&:id)
|
208
|
-
).any?
|
209
|
-
end
|
197
|
+
user.orders.complete.joins(:promotions).joins(:all_adjustments).
|
198
|
+
where.not(spree_orders: { id: excluded_orders.map(&:id) }).
|
199
|
+
where(spree_promotions: { id: id }).
|
200
|
+
where(spree_adjustments: { source_type: 'Spree::PromotionAction', eligible: true }).any?
|
210
201
|
end
|
211
202
|
|
212
203
|
private
|
@@ -227,6 +218,10 @@ module Spree
|
|
227
218
|
end
|
228
219
|
end
|
229
220
|
|
221
|
+
def normalize_code
|
222
|
+
self.code = code.strip if code.present?
|
223
|
+
end
|
224
|
+
|
230
225
|
def match_all?
|
231
226
|
match_policy == 'all'
|
232
227
|
end
|
@@ -25,10 +25,9 @@ module Spree
|
|
25
25
|
|
26
26
|
def remove(coupon_code)
|
27
27
|
promotion = order.promotions.with_coupon_code(coupon_code)
|
28
|
-
|
29
28
|
if promotion.present?
|
30
29
|
# Order promotion has to be destroyed before line item removing
|
31
|
-
order.order_promotions.
|
30
|
+
order.order_promotions.where(promotion_id: promotion.id).destroy_all
|
32
31
|
|
33
32
|
remove_promotion_adjustments(promotion)
|
34
33
|
remove_promotion_line_items(promotion)
|
@@ -76,7 +75,7 @@ module Spree
|
|
76
75
|
line_item = order.find_line_item_by_variant(item.variant)
|
77
76
|
next if line_item.blank?
|
78
77
|
|
79
|
-
Spree::Dependencies.cart_remove_item_service(order: order, item: item.variant, quantity: item.quantity)
|
78
|
+
Spree::Dependencies.cart_remove_item_service.constantize.call(order: order, item: item.variant, quantity: item.quantity)
|
80
79
|
end
|
81
80
|
end
|
82
81
|
|
@@ -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}
|
11
|
+
@new_promotion.path = "#{@promotion.path}_#{@random_string}"
|
11
12
|
@new_promotion.name = "New #{@promotion.name}"
|
12
|
-
@new_promotion.code = "#{@promotion.code}
|
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
|
@@ -60,6 +60,8 @@ module Spree
|
|
60
60
|
class_attribute :reimbursement_failure_hooks
|
61
61
|
self.reimbursement_failure_hooks = []
|
62
62
|
|
63
|
+
delegate :store, :currency, to: :order
|
64
|
+
|
63
65
|
state_machine :reimbursement_status, initial: :pending do
|
64
66
|
event :errored do
|
65
67
|
transition to: :errored, from: :pending
|
@@ -42,6 +42,8 @@ module Spree
|
|
42
42
|
scope :reverse_chronological, -> { order(Arel.sql('coalesce(spree_shipments.shipped_at, spree_shipments.created_at) desc'), id: :desc) }
|
43
43
|
scope :valid, -> { where.not(state: :canceled) }
|
44
44
|
|
45
|
+
delegate :store, :currency, to: :order
|
46
|
+
|
45
47
|
# shipment state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
|
46
48
|
state_machine initial: :pending, use_transactions: false do
|
47
49
|
event :ready do
|
@@ -104,11 +106,6 @@ module Spree
|
|
104
106
|
inventory_units.any?(&:backordered?)
|
105
107
|
end
|
106
108
|
|
107
|
-
# TODO: delegate currency to Order, order.currency is mandatory
|
108
|
-
def currency
|
109
|
-
order ? order.currency : Spree::Config[:currency]
|
110
|
-
end
|
111
|
-
|
112
109
|
# Determines the appropriate +state+ according to the following logic:
|
113
110
|
#
|
114
111
|
# pending unless order is complete and +order.payment_state+ is +paid+
|
@@ -106,8 +106,19 @@ module Spree
|
|
106
106
|
private
|
107
107
|
|
108
108
|
def create_stock_items
|
109
|
-
|
110
|
-
|
109
|
+
variants_scope = Spree::Variant
|
110
|
+
prepared_stock_items = variants_scope.ids.map do |variant_id|
|
111
|
+
Hash[
|
112
|
+
'stock_location_id', id,
|
113
|
+
'variant_id', variant_id,
|
114
|
+
'backorderable', backorderable_default,
|
115
|
+
'created_at', Time.current,
|
116
|
+
'updated_at', Time.current
|
117
|
+
]
|
118
|
+
end
|
119
|
+
if prepared_stock_items.any?
|
120
|
+
stock_items.insert_all(prepared_stock_items)
|
121
|
+
variants_scope.touch_all
|
111
122
|
end
|
112
123
|
end
|
113
124
|
|