spree_core 3.3.6 → 3.4.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/helpers/spree/base_helper.rb +17 -18
- data/app/helpers/spree/products_helper.rb +5 -5
- data/app/models/concerns/spree/calculated_adjustments.rb +4 -3
- data/app/models/concerns/spree/default_price.rb +4 -5
- data/app/models/concerns/spree/display_money.rb +1 -1
- data/app/models/concerns/spree/named_type.rb +1 -1
- data/app/models/concerns/spree/ransackable_attributes.rb +5 -6
- data/app/models/concerns/spree/user_address.rb +6 -6
- data/app/models/concerns/spree/user_methods.rb +3 -3
- data/app/models/concerns/spree/user_payment_source.rb +4 -2
- data/app/models/concerns/spree/user_reporting.rb +1 -1
- data/app/models/spree/ability.rb +3 -3
- data/app/models/spree/address.rb +13 -9
- data/app/models/spree/adjustable/adjuster/promotion.rb +1 -1
- data/app/models/spree/adjustable/adjustments_updater.rb +2 -2
- data/app/models/spree/adjustable/promotion_accumulator.rb +6 -4
- data/app/models/spree/adjustment.rb +2 -3
- data/app/models/spree/app_configuration.rb +5 -6
- data/app/models/spree/base.rb +1 -1
- data/app/models/spree/calculator/default_tax.rb +4 -5
- data/app/models/spree/calculator/flat_percent_item_total.rb +1 -1
- data/app/models/spree/calculator/flat_rate.rb +3 -3
- data/app/models/spree/calculator/flexi_rate.rb +5 -5
- data/app/models/spree/calculator/price_sack.rb +9 -9
- data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +1 -1
- data/app/models/spree/calculator/shipping/flat_rate.rb +3 -3
- data/app/models/spree/calculator/shipping/flexi_rate.rb +7 -7
- data/app/models/spree/calculator/shipping/per_item.rb +2 -2
- data/app/models/spree/calculator/shipping/price_sack.rb +4 -4
- data/app/models/spree/calculator/tiered_flat_rate.rb +3 -2
- data/app/models/spree/calculator/tiered_percent.rb +4 -3
- data/app/models/spree/calculator.rb +4 -4
- data/app/models/spree/classification.rb +2 -2
- data/app/models/spree/credit_card.rb +1 -1
- data/app/models/spree/exchange.rb +4 -5
- data/app/models/spree/gateway/bogus.rb +20 -20
- data/app/models/spree/gateway/bogus_simple.rb +2 -4
- data/app/models/spree/gateway.rb +4 -4
- data/app/models/spree/image.rb +3 -3
- data/app/models/spree/inventory_unit.rb +30 -30
- data/app/models/spree/line_item.rb +7 -9
- data/app/models/spree/option_type.rb +1 -1
- data/app/models/spree/order/checkout.rb +5 -5
- data/app/models/spree/order/currency_updater.rb +1 -4
- data/app/models/spree/order/payments.rb +4 -4
- data/app/models/spree/order/store_credit.rb +2 -2
- data/app/models/spree/order.rb +11 -29
- data/app/models/spree/order_contents.rb +6 -5
- data/app/models/spree/order_inventory.rb +3 -4
- data/app/models/spree/order_updater.rb +13 -14
- data/app/models/spree/payment/processing.rb +25 -26
- data/app/models/spree/payment.rb +72 -79
- data/app/models/spree/payment_capture_event.rb +1 -1
- data/app/models/spree/payment_method/check.rb +1 -1
- data/app/models/spree/payment_method/store_credit.rb +5 -5
- data/app/models/spree/payment_method.rb +7 -7
- data/app/models/spree/preferences/configuration.rb +6 -9
- data/app/models/spree/preferences/preferable.rb +11 -11
- data/app/models/spree/preferences/preferable_class_methods.rb +2 -3
- data/app/models/spree/preferences/scoped_store.rb +6 -5
- data/app/models/spree/preferences/store.rb +9 -14
- data/app/models/spree/price.rb +1 -1
- data/app/models/spree/product/scopes.rb +49 -49
- data/app/models/spree/product.rb +16 -16
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +2 -1
- data/app/models/spree/promotion/actions/free_shipping.rb +1 -1
- data/app/models/spree/promotion/rules/first_order.rb +7 -6
- data/app/models/spree/promotion/rules/item_total.rb +3 -5
- data/app/models/spree/promotion/rules/one_use_per_user.rb +1 -2
- data/app/models/spree/promotion/rules/option_value.rb +14 -6
- data/app/models/spree/promotion/rules/product.rb +4 -4
- data/app/models/spree/promotion/rules/taxon.rb +6 -6
- data/app/models/spree/promotion/rules/user.rb +3 -3
- data/app/models/spree/promotion/rules/user_logged_in.rb +1 -1
- data/app/models/spree/promotion.rb +15 -16
- data/app/models/spree/promotion_action.rb +1 -1
- data/app/models/spree/promotion_handler/cart.rb +3 -2
- data/app/models/spree/promotion_handler/free_shipping.rb +1 -3
- data/app/models/spree/promotion_handler/page.rb +3 -3
- data/app/models/spree/promotion_rule.rb +5 -4
- data/app/models/spree/refund.rb +8 -8
- data/app/models/spree/reimbursement/credit.rb +1 -1
- data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -3
- data/app/models/spree/reimbursement.rb +4 -8
- data/app/models/spree/reimbursement_performer.rb +0 -5
- data/app/models/spree/reimbursement_tax_calculator.rb +5 -12
- data/app/models/spree/reimbursement_type.rb +2 -2
- data/app/models/spree/return_authorization.rb +22 -26
- data/app/models/spree/return_item/eligibility_validator/default.rb +3 -3
- data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/order_completed.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/rma_required.rb +2 -3
- data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +2 -2
- data/app/models/spree/return_item.rb +15 -19
- data/app/models/spree/returns_calculator.rb +1 -2
- data/app/models/spree/shipment.rb +14 -35
- data/app/models/spree/shipment_handler.rb +10 -12
- data/app/models/spree/shipping_calculator.rb +5 -6
- data/app/models/spree/shipping_method.rb +3 -3
- data/app/models/spree/shipping_rate.rb +2 -2
- data/app/models/spree/state.rb +2 -2
- data/app/models/spree/stock/availability_validator.rb +1 -1
- data/app/models/spree/stock/content_item.rb +2 -3
- data/app/models/spree/stock/coordinator.rb +3 -2
- data/app/models/spree/stock/differentiator.rb +3 -2
- data/app/models/spree/stock/estimator.rb +7 -5
- data/app/models/spree/stock/package.rb +5 -5
- data/app/models/spree/stock/packer.rb +1 -1
- data/app/models/spree/stock/prioritizer.rb +5 -7
- data/app/models/spree/stock/quantifier.rb +0 -1
- data/app/models/spree/stock/splitter/backordered.rb +2 -4
- data/app/models/spree/stock/splitter/base.rb +3 -2
- data/app/models/spree/stock/splitter/shipping_category.rb +2 -1
- data/app/models/spree/stock_item.rb +1 -1
- data/app/models/spree/stock_location.rb +12 -11
- data/app/models/spree/stock_movement.rb +1 -3
- data/app/models/spree/stock_transfer.rb +1 -1
- data/app/models/spree/store.rb +4 -4
- data/app/models/spree/store_credit.rb +3 -3
- data/app/models/spree/tax_category.rb +1 -1
- data/app/models/spree/tax_rate.rb +10 -10
- data/app/models/spree/taxon.rb +13 -13
- data/app/models/spree/taxonomy.rb +9 -8
- data/app/models/spree/validations/db_maximum_length_validator.rb +2 -3
- data/app/models/spree/variant.rb +30 -41
- data/app/models/spree/zone.rb +10 -10
- data/app/validators/db_maximum_length_validator.rb +5 -5
- data/config/initializers/acts_as_taggable_on.rb +3 -3
- data/config/initializers/assets.rb +1 -1
- data/config/initializers/friendly_id.rb +1 -1
- data/config/initializers/premailer_assets.rb +1 -1
- data/config/locales/en.yml +8 -2
- data/db/default/spree/states.rb +1 -0
- data/lib/generators/spree/custom_user/custom_user_generator.rb +12 -15
- data/lib/generators/spree/install/install_generator.rb +45 -32
- data/lib/spree/core/components.rb +3 -3
- data/lib/spree/core/controller_helpers/auth.rb +5 -10
- data/lib/spree/core/controller_helpers/common.rb +2 -3
- data/lib/spree/core/controller_helpers/order.rb +3 -7
- data/lib/spree/core/controller_helpers/respond_with.rb +4 -4
- data/lib/spree/core/engine.rb +3 -3
- data/lib/spree/core/environment/calculators.rb +0 -1
- data/lib/spree/core/environment_extension.rb +8 -8
- data/lib/spree/core/importer/order.rb +64 -67
- data/lib/spree/core/importer/product.rb +10 -9
- data/lib/spree/core/product_filters.rb +17 -18
- data/lib/spree/core/routes.rb +2 -6
- data/lib/spree/core/search/base.rb +62 -59
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +4 -6
- data/lib/spree/i18n.rb +3 -5
- data/lib/spree/localized_number.rb +0 -2
- data/lib/spree/migrations.rb +8 -7
- data/lib/spree/money.rb +3 -7
- data/lib/spree/permitted_attributes.rb +2 -2
- data/lib/spree/responder.rb +4 -5
- data/lib/spree/testing_support/authorization_helpers.rb +3 -3
- data/lib/spree/testing_support/caching.rb +5 -5
- data/lib/spree/testing_support/capybara_ext.rb +16 -18
- data/lib/spree/testing_support/common_rake.rb +8 -9
- data/lib/spree/testing_support/controller_requests.rb +6 -6
- data/lib/spree/testing_support/extension_rake.rb +2 -3
- data/lib/spree/testing_support/factories/address_factory.rb +1 -1
- data/lib/spree/testing_support/factories/adjustment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/calculator_factory.rb +1 -1
- data/lib/spree/testing_support/factories/country_factory.rb +1 -1
- data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
- data/lib/spree/testing_support/factories/customer_return_factory.rb +1 -3
- data/lib/spree/testing_support/factories/image_factory.rb +2 -2
- data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
- data/lib/spree/testing_support/factories/line_item_factory.rb +2 -2
- data/lib/spree/testing_support/factories/options_factory.rb +1 -1
- data/lib/spree/testing_support/factories/order_factory.rb +1 -1
- data/lib/spree/testing_support/factories/payment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/payment_method_factory.rb +4 -4
- data/lib/spree/testing_support/factories/price_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_option_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_property_factory.rb +1 -1
- data/lib/spree/testing_support/factories/promotion_category_factory.rb +1 -2
- data/lib/spree/testing_support/factories/promotion_factory.rb +1 -2
- data/lib/spree/testing_support/factories/promotion_rule_factory.rb +1 -1
- data/lib/spree/testing_support/factories/property_factory.rb +1 -1
- data/lib/spree/testing_support/factories/prototype_factory.rb +1 -1
- data/lib/spree/testing_support/factories/refund_factory.rb +1 -1
- data/lib/spree/testing_support/factories/reimbursement_factory.rb +2 -2
- data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/return_authorization_factory.rb +1 -1
- data/lib/spree/testing_support/factories/return_item_factory.rb +1 -1
- data/lib/spree/testing_support/factories/role_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipment_factory.rb +2 -2
- data/lib/spree/testing_support/factories/shipping_category_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +3 -3
- data/lib/spree/testing_support/factories/state_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_item_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_location_factory.rb +2 -2
- data/lib/spree/testing_support/factories/stock_movement_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_category_factory.rb +2 -2
- data/lib/spree/testing_support/factories/store_credit_event_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tag_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tax_category_factory.rb +2 -2
- data/lib/spree/testing_support/factories/tax_rate_factory.rb +1 -1
- data/lib/spree/testing_support/factories/taxon_factory.rb +1 -1
- data/lib/spree/testing_support/factories/taxonomy_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tracker_factory.rb +1 -1
- data/lib/spree/testing_support/factories/user_factory.rb +1 -1
- data/lib/spree/testing_support/factories/variant_factory.rb +1 -2
- data/lib/spree/testing_support/factories/zone_factory.rb +1 -1
- data/lib/spree/testing_support/factories/zone_member_factory.rb +1 -1
- data/lib/spree/testing_support/factories.rb +3 -3
- data/lib/spree/testing_support/flash.rb +1 -3
- data/lib/spree/testing_support/i18n.rb +5 -6
- data/lib/spree/testing_support/kernel.rb +1 -2
- data/lib/spree/testing_support/order_walkthrough.rb +12 -15
- data/lib/spree/testing_support/preferences.rb +0 -1
- data/lib/tasks/core.rake +47 -56
- data/lib/tasks/email.rake +2 -2
- data/lib/tasks/exchanges.rake +5 -5
- data/spree_core.gemspec +1 -1
- metadata +5 -9
- data/app/models/spree/calculator/percent_per_item.rb +0 -51
- data/config/initializers/premailer_rails.rb +0 -3
- data/lib/spree/core/delegate_belongs_to.rb +0 -99
- data/lib/spree/testing_support/microdata.rb +0 -192
@@ -6,7 +6,7 @@ module Spree
|
|
6
6
|
promotable.is_a?(Spree::Order)
|
7
7
|
end
|
8
8
|
|
9
|
-
def eligible?(order,
|
9
|
+
def eligible?(order, _options = {})
|
10
10
|
if order.user.present?
|
11
11
|
if promotion.used_by?(order.user, [order])
|
12
12
|
eligibility_errors.add(:base, eligibility_error_message(:limit_once_per_user))
|
@@ -21,4 +21,3 @@ module Spree
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
@@ -6,7 +6,7 @@ module Spree
|
|
6
6
|
values = super || {}
|
7
7
|
Hash[values.keys.map(&:to_i).zip(
|
8
8
|
values.values.map do |v|
|
9
|
-
(v.is_a?(Array) ? v : v.split(
|
9
|
+
(v.is_a?(Array) ? v : v.split(',')).map(&:to_i)
|
10
10
|
end
|
11
11
|
)]
|
12
12
|
end
|
@@ -31,12 +31,20 @@ module Spree
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def actionable?(line_item)
|
34
|
-
|
35
|
-
|
36
|
-
eligible_product_ids = preferred_eligible_values.keys
|
37
|
-
eligible_value_ids = preferred_eligible_values[product_id]
|
34
|
+
pid = line_item.product.id
|
35
|
+
ovids = line_item.variant.option_values.pluck(:id)
|
38
36
|
|
39
|
-
|
37
|
+
product_ids.include?(pid) && (value_ids(pid) - ovids).empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def product_ids
|
43
|
+
preferred_eligible_values.keys
|
44
|
+
end
|
45
|
+
|
46
|
+
def value_ids(product_id)
|
47
|
+
preferred_eligible_values[product_id]
|
40
48
|
end
|
41
49
|
end
|
42
50
|
end
|
@@ -21,19 +21,19 @@ module Spree
|
|
21
21
|
promotable.is_a?(Spree::Order)
|
22
22
|
end
|
23
23
|
|
24
|
-
def eligible?(order,
|
24
|
+
def eligible?(order, _options = {})
|
25
25
|
return true if eligible_products.empty?
|
26
26
|
|
27
27
|
if preferred_match_policy == 'all'
|
28
|
-
unless eligible_products.all? {|p| order.products.include?(p) }
|
28
|
+
unless eligible_products.all? { |p| order.products.include?(p) }
|
29
29
|
eligibility_errors.add(:base, eligibility_error_message(:missing_product))
|
30
30
|
end
|
31
31
|
elsif preferred_match_policy == 'any'
|
32
|
-
unless order.products.any? {|p| eligible_products.include?(p) }
|
32
|
+
unless order.products.any? { |p| eligible_products.include?(p) }
|
33
33
|
eligibility_errors.add(:base, eligibility_error_message(:no_applicable_products))
|
34
34
|
end
|
35
35
|
else
|
36
|
-
unless order.products.none? {|p| eligible_products.include?(p) }
|
36
|
+
unless order.products.none? { |p| eligible_products.include?(p) }
|
37
37
|
eligibility_errors.add(:base, eligibility_error_message(:has_excluded_product))
|
38
38
|
end
|
39
39
|
end
|
@@ -12,14 +12,14 @@ module Spree
|
|
12
12
|
promotable.is_a?(Spree::Order)
|
13
13
|
end
|
14
14
|
|
15
|
-
def eligible?(order,
|
15
|
+
def eligible?(order, _options = {})
|
16
16
|
if preferred_match_policy == 'all'
|
17
17
|
unless (taxons.to_a - taxons_in_order_including_parents(order)).empty?
|
18
18
|
eligibility_errors.add(:base, eligibility_error_message(:missing_taxon))
|
19
19
|
end
|
20
20
|
else
|
21
21
|
order_taxons = taxons_in_order_including_parents(order)
|
22
|
-
unless taxons.any?{ |taxon| order_taxons.include? taxon }
|
22
|
+
unless taxons.any? { |taxon| order_taxons.include? taxon }
|
23
23
|
eligibility_errors.add(:base, eligibility_error_message(:no_matching_taxons))
|
24
24
|
end
|
25
25
|
end
|
@@ -44,12 +44,12 @@ module Spree
|
|
44
44
|
|
45
45
|
# All taxons in an order
|
46
46
|
def order_taxons(order)
|
47
|
-
Spree::Taxon.joins(products: {variants_including_master: :line_items}).where(spree_line_items: {order_id: order.id}).distinct
|
47
|
+
Spree::Taxon.joins(products: { variants_including_master: :line_items }).where(spree_line_items: { order_id: order.id }).distinct
|
48
48
|
end
|
49
49
|
|
50
50
|
# ids of taxons rules and taxons rules children
|
51
51
|
def taxons_including_children_ids
|
52
|
-
taxons.inject([]){ |ids,taxon| ids += taxon.self_and_descendants.ids }
|
52
|
+
taxons.inject([]) { |ids, taxon| ids += taxon.self_and_descendants.ids }
|
53
53
|
end
|
54
54
|
|
55
55
|
# taxons order vs taxons rules and taxons rules children
|
@@ -58,11 +58,11 @@ module Spree
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def taxons_in_order_including_parents(order)
|
61
|
-
order_taxons_in_taxons_and_children(order).inject([]){ |taxons, taxon| taxons << taxon.self_and_ancestors }.flatten.uniq
|
61
|
+
order_taxons_in_taxons_and_children(order).inject([]) { |taxons, taxon| taxons << taxon.self_and_ancestors }.flatten.uniq
|
62
62
|
end
|
63
63
|
|
64
64
|
def taxon_product_ids
|
65
|
-
Spree::Product.joins(:taxons).where(spree_taxons: {id: taxons.pluck(:id)}).pluck(:id).uniq
|
65
|
+
Spree::Product.joins(:taxons).where(spree_taxons: { id: taxons.pluck(:id) }).pluck(:id).uniq
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -2,18 +2,18 @@ module Spree
|
|
2
2
|
class Promotion
|
3
3
|
module Rules
|
4
4
|
class User < PromotionRule
|
5
|
-
belongs_to :user, class_name: "::#{Spree.user_class
|
5
|
+
belongs_to :user, class_name: "::#{Spree.user_class}"
|
6
6
|
|
7
7
|
has_many :promotion_rule_users, class_name: 'Spree::PromotionRuleUser',
|
8
8
|
foreign_key: :promotion_rule_id,
|
9
9
|
dependent: :destroy
|
10
|
-
has_many :users, through: :promotion_rule_users, class_name: "::#{Spree.user_class
|
10
|
+
has_many :users, through: :promotion_rule_users, class_name: "::#{Spree.user_class}"
|
11
11
|
|
12
12
|
def applicable?(promotable)
|
13
13
|
promotable.is_a?(Spree::Order)
|
14
14
|
end
|
15
15
|
|
16
|
-
def eligible?(order,
|
16
|
+
def eligible?(order, _options = {})
|
17
17
|
users.include?(order.user)
|
18
18
|
end
|
19
19
|
|
@@ -1,17 +1,17 @@
|
|
1
1
|
module Spree
|
2
2
|
class Promotion < Spree::Base
|
3
3
|
MATCH_POLICIES = %w(all any)
|
4
|
-
UNACTIVATABLE_ORDER_STATES = [
|
4
|
+
UNACTIVATABLE_ORDER_STATES = ['complete', 'awaiting_return', 'returned']
|
5
5
|
|
6
6
|
attr_reader :eligibility_errors
|
7
7
|
|
8
8
|
belongs_to :promotion_category, optional: true
|
9
9
|
|
10
10
|
has_many :promotion_rules, autosave: true, dependent: :destroy
|
11
|
-
|
11
|
+
alias rules promotion_rules
|
12
12
|
|
13
13
|
has_many :promotion_actions, autosave: true, dependent: :destroy
|
14
|
-
|
14
|
+
alias actions promotion_actions
|
15
15
|
|
16
16
|
has_many :order_promotions, class_name: 'Spree::OrderPromotion'
|
17
17
|
has_many :orders, through: :order_promotions, class_name: 'Spree::Order'
|
@@ -40,9 +40,9 @@ module Spree
|
|
40
40
|
self.whitelisted_ransackable_attributes = ['path', 'promotion_category_id', 'code']
|
41
41
|
|
42
42
|
def self.with_coupon_code(coupon_code)
|
43
|
-
where("lower(#{table_name}.code) = ?", coupon_code.strip.downcase)
|
44
|
-
|
45
|
-
|
43
|
+
where("lower(#{table_name}.code) = ?", coupon_code.strip.downcase).
|
44
|
+
includes(:promotion_actions).where.not(spree_promotion_actions: { id: nil }).
|
45
|
+
first
|
46
46
|
end
|
47
47
|
|
48
48
|
def self.active
|
@@ -74,10 +74,10 @@ module Spree
|
|
74
74
|
action_taken = results.include?(true)
|
75
75
|
|
76
76
|
if action_taken
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
77
|
+
# connect to the order
|
78
|
+
# create the join_table entry.
|
79
|
+
orders << order
|
80
|
+
save
|
81
81
|
end
|
82
82
|
|
83
83
|
action_taken
|
@@ -122,7 +122,7 @@ module Spree
|
|
122
122
|
def eligible_rules(promotable, options = {})
|
123
123
|
# Promotions without rules are eligible by default.
|
124
124
|
return [] if rules.none?
|
125
|
-
eligible =
|
125
|
+
eligible = ->(r) { r.eligible?(promotable, options) }
|
126
126
|
specific_rules = rules.select { |rule| rule.applicable?(promotable) }
|
127
127
|
return [] if specific_rules.none?
|
128
128
|
|
@@ -149,7 +149,7 @@ module Spree
|
|
149
149
|
end
|
150
150
|
|
151
151
|
def products
|
152
|
-
rules.where(type:
|
152
|
+
rules.where(type: 'Spree::Promotion::Rules::Product').map(&:products).flatten.uniq
|
153
153
|
end
|
154
154
|
|
155
155
|
def usage_limit_exceeded?(promotable)
|
@@ -203,13 +203,14 @@ module Spree
|
|
203
203
|
end
|
204
204
|
|
205
205
|
private
|
206
|
+
|
206
207
|
def blacklisted?(promotable)
|
207
208
|
case promotable
|
208
209
|
when Spree::LineItem
|
209
210
|
!promotable.product.promotionable?
|
210
211
|
when Spree::Order
|
211
212
|
promotable.line_items.any? &&
|
212
|
-
|
213
|
+
promotable.line_items.joins(:product).where(spree_products: { promotionable: true }).none?
|
213
214
|
end
|
214
215
|
end
|
215
216
|
|
@@ -224,9 +225,7 @@ module Spree
|
|
224
225
|
end
|
225
226
|
|
226
227
|
def expires_at_must_be_later_than_starts_at
|
227
|
-
if expires_at < starts_at
|
228
|
-
errors.add(:expires_at, :invalid_date_range)
|
229
|
-
end
|
228
|
+
errors.add(:expires_at, :invalid_date_range) if expires_at < starts_at
|
230
229
|
end
|
231
230
|
end
|
232
231
|
end
|
@@ -12,7 +12,7 @@ module Spree
|
|
12
12
|
# Updates the state of the order or performs some other action depending on the subclass
|
13
13
|
# options will contain the payload from the event that activated the promotion. This will include
|
14
14
|
# the key :user which allows user based actions to be performed in addition to actions on the order
|
15
|
-
def perform(
|
15
|
+
def perform(_options = {})
|
16
16
|
raise 'perform should be implemented in a sub-class of PromotionAction'
|
17
17
|
end
|
18
18
|
|
@@ -16,8 +16,9 @@ module Spree
|
|
16
16
|
attr_reader :line_item, :order
|
17
17
|
attr_accessor :error, :success
|
18
18
|
|
19
|
-
def initialize(order, line_item=nil)
|
20
|
-
@order
|
19
|
+
def initialize(order, line_item = nil)
|
20
|
+
@order = order
|
21
|
+
@line_item = line_item
|
21
22
|
end
|
22
23
|
|
23
24
|
def activate
|
@@ -14,9 +14,7 @@ module Spree
|
|
14
14
|
promotions.each do |promotion|
|
15
15
|
next if promotion.code.present? && !order_promo_ids.include?(promotion.id)
|
16
16
|
|
17
|
-
if promotion.eligible?(order)
|
18
|
-
promotion.activate(order: order)
|
19
|
-
end
|
17
|
+
promotion.activate(order: order) if promotion.eligible?(order)
|
20
18
|
end
|
21
19
|
end
|
22
20
|
|
@@ -11,17 +11,17 @@ module Spree
|
|
11
11
|
all.select { |rule| rule.applicable?(promotable) }
|
12
12
|
end
|
13
13
|
|
14
|
-
def applicable?(
|
14
|
+
def applicable?(_promotable)
|
15
15
|
raise 'applicable? should be implemented in a sub-class of Spree::PromotionRule'
|
16
16
|
end
|
17
17
|
|
18
|
-
def eligible?(
|
18
|
+
def eligible?(_promotable, _options = {})
|
19
19
|
raise 'eligible? should be implemented in a sub-class of Spree::PromotionRule'
|
20
20
|
end
|
21
21
|
|
22
22
|
# This states if a promotion can be applied to the specified line item
|
23
23
|
# It is true by default, but can be overridden by promotion rules to provide conditions
|
24
|
-
def actionable?(
|
24
|
+
def actionable?(_line_item)
|
25
25
|
true
|
26
26
|
end
|
27
27
|
|
@@ -30,9 +30,10 @@ module Spree
|
|
30
30
|
end
|
31
31
|
|
32
32
|
private
|
33
|
+
|
33
34
|
def unique_per_promotion
|
34
35
|
if Spree::PromotionRule.exists?(promotion_id: promotion_id, type: self.class.name)
|
35
|
-
errors[:base] <<
|
36
|
+
errors[:base] << 'Promotion already contains this rule type'
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
data/app/models/spree/refund.rb
CHANGED
@@ -22,7 +22,7 @@ module Spree
|
|
22
22
|
scope :non_reimbursement, -> { where(reimbursement_id: nil) }
|
23
23
|
|
24
24
|
def money
|
25
|
-
Spree::Money.new(amount,
|
25
|
+
Spree::Money.new(amount, currency: payment.currency)
|
26
26
|
end
|
27
27
|
alias display_amount money
|
28
28
|
|
@@ -43,7 +43,7 @@ module Spree
|
|
43
43
|
def perform!
|
44
44
|
return true if transaction_id.present?
|
45
45
|
|
46
|
-
credit_cents = Spree::Money.new(amount.to_f, currency: payment.currency).
|
46
|
+
credit_cents = Spree::Money.new(amount.to_f, currency: payment.currency).money.cents
|
47
47
|
|
48
48
|
@response = process!(credit_cents)
|
49
49
|
|
@@ -55,21 +55,21 @@ module Spree
|
|
55
55
|
# return an activemerchant response object if successful or else raise an error
|
56
56
|
def process!(credit_cents)
|
57
57
|
response = if payment.payment_method.payment_profiles_supported?
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
payment.payment_method.credit(credit_cents, payment.source, payment.transaction_id, originator: self)
|
59
|
+
else
|
60
|
+
payment.payment_method.credit(credit_cents, payment.transaction_id, originator: self)
|
61
61
|
end
|
62
62
|
|
63
|
-
|
63
|
+
unless response.success?
|
64
64
|
logger.error(Spree.t(:gateway_error) + " #{response.to_yaml}")
|
65
65
|
text = response.params['message'] || response.params['response_reason_text'] || response.message
|
66
|
-
raise Core::GatewayError
|
66
|
+
raise Core::GatewayError, text
|
67
67
|
end
|
68
68
|
|
69
69
|
response
|
70
70
|
rescue ActiveMerchant::ConnectionError => e
|
71
71
|
logger.error(Spree.t(:gateway_error) + " #{e.inspect}")
|
72
|
-
raise Core::GatewayError
|
72
|
+
raise Core::GatewayError, Spree.t(:unable_to_connect_to_gateway)
|
73
73
|
end
|
74
74
|
|
75
75
|
def create_log_entry
|
@@ -16,7 +16,7 @@ module Spree
|
|
16
16
|
|
17
17
|
def initialize(return_items)
|
18
18
|
@return_items = return_items
|
19
|
-
@reimbursement_type_hash = Hash.new {|h,k| h[k] =
|
19
|
+
@reimbursement_type_hash = Hash.new { |h, k| h[k] = [] }
|
20
20
|
end
|
21
21
|
|
22
22
|
def calculate_reimbursement_types
|
@@ -38,8 +38,6 @@ module Spree
|
|
38
38
|
elsif return_item.preferred_reimbursement_type.present?
|
39
39
|
if valid_preferred_reimbursement_type?(return_item)
|
40
40
|
return_item.preferred_reimbursement_type.class
|
41
|
-
else
|
42
|
-
nil
|
43
41
|
end
|
44
42
|
elsif past_reimbursable_time_period?(return_item)
|
45
43
|
expired_reimbursement_type
|
@@ -61,7 +61,6 @@ module Spree
|
|
61
61
|
self.reimbursement_failure_hooks = []
|
62
62
|
|
63
63
|
state_machine :reimbursement_status, initial: :pending do
|
64
|
-
|
65
64
|
event :errored do
|
66
65
|
transition to: :errored, from: :pending
|
67
66
|
end
|
@@ -69,21 +68,18 @@ module Spree
|
|
69
68
|
event :reimbursed do
|
70
69
|
transition to: :reimbursed, from: [:pending, :errored]
|
71
70
|
end
|
72
|
-
|
73
71
|
end
|
74
72
|
|
75
73
|
class << self
|
76
74
|
def build_from_customer_return(customer_return)
|
77
75
|
order = customer_return.order
|
78
|
-
order.reimbursements.build(
|
79
|
-
|
80
|
-
return_items: customer_return.return_items.accepted.not_reimbursed,
|
81
|
-
})
|
76
|
+
order.reimbursements.build(customer_return: customer_return,
|
77
|
+
return_items: customer_return.return_items.accepted.not_reimbursed)
|
82
78
|
end
|
83
79
|
end
|
84
80
|
|
85
81
|
def display_total
|
86
|
-
Spree::Money.new(total,
|
82
|
+
Spree::Money.new(total, currency: order.currency)
|
87
83
|
end
|
88
84
|
|
89
85
|
def calculated_total
|
@@ -116,7 +112,7 @@ module Spree
|
|
116
112
|
else
|
117
113
|
errored!
|
118
114
|
reimbursement_failure_hooks.each { |h| h.call self }
|
119
|
-
raise IncompleteReimbursementError, Spree.t(
|
115
|
+
raise IncompleteReimbursementError, Spree.t('validation.unpaid_amount_not_zero', amount: unpaid_amount)
|
120
116
|
end
|
121
117
|
end
|
122
118
|
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module Spree
|
2
|
-
|
3
2
|
class ReimbursementPerformer
|
4
|
-
|
5
3
|
class << self
|
6
4
|
class_attribute :reimbursement_type_engine
|
7
5
|
self.reimbursement_type_engine = Spree::Reimbursement::ReimbursementTypeEngine
|
@@ -35,9 +33,6 @@ module Spree
|
|
35
33
|
# {Spree::ReimbursementType::OriginalPayment => [ReturnItem, ...], Spree::ReimbursementType::Exchange => [ReturnItem, ...]}
|
36
34
|
reimbursement_type_engine.new(reimbursement.return_items).calculate_reimbursement_types
|
37
35
|
end
|
38
|
-
|
39
36
|
end
|
40
|
-
|
41
37
|
end
|
42
|
-
|
43
38
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Spree
|
2
|
-
|
3
2
|
# Tax calculation is broken out at this level to allow easy integration with 3rd party
|
4
3
|
# taxation systems. Those systems are usually geared toward calculating all items at once
|
5
4
|
# rather than one at a time.
|
@@ -9,9 +8,7 @@ module Spree
|
|
9
8
|
# where `calculator_object` is an object that responds to "call" and accepts a reimbursement object
|
10
9
|
|
11
10
|
class ReimbursementTaxCalculator
|
12
|
-
|
13
11
|
class << self
|
14
|
-
|
15
12
|
def call(reimbursement)
|
16
13
|
reimbursement.return_items.includes(:inventory_unit).each do |return_item|
|
17
14
|
set_tax!(return_item)
|
@@ -24,21 +21,17 @@ module Spree
|
|
24
21
|
calculated_refund = Spree::ReturnItem.refund_amount_calculator.new.compute(return_item)
|
25
22
|
|
26
23
|
percent_of_tax = if return_item.pre_tax_amount <= 0 || calculated_refund <= 0
|
27
|
-
|
28
|
-
|
29
|
-
|
24
|
+
0
|
25
|
+
else
|
26
|
+
return_item.pre_tax_amount / calculated_refund
|
30
27
|
end
|
31
28
|
|
32
29
|
additional_tax_total = percent_of_tax * return_item.inventory_unit.additional_tax_total
|
33
30
|
included_tax_total = percent_of_tax * return_item.inventory_unit.included_tax_total
|
34
31
|
|
35
|
-
return_item.update_attributes!(
|
36
|
-
|
37
|
-
included_tax_total: included_tax_total,
|
38
|
-
})
|
32
|
+
return_item.update_attributes!(additional_tax_total: additional_tax_total,
|
33
|
+
included_tax_total: included_tax_total)
|
39
34
|
end
|
40
35
|
end
|
41
|
-
|
42
36
|
end
|
43
|
-
|
44
37
|
end
|
@@ -13,8 +13,8 @@ module Spree
|
|
13
13
|
# This method will reimburse the return items based on however its child implements it
|
14
14
|
# By default it takes a reimbursement, the return items it needs to reimburse, and if
|
15
15
|
# it is a simulation or a real reimbursement. This should return an array
|
16
|
-
def self.reimburse(
|
17
|
-
raise
|
16
|
+
def self.reimburse(_reimbursement, _return_items, _simulate)
|
17
|
+
raise 'Implement me'
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -21,7 +21,6 @@ module Spree
|
|
21
21
|
validates :order, :reason, :stock_location, presence: true
|
22
22
|
validate :must_have_shipped_units, on: :create
|
23
23
|
|
24
|
-
|
25
24
|
# These are called prior to generating expedited exchanges shipments.
|
26
25
|
# Should respond to a "call" method that takes the list of return items
|
27
26
|
class_attribute :pre_expedited_exchange_hooks
|
@@ -31,9 +30,8 @@ module Spree
|
|
31
30
|
before_transition to: :canceled, do: :cancel_return_items
|
32
31
|
|
33
32
|
event :cancel do
|
34
|
-
transition to: :canceled, from: :authorized, if:
|
33
|
+
transition to: :canceled, from: :authorized, if: ->(return_authorization) { return_authorization.can_cancel_return_items? }
|
35
34
|
end
|
36
|
-
|
37
35
|
end
|
38
36
|
|
39
37
|
extend DisplayMoney
|
@@ -63,37 +61,35 @@ module Spree
|
|
63
61
|
|
64
62
|
private
|
65
63
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
def cancel_return_items
|
74
|
-
return_items.each { |item| item.cancel! if item.can_cancel? }
|
64
|
+
def must_have_shipped_units
|
65
|
+
if order.nil? || order.inventory_units.shipped.none?
|
66
|
+
errors.add(:order, Spree.t(:has_no_shipped_units))
|
75
67
|
end
|
68
|
+
end
|
76
69
|
|
77
|
-
|
78
|
-
|
70
|
+
def cancel_return_items
|
71
|
+
return_items.each { |item| item.cancel! if item.can_cancel? }
|
72
|
+
end
|
79
73
|
|
80
|
-
|
81
|
-
|
82
|
-
items_to_exchange.select!(&:accepted?)
|
74
|
+
def generate_expedited_exchange_reimbursements
|
75
|
+
return unless Spree::Config[:expedited_exchanges]
|
83
76
|
|
84
|
-
|
77
|
+
items_to_exchange = return_items.select(&:exchange_required?)
|
78
|
+
items_to_exchange.each(&:attempt_accept)
|
79
|
+
items_to_exchange.select!(&:accepted?)
|
85
80
|
|
86
|
-
|
81
|
+
return if items_to_exchange.blank?
|
87
82
|
|
88
|
-
|
83
|
+
pre_expedited_exchange_hooks.each { |h| h.call items_to_exchange }
|
89
84
|
|
90
|
-
|
91
|
-
reimbursement.perform!
|
92
|
-
else
|
93
|
-
errors.add(:base, reimbursement.errors.full_messages)
|
94
|
-
raise ActiveRecord::RecordInvalid.new(self)
|
95
|
-
end
|
85
|
+
reimbursement = Reimbursement.new(return_items: items_to_exchange, order: order)
|
96
86
|
|
87
|
+
if reimbursement.save
|
88
|
+
reimbursement.perform!
|
89
|
+
else
|
90
|
+
errors.add(:base, reimbursement.errors.full_messages)
|
91
|
+
raise ActiveRecord::RecordInvalid, self
|
97
92
|
end
|
93
|
+
end
|
98
94
|
end
|
99
95
|
end
|
@@ -10,11 +10,11 @@ module Spree
|
|
10
10
|
]
|
11
11
|
|
12
12
|
def eligible_for_return?
|
13
|
-
validators.all?
|
13
|
+
validators.all?(&:eligible_for_return?)
|
14
14
|
end
|
15
15
|
|
16
16
|
def requires_manual_intervention?
|
17
|
-
validators.any?
|
17
|
+
validators.any?(&:requires_manual_intervention?)
|
18
18
|
end
|
19
19
|
|
20
20
|
def errors
|
@@ -24,7 +24,7 @@ module Spree
|
|
24
24
|
private
|
25
25
|
|
26
26
|
def validators
|
27
|
-
@validators ||= permitted_eligibility_validators.map{|v| v.new(@return_item) }
|
27
|
+
@validators ||= permitted_eligibility_validators.map { |v| v.new(@return_item) }
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -2,10 +2,10 @@ module Spree
|
|
2
2
|
class ReturnItem::EligibilityValidator::InventoryShipped < Spree::ReturnItem::EligibilityValidator::BaseValidator
|
3
3
|
def eligible_for_return?
|
4
4
|
if @return_item.inventory_unit.shipped?
|
5
|
-
|
5
|
+
true
|
6
6
|
else
|
7
7
|
add_error(:inventory_unit_shipped, Spree.t('return_item_inventory_unit_ineligible'))
|
8
|
-
|
8
|
+
false
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -3,9 +3,9 @@ module Spree
|
|
3
3
|
def eligible_for_return?
|
4
4
|
if Spree::ReturnItem.where(inventory_unit: @return_item.inventory_unit).where.not(reimbursement_id: nil).any?
|
5
5
|
add_error(:inventory_unit_reimbursed, Spree.t('return_item_inventory_unit_reimbursed'))
|
6
|
-
|
6
|
+
false
|
7
7
|
else
|
8
|
-
|
8
|
+
true
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -2,10 +2,10 @@ module Spree
|
|
2
2
|
class ReturnItem::EligibilityValidator::OrderCompleted < Spree::ReturnItem::EligibilityValidator::BaseValidator
|
3
3
|
def eligible_for_return?
|
4
4
|
if @return_item.inventory_unit.order.completed?
|
5
|
-
|
5
|
+
true
|
6
6
|
else
|
7
7
|
add_error(:order_not_completed, Spree.t('return_item_order_not_completed'))
|
8
|
-
|
8
|
+
false
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|