spree_core 2.1.12 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/helpers/spree/base_helper.rb +4 -7
- data/app/helpers/spree/products_helper.rb +11 -9
- data/app/helpers/spree/store_helper.rb +5 -0
- data/app/models/spree/ability.rb +4 -0
- data/app/models/spree/address.rb +6 -6
- data/app/models/spree/adjustment.rb +40 -61
- data/app/models/spree/app_configuration.rb +1 -14
- data/app/models/spree/calculator.rb +12 -4
- data/app/models/spree/calculator/default_tax.rb +42 -38
- data/app/models/spree/calculator/flat_percent_item_total.rb +2 -4
- data/app/models/spree/calculator/free_shipping.rb +5 -2
- data/app/models/spree/calculator/percent_on_line_item.rb +15 -0
- data/app/models/spree/calculator/percent_per_item.rb +3 -0
- data/app/models/spree/classification.rb +3 -2
- data/app/models/spree/credit_card.rb +7 -25
- data/app/models/spree/gateway/bogus.rb +5 -5
- data/app/models/spree/gateway/bogus_simple.rb +0 -8
- data/app/models/spree/image.rb +0 -9
- data/app/models/spree/inventory_unit.rb +10 -4
- data/app/models/spree/item_adjustments.rb +65 -0
- data/app/models/spree/legacy_user.rb +1 -0
- data/app/models/spree/line_item.rb +33 -13
- data/app/models/spree/option_type.rb +2 -2
- data/app/models/spree/option_value.rb +1 -1
- data/app/models/spree/order.rb +109 -89
- data/app/models/spree/order/checkout.rb +48 -0
- data/app/models/spree/order_contents.rb +72 -37
- data/app/models/spree/order_inventory.rb +65 -68
- data/app/models/spree/order_populator.rb +3 -17
- data/app/models/spree/order_updater.rb +63 -44
- data/app/models/spree/payment.rb +20 -5
- data/app/models/spree/payment/processing.rb +19 -25
- data/app/models/spree/payment_capture_event.rb +9 -0
- data/app/models/spree/payment_method/check.rb +0 -2
- data/app/models/spree/price.rb +1 -1
- data/app/models/spree/product.rb +14 -16
- data/app/models/spree/product/scopes.rb +4 -6
- data/app/models/spree/product_option_type.rb +2 -2
- data/app/models/spree/product_property.rb +2 -2
- data/app/models/spree/promotion.rb +71 -50
- data/app/models/spree/promotion/actions/create_adjustment.rb +31 -32
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +83 -0
- data/app/models/spree/promotion/actions/free_shipping.rb +36 -0
- data/app/models/spree/promotion/rules/first_order.rb +4 -0
- data/app/models/spree/promotion/rules/item_total.rb +5 -1
- data/app/models/spree/promotion/rules/product.rb +4 -0
- data/app/models/spree/promotion/rules/user.rb +5 -6
- data/app/models/spree/promotion/rules/user_logged_in.rb +4 -0
- data/app/models/spree/promotion_action.rb +1 -5
- data/app/models/spree/promotion_handler/cart.rb +38 -0
- data/app/models/spree/promotion_handler/coupon.rb +76 -0
- data/app/models/spree/promotion_handler/free_shipping.rb +31 -0
- data/app/models/spree/promotion_handler/page.rb +24 -0
- data/app/models/spree/promotion_rule.rb +15 -7
- data/app/models/spree/property.rb +1 -1
- data/app/models/spree/return_authorization.rb +7 -1
- data/app/models/spree/shipment.rb +113 -49
- data/app/models/spree/shipping_calculator.rb +4 -5
- data/app/models/spree/shipping_category.rb +2 -2
- data/app/models/spree/shipping_method.rb +12 -6
- data/app/models/spree/shipping_rate.rb +27 -7
- data/app/models/spree/stock/availability_validator.rb +1 -1
- data/app/models/spree/stock/estimator.rb +13 -1
- data/app/models/spree/stock/package.rb +11 -7
- data/app/models/spree/stock/packer.rb +3 -3
- data/app/models/spree/stock/quantifier.rb +9 -1
- data/app/models/spree/stock_item.rb +11 -6
- data/app/models/spree/stock_movement.rb +1 -2
- data/app/models/spree/tax_category.rb +6 -1
- data/app/models/spree/tax_rate.rb +57 -49
- data/app/models/spree/taxon.rb +10 -5
- data/app/models/spree/taxonomy.rb +5 -2
- data/app/models/spree/variant.rb +33 -16
- data/app/models/spree/zone.rb +24 -24
- data/app/views/spree/shared/_routes.html.erb +3 -0
- data/config/locales/en.yml +42 -26
- data/db/migrate/20130213191427_create_default_stock.rb +3 -3
- data/db/migrate/20130413230529_add_name_to_spree_credit_cards.rb +5 -0
- data/db/migrate/20130414000512_update_name_fields_on_spree_credit_cards.rb +13 -0
- data/db/migrate/20130417120035_update_adjustment_states.rb +2 -2
- data/db/migrate/20130417123427_add_shipping_rates_to_shipments.rb +1 -1
- data/db/migrate/20130509115210_add_number_to_stock_transfer.rb +1 -1
- data/db/migrate/20130611054351_rename_shipping_methods_zones_to_spree_shipping_methods_zones.rb +0 -5
- data/db/migrate/20130802022321_migrate_tax_categories_to_line_items.rb +7 -5
- data/db/migrate/20130807024301_upgrade_adjustments.rb +39 -0
- data/db/migrate/20130807024302_rename_adjustment_fields.rb +17 -0
- data/db/migrate/20130813004002_add_shipment_total_to_spree_orders.rb +5 -0
- data/db/migrate/20130813232134_rename_activators_to_promotions.rb +5 -0
- data/db/migrate/20130815000406_add_adjustment_total_to_line_items.rb +5 -0
- data/db/migrate/20130815024413_add_adjustment_total_to_shipments.rb +5 -0
- data/db/migrate/20130828234942_add_tax_total_to_line_items_shipments_and_orders.rb +8 -0
- data/db/migrate/20130830001159_migrate_old_shipping_calculators.rb +1 -1
- data/db/migrate/20130903183026_add_code_to_spree_promotion_rules.rb +5 -0
- data/db/migrate/20130917024658_remove_promotions_event_name_field.rb +5 -0
- data/db/migrate/20130924040529_add_promo_total_to_line_items_and_shipments_and_orders.rb +7 -0
- data/db/migrate/20131001013410_remove_unused_credit_card_fields.rb +7 -3
- data/db/migrate/20131107132123_add_tax_category_to_variants.rb +6 -0
- data/db/migrate/20131118043959_add_included_to_adjustments.rb +5 -0
- data/db/migrate/20131118050234_rename_tax_total_fields.rb +11 -0
- data/db/migrate/20131118183431_add_line_item_id_to_spree_inventory_units.rb +21 -0
- data/db/migrate/20131127001002_add_position_to_classifications.rb +5 -0
- data/db/migrate/20131211112807_create_spree_orders_promotions.rb +8 -0
- data/db/migrate/20131218054603_add_item_count_to_spree_orders.rb +5 -0
- data/db/migrate/20140106224208_rename_permalink_to_slug_for_products.rb +5 -0
- data/db/migrate/20140124023232_rename_activator_id_in_rules_and_actions_to_promotion_id.rb +6 -0
- data/db/migrate/20140203161722_add_approver_id_and_approved_at_to_orders.rb +6 -0
- data/db/migrate/20140204115338_add_confirmation_delivered_to_spree_orders.rb +5 -0
- data/db/migrate/20140205120320_create_spree_payment_capture_events.rb +12 -0
- data/db/migrate/20140205144710_add_uncaptured_amount_to_payments.rb +5 -0
- data/db/migrate/20140207085910_add_tax_category_id_to_shipping_methods.rb +5 -0
- data/db/migrate/20140207093021_add_tax_rate_id_to_shipping_rates.rb +5 -0
- data/db/migrate/20140211040159_add_pre_tax_amount_to_line_items_and_shipments.rb +6 -0
- data/db/migrate/20140213184916_add_more_indexes.rb +13 -0
- data/db/migrate/20140219060952_add_considered_risky_to_orders.rb +5 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +1 -6
- data/lib/generators/spree/install/install_generator.rb +6 -6
- data/lib/generators/spree/install/templates/{app/assets/javascripts/admin → vendor/assets/javascripts/spree/backend}/all.js +3 -3
- data/lib/generators/spree/install/templates/{app/assets/javascripts/store → vendor/assets/javascripts/spree/frontend}/all.js +3 -3
- data/lib/generators/spree/install/templates/{app/assets/stylesheets/store → vendor/assets/stylesheets/spree/backend}/all.css +3 -3
- data/lib/generators/spree/install/templates/{app/assets/stylesheets/admin → vendor/assets/stylesheets/spree/frontend}/all.css +3 -3
- data/lib/spree/core.rb +21 -8
- data/lib/spree/core/calculated_adjustments.rb +0 -40
- data/lib/spree/core/controller_helpers.rb +5 -0
- data/lib/spree/core/controller_helpers/auth.rb +2 -2
- data/lib/spree/core/controller_helpers/common.rb +0 -5
- data/lib/spree/core/controller_helpers/order.rb +8 -9
- data/lib/spree/core/engine.rb +10 -17
- data/lib/spree/core/permalinks.rb +1 -1
- data/lib/spree/core/product_duplicator.rb +3 -8
- data/lib/spree/core/user_address.rb +1 -1
- data/lib/spree/core/validators/email.rb +23 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/money.rb +1 -1
- data/lib/spree/permitted_attributes.rb +2 -2
- data/lib/spree/testing_support/caching.rb +47 -0
- data/lib/spree/testing_support/factories/adjustment_factory.rb +11 -2
- data/lib/spree/testing_support/factories/credit_card_factory.rb +2 -1
- data/lib/spree/testing_support/factories/order_factory.rb +10 -5
- data/lib/spree/testing_support/factories/payment_factory.rb +2 -2
- data/lib/spree/testing_support/factories/payment_method_factory.rb +3 -3
- data/lib/spree/testing_support/factories/promotion_factory.rb +16 -1
- data/lib/spree/testing_support/factories/shipment_factory.rb +8 -4
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +1 -3
- data/lib/spree/testing_support/factories/stock_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tax_rate_factory.rb +2 -2
- data/lib/spree/testing_support/order_walkthrough.rb +1 -1
- data/lib/tasks/core.rake +2 -2
- data/vendor/assets/fonts/FontAwesome.otf +0 -0
- data/vendor/assets/fonts/fontawesome-webfont.eot +0 -0
- data/vendor/assets/fonts/fontawesome-webfont.svg +399 -0
- data/vendor/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/vendor/assets/fonts/fontawesome-webfont.woff +0 -0
- data/vendor/assets/stylesheets/font-awesome.scss +1475 -0
- metadata +73 -44
- data/app/assets/javascripts/admin/handlebar_extensions.js +0 -9
- data/app/helpers/spree/admin/adjustments_helper.rb +0 -26
- data/app/helpers/spree/admin/images_helper.rb +0 -18
- data/app/helpers/spree/promotion_rules_helper.rb +0 -13
- data/app/models/spree/activator.rb +0 -29
- data/app/models/spree/calculator/per_item.rb +0 -41
- data/app/models/spree/stock/remaining_packer.rb +0 -22
- data/app/views/spree/payments/_payment.html.erb +0 -18
- data/db/migrate/20131118041203_add_tax_total_to_spree_orders.rb +0 -5
- data/db/migrate/20131118043021_add_order_id_to_spree_adjustments.rb +0 -6
- data/db/migrate/20131118074808_add_included_to_spree_adjustments.rb +0 -5
- data/db/migrate/20140415041315_add_user_id_created_by_id_index_to_order.rb +0 -5
- data/lib/spree/core/gateway_error.rb +0 -5
- data/lib/spree/core/preference_rescue.rb +0 -25
- data/lib/spree/core/s3_support.rb +0 -25
- data/lib/spree/promo/coupon_applicator.rb +0 -71
- data/lib/spree/testing_support/factories/activator_factory.rb +0 -8
@@ -29,7 +29,19 @@ module Spree
|
|
29
29
|
def calculate_shipping_rates(package)
|
30
30
|
shipping_methods(package).map do |shipping_method|
|
31
31
|
cost = shipping_method.calculator.compute(package)
|
32
|
-
shipping_method.
|
32
|
+
tax_category = shipping_method.tax_category
|
33
|
+
if tax_category
|
34
|
+
tax_rate = tax_category.tax_rates.detect do |rate|
|
35
|
+
rate.zone == package.order.tax_zone
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if cost
|
40
|
+
rate = shipping_method.shipping_rates.new(cost: cost)
|
41
|
+
rate.tax_rate = tax_rate if tax_rate
|
42
|
+
end
|
43
|
+
|
44
|
+
rate
|
33
45
|
end.compact
|
34
46
|
end
|
35
47
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spree
|
2
2
|
module Stock
|
3
3
|
class Package
|
4
|
-
ContentItem = Struct.new(:variant, :quantity, :state)
|
4
|
+
ContentItem = Struct.new(:line_item, :variant, :quantity, :state)
|
5
5
|
|
6
6
|
attr_reader :stock_location, :order, :contents
|
7
7
|
attr_accessor :shipping_rates
|
@@ -13,8 +13,8 @@ module Spree
|
|
13
13
|
@shipping_rates = Array.new
|
14
14
|
end
|
15
15
|
|
16
|
-
def add(
|
17
|
-
contents << ContentItem.new(variant, quantity, state)
|
16
|
+
def add(line_item, quantity, state = :on_hand, variant = nil)
|
17
|
+
contents << ContentItem.new(line_item, variant || line_item.variant, quantity, state)
|
18
18
|
end
|
19
19
|
|
20
20
|
def weight
|
@@ -29,10 +29,13 @@ module Spree
|
|
29
29
|
contents.select { |item| item.state == :backordered }
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
# Consider extensions and applications might create a inventory unit
|
33
|
+
# where the variant and the line_item might not refer to the same product
|
34
|
+
def find_item(variant, state = :on_hand, line_item = nil)
|
33
35
|
contents.select do |item|
|
34
36
|
item.variant == variant &&
|
35
|
-
item.state == state
|
37
|
+
item.state == state &&
|
38
|
+
(line_item.nil? || line_item == item.line_item)
|
36
39
|
end.first
|
37
40
|
end
|
38
41
|
|
@@ -55,7 +58,7 @@ module Spree
|
|
55
58
|
flat = []
|
56
59
|
contents.each do |item|
|
57
60
|
item.quantity.times do
|
58
|
-
flat << ContentItem.new(item.variant, 1, item.state)
|
61
|
+
flat << ContentItem.new(item.line_item, item.variant, 1, item.state)
|
59
62
|
end
|
60
63
|
end
|
61
64
|
flat
|
@@ -68,7 +71,7 @@ module Spree
|
|
68
71
|
if current_item
|
69
72
|
current_item.quantity += 1
|
70
73
|
else
|
71
|
-
add(item.
|
74
|
+
add(item.line_item, item.quantity, item.state)
|
72
75
|
end
|
73
76
|
end
|
74
77
|
end
|
@@ -105,6 +108,7 @@ module Spree
|
|
105
108
|
unit.pending = true
|
106
109
|
unit.order = order
|
107
110
|
unit.variant = item.variant
|
111
|
+
unit.line_item = item.line_item
|
108
112
|
unit.state = item.state.to_s
|
109
113
|
end
|
110
114
|
end
|
@@ -24,10 +24,10 @@ module Spree
|
|
24
24
|
next unless stock_location.stock_item(line_item.variant)
|
25
25
|
|
26
26
|
on_hand, backordered = stock_location.fill_status(line_item.variant, line_item.quantity)
|
27
|
-
package.add line_item
|
28
|
-
package.add line_item
|
27
|
+
package.add line_item, on_hand, :on_hand if on_hand > 0
|
28
|
+
package.add line_item, backordered, :backordered if backordered > 0
|
29
29
|
else
|
30
|
-
package.add line_item
|
30
|
+
package.add line_item, line_item.quantity, :on_hand
|
31
31
|
end
|
32
32
|
end
|
33
33
|
package
|
@@ -4,7 +4,7 @@ module Spree
|
|
4
4
|
attr_reader :stock_items
|
5
5
|
|
6
6
|
def initialize(variant)
|
7
|
-
@variant = variant
|
7
|
+
@variant = resolve_variant_id(variant)
|
8
8
|
@stock_items = Spree::StockItem.joins(:stock_location).where(:variant_id => @variant, Spree::StockLocation.table_name =>{ :active => true})
|
9
9
|
end
|
10
10
|
|
@@ -24,6 +24,14 @@ module Spree
|
|
24
24
|
total_on_hand >= required || backorderable?
|
25
25
|
end
|
26
26
|
|
27
|
+
private
|
28
|
+
|
29
|
+
# return variant when passed either variant object or variant id
|
30
|
+
def resolve_variant_id(variant)
|
31
|
+
variant = Spree::Variant.find_by_id(variant) unless variant.respond_to?(:should_track_inventory?)
|
32
|
+
variant
|
33
|
+
end
|
34
|
+
|
27
35
|
end
|
28
36
|
end
|
29
37
|
end
|
@@ -3,14 +3,17 @@ module Spree
|
|
3
3
|
acts_as_paranoid
|
4
4
|
|
5
5
|
belongs_to :stock_location, class_name: 'Spree::StockLocation'
|
6
|
-
belongs_to :variant, class_name: 'Spree::Variant',
|
7
|
-
has_many :stock_movements
|
6
|
+
belongs_to :variant, class_name: 'Spree::Variant', inverse_of: :stock_items
|
7
|
+
has_many :stock_movements, inverse_of: :stock_item
|
8
8
|
|
9
9
|
validates_presence_of :stock_location, :variant
|
10
10
|
validates_uniqueness_of :variant_id, scope: [:stock_location_id, :deleted_at]
|
11
11
|
|
12
12
|
delegate :weight, :should_track_inventory?, to: :variant
|
13
13
|
|
14
|
+
after_save :conditional_variant_touch
|
15
|
+
after_touch { variant.touch }
|
16
|
+
|
14
17
|
def backordered_inventory_units
|
15
18
|
Spree::InventoryUnit.backordered_for_stock_item(self)
|
16
19
|
end
|
@@ -44,10 +47,6 @@ module Spree
|
|
44
47
|
self.in_stock? || self.backorderable?
|
45
48
|
end
|
46
49
|
|
47
|
-
def variant
|
48
|
-
Spree::Variant.unscoped { super }
|
49
|
-
end
|
50
|
-
|
51
50
|
private
|
52
51
|
def count_on_hand=(value)
|
53
52
|
write_attribute(:count_on_hand, value)
|
@@ -63,5 +62,11 @@ module Spree
|
|
63
62
|
end
|
64
63
|
end
|
65
64
|
end
|
65
|
+
|
66
|
+
def conditional_variant_touch
|
67
|
+
if !Spree::Config.binary_inventory_cache || (count_on_hand_changed? && count_on_hand_change.any?(&:zero?))
|
68
|
+
variant.touch
|
69
|
+
end
|
70
|
+
end
|
66
71
|
end
|
67
72
|
end
|
@@ -1,9 +1,8 @@
|
|
1
1
|
module Spree
|
2
2
|
class StockMovement < ActiveRecord::Base
|
3
|
-
belongs_to :stock_item, class_name: 'Spree::StockItem'
|
3
|
+
belongs_to :stock_item, class_name: 'Spree::StockItem', inverse_of: :stock_movements
|
4
4
|
belongs_to :originator, polymorphic: true
|
5
5
|
|
6
|
-
|
7
6
|
after_create :update_stock_item_quantity
|
8
7
|
|
9
8
|
validates :stock_item, presence: true
|
@@ -11,7 +11,12 @@ module Spree
|
|
11
11
|
#set existing default tax category to false if this one has been marked as default
|
12
12
|
|
13
13
|
if is_default && tax_category = self.class.where(is_default: true).first
|
14
|
-
|
14
|
+
unless tax_category == self
|
15
|
+
tax_category.update_columns(
|
16
|
+
is_default: false,
|
17
|
+
updated_at: Time.now,
|
18
|
+
)
|
19
|
+
end
|
15
20
|
end
|
16
21
|
end
|
17
22
|
end
|
@@ -15,6 +15,8 @@ module Spree
|
|
15
15
|
belongs_to :zone, class_name: "Spree::Zone"
|
16
16
|
belongs_to :tax_category, class_name: "Spree::TaxCategory"
|
17
17
|
|
18
|
+
has_many :adjustments, as: :source, dependent: :destroy
|
19
|
+
|
18
20
|
validates :amount, presence: true, numericality: true
|
19
21
|
validates :tax_category_id, presence: true
|
20
22
|
validates_with DefaultTaxZoneValidator
|
@@ -23,20 +25,40 @@ module Spree
|
|
23
25
|
|
24
26
|
# Gets the array of TaxRates appropriate for the specified order
|
25
27
|
def self.match(order)
|
26
|
-
|
27
|
-
|
28
|
-
includes(zone: { zone_members: :zoneable }).load.select do |rate|
|
28
|
+
return [] unless order.tax_zone
|
29
|
+
all.select do |rate|
|
29
30
|
(!rate.included_in_price && (rate.zone == order.tax_zone || rate.zone.contains?(order.tax_zone) || (order.tax_address.nil? && rate.zone.default_tax))) ||
|
30
31
|
rate.included_in_price
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
# Pre-tax amounts must be stored so that we can calculate
|
36
|
+
# correct rate amounts in the future. For example:
|
37
|
+
# https://github.com/spree/spree/issues/4318#issuecomment-34723428
|
38
|
+
def self.store_pre_tax_amount(item, rates)
|
39
|
+
if rates.any? { |r| r.included_in_price }
|
40
|
+
case item
|
41
|
+
when Spree::LineItem
|
42
|
+
item_amount = item.discounted_amount
|
43
|
+
when Spree::Shipment
|
44
|
+
item_amount = item.discounted_cost
|
45
|
+
end
|
46
|
+
pre_tax_amount = item_amount / (1 + rates.map(&:amount).sum)
|
47
|
+
item.update_column(:pre_tax_amount, pre_tax_amount)
|
48
|
+
end
|
49
|
+
end
|
37
50
|
|
38
|
-
|
39
|
-
|
51
|
+
def self.adjust(order, items)
|
52
|
+
rates = self.match(order)
|
53
|
+
tax_categories = rates.map(&:tax_category)
|
54
|
+
relevant_items = items.select { |item| tax_categories.include?(item.tax_category) }
|
55
|
+
relevant_items.each do |item|
|
56
|
+
item.adjustments.tax.delete_all
|
57
|
+
relevant_rates = rates.select { |rate| rate.tax_category == item.tax_category }
|
58
|
+
store_pre_tax_amount(item, relevant_rates)
|
59
|
+
relevant_rates.each do |rate|
|
60
|
+
rate.adjust(order, item)
|
61
|
+
end
|
40
62
|
end
|
41
63
|
end
|
42
64
|
|
@@ -54,51 +76,37 @@ module Spree
|
|
54
76
|
end
|
55
77
|
|
56
78
|
# Creates necessary tax adjustments for the order.
|
57
|
-
def adjust(order)
|
58
|
-
|
59
|
-
|
79
|
+
def adjust(order, item)
|
80
|
+
amount = calculator.compute(item)
|
81
|
+
return if amount == 0
|
82
|
+
|
83
|
+
included = included_in_price &&
|
84
|
+
Zone.default_tax.contains?(item.order.tax_zone)
|
85
|
+
|
86
|
+
if amount < 0
|
87
|
+
label = Spree.t(:refund) + ' ' + create_label
|
88
|
+
end
|
89
|
+
|
90
|
+
self.adjustments.create!({
|
91
|
+
:adjustable => item,
|
92
|
+
:amount => amount,
|
93
|
+
:order => order,
|
94
|
+
:label => label || create_label,
|
95
|
+
:included => included
|
96
|
+
})
|
97
|
+
end
|
98
|
+
|
99
|
+
# This method is used by Adjustment#update to recalculate the cost.
|
100
|
+
def compute_amount(item)
|
60
101
|
if included_in_price
|
61
|
-
if Zone.default_tax.contains? order.tax_zone
|
62
|
-
|
63
|
-
amount = calculator.compute(line_item)
|
64
|
-
unless amount == 0
|
65
|
-
line_item.adjustments.create(
|
66
|
-
order: order,
|
67
|
-
amount: amount,
|
68
|
-
source: line_item,
|
69
|
-
originator: self,
|
70
|
-
label: label,
|
71
|
-
mandatory: false,
|
72
|
-
state: "closed",
|
73
|
-
included: true
|
74
|
-
)
|
75
|
-
end
|
76
|
-
end
|
102
|
+
if Zone.default_tax.contains? item.order.tax_zone
|
103
|
+
calculator.compute(item)
|
77
104
|
else
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
order.adjustments.create(
|
82
|
-
order: order,
|
83
|
-
amount: amount,
|
84
|
-
source: order,
|
85
|
-
originator: self,
|
86
|
-
state: "closed",
|
87
|
-
label: label
|
88
|
-
)
|
105
|
+
# In this case, it's a refund.
|
106
|
+
calculator.compute(item) * - 1
|
89
107
|
end
|
90
108
|
else
|
91
|
-
|
92
|
-
unless amount == 0
|
93
|
-
order.adjustments.create(
|
94
|
-
order: order,
|
95
|
-
amount: amount,
|
96
|
-
source: order,
|
97
|
-
originator: self,
|
98
|
-
state: "closed",
|
99
|
-
label: label
|
100
|
-
)
|
101
|
-
end
|
109
|
+
calculator.compute(item)
|
102
110
|
end
|
103
111
|
end
|
104
112
|
|
data/app/models/spree/taxon.rb
CHANGED
@@ -2,14 +2,16 @@ module Spree
|
|
2
2
|
class Taxon < ActiveRecord::Base
|
3
3
|
acts_as_nested_set dependent: :destroy
|
4
4
|
|
5
|
-
belongs_to :taxonomy, class_name: 'Spree::Taxonomy', :
|
6
|
-
has_many :classifications, dependent: :delete_all
|
5
|
+
belongs_to :taxonomy, class_name: 'Spree::Taxonomy', touch: true, inverse_of: :taxons
|
6
|
+
has_many :classifications, -> { order(:position) }, dependent: :delete_all, inverse_of: :taxon
|
7
7
|
has_many :products, through: :classifications
|
8
8
|
|
9
9
|
before_create :set_permalink
|
10
10
|
|
11
11
|
validates :name, presence: true
|
12
12
|
|
13
|
+
after_touch :touch_parent
|
14
|
+
|
13
15
|
has_attached_file :icon,
|
14
16
|
styles: { mini: '32x32>', normal: '128x128>' },
|
15
17
|
default_style: :mini,
|
@@ -17,9 +19,6 @@ module Spree
|
|
17
19
|
path: ':rails_root/public/spree/taxons/:id/:style/:basename.:extension',
|
18
20
|
default_url: '/assets/default_taxon.png'
|
19
21
|
|
20
|
-
include Spree::Core::S3Support
|
21
|
-
supports_s3 :icon
|
22
|
-
|
23
22
|
include Spree::Core::ProductFilters # for detailed defs of filters
|
24
23
|
|
25
24
|
# indicate which filters should be used for a taxon
|
@@ -78,5 +77,11 @@ module Spree
|
|
78
77
|
def child_index=(idx)
|
79
78
|
move_to_child_with_index(parent, idx.to_i) unless self.new_record?
|
80
79
|
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def touch_parent
|
84
|
+
parent.touch if parent
|
85
|
+
end
|
81
86
|
end
|
82
87
|
end
|
@@ -2,7 +2,7 @@ module Spree
|
|
2
2
|
class Taxonomy < ActiveRecord::Base
|
3
3
|
validates :name, presence: true
|
4
4
|
|
5
|
-
has_many :taxons
|
5
|
+
has_many :taxons, inverse_of: :taxonomy
|
6
6
|
has_one :root, -> { where parent_id: nil }, class_name: "Spree::Taxon", dependent: :destroy
|
7
7
|
|
8
8
|
after_save :set_name
|
@@ -12,7 +12,10 @@ module Spree
|
|
12
12
|
private
|
13
13
|
def set_name
|
14
14
|
if root
|
15
|
-
root.
|
15
|
+
root.update_columns(
|
16
|
+
name: name,
|
17
|
+
updated_at: Time.now,
|
18
|
+
)
|
16
19
|
else
|
17
20
|
self.root = Taxon.create!(taxonomy_id: id, name: name)
|
18
21
|
end
|
data/app/models/spree/variant.rb
CHANGED
@@ -2,20 +2,21 @@ module Spree
|
|
2
2
|
class Variant < ActiveRecord::Base
|
3
3
|
acts_as_paranoid
|
4
4
|
|
5
|
-
belongs_to :product, touch: true, class_name: 'Spree::Product'
|
5
|
+
belongs_to :product, touch: true, class_name: 'Spree::Product', inverse_of: :variants
|
6
|
+
belongs_to :tax_category, class_name: 'Spree::TaxCategory'
|
6
7
|
|
7
|
-
delegate_belongs_to :product, :name, :description, :
|
8
|
-
:
|
9
|
-
:
|
8
|
+
delegate_belongs_to :product, :name, :description, :slug, :available_on,
|
9
|
+
:shipping_category_id, :meta_description, :meta_keywords,
|
10
|
+
:shipping_category
|
10
11
|
|
11
12
|
has_many :inventory_units
|
12
|
-
has_many :line_items
|
13
|
+
has_many :line_items, inverse_of: :variant
|
13
14
|
|
14
|
-
has_many :stock_items, dependent: :destroy
|
15
|
+
has_many :stock_items, dependent: :destroy, inverse_of: :variant
|
15
16
|
has_many :stock_locations, through: :stock_items
|
16
17
|
has_many :stock_movements
|
17
18
|
|
18
|
-
has_and_belongs_to_many :option_values, join_table: :spree_option_values_variants
|
19
|
+
has_and_belongs_to_many :option_values, join_table: :spree_option_values_variants
|
19
20
|
has_many :images, -> { order(:position) }, as: :viewable, dependent: :destroy, class_name: "Spree::Image"
|
20
21
|
|
21
22
|
has_one :default_price,
|
@@ -27,7 +28,8 @@ module Spree
|
|
27
28
|
|
28
29
|
has_many :prices,
|
29
30
|
class_name: 'Spree::Price',
|
30
|
-
dependent: :destroy
|
31
|
+
dependent: :destroy,
|
32
|
+
inverse_of: :variant
|
31
33
|
|
32
34
|
validate :check_price
|
33
35
|
validates :price, numericality: { greater_than_or_equal_to: 0 }
|
@@ -39,6 +41,8 @@ module Spree
|
|
39
41
|
after_create :create_stock_items
|
40
42
|
after_create :set_position
|
41
43
|
|
44
|
+
after_touch :clear_in_stock_cache
|
45
|
+
|
42
46
|
# default variant scope only lists non-deleted variants
|
43
47
|
scope :deleted, lambda { where.not(deleted_at: nil) }
|
44
48
|
|
@@ -46,6 +50,14 @@ module Spree
|
|
46
50
|
joins(:prices).where(deleted_at: nil).where('spree_prices.currency' => currency || Spree::Config[:currency]).where('spree_prices.amount IS NOT NULL')
|
47
51
|
end
|
48
52
|
|
53
|
+
def tax_category
|
54
|
+
if self[:tax_category_id].nil?
|
55
|
+
product.tax_category
|
56
|
+
else
|
57
|
+
TaxCategory.find(self[:tax_category_id])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
49
61
|
def cost_price=(price)
|
50
62
|
self[:cost_price] = parse_price(price) if price.present?
|
51
63
|
end
|
@@ -75,7 +87,7 @@ module Spree
|
|
75
87
|
# allows extensions to override deleted? if they want to provide
|
76
88
|
# their own definition.
|
77
89
|
def deleted?
|
78
|
-
|
90
|
+
deleted_at
|
79
91
|
end
|
80
92
|
|
81
93
|
# Product may be created with deleted_at already set,
|
@@ -149,16 +161,13 @@ module Spree
|
|
149
161
|
"#{sku} #{options_text}".strip
|
150
162
|
end
|
151
163
|
|
152
|
-
def in_stock?
|
153
|
-
|
154
|
-
|
155
|
-
else
|
156
|
-
puts %q{[DEPRECATION] In Spree 2.2, Variant#in_stock? will no longer take a quantity. Use Variant#can_supply? instead.}
|
157
|
-
can_stock?(quantity)
|
164
|
+
def in_stock?
|
165
|
+
Rails.cache.fetch(in_stock_cache_key) do
|
166
|
+
total_on_hand > 0
|
158
167
|
end
|
159
168
|
end
|
160
169
|
|
161
|
-
def
|
170
|
+
def can_supply?(quantity=1)
|
162
171
|
Spree::Stock::Quantifier.new(self).can_supply?(quantity)
|
163
172
|
end
|
164
173
|
|
@@ -214,6 +223,14 @@ module Spree
|
|
214
223
|
def set_position
|
215
224
|
self.update_column(:position, product.variants.maximum(:position).to_i + 1)
|
216
225
|
end
|
226
|
+
|
227
|
+
def in_stock_cache_key
|
228
|
+
"variant-#{id}-in_stock"
|
229
|
+
end
|
230
|
+
|
231
|
+
def clear_in_stock_cache
|
232
|
+
Rails.cache.delete(in_stock_cache_key)
|
233
|
+
end
|
217
234
|
end
|
218
235
|
end
|
219
236
|
|