spree_core 2.1.12 → 2.2.0
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/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
@@ -0,0 +1,24 @@
|
|
1
|
+
module Spree
|
2
|
+
module PromotionHandler
|
3
|
+
class Page
|
4
|
+
attr_reader :order, :path
|
5
|
+
|
6
|
+
def initialize(order, path)
|
7
|
+
@order = order
|
8
|
+
@path = path.gsub(/\A\//, '')
|
9
|
+
end
|
10
|
+
|
11
|
+
def activate
|
12
|
+
if promotion && promotion.eligible?(order)
|
13
|
+
promotion.activate(:order => order)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def promotion
|
20
|
+
@promotion ||= Promotion.active.find_by(:path => path)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,23 +1,31 @@
|
|
1
1
|
# Base class for all promotion rules
|
2
2
|
module Spree
|
3
3
|
class PromotionRule < ActiveRecord::Base
|
4
|
-
belongs_to :promotion,
|
4
|
+
belongs_to :promotion, class_name: 'Spree::Promotion', inverse_of: :promotion_rules
|
5
5
|
|
6
6
|
scope :of_type, ->(t) { where(type: t) }
|
7
7
|
|
8
8
|
validate :promotion, presence: true
|
9
|
-
validate :
|
9
|
+
validate :unique_per_promotion, on: :create
|
10
10
|
|
11
|
-
def
|
12
|
-
|
11
|
+
def self.for(promotable)
|
12
|
+
all.select { |rule| rule.applicable?(promotable) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def applicable?(promotable)
|
16
|
+
raise 'applicable? should be implemented in a sub-class of Spree::PromotionRule'
|
17
|
+
end
|
18
|
+
|
19
|
+
def eligible?(promotable, options = {})
|
20
|
+
raise 'eligible? should be implemented in a sub-class of Spree::PromotionRule'
|
13
21
|
end
|
14
22
|
|
15
23
|
private
|
16
|
-
def
|
17
|
-
if Spree::PromotionRule.exists?(
|
24
|
+
def unique_per_promotion
|
25
|
+
if Spree::PromotionRule.exists?(promotion_id: promotion_id, type: self.class.name)
|
18
26
|
errors[:base] << "Promotion already contains this rule type"
|
19
27
|
end
|
20
28
|
end
|
21
|
-
|
29
|
+
|
22
30
|
end
|
23
31
|
end
|
@@ -2,7 +2,7 @@ module Spree
|
|
2
2
|
class Property < ActiveRecord::Base
|
3
3
|
has_and_belongs_to_many :prototypes, join_table: 'spree_properties_prototypes'
|
4
4
|
|
5
|
-
has_many :product_properties, dependent: :delete_all
|
5
|
+
has_many :product_properties, dependent: :delete_all, inverse_of: :property
|
6
6
|
has_many :products, through: :product_properties
|
7
7
|
|
8
8
|
validates :name, :presentation, presence: true
|
@@ -62,6 +62,11 @@ module Spree
|
|
62
62
|
order.shipped_shipments.collect{|s| s.inventory_units.to_a}.flatten
|
63
63
|
end
|
64
64
|
|
65
|
+
# Used when Adjustment#update! wants to update the related adjustmenrt
|
66
|
+
def compute_amount(*args)
|
67
|
+
amount.abs * -1
|
68
|
+
end
|
69
|
+
|
65
70
|
private
|
66
71
|
|
67
72
|
def must_have_shipped_units
|
@@ -82,10 +87,11 @@ module Spree
|
|
82
87
|
Spree::StockMovement.create!(stock_item_id: stock_item.id, quantity: 1)
|
83
88
|
end
|
84
89
|
|
85
|
-
credit = Adjustment.new(amount:
|
90
|
+
credit = Adjustment.new(amount: compute_amount, label: Spree.t(:rma_credit))
|
86
91
|
credit.source = self
|
87
92
|
credit.adjustable = order
|
88
93
|
credit.save
|
94
|
+
order.update!
|
89
95
|
|
90
96
|
order.return if inventory_units.all?(&:returned?)
|
91
97
|
end
|
@@ -2,17 +2,19 @@ require 'ostruct'
|
|
2
2
|
|
3
3
|
module Spree
|
4
4
|
class Shipment < ActiveRecord::Base
|
5
|
-
belongs_to :order, class_name: 'Spree::Order', touch: true
|
6
|
-
belongs_to :address, class_name: 'Spree::Address'
|
5
|
+
belongs_to :order, class_name: 'Spree::Order', touch: true, inverse_of: :shipments
|
6
|
+
belongs_to :address, class_name: 'Spree::Address', inverse_of: :shipments
|
7
7
|
belongs_to :stock_location, class_name: 'Spree::StockLocation'
|
8
8
|
|
9
9
|
has_many :shipping_rates, dependent: :delete_all
|
10
10
|
has_many :shipping_methods, through: :shipping_rates
|
11
11
|
has_many :state_changes, as: :stateful
|
12
|
-
has_many :inventory_units, dependent: :delete_all
|
13
|
-
|
12
|
+
has_many :inventory_units, dependent: :delete_all, inverse_of: :shipment
|
13
|
+
has_many :adjustments, as: :adjustable, dependent: :delete_all
|
14
14
|
|
15
|
-
after_save :
|
15
|
+
after_save :update_adjustments
|
16
|
+
|
17
|
+
before_validation :set_cost_zero_when_nil
|
16
18
|
|
17
19
|
attr_accessor :special_instructions
|
18
20
|
|
@@ -60,6 +62,14 @@ module Spree
|
|
60
62
|
transition from: :canceled, to: :pending
|
61
63
|
end
|
62
64
|
after_transition from: :canceled, to: [:pending, :ready], do: :after_resume
|
65
|
+
|
66
|
+
after_transition do |shipment, transition|
|
67
|
+
shipment.state_changes.create!(
|
68
|
+
previous_state: transition.from,
|
69
|
+
next_state: transition.to,
|
70
|
+
name: 'shipment',
|
71
|
+
)
|
72
|
+
end
|
63
73
|
end
|
64
74
|
|
65
75
|
def to_param
|
@@ -70,6 +80,10 @@ module Spree
|
|
70
80
|
inventory_units.any? { |inventory_unit| inventory_unit.backordered? }
|
71
81
|
end
|
72
82
|
|
83
|
+
def ready_or_pending?
|
84
|
+
self.ready? || self.pending?
|
85
|
+
end
|
86
|
+
|
73
87
|
def shipped=(value)
|
74
88
|
return unless value == '1' && shipped_at.nil?
|
75
89
|
self.shipped_at = Time.now
|
@@ -97,6 +111,10 @@ module Spree
|
|
97
111
|
self.save!
|
98
112
|
end
|
99
113
|
|
114
|
+
def tax_category
|
115
|
+
selected_shipping_rate.try(:tax_rate).try(:tax_category)
|
116
|
+
end
|
117
|
+
|
100
118
|
def refresh_rates
|
101
119
|
return shipping_rates if shipped?
|
102
120
|
return [] unless can_get_rates?
|
@@ -120,54 +138,59 @@ module Spree
|
|
120
138
|
order ? order.currency : Spree::Config[:currency]
|
121
139
|
end
|
122
140
|
|
123
|
-
# The adjustment amount associated with this shipment (if any.) Returns only the first adjustment to match
|
124
|
-
# the shipment but there should never really be more than one.
|
125
|
-
def cost
|
126
|
-
adjustment ? adjustment.amount : 0
|
127
|
-
end
|
128
|
-
|
129
|
-
alias_method :amount, :cost
|
130
|
-
|
131
141
|
def display_cost
|
132
142
|
Spree::Money.new(cost, { currency: currency })
|
133
143
|
end
|
134
|
-
|
135
|
-
alias_method :display_amount, :display_cost
|
144
|
+
alias display_amount display_cost
|
136
145
|
|
137
146
|
def item_cost
|
138
147
|
line_items.map(&:amount).sum
|
139
148
|
end
|
140
149
|
|
141
|
-
def
|
142
|
-
|
150
|
+
def discounted_cost
|
151
|
+
cost + promo_total
|
152
|
+
end
|
153
|
+
alias discounted_amount discounted_cost
|
154
|
+
|
155
|
+
# Only one of either included_tax_total or additional_tax_total is set
|
156
|
+
# This method returns the total of the two. Saves having to check if
|
157
|
+
# tax is included or additional.
|
158
|
+
def tax_total
|
159
|
+
included_tax_total + additional_tax_total
|
160
|
+
end
|
161
|
+
|
162
|
+
def final_price
|
163
|
+
discounted_cost + tax_total
|
143
164
|
end
|
144
165
|
|
145
|
-
def
|
146
|
-
|
166
|
+
def display_discounted_cost
|
167
|
+
Spree::Money.new(discounted_cost, { currency: currency })
|
147
168
|
end
|
148
169
|
|
149
|
-
def
|
150
|
-
Spree::Money.new(
|
170
|
+
def display_item_cost
|
171
|
+
Spree::Money.new(item_cost, { currency: currency })
|
151
172
|
end
|
152
173
|
|
153
174
|
def editable_by?(user)
|
154
175
|
!shipped?
|
155
176
|
end
|
156
177
|
|
178
|
+
ManifestItem = Struct.new(:line_item, :variant, :quantity, :states)
|
179
|
+
|
157
180
|
def manifest
|
158
181
|
inventory_units.group_by(&:variant).map do |variant, units|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
182
|
+
units.group_by(&:line_item).map do |line_item, units|
|
183
|
+
|
184
|
+
states = {}
|
185
|
+
units.group_by(&:state).each { |state, iu| states[state] = iu.count }
|
186
|
+
|
187
|
+
ManifestItem.new(line_item, variant, units.length, states)
|
188
|
+
end
|
189
|
+
end.flatten
|
163
190
|
end
|
164
191
|
|
165
192
|
def line_items
|
166
|
-
|
167
|
-
order.line_items.select { |li| !li.should_track_inventory? || inventory_units.pluck(:variant_id).include?(li.variant_id) }
|
168
|
-
else
|
169
|
-
order.line_items
|
170
|
-
end
|
193
|
+
inventory_units.includes(:line_item).map(&:line_item).uniq
|
171
194
|
end
|
172
195
|
|
173
196
|
def finalize!
|
@@ -189,7 +212,10 @@ module Spree
|
|
189
212
|
def update!(order)
|
190
213
|
old_state = state
|
191
214
|
new_state = determine_state(order)
|
192
|
-
|
215
|
+
update_columns(
|
216
|
+
state: new_state,
|
217
|
+
updated_at: Time.now,
|
218
|
+
)
|
193
219
|
after_ship if new_state == 'shipped' and old_state != 'shipped'
|
194
220
|
end
|
195
221
|
|
@@ -215,19 +241,45 @@ module Spree
|
|
215
241
|
end
|
216
242
|
|
217
243
|
def inventory_units_for(variant)
|
218
|
-
inventory_units.
|
244
|
+
inventory_units.where(variant_id: variant.id)
|
245
|
+
end
|
246
|
+
|
247
|
+
def inventory_units_for_item(line_item, variant = nil)
|
248
|
+
inventory_units.where(line_item_id: line_item.id, variant_id: line_item.variant.id || variant.id)
|
219
249
|
end
|
220
250
|
|
221
251
|
def to_package
|
222
252
|
package = Stock::Package.new(stock_location, order)
|
223
|
-
inventory_units.includes(:
|
224
|
-
|
253
|
+
grouped_inventory_units = inventory_units.includes(:line_item).group_by do |iu|
|
254
|
+
[iu.line_item, iu.state_name]
|
255
|
+
end
|
256
|
+
|
257
|
+
grouped_inventory_units.each do |(line_item, state_name), inventory_units|
|
258
|
+
package.add line_item, inventory_units.count, state_name
|
225
259
|
end
|
226
260
|
package
|
227
261
|
end
|
228
262
|
|
229
|
-
def set_up_inventory(state, variant, order)
|
230
|
-
self.inventory_units.create(
|
263
|
+
def set_up_inventory(state, variant, order, line_item)
|
264
|
+
self.inventory_units.create(
|
265
|
+
state: state,
|
266
|
+
variant_id: variant.id,
|
267
|
+
order_id: order.id,
|
268
|
+
line_item_id: line_item.id
|
269
|
+
)
|
270
|
+
end
|
271
|
+
|
272
|
+
def persist_cost
|
273
|
+
self.cost = selected_shipping_rate.cost
|
274
|
+
update_amounts
|
275
|
+
end
|
276
|
+
|
277
|
+
def update_amounts
|
278
|
+
self.update_columns(
|
279
|
+
cost: selected_shipping_rate.cost,
|
280
|
+
adjustment_total: adjustments.map(&:update!).compact.sum,
|
281
|
+
updated_at: Time.now,
|
282
|
+
)
|
231
283
|
end
|
232
284
|
|
233
285
|
private
|
@@ -250,32 +302,44 @@ module Spree
|
|
250
302
|
"#{Spree.t(:shipping)} (#{shipping_method.name})"
|
251
303
|
end
|
252
304
|
|
305
|
+
def validate_shipping_method
|
306
|
+
unless shipping_method.nil?
|
307
|
+
errors.add :shipping_method, Spree.t(:is_not_available_to_shipment_address) unless shipping_method.include?(address)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
253
311
|
def after_ship
|
254
312
|
inventory_units.each &:ship!
|
255
|
-
adjustment.finalize!
|
256
313
|
send_shipped_email
|
257
314
|
touch :shipped_at
|
315
|
+
update_order_shipment_state
|
316
|
+
end
|
317
|
+
|
318
|
+
def update_order_shipment_state
|
319
|
+
new_state = OrderUpdater.new(order).update_shipment_state
|
320
|
+
order.update_columns(
|
321
|
+
shipment_state: new_state,
|
322
|
+
updated_at: Time.now,
|
323
|
+
)
|
258
324
|
end
|
259
325
|
|
260
326
|
def send_shipped_email
|
261
327
|
ShipmentMailer.shipped_email(self.id).deliver
|
262
328
|
end
|
263
329
|
|
264
|
-
def
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
shipping_method.create_adjustment shipping_method.adjustment_label, order, self, true, "open"
|
273
|
-
reload #ensure adjustment is present on later saves
|
330
|
+
def set_cost_zero_when_nil
|
331
|
+
self.cost = 0 unless self.cost
|
332
|
+
end
|
333
|
+
|
334
|
+
|
335
|
+
def update_adjustments
|
336
|
+
if cost_changed? && state != 'shipped'
|
337
|
+
recalculate_adjustments
|
274
338
|
end
|
275
339
|
end
|
276
340
|
|
277
|
-
def
|
278
|
-
|
341
|
+
def recalculate_adjustments
|
342
|
+
Spree::ItemAdjustments.new(self).update
|
279
343
|
end
|
280
344
|
|
281
345
|
def can_get_rates?
|
@@ -1,13 +1,12 @@
|
|
1
1
|
module Spree
|
2
2
|
class ShippingCalculator < Calculator
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
compute_package package
|
3
|
+
|
4
|
+
def compute_shipment(shipment)
|
5
|
+
raise NotImplementedError, "Please implement 'compute_shipment(shipment)' in your calculator: #{self.class.name}"
|
7
6
|
end
|
8
7
|
|
9
8
|
def compute_package(package)
|
10
|
-
raise
|
9
|
+
raise NotImplementedError, "Please implement 'compute_package(package)' in your calculator: #{self.class.name}"
|
11
10
|
end
|
12
11
|
|
13
12
|
def available?(package)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Spree
|
2
2
|
class ShippingCategory < ActiveRecord::Base
|
3
3
|
validates :name, presence: true
|
4
|
-
has_many :products
|
4
|
+
has_many :products, inverse_of: :shipping_category
|
5
5
|
has_many :shipping_method_categories
|
6
6
|
has_many :shipping_methods, through: :shipping_method_categories
|
7
7
|
end
|
8
|
-
end
|
8
|
+
end
|
@@ -1,28 +1,26 @@
|
|
1
1
|
module Spree
|
2
2
|
class ShippingMethod < ActiveRecord::Base
|
3
|
-
acts_as_paranoid
|
4
3
|
include Spree::Core::CalculatedAdjustments
|
5
4
|
DISPLAY = [:both, :front_end, :back_end]
|
6
5
|
|
7
6
|
default_scope -> { where(deleted_at: nil) }
|
8
7
|
|
8
|
+
has_many :adjustments, as: :source
|
9
|
+
has_many :shipments
|
9
10
|
has_many :shipping_method_categories, :dependent => :destroy
|
10
11
|
has_many :shipping_categories, through: :shipping_method_categories
|
11
12
|
has_many :shipping_rates, inverse_of: :shipping_method
|
12
|
-
has_many :shipments, :through => :shipping_rates
|
13
13
|
|
14
14
|
has_and_belongs_to_many :zones, :join_table => 'spree_shipping_methods_zones',
|
15
15
|
:class_name => 'Spree::Zone',
|
16
16
|
:foreign_key => 'shipping_method_id'
|
17
17
|
|
18
|
+
belongs_to :tax_category, :class_name => 'Spree::TaxCategory'
|
19
|
+
|
18
20
|
validates :name, presence: true
|
19
21
|
|
20
22
|
validate :at_least_one_shipping_category
|
21
23
|
|
22
|
-
def adjustment_label
|
23
|
-
Spree.t(:shipping)
|
24
|
-
end
|
25
|
-
|
26
24
|
def include?(address)
|
27
25
|
return false unless address
|
28
26
|
zones.any? do |zone|
|
@@ -44,7 +42,15 @@ module Spree
|
|
44
42
|
self.display_on != "back_end"
|
45
43
|
end
|
46
44
|
|
45
|
+
def tax_category
|
46
|
+
Spree::TaxCategory.unscoped { super }
|
47
|
+
end
|
48
|
+
|
47
49
|
private
|
50
|
+
def compute_amount(calculable)
|
51
|
+
self.calculator.compute(calculable)
|
52
|
+
end
|
53
|
+
|
48
54
|
def at_least_one_shipping_category
|
49
55
|
if self.shipping_categories.empty?
|
50
56
|
self.errors[:base] << "You need to select at least one shipping category"
|
@@ -2,24 +2,44 @@ module Spree
|
|
2
2
|
class ShippingRate < ActiveRecord::Base
|
3
3
|
belongs_to :shipment, class_name: 'Spree::Shipment'
|
4
4
|
belongs_to :shipping_method, class_name: 'Spree::ShippingMethod', inverse_of: :shipping_rates
|
5
|
+
belongs_to :tax_rate, class_name: 'Spree::TaxRate'
|
6
|
+
|
7
|
+
scope :with_shipping_method,
|
8
|
+
-> { includes(:shipping_method).
|
9
|
+
references(:shipping_method).
|
10
|
+
order("cost ASC") }
|
5
11
|
|
6
12
|
delegate :order, :currency, to: :shipment
|
7
13
|
delegate :name, to: :shipping_method
|
8
14
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
else
|
13
|
-
price = cost
|
14
|
-
end
|
15
|
+
def display_base_price
|
16
|
+
Spree::Money.new(cost, currency: currency)
|
17
|
+
end
|
15
18
|
|
16
|
-
|
19
|
+
def display_tax_amount
|
20
|
+
Spree::Money.new(tax_rate.calculator.compute_shipping_rate(self), currency: currency)
|
17
21
|
end
|
18
22
|
|
23
|
+
def display_price
|
24
|
+
price = display_base_price.to_s
|
25
|
+
if tax_rate
|
26
|
+
amount = "#{display_tax_amount} #{tax_rate.name}"
|
27
|
+
if tax_rate.included_in_price?
|
28
|
+
price += " (incl. #{amount})"
|
29
|
+
else
|
30
|
+
price += " (+ #{amount})"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
price
|
34
|
+
end
|
19
35
|
alias_method :display_cost, :display_price
|
20
36
|
|
21
37
|
def shipping_method
|
22
38
|
Spree::ShippingMethod.unscoped { super }
|
23
39
|
end
|
40
|
+
|
41
|
+
def tax_rate
|
42
|
+
Spree::TaxRate.unscoped { super }
|
43
|
+
end
|
24
44
|
end
|
25
45
|
end
|