spree_core 3.6.6 → 3.7.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/spree.js +60 -0
- data/app/finders/spree/countries/find.rb +31 -0
- data/app/finders/spree/credit_cards/find.rb +12 -0
- data/app/finders/spree/line_items/find_by_variant.rb +13 -0
- data/app/finders/spree/orders/find_current.rb +34 -0
- data/app/finders/spree/products/find.rb +93 -0
- data/app/finders/spree/taxons/find.rb +79 -0
- data/app/helpers/spree/base_helper.rb +7 -3
- data/app/helpers/spree/products_helper.rb +2 -1
- data/app/models/concerns/spree/adjustment_source.rb +11 -6
- data/app/models/concerns/spree/user_address.rb +2 -2
- data/app/models/concerns/spree/vat_price_calculation.rb +2 -1
- data/app/models/spree/ability.rb +2 -2
- data/app/models/spree/address.rb +23 -14
- data/app/models/spree/adjustable/adjustments_updater.rb +1 -1
- data/app/models/spree/adjustable/promotion_accumulator.rb +2 -1
- data/app/models/spree/adjustment.rb +18 -3
- data/app/models/spree/asset/support/active_storage.rb +1 -1
- data/app/models/spree/calculator.rb +1 -4
- data/app/models/spree/calculator/flexi_rate.rb +8 -11
- data/app/models/spree/calculator/returns/default_refund_amount.rb +3 -1
- data/app/models/spree/calculator/shipping/flexi_rate.rb +13 -13
- data/app/models/spree/country.rb +4 -0
- data/app/models/spree/credit_card.rb +8 -2
- data/app/models/spree/customer_return.rb +1 -0
- data/app/models/spree/fulfilment_changer.rb +117 -0
- data/app/models/spree/gateway.rb +1 -0
- data/app/models/spree/gateway/bogus.rb +3 -2
- data/app/models/spree/image.rb +13 -0
- data/app/models/spree/image/configuration/active_storage.rb +3 -3
- data/app/models/spree/inventory_unit.rb +1 -1
- data/app/models/spree/line_item.rb +3 -2
- data/app/models/spree/order.rb +72 -28
- data/app/models/spree/order/checkout.rb +10 -0
- data/app/models/spree/order/store_credit.rb +14 -35
- data/app/models/spree/order_contents.rb +22 -118
- data/app/models/spree/order_inventory.rb +6 -2
- data/app/models/spree/order_merger.rb +1 -3
- data/app/models/spree/order_promotion.rb +10 -0
- data/app/models/spree/order_updater.rb +11 -8
- data/app/models/spree/payment.rb +9 -3
- data/app/models/spree/payment/processing.rb +4 -4
- data/app/models/spree/preferences/store.rb +3 -3
- data/app/models/spree/product.rb +32 -0
- data/app/models/spree/product/scopes.rb +13 -34
- data/app/models/spree/product_property.rb +1 -1
- data/app/models/spree/promotion.rb +2 -0
- data/app/models/spree/promotion/actions/create_adjustment.rb +6 -1
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +10 -2
- data/app/models/spree/promotion/actions/create_line_items.rb +3 -2
- data/app/models/spree/promotion/actions/free_shipping.rb +1 -0
- data/app/models/spree/promotion/rules/item_total.rb +2 -2
- data/app/models/spree/promotion_handler/coupon.rb +10 -6
- data/app/models/spree/promotion_handler/page.rb +1 -1
- data/app/models/spree/promotion_handler/promotion_duplicator.rb +4 -4
- data/app/models/spree/refund.rb +1 -1
- data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -0
- data/app/models/spree/reimbursement_tax_calculator.rb +2 -2
- data/app/models/spree/return_item.rb +7 -4
- data/app/models/spree/return_item/eligibility_validator/default.rb +6 -6
- data/app/models/spree/return_item/exchange_variant_eligibility/same_product.rb +1 -1
- data/app/models/spree/shipment.rb +27 -34
- data/app/models/spree/shipping_method.rb +2 -0
- data/app/models/spree/shipping_rate.rb +31 -16
- data/app/models/spree/stock/adjuster.rb +1 -0
- data/app/models/spree/stock/estimator.rb +2 -0
- data/app/models/spree/stock/inventory_unit_builder.rb +5 -5
- data/app/models/spree/stock/packer.rb +1 -0
- data/app/models/spree/stock/quantifier.rb +16 -4
- data/app/models/spree/stock_item.rb +1 -0
- data/app/models/spree/stock_location.rb +1 -1
- data/app/models/spree/stock_movement.rb +1 -0
- data/app/models/spree/stock_transfer.rb +1 -1
- data/app/models/spree/store_credit.rb +5 -10
- data/app/models/spree/tax_rate.rb +3 -0
- data/app/models/spree/taxon.rb +2 -2
- data/app/models/spree/taxon_image.rb +18 -0
- data/app/models/spree/{taxon_icon → taxon_image}/configuration/active_storage.rb +2 -2
- data/app/models/spree/{taxon_icon → taxon_image}/configuration/paperclip.rb +1 -1
- data/app/models/spree/variant.rb +28 -2
- data/app/models/spree/zone.rb +5 -5
- data/app/paginators/spree/shared/paginate.rb +19 -0
- data/app/services/spree/cart/add_item.rb +43 -0
- data/app/services/spree/cart/create.rb +21 -0
- data/app/services/spree/cart/recalculate.rb +32 -0
- data/app/services/spree/cart/remove_item.rb +37 -0
- data/app/services/spree/cart/remove_line_item.rb +16 -0
- data/app/services/spree/cart/set_quantity.rb +22 -0
- data/app/services/spree/cart/update.rb +37 -0
- data/app/services/spree/checkout/add_store_credit.rb +51 -0
- data/app/services/spree/checkout/advance.rb +18 -0
- data/app/services/spree/checkout/complete.rb +23 -0
- data/app/services/spree/checkout/get_shipping_rates.rb +48 -0
- data/app/services/spree/checkout/next.rb +13 -0
- data/app/services/spree/checkout/remove_store_credit.rb +17 -0
- data/app/services/spree/checkout/update.rb +13 -0
- data/app/services/spree/compare_line_items.rb +21 -0
- data/app/services/spree/generate_token.rb +20 -0
- data/app/sorters/spree/products/sort.rb +58 -0
- data/config/locales/en.yml +20 -1
- data/db/default/spree/countries.rb +1 -1
- data/db/default/spree/default_reimbursement_type.rb +1 -1
- data/db/default/spree/roles.rb +2 -2
- data/db/default/spree/states.rb +2 -1
- data/db/default/spree/stores.rb +1 -1
- data/db/default/spree/zones.rb +5 -6
- data/db/migrate/20120831092320_spree_one_two.rb +36 -36
- data/db/migrate/20120831092359_spree_promo_one_two.rb +1 -1
- data/db/migrate/20130211190146_create_spree_stock_items.rb +1 -1
- data/db/migrate/20130211191120_create_spree_stock_locations.rb +1 -1
- data/db/migrate/20130301162924_create_shipping_method_categories.rb +1 -1
- data/db/migrate/20130304162240_create_spree_shipping_rates.rb +1 -1
- data/db/migrate/20130305143310_create_stock_movements.rb +1 -1
- data/db/migrate/20130418125341_create_spree_stock_transfers.rb +1 -1
- data/db/migrate/20140205120320_create_spree_payment_capture_events.rb +1 -1
- data/db/migrate/20140309023735_migrate_old_preferences.rb +5 -1
- data/db/migrate/20140309024355_create_spree_stores.rb +1 -1
- data/db/migrate/20140625214618_create_spree_refunds.rb +1 -1
- data/db/migrate/20140702140656_create_spree_return_authorization_inventory_unit.rb +1 -1
- data/db/migrate/20140713140455_create_spree_return_authorization_reasons.rb +1 -1
- data/db/migrate/20140713140527_create_spree_refund_reasons.rb +1 -1
- data/db/migrate/20140715182625_create_spree_promotion_categories.rb +1 -1
- data/db/migrate/20140718133010_create_spree_customer_returns.rb +1 -1
- data/db/migrate/20140725131539_create_spree_reimbursements.rb +1 -1
- data/db/migrate/20140731150017_create_spree_reimbursement_types.rb +1 -1
- data/db/migrate/20150118210639_create_spree_store_credits.rb +1 -1
- data/db/migrate/20150118211500_create_spree_store_credit_categories.rb +1 -1
- data/db/migrate/20150118212051_create_spree_store_credit_events.rb +1 -1
- data/db/migrate/20150118212101_create_spree_store_credit_types.rb +1 -1
- data/db/migrate/20150309161154_ensure_payments_have_numbers.rb +6 -2
- data/db/migrate/20180613080857_rename_guest_token_to_token_in_orders.rb +5 -0
- data/db/migrate/20180915160001_add_timestamps_to_spree_prices.rb +12 -0
- data/db/migrate/20181024100754_add_deleted_at_to_spree_credit_cards.rb +6 -0
- data/lib/generators/spree/custom_user/custom_user_generator.rb +1 -3
- data/lib/generators/spree/dummy/dummy_generator.rb +30 -33
- data/lib/generators/spree/dummy/templates/rails/database.yml +6 -1
- data/lib/generators/spree/dummy/templates/rails/test.rb +2 -0
- data/lib/generators/spree/dummy_model/dummy_model_generator.rb +1 -1
- data/lib/generators/spree/install/install_generator.rb +2 -1
- data/lib/spree/core.rb +2 -4
- data/lib/spree/core/controller_helpers/auth.rb +15 -5
- data/lib/spree/core/controller_helpers/common.rb +0 -11
- data/lib/spree/core/controller_helpers/order.rb +6 -6
- data/lib/spree/core/controller_helpers/respond_with.rb +3 -1
- data/lib/spree/core/controller_helpers/strong_parameters.rb +1 -0
- data/lib/spree/core/engine.rb +9 -3
- data/lib/spree/core/importer/order.rb +8 -12
- data/lib/spree/core/product_duplicator.rb +6 -1
- data/lib/spree/core/product_filters.rb +15 -14
- data/lib/spree/core/query_filters.rb +11 -0
- data/lib/spree/core/query_filters/comparable.rb +46 -0
- data/lib/spree/core/query_filters/date.rb +8 -0
- data/lib/spree/core/query_filters/number.rb +8 -0
- data/lib/spree/core/query_filters/text.rb +32 -0
- data/lib/spree/core/token_generator.rb +2 -2
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/i18n.rb +1 -1
- data/lib/spree/migrations.rb +2 -0
- data/lib/spree/money.rb +12 -12
- data/lib/spree/permitted_attributes.rb +11 -6
- data/lib/spree/service_module.rb +98 -0
- data/lib/spree/testing_support/capybara_config.rb +20 -0
- data/lib/spree/testing_support/capybara_ext.rb +6 -3
- data/lib/spree/testing_support/factories.rb +1 -1
- data/lib/spree/testing_support/factories/address_factory.rb +10 -9
- data/lib/spree/testing_support/factories/adjustment_factory.rb +8 -6
- data/lib/spree/testing_support/factories/country_factory.rb +4 -4
- data/lib/spree/testing_support/factories/credit_card_factory.rb +7 -5
- data/lib/spree/testing_support/factories/customer_return_factory.rb +1 -1
- data/lib/spree/testing_support/factories/image_factory.rb +7 -1
- data/lib/spree/testing_support/factories/inventory_unit_factory.rb +5 -4
- data/lib/spree/testing_support/factories/line_item_factory.rb +3 -2
- data/lib/spree/testing_support/factories/options_factory.rb +2 -3
- data/lib/spree/testing_support/factories/order_factory.rb +16 -12
- data/lib/spree/testing_support/factories/order_promotion_factory.rb +6 -0
- data/lib/spree/testing_support/factories/payment_factory.rb +9 -7
- data/lib/spree/testing_support/factories/payment_method_factory.rb +8 -8
- data/lib/spree/testing_support/factories/price_factory.rb +2 -2
- data/lib/spree/testing_support/factories/product_factory.rb +10 -10
- data/lib/spree/testing_support/factories/promotion_category_factory.rb +1 -1
- data/lib/spree/testing_support/factories/promotion_factory.rb +14 -4
- data/lib/spree/testing_support/factories/property_factory.rb +2 -2
- data/lib/spree/testing_support/factories/prototype_factory.rb +3 -3
- data/lib/spree/testing_support/factories/refund_factory.rb +6 -6
- data/lib/spree/testing_support/factories/reimbursement_factory.rb +1 -1
- data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +2 -2
- data/lib/spree/testing_support/factories/return_authorization_factory.rb +4 -3
- data/lib/spree/testing_support/factories/role_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipment_factory.rb +3 -3
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +4 -4
- data/lib/spree/testing_support/factories/state_factory.rb +2 -5
- data/lib/spree/testing_support/factories/stock_factory.rb +3 -3
- data/lib/spree/testing_support/factories/stock_item_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_location_factory.rb +7 -7
- data/lib/spree/testing_support/factories/stock_movement_factory.rb +3 -3
- data/lib/spree/testing_support/factories/store_credit_category_factory.rb +2 -2
- data/lib/spree/testing_support/factories/store_credit_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_factory.rb +5 -4
- data/lib/spree/testing_support/factories/tax_rate_factory.rb +2 -1
- data/lib/spree/testing_support/factories/user_factory.rb +4 -4
- data/lib/spree/testing_support/factories/variant_factory.rb +15 -15
- data/lib/spree/testing_support/factories/zone_factory.rb +3 -3
- data/lib/spree/testing_support/image_helpers.rb +19 -0
- data/lib/tasks/core.rake +21 -4
- data/lib/tasks/exchanges.rake +4 -4
- data/spree_core.gemspec +3 -3
- data/vendor/assets/javascripts/fetch.umd.js +531 -0
- data/vendor/assets/javascripts/polyfill.min.js +1 -0
- metadata +50 -17
- data/app/assets/javascripts/spree.js.coffee +0 -59
- data/app/models/spree/taxon_icon.rb +0 -5
- data/lib/generators/spree/dummy/templates/initializers/custom_user.rb +0 -1
- data/lib/spree/core/environment.rb +0 -15
- data/lib/spree/core/environment/calculators.rb +0 -11
- data/lib/spree/core/environment_extension.rb +0 -28
- data/lib/spree/core/validators/email.rb +0 -8
- data/lib/spree/promo/environment.rb +0 -9
@@ -33,6 +33,7 @@ module Spree
|
|
33
33
|
cost = shipping_method.calculator.compute(package)
|
34
34
|
|
35
35
|
next unless cost
|
36
|
+
|
36
37
|
shipping_method.shipping_rates.new(
|
37
38
|
cost: gross_amount(cost, taxation_options_for(shipping_method)),
|
38
39
|
tax_rate: first_tax_rate_for(shipping_method.tax_category)
|
@@ -52,6 +53,7 @@ module Spree
|
|
52
53
|
|
53
54
|
def first_tax_rate_for(tax_category)
|
54
55
|
return unless @order.tax_zone && tax_category
|
56
|
+
|
55
57
|
Spree::TaxRate.for_tax_category(tax_category).
|
56
58
|
potential_rates_for_zone(@order.tax_zone).first
|
57
59
|
end
|
@@ -10,11 +10,11 @@ module Spree
|
|
10
10
|
# They go through multiple splits, avoid loading the
|
11
11
|
# association to order until needed.
|
12
12
|
InventoryUnit.new(
|
13
|
-
pending:
|
14
|
-
line_item:
|
15
|
-
variant:
|
16
|
-
quantity:
|
17
|
-
order_id:
|
13
|
+
pending: true,
|
14
|
+
line_item: line_item,
|
15
|
+
variant: line_item.variant,
|
16
|
+
quantity: line_item.quantity,
|
17
|
+
order_id: @order.id
|
18
18
|
)
|
19
19
|
end
|
20
20
|
end
|
@@ -26,6 +26,7 @@ module Spree
|
|
26
26
|
unit = inventory_unit.dup # Can be used by others, do not use directly
|
27
27
|
if variant.should_track_inventory?
|
28
28
|
next unless stock_location.stocks? variant
|
29
|
+
|
29
30
|
on_hand, backordered = stock_location.fill_status(variant, unit.quantity)
|
30
31
|
package.add(InventoryUnit.split(unit, backordered), :backordered) if backordered.positive?
|
31
32
|
package.add(InventoryUnit.split(unit, on_hand), :on_hand) if on_hand.positive?
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Spree
|
2
2
|
module Stock
|
3
3
|
class Quantifier
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :variant, :stock_location
|
5
5
|
|
6
|
-
def initialize(variant)
|
7
|
-
@variant
|
8
|
-
@
|
6
|
+
def initialize(variant, stock_location = nil)
|
7
|
+
@variant = variant
|
8
|
+
@stock_location = stock_location
|
9
9
|
end
|
10
10
|
|
11
11
|
def total_on_hand
|
@@ -23,6 +23,18 @@ module Spree
|
|
23
23
|
def can_supply?(required = 1)
|
24
24
|
variant.available? && (total_on_hand >= required || backorderable?)
|
25
25
|
end
|
26
|
+
|
27
|
+
def stock_items
|
28
|
+
@stock_items ||= scope_to_location(variant.stock_items)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def scope_to_location(collection)
|
34
|
+
return collection.with_active_stock_location unless stock_location.present?
|
35
|
+
|
36
|
+
collection.where(stock_location: stock_location)
|
37
|
+
end
|
26
38
|
end
|
27
39
|
end
|
28
40
|
end
|
@@ -75,6 +75,7 @@ module Spree
|
|
75
75
|
# If stock was -20 but then was -25 (decrease of 5 units), do nothing.
|
76
76
|
def process_backorders(number)
|
77
77
|
return unless number.positive?
|
78
|
+
|
78
79
|
units = backordered_inventory_units.first(number) # We can process atmost n backorders
|
79
80
|
|
80
81
|
units.each do |unit|
|
@@ -7,7 +7,7 @@ module Spree
|
|
7
7
|
belongs_to :state, class_name: 'Spree::State', optional: true
|
8
8
|
belongs_to :country, class_name: 'Spree::Country'
|
9
9
|
|
10
|
-
validates :name, presence: true
|
10
|
+
validates :name, presence: true, uniqueness: { allow_blank: true }
|
11
11
|
|
12
12
|
scope :active, -> { where(active: true) }
|
13
13
|
scope :order_default, -> { order(default: :desc, name: :asc) }
|
@@ -26,7 +26,7 @@ module Spree
|
|
26
26
|
def transfer(source_location, destination_location, variants)
|
27
27
|
transaction do
|
28
28
|
variants.each_pair do |variant, quantity|
|
29
|
-
source_location
|
29
|
+
source_location&.unstock(variant, quantity, self)
|
30
30
|
destination_location.restock(variant, quantity, self)
|
31
31
|
|
32
32
|
self.source_location = source_location
|
@@ -35,13 +35,8 @@ module Spree
|
|
35
35
|
|
36
36
|
attr_accessor :action, :action_amount, :action_originator, :action_authorization_code
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
def display_amount_used
|
43
|
-
Spree::Money.new(amount_used)
|
44
|
-
end
|
38
|
+
extend Spree::DisplayMoney
|
39
|
+
money_methods :amount, :amount_used
|
45
40
|
|
46
41
|
def amount_remaining
|
47
42
|
amount - amount_used - amount_authorized
|
@@ -204,9 +199,9 @@ module Spree
|
|
204
199
|
|
205
200
|
def store_event
|
206
201
|
return unless saved_change_to_amount? ||
|
207
|
-
|
208
|
-
|
209
|
-
|
202
|
+
saved_change_to_amount_used? ||
|
203
|
+
saved_change_to_amount_authorized? ||
|
204
|
+
action == ELIGIBLE_ACTION
|
210
205
|
|
211
206
|
event = if action
|
212
207
|
store_credit_events.build(action: action)
|
@@ -30,6 +30,7 @@ module Spree
|
|
30
30
|
# Gets the array of TaxRates appropriate for the specified tax zone
|
31
31
|
def self.match(order_tax_zone)
|
32
32
|
return [] unless order_tax_zone
|
33
|
+
|
33
34
|
potential_rates_for_zone(order_tax_zone)
|
34
35
|
end
|
35
36
|
|
@@ -82,6 +83,7 @@ module Spree
|
|
82
83
|
|
83
84
|
def self.included_tax_amount_for(options)
|
84
85
|
return 0 unless options[:tax_zone] && options[:tax_category]
|
86
|
+
|
85
87
|
potential_rates_for_zone(options[:tax_zone]).
|
86
88
|
included_in_price.
|
87
89
|
for_tax_category(options[:tax_category]).
|
@@ -107,6 +109,7 @@ module Spree
|
|
107
109
|
|
108
110
|
def amount_for_label
|
109
111
|
return '' unless show_rate_in_label?
|
112
|
+
|
110
113
|
' ' + ActiveSupport::NumberHelper::NumberToPercentageConverter.convert(
|
111
114
|
amount * 100,
|
112
115
|
locale: I18n.locale
|
data/app/models/spree/taxon.rb
CHANGED
@@ -32,7 +32,7 @@ module Spree
|
|
32
32
|
after_save :touch_ancestors_and_taxonomy
|
33
33
|
after_touch :touch_ancestors_and_taxonomy
|
34
34
|
|
35
|
-
has_one :icon, as: :viewable, dependent: :destroy, class_name: 'Spree::
|
35
|
+
has_one :icon, as: :viewable, dependent: :destroy, class_name: 'Spree::TaxonImage'
|
36
36
|
|
37
37
|
self.whitelisted_ransackable_associations = %w[taxonomy]
|
38
38
|
|
@@ -97,7 +97,7 @@ module Spree
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def check_for_root
|
100
|
-
if taxonomy.try(:root).present? && parent_id
|
100
|
+
if taxonomy.try(:root).present? && parent_id.nil?
|
101
101
|
errors.add(:root_conflict, 'this taxonomy already has a root taxon')
|
102
102
|
end
|
103
103
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Spree
|
2
|
+
class TaxonImage < Asset
|
3
|
+
include Rails.application.config.use_paperclip ? Configuration::Paperclip : Configuration::ActiveStorage
|
4
|
+
include Rails.application.routes.url_helpers
|
5
|
+
|
6
|
+
def styles
|
7
|
+
self.class.styles.map do |_, size|
|
8
|
+
width, height = size[/(\d+)x(\d+)/].split('x')
|
9
|
+
|
10
|
+
{
|
11
|
+
url: polymorphic_path(attachment.variant(resize: size), only_path: true),
|
12
|
+
width: width,
|
13
|
+
height: height
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Spree
|
2
|
-
class
|
2
|
+
class TaxonImage < Asset
|
3
3
|
module Configuration
|
4
4
|
module ActiveStorage
|
5
5
|
extend ActiveSupport::Concern
|
@@ -11,7 +11,7 @@ module Spree
|
|
11
11
|
|
12
12
|
def self.styles
|
13
13
|
@styles ||= {
|
14
|
-
mini:
|
14
|
+
mini: '32x32>',
|
15
15
|
normal: '128x128>'
|
16
16
|
}
|
17
17
|
end
|
data/app/models/spree/variant.rb
CHANGED
@@ -56,6 +56,22 @@ module Spree
|
|
56
56
|
after_touch :clear_in_stock_cache
|
57
57
|
|
58
58
|
scope :in_stock, -> { joins(:stock_items).where('count_on_hand > ? OR track_inventory = ?', 0, false) }
|
59
|
+
scope :backorderable, -> { joins(:stock_items).where(spree_stock_items: { backorderable: true }) }
|
60
|
+
scope :in_stock_or_backorderable, -> { in_stock.or(backorderable) }
|
61
|
+
|
62
|
+
scope :eligible, -> {
|
63
|
+
where(is_master: false).or(
|
64
|
+
where(
|
65
|
+
<<-SQL
|
66
|
+
#{Variant.quoted_table_name}.id IN (
|
67
|
+
SELECT MIN(#{Variant.quoted_table_name}.id) FROM #{Variant.quoted_table_name}
|
68
|
+
GROUP BY #{Variant.quoted_table_name}.product_id
|
69
|
+
HAVING COUNT(*) = 1
|
70
|
+
)
|
71
|
+
SQL
|
72
|
+
)
|
73
|
+
)
|
74
|
+
}
|
59
75
|
|
60
76
|
scope :not_discontinued, -> do
|
61
77
|
where(
|
@@ -159,6 +175,7 @@ module Spree
|
|
159
175
|
end
|
160
176
|
else
|
161
177
|
return if current_value.name == opt_value
|
178
|
+
|
162
179
|
option_values.delete(current_value)
|
163
180
|
end
|
164
181
|
|
@@ -227,6 +244,10 @@ module Spree
|
|
227
244
|
|
228
245
|
alias is_backorderable? backorderable?
|
229
246
|
|
247
|
+
def purchasable?
|
248
|
+
in_stock? || backorderable?
|
249
|
+
end
|
250
|
+
|
230
251
|
# Shortcut method to determine if inventory tracking is enabled for this variant
|
231
252
|
# This considers both variant tracking flag and site-wide inventory tracking settings
|
232
253
|
def should_track_inventory?
|
@@ -253,6 +274,10 @@ module Spree
|
|
253
274
|
!!discontinue_on && discontinue_on <= Time.current
|
254
275
|
end
|
255
276
|
|
277
|
+
def backordered?
|
278
|
+
total_on_hand <= 0 && stock_items.exists?(backorderable: true)
|
279
|
+
end
|
280
|
+
|
256
281
|
private
|
257
282
|
|
258
283
|
def ensure_no_line_items
|
@@ -267,7 +292,7 @@ module Spree
|
|
267
292
|
end
|
268
293
|
|
269
294
|
def set_master_out_of_stock
|
270
|
-
if product.master
|
295
|
+
if product.master&.in_stock?
|
271
296
|
product.master.stock_items.update_all(backorderable: false)
|
272
297
|
product.master.stock_items.each(&:reduce_count_on_hand_to_zero)
|
273
298
|
end
|
@@ -276,8 +301,9 @@ module Spree
|
|
276
301
|
# Ensures a new variant takes the product master price when price is not supplied
|
277
302
|
def check_price
|
278
303
|
if price.nil? && Spree::Config[:require_master_price]
|
279
|
-
return errors.add(:base, :no_master_variant_found_to_infer_price) unless product
|
304
|
+
return errors.add(:base, :no_master_variant_found_to_infer_price) unless product&.master
|
280
305
|
return errors.add(:base, :must_supply_price_for_variant_or_master) if self == product.master
|
306
|
+
|
281
307
|
self.price = product.master.price
|
282
308
|
end
|
283
309
|
if price.present? && currency.nil?
|
data/app/models/spree/zone.rb
CHANGED
@@ -52,12 +52,12 @@ module Spree
|
|
52
52
|
# Returns nil in the case of no matches.
|
53
53
|
def self.match(address)
|
54
54
|
return unless address &&
|
55
|
-
|
55
|
+
matches = includes(:zone_members).
|
56
56
|
order('spree_zones.zone_members_count', 'spree_zones.created_at').
|
57
57
|
where("(spree_zone_members.zoneable_type = 'Spree::Country' AND " \
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
'spree_zone_members.zoneable_id = ?) OR ' \
|
59
|
+
"(spree_zone_members.zoneable_type = 'Spree::State' AND " \
|
60
|
+
'spree_zone_members.zoneable_id = ?)', address.country_id, address.state_id).
|
61
61
|
references(:zones)
|
62
62
|
|
63
63
|
%w[state country].each do |zone_kind|
|
@@ -74,7 +74,7 @@ module Spree
|
|
74
74
|
else
|
75
75
|
not_nil_scope = members.where.not(zoneable_type: nil)
|
76
76
|
zone_type = not_nil_scope.order('created_at ASC').pluck(:zoneable_type).last
|
77
|
-
zone_type
|
77
|
+
zone_type&.demodulize&.underscore
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Spree
|
2
|
+
module Shared
|
3
|
+
class Paginate
|
4
|
+
def initialize(collection, params)
|
5
|
+
@collection = collection
|
6
|
+
@page = params[:page]
|
7
|
+
@per_page = params[:per_page]
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
collection.page(page).per(per_page)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_reader :collection, :page, :per_page
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Spree
|
2
|
+
module Cart
|
3
|
+
class AddItem
|
4
|
+
prepend Spree::ServiceModule::Base
|
5
|
+
|
6
|
+
def call(order:, variant:, quantity: nil, options: {})
|
7
|
+
ApplicationRecord.transaction do
|
8
|
+
run :add_to_line_item
|
9
|
+
run Spree::Cart::Recalculate
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def add_to_line_item(order:, variant:, quantity: nil, options: {})
|
16
|
+
options ||= {}
|
17
|
+
quantity ||= 1
|
18
|
+
|
19
|
+
line_item = Spree::LineItems::FindByVariant.new.execute(order: order, variant: variant, options: options)
|
20
|
+
|
21
|
+
line_item_created = line_item.nil?
|
22
|
+
if line_item.nil?
|
23
|
+
opts = ::Spree::PermittedAttributes.line_item_attributes.flatten.each_with_object({}) do |attribute, result|
|
24
|
+
result[attribute] = options[attribute]
|
25
|
+
end.merge(currency: order.currency).delete_if { |_key, value| value.nil? }
|
26
|
+
|
27
|
+
line_item = order.line_items.new(quantity: quantity,
|
28
|
+
variant: variant,
|
29
|
+
options: opts)
|
30
|
+
else
|
31
|
+
line_item.quantity += quantity.to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
line_item.target_shipment = options[:shipment] if options.key? :shipment
|
35
|
+
|
36
|
+
return failure(line_item) unless line_item.save
|
37
|
+
|
38
|
+
::Spree::TaxRate.adjust(order, [line_item.reload]) if line_item_created
|
39
|
+
success(order: order, line_item: line_item, line_item_created: line_item_created, options: options)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Spree
|
2
|
+
module Cart
|
3
|
+
class Create
|
4
|
+
prepend Spree::ServiceModule::Base
|
5
|
+
|
6
|
+
def call(user:, store:, currency:, order_params: nil)
|
7
|
+
order_params ||= {}
|
8
|
+
|
9
|
+
default_params = {
|
10
|
+
user: user,
|
11
|
+
store: store,
|
12
|
+
currency: currency,
|
13
|
+
token: GenerateToken.new.call(Spree::Order)
|
14
|
+
}
|
15
|
+
|
16
|
+
order = Spree::Order.create!(default_params.merge(order_params))
|
17
|
+
success(order)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Spree
|
2
|
+
module Cart
|
3
|
+
class Recalculate
|
4
|
+
prepend Spree::ServiceModule::Base
|
5
|
+
|
6
|
+
def call(order:, line_item:, line_item_created: false, options: {})
|
7
|
+
order_updater = ::Spree::OrderUpdater.new(order)
|
8
|
+
|
9
|
+
order.payments.store_credits.checkout.destroy_all
|
10
|
+
order_updater.update
|
11
|
+
|
12
|
+
shipment = options[:shipment]
|
13
|
+
if shipment.present?
|
14
|
+
# ADMIN END SHIPMENT RATE FIX
|
15
|
+
# refresh shipments to ensure correct shipment amount is calculated when using price sack calculator
|
16
|
+
# for calculating shipment rates.
|
17
|
+
# Currently shipment rate is calculated on previous order total instead of current order total when updating a shipment from admin end.
|
18
|
+
order.refresh_shipment_rates(::Spree::ShippingMethod::DISPLAY_ON_BACK_END)
|
19
|
+
shipment.update_amounts
|
20
|
+
else
|
21
|
+
order.ensure_updated_shipments
|
22
|
+
end
|
23
|
+
|
24
|
+
::Spree::PromotionHandler::Cart.new(order, line_item).activate
|
25
|
+
::Spree::Adjustable::AdjustmentsUpdater.update(line_item)
|
26
|
+
::Spree::TaxRate.adjust(order, [line_item.reload]) if line_item_created
|
27
|
+
order_updater.update
|
28
|
+
success(line_item)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|