spree_core 2.0.13 → 2.1.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/controllers/spree/base_controller.rb +3 -0
- data/app/helpers/spree/base_helper.rb +6 -16
- data/app/helpers/spree/products_helper.rb +3 -8
- data/app/helpers/spree/taxons_helper.rb +1 -1
- data/app/mailers/spree/base_mailer.rb +0 -5
- data/app/models/spree/ability.rb +10 -7
- data/app/models/spree/address.rb +7 -17
- data/app/models/spree/adjustment.rb +15 -11
- data/app/models/spree/app_configuration.rb +0 -5
- data/app/models/spree/billing_integration.rb +0 -1
- data/app/models/spree/calculator/flat_percent_item_total.rb +1 -3
- data/app/models/spree/calculator/flat_rate.rb +2 -4
- data/app/models/spree/calculator/flexi_rate.rb +6 -9
- data/app/models/spree/calculator/per_item.rb +2 -4
- data/app/models/spree/calculator/percent_per_item.rb +1 -3
- data/app/models/spree/calculator/price_sack.rb +4 -9
- data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +1 -2
- data/app/models/spree/calculator/shipping/flat_rate.rb +2 -4
- data/app/models/spree/calculator/shipping/flexi_rate.rb +4 -9
- data/app/models/spree/calculator/shipping/per_item.rb +2 -3
- data/app/models/spree/calculator/shipping/price_sack.rb +4 -9
- data/app/models/spree/classification.rb +0 -3
- data/app/models/spree/country.rb +1 -3
- data/app/models/spree/credit_card.rb +37 -38
- data/app/models/spree/gateway/bogus_simple.rb +0 -8
- data/app/models/spree/gateway.rb +1 -3
- data/app/models/spree/image.rb +1 -3
- data/app/models/spree/inventory_unit.rb +5 -8
- data/app/models/spree/legacy_user.rb +0 -4
- data/app/models/spree/line_item.rb +2 -15
- data/app/models/spree/option_type.rb +2 -5
- data/app/models/spree/option_value.rb +1 -3
- data/app/models/spree/order/checkout.rb +4 -13
- data/app/models/spree/order.rb +47 -99
- data/app/models/spree/order_contents.rb +4 -7
- data/app/models/spree/order_inventory.rb +4 -8
- data/app/models/spree/order_updater.rb +13 -12
- data/app/models/spree/payment/processing.rb +12 -19
- data/app/models/spree/payment.rb +17 -30
- data/app/models/spree/payment_method.rb +2 -3
- data/app/models/spree/preference.rb +1 -1
- data/app/models/spree/preferences/configuration.rb +1 -1
- data/app/models/spree/preferences/preferable.rb +1 -1
- data/app/models/spree/preferences/store.rb +1 -1
- data/app/models/spree/price.rb +0 -7
- data/app/models/spree/product/scopes.rb +16 -17
- data/app/models/spree/product.rb +27 -62
- data/app/models/spree/product_property.rb +3 -5
- data/app/models/spree/promotion/actions/create_adjustment.rb +9 -8
- data/app/models/spree/promotion/actions/create_line_items.rb +1 -2
- data/app/models/spree/promotion/rules/first_order.rb +1 -1
- data/app/models/spree/promotion/rules/item_total.rb +2 -4
- data/app/models/spree/promotion/rules/product.rb +2 -2
- data/app/models/spree/promotion/rules/user.rb +1 -3
- data/app/models/spree/promotion.rb +23 -24
- data/app/models/spree/promotion_action.rb +0 -2
- data/app/models/spree/promotion_action_line_item.rb +1 -3
- data/app/models/spree/promotion_rule.rb +0 -2
- data/app/models/spree/property.rb +2 -4
- data/app/models/spree/prototype.rb +0 -2
- data/app/models/spree/return_authorization.rb +6 -9
- data/app/models/spree/role.rb +0 -2
- data/app/models/spree/shipment.rb +19 -25
- data/app/models/spree/shipping_calculator.rb +0 -2
- data/app/models/spree/shipping_category.rb +0 -2
- data/app/models/spree/shipping_method.rb +6 -20
- data/app/models/spree/shipping_rate.rb +12 -10
- data/app/models/spree/state.rb +2 -4
- data/app/models/spree/stock/availability_validator.rb +2 -2
- data/app/models/spree/stock/estimator.rb +6 -20
- data/app/models/spree/stock/packer.rb +1 -1
- data/app/models/spree/stock/quantifier.rb +2 -3
- data/app/models/spree/stock/splitter/base.rb +1 -1
- data/app/models/spree/stock_item.rb +8 -18
- data/app/models/spree/stock_location.rb +2 -11
- data/app/models/spree/stock_movement.rb +2 -5
- data/app/models/spree/stock_transfer.rb +0 -2
- data/app/models/spree/tax_category.rb +0 -2
- data/app/models/spree/tax_rate.rb +12 -12
- data/app/models/spree/taxon.rb +1 -13
- data/app/models/spree/taxonomy.rb +3 -6
- data/app/models/spree/tracker.rb +0 -2
- data/app/models/spree/variant/scopes.rb +2 -2
- data/app/models/spree/variant.rb +13 -31
- data/app/models/spree/zone.rb +2 -7
- data/app/models/spree/zone_member.rb +0 -2
- data/app/views/spree/payments/_payment.html.erb +1 -3
- data/config/locales/en.yml +11 -26
- data/db/default/spree/countries.rb +230 -229
- data/db/default/spree/states.rb +57 -56
- data/db/default/spree/zones.rb +5 -5
- data/db/migrate/20130213191427_create_default_stock.rb +4 -7
- 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/20130611185927_add_user_id_index_to_spree_orders.rb +5 -0
- data/db/migrate/20130618041418_add_updated_at_to_spree_countries.rb +9 -0
- data/db/migrate/20130619012236_add_updated_at_to_spree_states.rb +9 -0
- data/db/migrate/20130802022321_migrate_tax_categories_to_line_items.rb +4 -5
- data/db/migrate/20130806145853_set_default_stock_location_on_shipments.rb +1 -1
- data/lib/generators/spree/dummy/dummy_generator.rb +3 -14
- data/lib/generators/spree/dummy/templates/rails/database.yml +0 -10
- data/lib/generators/spree/dummy/templates/rails/test.rb +2 -7
- data/lib/generators/spree/install/install_generator.rb +11 -8
- data/lib/spree/core/calculated_adjustments.rb +9 -8
- data/lib/spree/core/controller_helpers/auth.rb +2 -3
- data/lib/spree/core/controller_helpers/order.rb +8 -13
- data/lib/spree/core/controller_helpers/ssl.rb +13 -22
- data/lib/spree/core/controller_helpers/strong_parameters.rb +36 -0
- data/lib/spree/core/delegate_belongs_to.rb +0 -2
- data/lib/spree/core/engine.rb +1 -5
- data/lib/spree/core/ext/active_record.rb +2 -9
- data/lib/spree/core/permalinks.rb +1 -5
- data/lib/spree/core/product_duplicator.rb +2 -16
- data/lib/spree/core/product_filters.rb +37 -33
- data/lib/spree/core/search/base.rb +1 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +3 -31
- data/lib/spree/i18n.rb +0 -1
- data/lib/spree/money.rb +2 -177
- data/lib/spree/permitted_attributes.rb +95 -0
- data/lib/spree/promo/coupon_applicator.rb +4 -12
- data/lib/spree/testing_support/capybara_ext.rb +13 -17
- data/lib/spree/testing_support/common_rake.rb +1 -1
- data/lib/spree/testing_support/controller_requests.rb +3 -3
- data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_factory.rb +0 -4
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +1 -3
- data/lib/spree/testing_support/factories/user_factory.rb +1 -1
- data/lib/spree/testing_support/factories/variant_factory.rb +0 -15
- data/lib/spree/testing_support/factories.rb +1 -1
- data/lib/spree/testing_support/order_walkthrough.rb +1 -1
- data/lib/tasks/core.rake +2 -2
- data/vendor/assets/javascripts/jquery.payment.js +497 -0
- metadata +166 -172
- data/app/views/spree/admin/shared/_report_order_criteria.html.erb +0 -17
- data/db/migrate/20130417120034_add_index_to_source_columns_on_adjustments.rb +0 -5
- data/db/migrate/20130830001033_add_shipping_category_to_shipping_methods_and_products.rb +0 -15
- data/db/migrate/20130830001159_migrate_old_shipping_calculators.rb +0 -19
- data/db/migrate/20130909115621_change_states_required_for_countries.rb +0 -9
- data/db/migrate/20131001013410_remove_unused_credit_card_fields.rb +0 -12
- data/db/migrate/20131026154747_add_track_inventory_to_variant.rb +0 -5
- data/db/migrate/20131113035136_add_channel_to_spree_orders.rb +0 -5
- data/db/migrate/20140120160805_add_index_to_variant_id_and_currency_on_prices.rb +0 -5
- data/db/migrate/20140205181631_default_variant_weight_to_zero.rb +0 -11
- data/db/migrate/20140415041315_add_user_id_created_by_id_index_to_order.rb +0 -5
- data/lib/spree/core/preference_rescue.rb +0 -25
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
class ProductProperty < ActiveRecord::Base
|
|
3
|
-
belongs_to :product,
|
|
3
|
+
belongs_to :product, class_name: 'Spree::Product'
|
|
4
4
|
belongs_to :property, class_name: 'Spree::Property'
|
|
5
5
|
|
|
6
6
|
validates :property, presence: true
|
|
7
7
|
validates :value, length: { maximum: 255 }
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
default_scope order: "#{quoted_table_name}.position"
|
|
9
|
+
default_scope -> { order("#{self.table_name}.position") }
|
|
12
10
|
|
|
13
11
|
# virtual attributes for use with AJAX completion stuff
|
|
14
12
|
def property_name
|
|
@@ -17,7 +15,7 @@ module Spree
|
|
|
17
15
|
|
|
18
16
|
def property_name=(name)
|
|
19
17
|
unless name.blank?
|
|
20
|
-
unless property = Property.
|
|
18
|
+
unless property = Property.find_by(name: name)
|
|
21
19
|
property = Property.create(name: name, presentation: name)
|
|
22
20
|
end
|
|
23
21
|
self.property = property
|
|
@@ -6,9 +6,9 @@ module Spree
|
|
|
6
6
|
class CreateAdjustment < PromotionAction
|
|
7
7
|
include Spree::Core::CalculatedAdjustments
|
|
8
8
|
|
|
9
|
-
has_many :adjustments, :
|
|
9
|
+
has_many :adjustments, as: :originator
|
|
10
10
|
|
|
11
|
-
delegate :eligible?, :
|
|
11
|
+
delegate :eligible?, to: :promotion
|
|
12
12
|
|
|
13
13
|
before_validation :ensure_action_has_calculator
|
|
14
14
|
before_destroy :deals_with_adjustments
|
|
@@ -34,12 +34,13 @@ module Spree
|
|
|
34
34
|
# is saved
|
|
35
35
|
def create_adjustment(label, target, calculable, mandatory=false)
|
|
36
36
|
amount = compute_amount(calculable)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
target.adjustments.create(
|
|
38
|
+
amount: amount,
|
|
39
|
+
source: calculable,
|
|
40
|
+
originator: self,
|
|
41
|
+
label: label,
|
|
42
|
+
mandatory: mandatory
|
|
43
|
+
)
|
|
43
44
|
end
|
|
44
45
|
|
|
45
46
|
# Ensure a negative amount which does not exceed the sum of the order's
|
|
@@ -2,9 +2,8 @@ module Spree
|
|
|
2
2
|
class Promotion
|
|
3
3
|
module Actions
|
|
4
4
|
class CreateLineItems < PromotionAction
|
|
5
|
-
has_many :promotion_action_line_items, :
|
|
5
|
+
has_many :promotion_action_line_items, foreign_key: :promotion_action_id
|
|
6
6
|
accepts_nested_attributes_for :promotion_action_line_items
|
|
7
|
-
attr_accessible :promotion_action_line_items_attributes
|
|
8
7
|
|
|
9
8
|
delegate :eligible?, :to => :promotion
|
|
10
9
|
|
|
@@ -4,10 +4,8 @@ module Spree
|
|
|
4
4
|
class Promotion
|
|
5
5
|
module Rules
|
|
6
6
|
class ItemTotal < PromotionRule
|
|
7
|
-
preference :amount, :decimal, :
|
|
8
|
-
preference :operator, :string, :
|
|
9
|
-
|
|
10
|
-
attr_accessible :preferred_amount, :preferred_operator
|
|
7
|
+
preference :amount, :decimal, default: 100.00
|
|
8
|
+
preference :operator, :string, default: '>'
|
|
11
9
|
|
|
12
10
|
OPERATORS = ['gt', 'gte']
|
|
13
11
|
|
|
@@ -5,11 +5,11 @@ module Spree
|
|
|
5
5
|
class Promotion
|
|
6
6
|
module Rules
|
|
7
7
|
class Product < PromotionRule
|
|
8
|
-
has_and_belongs_to_many :products, :
|
|
8
|
+
has_and_belongs_to_many :products, class_name: '::Spree::Product', join_table: 'spree_products_promotion_rules', foreign_key: 'promotion_rule_id'
|
|
9
9
|
validate :only_one_promotion_per_product
|
|
10
10
|
|
|
11
11
|
MATCH_POLICIES = %w(any all)
|
|
12
|
-
preference :match_policy, :string, :
|
|
12
|
+
preference :match_policy, :string, default: MATCH_POLICIES.first
|
|
13
13
|
|
|
14
14
|
# scope/association that is used to test eligibility
|
|
15
15
|
def eligible_products
|
|
@@ -2,14 +2,12 @@ module Spree
|
|
|
2
2
|
class Promotion
|
|
3
3
|
module Rules
|
|
4
4
|
class User < PromotionRule
|
|
5
|
-
attr_accessible :user_ids_string
|
|
6
|
-
|
|
7
5
|
if Spree.user_class
|
|
8
6
|
belongs_to :user, class_name: Spree.user_class.to_s
|
|
9
7
|
has_and_belongs_to_many :users, class_name: Spree.user_class.to_s, join_table: 'spree_promotion_rules_users', foreign_key: 'promotion_rule_id'
|
|
10
8
|
else
|
|
11
9
|
belongs_to :user
|
|
12
|
-
has_and_belongs_to_many :users, join_table: 'spree_promotion_rules_users', foreign_key: 'promotion_rule_id'
|
|
10
|
+
has_and_belongs_to_many :users, join_table: 'spree_promotion_rules_users', foreign_key: 'promotion_rule_id'
|
|
13
11
|
end
|
|
14
12
|
|
|
15
13
|
def eligible?(order, options = {})
|
|
@@ -14,11 +14,6 @@ module Spree
|
|
|
14
14
|
|
|
15
15
|
accepts_nested_attributes_for :promotion_actions, :promotion_rules
|
|
16
16
|
|
|
17
|
-
attr_accessible :name, :event_name, :code, :match_policy,
|
|
18
|
-
:path, :advertise, :description, :usage_limit,
|
|
19
|
-
:starts_at, :expires_at, :promotion_rules_attributes,
|
|
20
|
-
:promotion_actions_attributes
|
|
21
|
-
|
|
22
17
|
validates_associated :rules
|
|
23
18
|
|
|
24
19
|
validates :name, presence: true
|
|
@@ -26,6 +21,13 @@ module Spree
|
|
|
26
21
|
validates :path, presence: true, if: lambda{|r| r.event_name == 'spree.content.visited' }
|
|
27
22
|
validates :usage_limit, numericality: { greater_than: 0, allow_nil: true }
|
|
28
23
|
|
|
24
|
+
# TODO: This shouldn't be necessary with :autosave option but nested attribute updating of actions is broken without it
|
|
25
|
+
after_save :save_rules_and_actions
|
|
26
|
+
|
|
27
|
+
def save_rules_and_actions
|
|
28
|
+
(rules + actions).each &:save
|
|
29
|
+
end
|
|
30
|
+
|
|
29
31
|
def self.advertised
|
|
30
32
|
where(advertise: true)
|
|
31
33
|
end
|
|
@@ -35,24 +37,21 @@ module Spree
|
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
def activate(payload)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return true
|
|
40
|
+
return unless order_activatable? payload[:order]
|
|
41
|
+
|
|
42
|
+
# make sure code is always downcased (old databases might have mixed case codes)
|
|
43
|
+
if code.present?
|
|
44
|
+
event_code = payload[:coupon_code]
|
|
45
|
+
return unless event_code == self.code.downcase.strip
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
if path.present?
|
|
49
|
+
return unless path == payload[:path]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
actions.each do |action|
|
|
53
|
+
action.perform(payload)
|
|
54
54
|
end
|
|
55
|
-
false
|
|
56
55
|
end
|
|
57
56
|
|
|
58
57
|
# called anytime order.update! happens
|
|
@@ -77,7 +76,7 @@ module Spree
|
|
|
77
76
|
|
|
78
77
|
# Products assigned to all product rules
|
|
79
78
|
def products
|
|
80
|
-
@products ||= self.rules.
|
|
79
|
+
@products ||= self.rules.to_a.inject([]) do |products, rule|
|
|
81
80
|
rule.respond_to?(:products) ? products << rule.products : products
|
|
82
81
|
end.flatten.uniq
|
|
83
82
|
end
|
|
@@ -92,7 +91,7 @@ module Spree
|
|
|
92
91
|
end
|
|
93
92
|
|
|
94
93
|
def credits
|
|
95
|
-
Adjustment.
|
|
94
|
+
Adjustment.promotion.where(originator_id: actions.map(&:id))
|
|
96
95
|
end
|
|
97
96
|
|
|
98
97
|
def credits_count
|
|
@@ -6,8 +6,6 @@ module Spree
|
|
|
6
6
|
|
|
7
7
|
scope :of_type, ->(t) { where(type: t) }
|
|
8
8
|
|
|
9
|
-
attr_accessible :line_items_string
|
|
10
|
-
|
|
11
9
|
# This method should be overriden in subclass
|
|
12
10
|
# Updates the state of the order or performs some other action depending on the subclass
|
|
13
11
|
# options will contain the payload from the event that activated the promotion. This will include
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
class PromotionActionLineItem < ActiveRecord::Base
|
|
3
3
|
belongs_to :promotion_action, class_name: 'Spree::Promotion::Actions::CreateLineItems'
|
|
4
|
-
belongs_to :variant, class_name:
|
|
5
|
-
|
|
6
|
-
attr_accessible :quantity, :variant_id
|
|
4
|
+
belongs_to :variant, class_name: 'Spree::Variant'
|
|
7
5
|
end
|
|
8
6
|
end
|
|
@@ -8,8 +8,6 @@ module Spree
|
|
|
8
8
|
validate :promotion, presence: true
|
|
9
9
|
validate :unique_per_activator, on: :create
|
|
10
10
|
|
|
11
|
-
attr_accessible :preferred_operator, :preferred_amount, :product, :product_ids_string, :preferred_match_policy
|
|
12
|
-
|
|
13
11
|
def eligible?(order, options = {})
|
|
14
12
|
raise 'eligible? should be implemented in a sub-class of Promotion::PromotionRule'
|
|
15
13
|
end
|
|
@@ -5,16 +5,14 @@ module Spree
|
|
|
5
5
|
has_many :product_properties, dependent: :delete_all
|
|
6
6
|
has_many :products, through: :product_properties
|
|
7
7
|
|
|
8
|
-
attr_accessible :name, :presentation
|
|
9
|
-
|
|
10
8
|
validates :name, :presentation, presence: true
|
|
11
9
|
|
|
12
|
-
scope :sorted, -> { order(
|
|
10
|
+
scope :sorted, -> { order(:name) }
|
|
13
11
|
|
|
14
12
|
def self.find_all_by_prototype(prototype)
|
|
15
13
|
id = prototype
|
|
16
14
|
id = prototype.id if prototype.class == Prototype
|
|
17
|
-
joins("LEFT JOIN properties_prototypes ON property_id = #{
|
|
15
|
+
joins("LEFT JOIN properties_prototypes ON property_id = #{self.table_name}.id").
|
|
18
16
|
where(prototype_id: id)
|
|
19
17
|
end
|
|
20
18
|
end
|
|
@@ -3,8 +3,6 @@ module Spree
|
|
|
3
3
|
has_and_belongs_to_many :properties, join_table: :spree_properties_prototypes
|
|
4
4
|
has_and_belongs_to_many :option_types, join_table: :spree_option_types_prototypes
|
|
5
5
|
|
|
6
|
-
attr_accessible :name, :property_ids, :option_type_ids
|
|
7
|
-
|
|
8
6
|
validates :name, presence: true
|
|
9
7
|
end
|
|
10
8
|
end
|
|
@@ -11,16 +11,14 @@ module Spree
|
|
|
11
11
|
validates :amount, numericality: true
|
|
12
12
|
validate :must_have_shipped_units
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
state_machine initial: 'authorized' do
|
|
17
|
-
after_transition to: 'received', do: :process_return
|
|
14
|
+
state_machine initial: :authorized do
|
|
15
|
+
after_transition to: :received, do: :process_return
|
|
18
16
|
|
|
19
17
|
event :receive do
|
|
20
|
-
transition to:
|
|
18
|
+
transition to: :received, from: :authorized, if: :allow_receive?
|
|
21
19
|
end
|
|
22
20
|
event :cancel do
|
|
23
|
-
transition to:
|
|
21
|
+
transition to: :canceled, from: :authorized
|
|
24
22
|
end
|
|
25
23
|
end
|
|
26
24
|
|
|
@@ -61,7 +59,7 @@ module Spree
|
|
|
61
59
|
end
|
|
62
60
|
|
|
63
61
|
def returnable_inventory
|
|
64
|
-
order.shipped_shipments.collect{|s| s.inventory_units.
|
|
62
|
+
order.shipped_shipments.collect{|s| s.inventory_units.to_a}.flatten
|
|
65
63
|
end
|
|
66
64
|
|
|
67
65
|
private
|
|
@@ -83,8 +81,7 @@ module Spree
|
|
|
83
81
|
def process_return
|
|
84
82
|
inventory_units.each do |iu|
|
|
85
83
|
iu.return!
|
|
86
|
-
|
|
87
|
-
Spree::StockMovement.create!(stock_item_id: stock_item.id, quantity: 1)
|
|
84
|
+
Spree::StockMovement.create!(stock_item_id: iu.find_stock_item.id, quantity: 1)
|
|
88
85
|
end
|
|
89
86
|
|
|
90
87
|
credit = Adjustment.new(amount: amount.abs * -1, label: Spree.t(:rma_credit))
|
data/app/models/spree/role.rb
CHANGED
|
@@ -2,7 +2,7 @@ require 'ostruct'
|
|
|
2
2
|
|
|
3
3
|
module Spree
|
|
4
4
|
class Shipment < ActiveRecord::Base
|
|
5
|
-
belongs_to :order, class_name: 'Spree::Order'
|
|
5
|
+
belongs_to :order, class_name: 'Spree::Order'
|
|
6
6
|
belongs_to :address, class_name: 'Spree::Address'
|
|
7
7
|
belongs_to :stock_location, class_name: 'Spree::StockLocation'
|
|
8
8
|
|
|
@@ -12,16 +12,15 @@ module Spree
|
|
|
12
12
|
has_many :inventory_units, dependent: :delete_all
|
|
13
13
|
has_one :adjustment, as: :source, dependent: :destroy
|
|
14
14
|
|
|
15
|
+
before_create :generate_shipment_number
|
|
15
16
|
after_save :ensure_correct_adjustment, :update_order
|
|
16
17
|
|
|
17
18
|
attr_accessor :special_instructions
|
|
18
|
-
attr_accessible :order, :special_instructions, :stock_location_id, :number,
|
|
19
|
-
:tracking, :address, :inventory_units, :selected_shipping_rate_id
|
|
20
19
|
|
|
21
20
|
accepts_nested_attributes_for :address
|
|
22
21
|
accepts_nested_attributes_for :inventory_units
|
|
23
22
|
|
|
24
|
-
make_permalink field: :number
|
|
23
|
+
make_permalink field: :number
|
|
25
24
|
|
|
26
25
|
scope :shipped, -> { with_state('shipped') }
|
|
27
26
|
scope :ready, -> { with_state('ready') }
|
|
@@ -65,7 +64,9 @@ module Spree
|
|
|
65
64
|
end
|
|
66
65
|
|
|
67
66
|
def to_param
|
|
68
|
-
number
|
|
67
|
+
number if number
|
|
68
|
+
generate_shipment_number unless number
|
|
69
|
+
number.to_s.to_url.upcase
|
|
69
70
|
end
|
|
70
71
|
|
|
71
72
|
def backordered?
|
|
@@ -101,16 +102,12 @@ module Spree
|
|
|
101
102
|
|
|
102
103
|
def refresh_rates
|
|
103
104
|
return shipping_rates if shipped?
|
|
104
|
-
return [] unless can_get_rates?
|
|
105
|
-
|
|
106
|
-
# StockEstimator.new assigment below will replace the current shipping_method
|
|
107
|
-
original_shipping_method_id = shipping_method.try(:id)
|
|
108
105
|
|
|
109
106
|
self.shipping_rates = Stock::Estimator.new(order).shipping_rates(to_package)
|
|
110
107
|
|
|
111
108
|
if shipping_method
|
|
112
109
|
selected_rate = shipping_rates.detect { |rate|
|
|
113
|
-
rate.shipping_method_id ==
|
|
110
|
+
rate.shipping_method_id == shipping_method.id
|
|
114
111
|
}
|
|
115
112
|
self.selected_shipping_rate_id = selected_rate.id if selected_rate
|
|
116
113
|
end
|
|
@@ -165,8 +162,8 @@ module Spree
|
|
|
165
162
|
end
|
|
166
163
|
|
|
167
164
|
def line_items
|
|
168
|
-
if order.complete? and Spree::Config
|
|
169
|
-
order.line_items.select { |li|
|
|
165
|
+
if order.complete? and Spree::Config[:track_inventory_levels]
|
|
166
|
+
order.line_items.select { |li| inventory_units.pluck(:variant_id).include?(li.variant_id) }
|
|
170
167
|
else
|
|
171
168
|
order.line_items
|
|
172
169
|
end
|
|
@@ -229,10 +226,7 @@ module Spree
|
|
|
229
226
|
end
|
|
230
227
|
|
|
231
228
|
def set_up_inventory(state, variant, order)
|
|
232
|
-
self.inventory_units.create(
|
|
233
|
-
{ variant_id: variant.id, state: state, order_id: order.id },
|
|
234
|
-
without_protection: true
|
|
235
|
-
)
|
|
229
|
+
self.inventory_units.create(variant_id: variant.id, state: state, order_id: order.id)
|
|
236
230
|
end
|
|
237
231
|
|
|
238
232
|
private
|
|
@@ -242,13 +236,17 @@ module Spree
|
|
|
242
236
|
end
|
|
243
237
|
|
|
244
238
|
def manifest_restock(item)
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
end
|
|
239
|
+
stock_location.restock item.variant, item.quantity, self
|
|
240
|
+
end
|
|
248
241
|
|
|
249
|
-
|
|
250
|
-
|
|
242
|
+
def generate_shipment_number
|
|
243
|
+
return number unless number.blank?
|
|
244
|
+
record = true
|
|
245
|
+
while record
|
|
246
|
+
random = "H#{Array.new(11) { rand(9) }.join}"
|
|
247
|
+
record = self.class.where(number: random).first
|
|
251
248
|
end
|
|
249
|
+
self.number = random
|
|
252
250
|
end
|
|
253
251
|
|
|
254
252
|
def description_for_shipping_charge
|
|
@@ -288,9 +286,5 @@ module Spree
|
|
|
288
286
|
def update_order
|
|
289
287
|
order.update!
|
|
290
288
|
end
|
|
291
|
-
|
|
292
|
-
def can_get_rates?
|
|
293
|
-
order.ship_address && order.ship_address.valid?
|
|
294
|
-
end
|
|
295
289
|
end
|
|
296
290
|
end
|
|
@@ -3,20 +3,17 @@ module Spree
|
|
|
3
3
|
include Spree::Core::CalculatedAdjustments
|
|
4
4
|
DISPLAY = [:both, :front_end, :back_end]
|
|
5
5
|
|
|
6
|
-
default_scope where(deleted_at: nil)
|
|
6
|
+
default_scope -> { where(deleted_at: nil) }
|
|
7
7
|
|
|
8
|
+
has_many :shipments
|
|
8
9
|
has_many :shipping_method_categories
|
|
9
10
|
has_many :shipping_categories, through: :shipping_method_categories
|
|
10
11
|
has_many :shipping_rates
|
|
11
|
-
has_many :shipments, :through => :shipping_rates
|
|
12
12
|
|
|
13
13
|
has_and_belongs_to_many :zones, :join_table => 'spree_shipping_methods_zones',
|
|
14
14
|
:class_name => 'Spree::Zone',
|
|
15
15
|
:foreign_key => 'shipping_method_id'
|
|
16
16
|
|
|
17
|
-
attr_accessible :name, :admin_name, :zones, :display_on, :shipping_category_id,
|
|
18
|
-
:match_none, :match_one, :match_all, :tracking_url
|
|
19
|
-
|
|
20
17
|
validates :name, presence: true
|
|
21
18
|
|
|
22
19
|
validate :at_least_one_shipping_category
|
|
@@ -25,16 +22,6 @@ module Spree
|
|
|
25
22
|
Spree.t(:shipping)
|
|
26
23
|
end
|
|
27
24
|
|
|
28
|
-
def zone
|
|
29
|
-
ActiveSupport::Deprecation.warn("[SPREE] ShippingMethod#zone is no longer correct. Multiple zones need to be supported")
|
|
30
|
-
zones.first
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def zone=(zone)
|
|
34
|
-
ActiveSupport::Deprecation.warn("[SPREE] ShippingMethod#zone= is no longer correct. Multiple zones need to be supported")
|
|
35
|
-
zones = zone
|
|
36
|
-
end
|
|
37
|
-
|
|
38
25
|
def include?(address)
|
|
39
26
|
return false unless address
|
|
40
27
|
zones.any? do |zone|
|
|
@@ -43,12 +30,11 @@ module Spree
|
|
|
43
30
|
end
|
|
44
31
|
|
|
45
32
|
def build_tracking_url(tracking)
|
|
46
|
-
|
|
47
|
-
tracking_url.gsub(/:tracking/, ERB::Util.url_encode(tracking)) # :url_encode exists in 1.8.7 through 2.1.0
|
|
33
|
+
tracking_url.gsub(/:tracking/, tracking) unless tracking.blank? || tracking_url.blank?
|
|
48
34
|
end
|
|
49
35
|
|
|
50
36
|
def self.calculators
|
|
51
|
-
spree_calculators.send(model_name_without_spree_namespace).select{|c| c
|
|
37
|
+
spree_calculators.send(model_name_without_spree_namespace).select{ |c| c < Spree::ShippingCalculator }
|
|
52
38
|
end
|
|
53
39
|
|
|
54
40
|
# Some shipping methods are only meant to be set via backend
|
|
@@ -64,11 +50,11 @@ module Spree
|
|
|
64
50
|
end
|
|
65
51
|
|
|
66
52
|
def self.on_backend_query
|
|
67
|
-
"#{
|
|
53
|
+
"#{table_name}.display_on != 'front_end' OR #{table_name}.display_on IS NULL"
|
|
68
54
|
end
|
|
69
55
|
|
|
70
56
|
def self.on_frontend_query
|
|
71
|
-
"#{
|
|
57
|
+
"#{table_name}.display_on != 'back_end' OR #{table_name}.display_on IS NULL"
|
|
72
58
|
end
|
|
73
59
|
end
|
|
74
60
|
end
|
|
@@ -3,12 +3,17 @@ module Spree
|
|
|
3
3
|
belongs_to :shipment, class_name: 'Spree::Shipment'
|
|
4
4
|
belongs_to :shipping_method, class_name: 'Spree::ShippingMethod'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
scope :frontend,
|
|
7
|
+
-> { includes(:shipping_method).
|
|
8
|
+
where(ShippingMethod.on_frontend_query).
|
|
9
|
+
references(:shipping_method).
|
|
10
|
+
order("cost ASC") }
|
|
11
|
+
scope :backend,
|
|
12
|
+
-> { includes(:shipping_method).
|
|
13
|
+
where(ShippingMethod.on_backend_query).
|
|
14
|
+
references(:shipping_method).
|
|
15
|
+
order("cost ASC") }
|
|
16
|
+
|
|
12
17
|
delegate :order, :currency, to: :shipment
|
|
13
18
|
delegate :name, to: :shipping_method
|
|
14
19
|
|
|
@@ -21,10 +26,7 @@ module Spree
|
|
|
21
26
|
|
|
22
27
|
Spree::Money.new(price, { currency: currency })
|
|
23
28
|
end
|
|
24
|
-
alias_method :display_cost, :display_price
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
Spree::ShippingMethod.unscoped { super }
|
|
28
|
-
end
|
|
30
|
+
alias_method :display_cost, :display_price
|
|
29
31
|
end
|
|
30
32
|
end
|
data/app/models/spree/state.rb
CHANGED
|
@@ -4,17 +4,15 @@ module Spree
|
|
|
4
4
|
|
|
5
5
|
validates :country, :name, presence: true
|
|
6
6
|
|
|
7
|
-
attr_accessible :name, :abbr
|
|
8
|
-
|
|
9
7
|
def self.find_all_by_name_or_abbr(name_or_abbr)
|
|
10
|
-
where(
|
|
8
|
+
where('name = ? OR abbr = ?', name_or_abbr, name_or_abbr)
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
# table of { country.id => [ state.id , state.name ] }, arrays sorted by name
|
|
14
12
|
# blank is added elsewhere, if needed
|
|
15
13
|
def self.states_group_by_country_id
|
|
16
14
|
state_info = Hash.new { |h, k| h[k] = [] }
|
|
17
|
-
self.order(
|
|
15
|
+
self.order('name ASC').each { |state|
|
|
18
16
|
state_info[state.country_id.to_s].push [state.id, state.name]
|
|
19
17
|
}
|
|
20
18
|
state_info
|
|
@@ -10,14 +10,14 @@ module Spree
|
|
|
10
10
|
quantity = line_item.quantity
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
quantifier = Stock::Quantifier.new(line_item.
|
|
13
|
+
quantifier = Stock::Quantifier.new(line_item.variant_id)
|
|
14
14
|
|
|
15
15
|
unless quantifier.can_supply? quantity
|
|
16
16
|
variant = line_item.variant
|
|
17
17
|
display_name = %Q{#{variant.name}}
|
|
18
18
|
display_name += %Q{ (#{variant.options_text})} unless variant.options_text.blank?
|
|
19
19
|
|
|
20
|
-
line_item.errors[:quantity] << Spree.t(:
|
|
20
|
+
line_item.errors[:quantity] << Spree.t(:out_of_stock, :scope => :order_populator, :item => display_name.inspect)
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
end
|
|
@@ -15,8 +15,7 @@ module Spree
|
|
|
15
15
|
|
|
16
16
|
shipping_methods.each do |shipping_method|
|
|
17
17
|
cost = calculate_cost(shipping_method, package)
|
|
18
|
-
|
|
19
|
-
shipping_rates << rate unless rate.nil?
|
|
18
|
+
shipping_rates << shipping_method.shipping_rates.new(:cost => cost) unless cost.nil?
|
|
20
19
|
end
|
|
21
20
|
|
|
22
21
|
shipping_rates.sort_by! { |r| r.cost || 0 }
|
|
@@ -35,30 +34,17 @@ module Spree
|
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
private
|
|
38
|
-
|
|
39
37
|
def shipping_methods(package)
|
|
40
|
-
package.shipping_methods
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
(calculator.preferences[:currency].nil? ||
|
|
46
|
-
calculator.preferences[:currency] == currency)
|
|
47
|
-
rescue Exception => exception
|
|
48
|
-
log_calculator_exception(ship_method, exception)
|
|
49
|
-
end
|
|
50
|
-
end
|
|
38
|
+
shipping_methods = package.shipping_methods
|
|
39
|
+
shipping_methods.delete_if { |ship_method| !ship_method.calculator.available?(package) }
|
|
40
|
+
shipping_methods.delete_if { |ship_method| !ship_method.include?(order.ship_address) }
|
|
41
|
+
shipping_methods.delete_if { |ship_method| !(ship_method.calculator.preferences[:currency].nil? || ship_method.calculator.preferences[:currency] == currency) }
|
|
42
|
+
shipping_methods
|
|
51
43
|
end
|
|
52
44
|
|
|
53
45
|
def calculate_cost(shipping_method, package)
|
|
54
46
|
shipping_method.calculator.compute(package)
|
|
55
47
|
end
|
|
56
|
-
|
|
57
|
-
def log_calculator_exception(ship_method, exception)
|
|
58
|
-
Rails.logger.error("Something went wrong calculating rates with the #{ship_method.name} (ID=#{ship_method.id}) shipping method.")
|
|
59
|
-
Rails.logger.error("*" * 50)
|
|
60
|
-
Rails.logger.error(exception.backtrace.join("\n"))
|
|
61
|
-
end
|
|
62
48
|
end
|
|
63
49
|
end
|
|
64
50
|
end
|
|
@@ -20,7 +20,7 @@ module Spree
|
|
|
20
20
|
def default_package
|
|
21
21
|
package = Package.new(stock_location, order)
|
|
22
22
|
order.line_items.each do |line_item|
|
|
23
|
-
if
|
|
23
|
+
if Config.track_inventory_levels
|
|
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)
|