spree_core 2.4.10 → 3.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/app/assets/images/logo/spree_50.png +0 -0
- data/app/controllers/spree/base_controller.rb +1 -2
- data/app/helpers/spree/base_helper.rb +41 -131
- data/app/helpers/spree/products_helper.rb +1 -1
- data/app/models/concerns/spree/adjustment_source.rb +51 -15
- data/app/models/concerns/spree/calculated_adjustments.rb +1 -0
- data/app/models/concerns/spree/display_money.rb +32 -0
- data/app/models/concerns/spree/named_type.rb +1 -1
- data/app/models/concerns/spree/number_generator.rb +39 -0
- data/app/models/concerns/spree/user_reporting.rb +3 -8
- data/app/models/spree/address.rb +0 -2
- data/app/models/spree/adjustable/adjustments_updater.rb +70 -0
- data/app/models/spree/adjustable/promotion_accumulator.rb +75 -0
- data/app/models/spree/adjustment.rb +17 -26
- data/app/models/spree/app_configuration.rb +4 -33
- data/app/models/spree/base.rb +0 -3
- data/app/models/spree/calculator.rb +0 -5
- data/app/models/spree/classification.rb +1 -1
- data/app/models/spree/country.rb +10 -4
- data/app/models/spree/credit_card.rb +14 -15
- data/app/models/spree/customer_return.rb +18 -25
- data/app/models/spree/gateway/bogus.rb +0 -4
- data/app/models/spree/line_item.rb +2 -5
- data/app/models/spree/option_type.rb +2 -4
- data/app/models/spree/option_value.rb +0 -2
- data/app/models/spree/order.rb +74 -134
- data/app/models/spree/order/checkout.rb +1 -1
- data/app/models/spree/order_contents.rb +9 -8
- data/app/models/spree/order_updater.rb +8 -1
- data/app/models/spree/payment.rb +13 -23
- data/app/models/spree/payment/gateway_options.rb +86 -0
- data/app/models/spree/payment/processing.rb +8 -39
- data/app/models/spree/payment_method.rb +3 -6
- data/app/models/spree/price.rb +2 -6
- data/app/models/spree/product.rb +27 -16
- data/app/models/spree/product_property.rb +1 -5
- data/app/models/spree/promotion.rb +7 -15
- data/app/models/spree/promotion/actions/create_adjustment.rb +4 -45
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +8 -63
- data/app/models/spree/promotion/actions/create_line_items.rb +3 -12
- data/app/models/spree/promotion/actions/free_shipping.rb +4 -24
- data/app/models/spree/promotion/rules/option_value.rb +49 -0
- data/app/models/spree/promotion_action.rb +6 -0
- data/app/models/spree/promotion_handler/cart.rb +14 -18
- data/app/models/spree/promotion_handler/coupon.rb +1 -1
- data/app/models/spree/promotion_rule.rb +0 -1
- data/app/models/spree/property.rb +0 -2
- data/app/models/spree/refund.rb +0 -15
- data/app/models/spree/reimbursement.rb +4 -4
- data/app/models/spree/reimbursement_type/credit.rb +1 -1
- data/app/models/spree/reimbursement_type/original_payment.rb +1 -1
- data/app/models/spree/return_authorization.rb +4 -11
- data/app/models/spree/return_item.rb +16 -11
- data/app/models/spree/return_item/eligibility_validator/default.rb +2 -0
- data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +16 -0
- data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +16 -0
- data/app/models/spree/shipment.rb +20 -31
- data/app/models/spree/shipment_handler.rb +1 -1
- data/app/models/spree/shipping_method.rb +12 -13
- data/app/models/spree/state.rb +7 -0
- data/app/models/spree/state_change.rb +1 -6
- data/app/models/spree/stock/availability_validator.rb +9 -10
- data/app/models/spree/stock/coordinator.rb +1 -1
- data/app/models/spree/stock/estimator.rb +6 -6
- data/app/models/spree/stock/quantifier.rb +1 -1
- data/app/models/spree/stock_item.rb +1 -7
- data/app/models/spree/stock_location.rb +3 -1
- data/app/models/spree/stock_movement.rb +1 -8
- data/app/models/spree/stock_transfer.rb +11 -5
- data/app/models/spree/store.rb +2 -2
- data/app/models/spree/tax_rate.rb +30 -55
- data/app/models/spree/taxon.rb +8 -8
- data/app/models/spree/taxonomy.rb +8 -13
- data/app/models/spree/tracker.rb +1 -1
- data/app/models/spree/variant.rb +6 -15
- data/app/models/spree/zone.rb +43 -9
- data/config/initializers/user_class_extensions.rb +0 -12
- data/config/locales/en.yml +76 -85
- data/config/routes.rb +1 -1
- data/db/default/spree/countries.rb +23 -13
- data/db/default/spree/states.rb +24 -12
- data/db/default/spree/stores.rb +1 -1
- 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/20140309024355_create_spree_stores.rb +1 -1
- data/db/migrate/20140309033438_create_store_from_preferences.rb +0 -7
- 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/20140911173301_add_kind_to_zone.rb +11 -0
- data/db/migrate/20141215232040_remove_token_permissions_table.rb +6 -0
- data/db/migrate/20141215235502_remove_extra_products_slug_index.rb +5 -0
- data/db/migrate/20141217215630_update_product_slug_index.rb +6 -0
- data/db/migrate/20141218025915_rename_identifier_to_number_for_payment.rb +5 -0
- data/db/migrate/20150121022521_remove_environment_from_payment_method.rb +6 -0
- data/db/migrate/20150122145607_add_resellable_to_return_items.rb +5 -0
- data/db/migrate/20150122202432_add_code_to_spree_promotion_categories.rb +5 -0
- data/db/migrate/20150128032538_remove_environment_from_tracker.rb +6 -0
- data/db/migrate/20150128060325_remove_spree_configurations.rb +16 -0
- data/lib/generators/spree/dummy/templates/rails/test.rb +1 -1
- data/lib/generators/spree/install/templates/config/initializers/spree.rb +4 -0
- data/lib/spree/core.rb +2 -12
- data/lib/spree/core/controller_helpers/respond_with.rb +8 -18
- data/lib/spree/core/engine.rb +1 -7
- data/lib/spree/core/routes.rb +1 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/money.rb +10 -10
- data/lib/spree/permitted_attributes.rb +4 -8
- data/lib/spree/testing_support/authorization_helpers.rb +3 -5
- data/lib/spree/testing_support/capybara_ext.rb +3 -3
- data/lib/spree/testing_support/common_rake.rb +2 -2
- data/lib/spree/testing_support/factories/order_factory.rb +3 -13
- data/lib/spree/testing_support/factories/payment_method_factory.rb +0 -3
- data/lib/spree/testing_support/factories/prototype_factory.rb +5 -0
- data/lib/spree/testing_support/factories/return_item_factory.rb +5 -1
- data/lib/spree/testing_support/factories/stock_location_factory.rb +3 -3
- data/lib/spree/testing_support/factories/tracker_factory.rb +0 -1
- data/lib/spree/testing_support/factories/user_factory.rb +1 -1
- data/lib/spree/testing_support/factories/zone_factory.rb +8 -0
- data/lib/tasks/core.rake +1 -1
- data/lib/tasks/email.rake +6 -3
- metadata +48 -35
- data/app/helpers/spree/checkout_helper.rb +0 -31
- data/app/helpers/spree/orders_helper.rb +0 -17
- data/app/helpers/spree/store_helper.rb +0 -16
- data/app/helpers/spree/taxons_helper.rb +0 -19
- data/app/models/concerns/spree/ransackable_attributes.rb +0 -19
- data/app/models/friendly_id/slug_decorator.rb +0 -3
- data/app/models/spree/billing_integration.rb +0 -21
- data/app/models/spree/configuration.rb +0 -5
- data/app/models/spree/item_adjustments.rb +0 -82
- data/app/models/spree/order_merger.rb +0 -65
- data/app/models/spree/order_populator.rb +0 -43
- data/app/models/spree/product_scope/scopes.rb +0 -47
- data/app/models/spree/variant/scopes.rb +0 -42
- data/db/migrate/20150515211137_fix_adjustment_order_id.rb +0 -70
- data/db/migrate/20150522181728_add_deleted_at_to_friendly_id_slugs.rb +0 -6
- data/db/migrate/20150707204155_enable_acts_as_paranoid_on_calculators.rb +0 -6
- data/lib/spree/core/controller_helpers/ssl.rb +0 -60
- data/lib/spree/core/permalinks.rb +0 -71
- data/lib/spree/testing_support/factories/configuration_factory.rb +0 -6
@@ -31,7 +31,7 @@ module Spree
|
|
31
31
|
# Returns an array of Package instances
|
32
32
|
def build_packages(packages = Array.new)
|
33
33
|
StockLocation.active.each do |stock_location|
|
34
|
-
next unless stock_location.stock_items.where(:variant_id => inventory_units.map(&:variant_id)).exists?
|
34
|
+
next unless stock_location.stock_items.where(:variant_id => inventory_units.map(&:variant_id).uniq).exists?
|
35
35
|
|
36
36
|
packer = build_packer(stock_location, inventory_units)
|
37
37
|
packages += packer.packages
|
@@ -8,9 +8,8 @@ module Spree
|
|
8
8
|
@currency = order.currency
|
9
9
|
end
|
10
10
|
|
11
|
-
def shipping_rates(package,
|
12
|
-
rates = calculate_shipping_rates(package)
|
13
|
-
rates.select! { |rate| rate.shipping_method.frontend? } if frontend_only
|
11
|
+
def shipping_rates(package, shipping_method_filter = ShippingMethod::DISPLAY_ON_FRONT_END)
|
12
|
+
rates = calculate_shipping_rates(package, shipping_method_filter)
|
14
13
|
choose_default_shipping_rate(rates)
|
15
14
|
sort_shipping_rates(rates)
|
16
15
|
end
|
@@ -26,8 +25,8 @@ module Spree
|
|
26
25
|
shipping_rates.sort_by!(&:cost)
|
27
26
|
end
|
28
27
|
|
29
|
-
def calculate_shipping_rates(package)
|
30
|
-
shipping_methods(package).map do |shipping_method|
|
28
|
+
def calculate_shipping_rates(package, ui_filter)
|
29
|
+
shipping_methods(package, ui_filter).map do |shipping_method|
|
31
30
|
cost = shipping_method.calculator.compute(package)
|
32
31
|
tax_category = shipping_method.tax_category
|
33
32
|
if tax_category
|
@@ -48,10 +47,11 @@ module Spree
|
|
48
47
|
end.compact
|
49
48
|
end
|
50
49
|
|
51
|
-
def shipping_methods(package)
|
50
|
+
def shipping_methods(package, display_filter)
|
52
51
|
package.shipping_methods.select do |ship_method|
|
53
52
|
calculator = ship_method.calculator
|
54
53
|
begin
|
54
|
+
ship_method.available_to_display(display_filter) &&
|
55
55
|
ship_method.include?(order.ship_address) &&
|
56
56
|
calculator.available?(package) &&
|
57
57
|
(calculator.preferences[:currency].blank? ||
|
@@ -5,7 +5,7 @@ module Spree
|
|
5
5
|
|
6
6
|
def initialize(variant)
|
7
7
|
@variant = variant
|
8
|
-
@stock_items = Spree::StockItem.joins(:stock_location).where(:
|
8
|
+
@stock_items = Spree::StockItem.joins(:stock_location).where(variant_id: @variant, Spree::StockLocation.table_name => { active: true })
|
9
9
|
end
|
10
10
|
|
11
11
|
def total_on_hand
|
@@ -8,19 +8,13 @@ module Spree
|
|
8
8
|
|
9
9
|
validates_presence_of :stock_location, :variant
|
10
10
|
validates_uniqueness_of :variant_id, scope: [:stock_location_id, :deleted_at]
|
11
|
-
|
12
|
-
validates_numericality_of :count_on_hand,
|
13
|
-
greater_than_or_equal_to: 0,
|
14
|
-
less_than_or_equal_to: 2**31 - 1,
|
15
|
-
only_integer: true, if: :verify_count_on_hand?
|
11
|
+
validates :count_on_hand, numericality: { greater_than_or_equal_to: 0 }, if: :verify_count_on_hand?
|
16
12
|
|
17
13
|
delegate :weight, :should_track_inventory?, to: :variant
|
18
14
|
|
19
15
|
after_save :conditional_variant_touch, if: :changed?
|
20
16
|
after_touch { variant.touch }
|
21
17
|
|
22
|
-
self.whitelisted_ransackable_attributes = ['count_on_hand', 'stock_location_id']
|
23
|
-
|
24
18
|
def backordered_inventory_units
|
25
19
|
Spree::InventoryUnit.backordered_for_stock_item(self)
|
26
20
|
end
|
@@ -107,7 +107,9 @@ module Spree
|
|
107
107
|
|
108
108
|
private
|
109
109
|
def create_stock_items
|
110
|
-
Variant.find_each
|
110
|
+
Variant.includes(:product).find_each do |variant|
|
111
|
+
propagate_variant(variant)
|
112
|
+
end
|
111
113
|
end
|
112
114
|
|
113
115
|
def ensure_one_default
|
@@ -6,17 +6,10 @@ module Spree
|
|
6
6
|
after_create :update_stock_item_quantity
|
7
7
|
|
8
8
|
validates :stock_item, presence: true
|
9
|
-
validates :quantity, presence: true
|
10
|
-
greater_than_or_equal_to: -2**31,
|
11
|
-
less_than_or_equal_to: 2**31-1,
|
12
|
-
only_integer: true,
|
13
|
-
allow_nil: true
|
14
|
-
}
|
9
|
+
validates :quantity, presence: true
|
15
10
|
|
16
11
|
scope :recent, -> { order('created_at DESC') }
|
17
12
|
|
18
|
-
self.whitelisted_ransackable_attributes = ['quantity']
|
19
|
-
|
20
13
|
def readonly?
|
21
14
|
!new_record?
|
22
15
|
end
|
@@ -1,13 +1,19 @@
|
|
1
1
|
module Spree
|
2
2
|
class StockTransfer < Spree::Base
|
3
|
-
|
3
|
+
extend FriendlyId
|
4
|
+
friendly_id :number, slug_column: :number, use: :slugged
|
4
5
|
|
5
|
-
|
6
|
-
belongs_to :destination_location, :class_name => 'StockLocation'
|
6
|
+
include Spree::NumberGenerator
|
7
7
|
|
8
|
-
|
8
|
+
def generate_number(options = {})
|
9
|
+
options[:prefix] ||= 'T'
|
10
|
+
super(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
has_many :stock_movements, as: :originator
|
9
14
|
|
10
|
-
|
15
|
+
belongs_to :source_location, class_name: 'StockLocation'
|
16
|
+
belongs_to :destination_location, class_name: 'StockLocation'
|
11
17
|
|
12
18
|
def to_param
|
13
19
|
number
|
data/app/models/spree/store.rb
CHANGED
@@ -5,7 +5,7 @@ module Spree
|
|
5
5
|
validates :url, presence: true
|
6
6
|
validates :mail_from_address, presence: true
|
7
7
|
|
8
|
-
|
8
|
+
before_create :ensure_default_exists_and_is_unique
|
9
9
|
before_destroy :validate_not_default
|
10
10
|
|
11
11
|
scope :by_url, lambda { |url| where("url like ?", "%#{url}%") }
|
@@ -23,7 +23,7 @@ module Spree
|
|
23
23
|
|
24
24
|
def ensure_default_exists_and_is_unique
|
25
25
|
if default
|
26
|
-
Store.
|
26
|
+
Store.update_all(default: false)
|
27
27
|
elsif Store.where(default: true).count == 0
|
28
28
|
self.default = true
|
29
29
|
end
|
@@ -12,27 +12,31 @@ module Spree
|
|
12
12
|
class TaxRate < Spree::Base
|
13
13
|
acts_as_paranoid
|
14
14
|
|
15
|
-
# Need to deal with adjustments before calculator is destroyed.
|
16
|
-
before_destroy :deals_with_adjustments_for_deleted_source
|
17
|
-
|
18
15
|
include Spree::CalculatedAdjustments
|
19
16
|
include Spree::AdjustmentSource
|
20
17
|
|
21
18
|
belongs_to :zone, class_name: "Spree::Zone", inverse_of: :tax_rates
|
22
19
|
belongs_to :tax_category, class_name: "Spree::TaxCategory", inverse_of: :tax_rates
|
23
20
|
|
24
|
-
has_many :adjustments, as: :source
|
25
|
-
|
26
21
|
validates :amount, presence: true, numericality: true
|
27
22
|
validates :tax_category_id, presence: true
|
28
23
|
validates_with DefaultTaxZoneValidator
|
29
24
|
|
30
25
|
scope :by_zone, ->(zone) { where(zone_id: zone) }
|
31
26
|
|
27
|
+
def self.potential_rates_for_zone(zone)
|
28
|
+
select("spree_tax_rates.*, spree_zones.default_tax").
|
29
|
+
joins(:zone).
|
30
|
+
merge(Spree::Zone.potential_matching_zones(zone)).
|
31
|
+
order("spree_zones.default_tax DESC")
|
32
|
+
end
|
33
|
+
|
32
34
|
# Gets the array of TaxRates appropriate for the specified order
|
33
35
|
def self.match(order_tax_zone)
|
34
36
|
return [] unless order_tax_zone
|
35
|
-
|
37
|
+
|
38
|
+
potential_rates = potential_rates_for_zone(order_tax_zone)
|
39
|
+
rates = potential_rates.includes(zone: { zone_members: :zoneable }).load.select do |rate|
|
36
40
|
# Why "potentially"?
|
37
41
|
# Go see the documentation for that method.
|
38
42
|
rate.potentially_applicable?(order_tax_zone)
|
@@ -75,20 +79,16 @@ module Spree
|
|
75
79
|
end
|
76
80
|
|
77
81
|
# This method is best described by the documentation on #potentially_applicable?
|
78
|
-
def self.adjust(
|
79
|
-
rates =
|
82
|
+
def self.adjust(order, items)
|
83
|
+
rates = match(order.tax_zone)
|
80
84
|
tax_categories = rates.map(&:tax_category)
|
81
85
|
relevant_items, non_relevant_items = items.partition { |item| tax_categories.include?(item.tax_category) }
|
82
|
-
|
83
|
-
if relevant_items.present?
|
84
|
-
Spree::Adjustment.where(adjustable: relevant_items).tax.destroy_all # using destroy_all to ensure adjustment destroy callback fires.
|
85
|
-
end
|
86
|
-
|
86
|
+
Spree::Adjustment.where(adjustable: relevant_items).tax.destroy_all # using destroy_all to ensure adjustment destroy callback fires.
|
87
87
|
relevant_items.each do |item|
|
88
88
|
relevant_rates = rates.select { |rate| rate.tax_category == item.tax_category }
|
89
89
|
store_pre_tax_amount(item, relevant_rates)
|
90
90
|
relevant_rates.each do |rate|
|
91
|
-
rate.adjust(
|
91
|
+
rate.adjust(order, item)
|
92
92
|
end
|
93
93
|
end
|
94
94
|
non_relevant_items.each do |item|
|
@@ -148,54 +148,29 @@ module Spree
|
|
148
148
|
(self.included_in_price? && self.zone.default_tax)
|
149
149
|
end
|
150
150
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
return if amount == 0
|
155
|
-
|
156
|
-
included = included_in_price && default_zone_or_zone_match?(order_tax_zone)
|
157
|
-
|
158
|
-
if amount < 0
|
159
|
-
label = Spree.t(:refund) + ' ' + create_label
|
160
|
-
end
|
161
|
-
|
162
|
-
self.adjustments.create!({
|
163
|
-
:adjustable => item,
|
164
|
-
:amount => amount,
|
165
|
-
:order_id => item.order_id,
|
166
|
-
:label => label || create_label,
|
167
|
-
:included => included
|
168
|
-
})
|
151
|
+
def adjust(order, item)
|
152
|
+
included = included_in_price && default_zone_or_zone_match?(order)
|
153
|
+
create_adjustment(order, item, included)
|
169
154
|
end
|
170
155
|
|
171
|
-
# This method is used by Adjustment#update to recalculate the cost.
|
172
156
|
def compute_amount(item)
|
173
|
-
|
174
|
-
|
175
|
-
calculator.compute(item)
|
176
|
-
else
|
177
|
-
# In this case, it's a refund.
|
178
|
-
calculator.compute(item) * - 1
|
179
|
-
end
|
180
|
-
else
|
181
|
-
calculator.compute(item)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def default_zone_or_zone_match?(order_tax_zone)
|
186
|
-
default_tax = Zone.default_tax
|
187
|
-
(default_tax && default_tax.contains?(order_tax_zone)) || order_tax_zone == self.zone
|
157
|
+
refund = included_in_price && !default_zone_or_zone_match?(item.order)
|
158
|
+
compute(item) * (refund ? -1 : 1)
|
188
159
|
end
|
189
160
|
|
190
161
|
private
|
191
162
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
label << (show_rate_in_label? ? "#{amount * 100}%" : "")
|
196
|
-
label << " (#{Spree.t(:included_in_price)})" if included_in_price?
|
197
|
-
label
|
198
|
-
end
|
163
|
+
def default_zone_or_zone_match?(order)
|
164
|
+
Zone.default_tax.try(:contains?, order.tax_zone) || order.tax_zone == zone
|
165
|
+
end
|
199
166
|
|
167
|
+
def label(adjustment_amount)
|
168
|
+
label = ""
|
169
|
+
label << Spree.t(:refund) << ' ' if adjustment_amount < 0
|
170
|
+
label << (name.present? ? name : tax_category.name) + " "
|
171
|
+
label << (show_rate_in_label? ? "#{amount * 100}%" : "")
|
172
|
+
label << " (#{Spree.t(:included_in_price)})" if included_in_price?
|
173
|
+
label
|
174
|
+
end
|
200
175
|
end
|
201
176
|
end
|
data/app/models/spree/taxon.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
|
+
# TODO let friendly id take care of sanitizing the url
|
2
|
+
require 'stringex'
|
3
|
+
|
1
4
|
module Spree
|
2
5
|
class Taxon < Spree::Base
|
6
|
+
extend FriendlyId
|
7
|
+
friendly_id :permalink, slug_column: :permalink, use: :slugged
|
8
|
+
before_create :set_permalink
|
9
|
+
|
3
10
|
acts_as_nested_set dependent: :destroy
|
4
11
|
|
5
12
|
belongs_to :taxonomy, class_name: 'Spree::Taxonomy', inverse_of: :taxons
|
@@ -8,8 +15,6 @@ module Spree
|
|
8
15
|
|
9
16
|
has_and_belongs_to_many :prototypes, join_table: :spree_taxons_prototypes
|
10
17
|
|
11
|
-
before_create :set_permalink
|
12
|
-
|
13
18
|
validates :name, presence: true
|
14
19
|
validates :meta_keywords, length: { maximum: 255 }
|
15
20
|
validates :meta_description, length: { maximum: 255 }
|
@@ -49,7 +54,7 @@ module Spree
|
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
52
|
-
# Creates permalink
|
57
|
+
# Creates permalink base for friendly_id
|
53
58
|
def set_permalink
|
54
59
|
if parent.present?
|
55
60
|
self.permalink = [parent.permalink, (permalink.blank? ? name.to_url : permalink.split('/').last)].join('/')
|
@@ -58,11 +63,6 @@ module Spree
|
|
58
63
|
end
|
59
64
|
end
|
60
65
|
|
61
|
-
# For #2759
|
62
|
-
def to_param
|
63
|
-
permalink
|
64
|
-
end
|
65
|
-
|
66
66
|
def active_products
|
67
67
|
products.active
|
68
68
|
end
|
@@ -1,27 +1,22 @@
|
|
1
1
|
module Spree
|
2
2
|
class Taxonomy < Spree::Base
|
3
|
-
acts_as_list
|
4
|
-
|
5
3
|
validates :name, presence: true
|
6
4
|
|
7
5
|
has_many :taxons, inverse_of: :taxonomy
|
8
6
|
has_one :root, -> { where parent_id: nil }, class_name: "Spree::Taxon", dependent: :destroy
|
9
7
|
|
10
|
-
|
8
|
+
after_create :set_root
|
9
|
+
after_save :set_root_taxon_name
|
11
10
|
|
12
|
-
default_scope
|
11
|
+
default_scope { order("#{self.table_name}.position, #{self.table_name}.created_at") }
|
13
12
|
|
14
13
|
private
|
15
|
-
def
|
16
|
-
|
17
|
-
root.update_columns(
|
18
|
-
name: name,
|
19
|
-
updated_at: Time.now,
|
20
|
-
)
|
21
|
-
else
|
22
|
-
self.root = Taxon.create!(taxonomy_id: id, name: name)
|
23
|
-
end
|
14
|
+
def set_root
|
15
|
+
self.root ||= Taxon.create!(taxonomy_id: id, name: name)
|
24
16
|
end
|
25
17
|
|
18
|
+
def set_root_taxon_name
|
19
|
+
root.update_attributes(name: name)
|
20
|
+
end
|
26
21
|
end
|
27
22
|
end
|
data/app/models/spree/tracker.rb
CHANGED
data/app/models/spree/variant.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Spree
|
2
2
|
class Variant < Spree::Base
|
3
3
|
acts_as_paranoid
|
4
|
-
acts_as_list scope: :product
|
5
4
|
|
6
5
|
include Spree::DefaultPrice
|
7
6
|
|
@@ -37,23 +36,17 @@ module Spree
|
|
37
36
|
validates_uniqueness_of :sku, allow_blank: true, conditions: -> { where(deleted_at: nil) }
|
38
37
|
|
39
38
|
after_create :create_stock_items
|
39
|
+
after_create :set_position
|
40
40
|
after_create :set_master_out_of_stock, unless: :is_master?
|
41
41
|
|
42
42
|
after_touch :clear_in_stock_cache
|
43
43
|
|
44
44
|
scope :in_stock, -> { joins(:stock_items).where('count_on_hand > ? OR track_inventory = ?', 0, false) }
|
45
45
|
|
46
|
-
self.whitelisted_ransackable_associations = %w[option_values product prices default_price]
|
47
|
-
self.whitelisted_ransackable_attributes = %w[weight sku]
|
48
|
-
|
49
46
|
def self.active(currency = nil)
|
50
47
|
joins(:prices).where(deleted_at: nil).where('spree_prices.currency' => currency || Spree::Config[:currency]).where('spree_prices.amount IS NOT NULL')
|
51
48
|
end
|
52
49
|
|
53
|
-
def self.having_orders
|
54
|
-
joins(:line_items).distinct
|
55
|
-
end
|
56
|
-
|
57
50
|
def tax_category
|
58
51
|
if self[:tax_category_id].nil?
|
59
52
|
product.tax_category
|
@@ -96,10 +89,6 @@ module Spree
|
|
96
89
|
is_master? ? name : options_text
|
97
90
|
end
|
98
91
|
|
99
|
-
def descriptive_name
|
100
|
-
is_master? ? name + ' - Master' : name + ' - ' + options_text
|
101
|
-
end
|
102
|
-
|
103
92
|
# use deleted? rather than checking the attribute directly. this
|
104
93
|
# allows extensions to override deleted? if they want to provide
|
105
94
|
# their own definition.
|
@@ -179,7 +168,7 @@ module Spree
|
|
179
168
|
return 0 unless options.present?
|
180
169
|
|
181
170
|
options.keys.map { |key|
|
182
|
-
m = "#{key}_price_modifier_amount".to_sym
|
171
|
+
m = "#{options[key]}_price_modifier_amount".to_sym
|
183
172
|
if self.respond_to? m
|
184
173
|
self.send(m, options[key])
|
185
174
|
else
|
@@ -247,6 +236,10 @@ module Spree
|
|
247
236
|
end
|
248
237
|
end
|
249
238
|
|
239
|
+
def set_position
|
240
|
+
self.update_column(:position, product.variants.maximum(:position).to_i + 1)
|
241
|
+
end
|
242
|
+
|
250
243
|
def in_stock_cache_key
|
251
244
|
"variant-#{id}-in_stock"
|
252
245
|
end
|
@@ -256,5 +249,3 @@ module Spree
|
|
256
249
|
end
|
257
250
|
end
|
258
251
|
end
|
259
|
-
|
260
|
-
require_dependency 'spree/variant/scopes'
|
data/app/models/spree/zone.rb
CHANGED
@@ -2,21 +2,48 @@ module Spree
|
|
2
2
|
class Zone < Spree::Base
|
3
3
|
has_many :zone_members, dependent: :destroy, class_name: "Spree::ZoneMember", inverse_of: :zone
|
4
4
|
has_many :tax_rates, dependent: :destroy, inverse_of: :zone
|
5
|
+
has_many :countries, through: :zone_members, source: :zoneable,
|
6
|
+
source_type: "Spree::Country"
|
7
|
+
has_many :states, through: :zone_members, source: :zoneable,
|
8
|
+
source_type: "Spree::State"
|
9
|
+
|
5
10
|
has_and_belongs_to_many :shipping_methods, :join_table => 'spree_shipping_methods_zones'
|
6
11
|
|
7
12
|
validates :name, presence: true, uniqueness: { allow_blank: true }
|
13
|
+
|
8
14
|
after_save :remove_defunct_members
|
9
15
|
after_save :remove_previous_default
|
10
16
|
|
11
17
|
alias :members :zone_members
|
12
18
|
accepts_nested_attributes_for :zone_members, allow_destroy: true, reject_if: proc { |a| a['zoneable_id'].blank? }
|
13
19
|
|
14
|
-
self.whitelisted_ransackable_attributes = ['description']
|
15
|
-
|
16
20
|
def self.default_tax
|
17
21
|
where(default_tax: true).first
|
18
22
|
end
|
19
23
|
|
24
|
+
def self.potential_matching_zones(zone)
|
25
|
+
if zone.country?
|
26
|
+
# Match zones of the same kind with simialr countries
|
27
|
+
joins(countries: :zones).
|
28
|
+
where('zone_members_spree_countries_join.zone_id = ? OR ' +
|
29
|
+
'spree_zones.default_tax = ?', zone.id, true).
|
30
|
+
uniq
|
31
|
+
else
|
32
|
+
# Match zones of the same kind with similar states in AND match zones
|
33
|
+
# that have the states countries in
|
34
|
+
joins(:zone_members).where(
|
35
|
+
"(spree_zone_members.zoneable_type = 'Spree::State' AND
|
36
|
+
spree_zone_members.zoneable_id IN (?))
|
37
|
+
OR (spree_zone_members.zoneable_type = 'Spree::Country' AND
|
38
|
+
spree_zone_members.zoneable_id IN (?))
|
39
|
+
OR default_tax = ?",
|
40
|
+
zone.state_ids,
|
41
|
+
zone.states.pluck(:country_id),
|
42
|
+
true
|
43
|
+
).uniq
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
20
47
|
# Returns the matching zone with the highest priority zone type (State, Country, Zone.)
|
21
48
|
# Returns nil in the case of no matches.
|
22
49
|
def self.match(address)
|
@@ -34,13 +61,21 @@ module Spree
|
|
34
61
|
end
|
35
62
|
|
36
63
|
def kind
|
37
|
-
if
|
38
|
-
|
64
|
+
if kind?
|
65
|
+
super
|
66
|
+
else
|
67
|
+
not_nil_scope = members.where.not(zoneable_type: nil)
|
68
|
+
zone_type = not_nil_scope.order('created_at ASC').pluck(:zoneable_type).last
|
69
|
+
zone_type.demodulize.underscore if zone_type
|
39
70
|
end
|
40
71
|
end
|
41
72
|
|
42
|
-
def
|
43
|
-
|
73
|
+
def country?
|
74
|
+
kind == 'country'
|
75
|
+
end
|
76
|
+
|
77
|
+
def state?
|
78
|
+
kind == 'state'
|
44
79
|
end
|
45
80
|
|
46
81
|
def include?(address)
|
@@ -108,15 +143,14 @@ module Spree
|
|
108
143
|
return false if zone_members.empty? || target.zone_members.empty?
|
109
144
|
|
110
145
|
if kind == target.kind
|
111
|
-
return false if (target.
|
146
|
+
return false if (target.countries.pluck(:id) - countries.pluck(:id)).present?
|
112
147
|
else
|
113
|
-
return false if (target.
|
148
|
+
return false if (target.states.pluck(:country_id) - countries.pluck(:id)).present?
|
114
149
|
end
|
115
150
|
true
|
116
151
|
end
|
117
152
|
|
118
153
|
private
|
119
|
-
|
120
154
|
def remove_defunct_members
|
121
155
|
if zone_members.any?
|
122
156
|
zone_members.where('zoneable_id IS NULL OR zoneable_type != ?', "Spree::#{kind.classify}").destroy_all
|