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.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/app/assets/images/logo/spree_50.png +0 -0
  4. data/app/controllers/spree/base_controller.rb +1 -2
  5. data/app/helpers/spree/base_helper.rb +41 -131
  6. data/app/helpers/spree/products_helper.rb +1 -1
  7. data/app/models/concerns/spree/adjustment_source.rb +51 -15
  8. data/app/models/concerns/spree/calculated_adjustments.rb +1 -0
  9. data/app/models/concerns/spree/display_money.rb +32 -0
  10. data/app/models/concerns/spree/named_type.rb +1 -1
  11. data/app/models/concerns/spree/number_generator.rb +39 -0
  12. data/app/models/concerns/spree/user_reporting.rb +3 -8
  13. data/app/models/spree/address.rb +0 -2
  14. data/app/models/spree/adjustable/adjustments_updater.rb +70 -0
  15. data/app/models/spree/adjustable/promotion_accumulator.rb +75 -0
  16. data/app/models/spree/adjustment.rb +17 -26
  17. data/app/models/spree/app_configuration.rb +4 -33
  18. data/app/models/spree/base.rb +0 -3
  19. data/app/models/spree/calculator.rb +0 -5
  20. data/app/models/spree/classification.rb +1 -1
  21. data/app/models/spree/country.rb +10 -4
  22. data/app/models/spree/credit_card.rb +14 -15
  23. data/app/models/spree/customer_return.rb +18 -25
  24. data/app/models/spree/gateway/bogus.rb +0 -4
  25. data/app/models/spree/line_item.rb +2 -5
  26. data/app/models/spree/option_type.rb +2 -4
  27. data/app/models/spree/option_value.rb +0 -2
  28. data/app/models/spree/order.rb +74 -134
  29. data/app/models/spree/order/checkout.rb +1 -1
  30. data/app/models/spree/order_contents.rb +9 -8
  31. data/app/models/spree/order_updater.rb +8 -1
  32. data/app/models/spree/payment.rb +13 -23
  33. data/app/models/spree/payment/gateway_options.rb +86 -0
  34. data/app/models/spree/payment/processing.rb +8 -39
  35. data/app/models/spree/payment_method.rb +3 -6
  36. data/app/models/spree/price.rb +2 -6
  37. data/app/models/spree/product.rb +27 -16
  38. data/app/models/spree/product_property.rb +1 -5
  39. data/app/models/spree/promotion.rb +7 -15
  40. data/app/models/spree/promotion/actions/create_adjustment.rb +4 -45
  41. data/app/models/spree/promotion/actions/create_item_adjustments.rb +8 -63
  42. data/app/models/spree/promotion/actions/create_line_items.rb +3 -12
  43. data/app/models/spree/promotion/actions/free_shipping.rb +4 -24
  44. data/app/models/spree/promotion/rules/option_value.rb +49 -0
  45. data/app/models/spree/promotion_action.rb +6 -0
  46. data/app/models/spree/promotion_handler/cart.rb +14 -18
  47. data/app/models/spree/promotion_handler/coupon.rb +1 -1
  48. data/app/models/spree/promotion_rule.rb +0 -1
  49. data/app/models/spree/property.rb +0 -2
  50. data/app/models/spree/refund.rb +0 -15
  51. data/app/models/spree/reimbursement.rb +4 -4
  52. data/app/models/spree/reimbursement_type/credit.rb +1 -1
  53. data/app/models/spree/reimbursement_type/original_payment.rb +1 -1
  54. data/app/models/spree/return_authorization.rb +4 -11
  55. data/app/models/spree/return_item.rb +16 -11
  56. data/app/models/spree/return_item/eligibility_validator/default.rb +2 -0
  57. data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +16 -0
  58. data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +16 -0
  59. data/app/models/spree/shipment.rb +20 -31
  60. data/app/models/spree/shipment_handler.rb +1 -1
  61. data/app/models/spree/shipping_method.rb +12 -13
  62. data/app/models/spree/state.rb +7 -0
  63. data/app/models/spree/state_change.rb +1 -6
  64. data/app/models/spree/stock/availability_validator.rb +9 -10
  65. data/app/models/spree/stock/coordinator.rb +1 -1
  66. data/app/models/spree/stock/estimator.rb +6 -6
  67. data/app/models/spree/stock/quantifier.rb +1 -1
  68. data/app/models/spree/stock_item.rb +1 -7
  69. data/app/models/spree/stock_location.rb +3 -1
  70. data/app/models/spree/stock_movement.rb +1 -8
  71. data/app/models/spree/stock_transfer.rb +11 -5
  72. data/app/models/spree/store.rb +2 -2
  73. data/app/models/spree/tax_rate.rb +30 -55
  74. data/app/models/spree/taxon.rb +8 -8
  75. data/app/models/spree/taxonomy.rb +8 -13
  76. data/app/models/spree/tracker.rb +1 -1
  77. data/app/models/spree/variant.rb +6 -15
  78. data/app/models/spree/zone.rb +43 -9
  79. data/config/initializers/user_class_extensions.rb +0 -12
  80. data/config/locales/en.yml +76 -85
  81. data/config/routes.rb +1 -1
  82. data/db/default/spree/countries.rb +23 -13
  83. data/db/default/spree/states.rb +24 -12
  84. data/db/default/spree/stores.rb +1 -1
  85. data/db/migrate/20120831092320_spree_one_two.rb +36 -36
  86. data/db/migrate/20120831092359_spree_promo_one_two.rb +1 -1
  87. data/db/migrate/20130211190146_create_spree_stock_items.rb +1 -1
  88. data/db/migrate/20130211191120_create_spree_stock_locations.rb +1 -1
  89. data/db/migrate/20130301162924_create_shipping_method_categories.rb +1 -1
  90. data/db/migrate/20130304162240_create_spree_shipping_rates.rb +1 -1
  91. data/db/migrate/20130305143310_create_stock_movements.rb +1 -1
  92. data/db/migrate/20130418125341_create_spree_stock_transfers.rb +1 -1
  93. data/db/migrate/20140205120320_create_spree_payment_capture_events.rb +1 -1
  94. data/db/migrate/20140309024355_create_spree_stores.rb +1 -1
  95. data/db/migrate/20140309033438_create_store_from_preferences.rb +0 -7
  96. data/db/migrate/20140625214618_create_spree_refunds.rb +1 -1
  97. data/db/migrate/20140702140656_create_spree_return_authorization_inventory_unit.rb +1 -1
  98. data/db/migrate/20140713140455_create_spree_return_authorization_reasons.rb +1 -1
  99. data/db/migrate/20140713140527_create_spree_refund_reasons.rb +1 -1
  100. data/db/migrate/20140715182625_create_spree_promotion_categories.rb +1 -1
  101. data/db/migrate/20140718133010_create_spree_customer_returns.rb +1 -1
  102. data/db/migrate/20140725131539_create_spree_reimbursements.rb +1 -1
  103. data/db/migrate/20140731150017_create_spree_reimbursement_types.rb +1 -1
  104. data/db/migrate/20140911173301_add_kind_to_zone.rb +11 -0
  105. data/db/migrate/20141215232040_remove_token_permissions_table.rb +6 -0
  106. data/db/migrate/20141215235502_remove_extra_products_slug_index.rb +5 -0
  107. data/db/migrate/20141217215630_update_product_slug_index.rb +6 -0
  108. data/db/migrate/20141218025915_rename_identifier_to_number_for_payment.rb +5 -0
  109. data/db/migrate/20150121022521_remove_environment_from_payment_method.rb +6 -0
  110. data/db/migrate/20150122145607_add_resellable_to_return_items.rb +5 -0
  111. data/db/migrate/20150122202432_add_code_to_spree_promotion_categories.rb +5 -0
  112. data/db/migrate/20150128032538_remove_environment_from_tracker.rb +6 -0
  113. data/db/migrate/20150128060325_remove_spree_configurations.rb +16 -0
  114. data/lib/generators/spree/dummy/templates/rails/test.rb +1 -1
  115. data/lib/generators/spree/install/templates/config/initializers/spree.rb +4 -0
  116. data/lib/spree/core.rb +2 -12
  117. data/lib/spree/core/controller_helpers/respond_with.rb +8 -18
  118. data/lib/spree/core/engine.rb +1 -7
  119. data/lib/spree/core/routes.rb +1 -1
  120. data/lib/spree/core/version.rb +1 -1
  121. data/lib/spree/money.rb +10 -10
  122. data/lib/spree/permitted_attributes.rb +4 -8
  123. data/lib/spree/testing_support/authorization_helpers.rb +3 -5
  124. data/lib/spree/testing_support/capybara_ext.rb +3 -3
  125. data/lib/spree/testing_support/common_rake.rb +2 -2
  126. data/lib/spree/testing_support/factories/order_factory.rb +3 -13
  127. data/lib/spree/testing_support/factories/payment_method_factory.rb +0 -3
  128. data/lib/spree/testing_support/factories/prototype_factory.rb +5 -0
  129. data/lib/spree/testing_support/factories/return_item_factory.rb +5 -1
  130. data/lib/spree/testing_support/factories/stock_location_factory.rb +3 -3
  131. data/lib/spree/testing_support/factories/tracker_factory.rb +0 -1
  132. data/lib/spree/testing_support/factories/user_factory.rb +1 -1
  133. data/lib/spree/testing_support/factories/zone_factory.rb +8 -0
  134. data/lib/tasks/core.rake +1 -1
  135. data/lib/tasks/email.rake +6 -3
  136. metadata +48 -35
  137. data/app/helpers/spree/checkout_helper.rb +0 -31
  138. data/app/helpers/spree/orders_helper.rb +0 -17
  139. data/app/helpers/spree/store_helper.rb +0 -16
  140. data/app/helpers/spree/taxons_helper.rb +0 -19
  141. data/app/models/concerns/spree/ransackable_attributes.rb +0 -19
  142. data/app/models/friendly_id/slug_decorator.rb +0 -3
  143. data/app/models/spree/billing_integration.rb +0 -21
  144. data/app/models/spree/configuration.rb +0 -5
  145. data/app/models/spree/item_adjustments.rb +0 -82
  146. data/app/models/spree/order_merger.rb +0 -65
  147. data/app/models/spree/order_populator.rb +0 -43
  148. data/app/models/spree/product_scope/scopes.rb +0 -47
  149. data/app/models/spree/variant/scopes.rb +0 -42
  150. data/db/migrate/20150515211137_fix_adjustment_order_id.rb +0 -70
  151. data/db/migrate/20150522181728_add_deleted_at_to_friendly_id_slugs.rb +0 -6
  152. data/db/migrate/20150707204155_enable_acts_as_paranoid_on_calculators.rb +0 -6
  153. data/lib/spree/core/controller_helpers/ssl.rb +0 -60
  154. data/lib/spree/core/permalinks.rb +0 -71
  155. data/lib/spree/testing_support/factories/configuration_factory.rb +0 -6
@@ -1,7 +1,5 @@
1
1
  module Spree
2
2
  class ProductProperty < Spree::Base
3
- acts_as_list scope: :product
4
-
5
3
  belongs_to :product, touch: true, class_name: 'Spree::Product', inverse_of: :product_properties
6
4
  belongs_to :property, class_name: 'Spree::Property', inverse_of: :product_properties
7
5
 
@@ -9,9 +7,7 @@ module Spree
9
7
 
10
8
  validates_with Spree::Validations::DbMaximumLengthValidator, field: :value
11
9
 
12
- default_scope -> { order("#{self.table_name}.position") }
13
-
14
- self.whitelisted_ransackable_attributes = ['value']
10
+ default_scope { order("#{self.table_name}.position") }
15
11
 
16
12
  # virtual attributes for use with AJAX completion stuff
17
13
  def property_name
@@ -32,8 +32,6 @@ module Spree
32
32
 
33
33
  scope :applied, -> { joins("INNER JOIN #{order_join_table} ON #{order_join_table}.promotion_id = #{table_name}.id").uniq }
34
34
 
35
- self.whitelisted_ransackable_attributes = ['code', 'path', 'promotion_category_id']
36
-
37
35
  def self.advertised
38
36
  where(advertise: true)
39
37
  end
@@ -43,8 +41,8 @@ module Spree
43
41
  end
44
42
 
45
43
  def self.active
46
- where('spree_promotions.starts_at IS NULL OR spree_promotions.starts_at < ?', Time.now).
47
- where('spree_promotions.expires_at IS NULL OR spree_promotions.expires_at > ?', Time.now)
44
+ where('starts_at IS NULL OR starts_at < ?', Time.now).
45
+ where('expires_at IS NULL OR expires_at > ?', Time.now)
48
46
  end
49
47
 
50
48
  def self.order_activatable?(order)
@@ -93,28 +91,23 @@ module Spree
93
91
  # Promotions without rules are eligible by default.
94
92
  return [] if rules.none?
95
93
  eligible = lambda { |r| r.eligible?(promotable, options) }
96
- specific_rules = rules.select { |rule| rule.applicable?(promotable) }
94
+ specific_rules = rules.for(promotable)
97
95
  return [] if specific_rules.none?
98
96
 
99
- rule_eligibility = Hash[specific_rules.map do |rule|
100
- [rule, rule.eligible?(promotable, options)]
101
- end]
102
-
103
97
  if match_all?
104
98
  # If there are rules for this promotion, but no rules for this
105
99
  # particular promotable, then the promotion is ineligible by default.
106
- unless rule_eligibility.values.all?
100
+ unless specific_rules.all?(&eligible)
107
101
  @eligibility_errors = specific_rules.map(&:eligibility_errors).detect(&:present?)
108
102
  return nil
109
103
  end
110
104
  specific_rules
111
105
  else
112
- unless rule_eligibility.values.any?
106
+ unless specific_rules.any?(&eligible)
113
107
  @eligibility_errors = specific_rules.map(&:eligibility_errors).detect(&:present?)
114
108
  return nil
115
109
  end
116
-
117
- [rule_eligibility.detect { |_, eligibility| eligibility }.first]
110
+ specific_rules.select(&eligible)
118
111
  end
119
112
  end
120
113
 
@@ -127,8 +120,7 @@ module Spree
127
120
  end
128
121
 
129
122
  def adjusted_credits_count(promotable)
130
- adjustments = promotable.is_a?(Order) ? promotable.all_adjustments : promotable.adjustments
131
- credits_count - adjustments.promotion.where(:source_id => actions.pluck(:id)).count
123
+ credits_count - promotable.adjustments.promotion.where(:source_id => actions.pluck(:id)).count
132
124
  end
133
125
 
134
126
  def credits
@@ -5,57 +5,16 @@ module Spree
5
5
  include Spree::CalculatedAdjustments
6
6
  include Spree::AdjustmentSource
7
7
 
8
- has_many :adjustments, as: :source
8
+ before_validation -> { self.calculator ||= Calculator::FlatPercentItemTotal.new }
9
9
 
10
- delegate :eligible?, to: :promotion
11
-
12
- before_validation :ensure_action_has_calculator
13
- before_destroy :deals_with_adjustments_for_deleted_source
14
-
15
- # Creates the adjustment related to a promotion for the order passed
16
- # through options hash
17
- #
18
- # Returns `true` if an adjustment is applied to an order,
19
- # `false` if the promotion has already been applied.
20
10
  def perform(options = {})
21
11
  order = options[:order]
22
- return if promotion_credit_exists?(order)
23
-
24
- amount = compute_amount(order)
25
- return if amount == 0
26
- Spree::Adjustment.create!(
27
- amount: amount,
28
- order: order,
29
- adjustable: order,
30
- source: self,
31
- label: "#{Spree.t(:promotion)} (#{promotion.name})"
32
- )
33
- true
12
+ create_unique_adjustment(order, order)
34
13
  end
35
14
 
36
- # Ensure a negative amount which does not exceed the sum of the order's
37
- # item_total and ship_total
38
- def compute_amount(calculable)
39
- amount = self.calculator.compute(calculable).to_f.abs
40
- [(calculable.item_total + calculable.ship_total), amount].min * -1
15
+ def compute_amount(order)
16
+ [(order.item_total + order.ship_total), compute(order)].min * -1
41
17
  end
42
-
43
- private
44
- # Tells us if there if the specified promotion is already associated with the line item
45
- # regardless of whether or not its currently eligible. Useful because generally
46
- # you would only want a promotion action to apply to order no more than once.
47
- #
48
- # Receives an adjustment +source+ (here a PromotionAction object) and tells
49
- # if the order has adjustments from that already
50
- def promotion_credit_exists?(adjustable)
51
- self.adjustments.where(:adjustable_id => adjustable.id).exists?
52
- end
53
-
54
- def ensure_action_has_calculator
55
- return if self.calculator
56
- self.calculator = Calculator::FlatPercentItemTotal.new
57
- end
58
-
59
18
  end
60
19
  end
61
20
  end
@@ -5,74 +5,19 @@ module Spree
5
5
  include Spree::CalculatedAdjustments
6
6
  include Spree::AdjustmentSource
7
7
 
8
- has_many :adjustments, as: :source
8
+ before_validation -> { self.calculator ||= Calculator::PercentOnLineItem.new }
9
9
 
10
- delegate :eligible?, to: :promotion
11
-
12
- before_validation :ensure_action_has_calculator
13
- before_destroy :deals_with_adjustments_for_deleted_source
14
-
15
- def perform(payload = {})
16
- order = payload[:order]
17
- promotion = payload[:promotion]
18
-
19
- result = false
20
-
21
- line_items_to_adjust(promotion, order).each do |line_item|
22
- current_result = self.create_adjustment(line_item, order)
23
- result ||= current_result
10
+ def perform(options = {})
11
+ order, promotion = options[:order], options[:promotion]
12
+ create_unique_adjustments(order, order.line_items) do |line_item|
13
+ promotion.line_item_actionable?(order, line_item)
24
14
  end
25
- return result
26
15
  end
27
16
 
28
- def create_adjustment(adjustable, order)
29
- amount = self.compute_amount(adjustable)
30
- return if amount == 0
31
- self.adjustments.create!(
32
- amount: amount,
33
- adjustable: adjustable,
34
- order: order,
35
- label: "#{Spree.t(:promotion)} (#{promotion.name})",
36
- )
37
- true
17
+ def compute_amount(line_item)
18
+ return 0 unless promotion.line_item_actionable?(line_item.order, line_item)
19
+ [line_item.amount, compute(line_item)].min * -1
38
20
  end
39
-
40
- # Ensure a negative amount which does not exceed the sum of the order's
41
- # item_total and ship_total
42
- def compute_amount(adjustable)
43
- order = adjustable.is_a?(Order) ? adjustable : adjustable.order
44
- return 0 unless promotion.line_item_actionable?(order, adjustable)
45
- promotion_amount = self.calculator.compute(adjustable).to_f.abs
46
-
47
- [adjustable.amount, promotion_amount].min * -1
48
- end
49
-
50
- private
51
- # Tells us if there if the specified promotion is already associated with the line item
52
- # regardless of whether or not its currently eligible. Useful because generally
53
- # you would only want a promotion action to apply to line item no more than once.
54
- #
55
- # Receives an adjustment +source+ (here a PromotionAction object) and tells
56
- # if the order has adjustments from that already
57
- def promotion_credit_exists?(adjustable)
58
- self.adjustments.where(:adjustable_id => adjustable.id).exists?
59
- end
60
-
61
- def ensure_action_has_calculator
62
- return if self.calculator
63
- self.calculator = Calculator::PercentOnLineItem.new
64
- end
65
-
66
- def line_items_to_adjust(promotion, order)
67
- excluded_ids = self.adjustments.
68
- where(adjustable_id: order.line_items.pluck(:id), adjustable_type: 'Spree::LineItem').
69
- pluck(:adjustable_id)
70
-
71
- order.line_items.where.not(id: excluded_ids).select do |line_item|
72
- promotion.line_item_actionable? order, line_item
73
- end
74
- end
75
-
76
21
  end
77
22
  end
78
23
  end
@@ -39,23 +39,14 @@ module Spree
39
39
  order = options[:order]
40
40
  return unless self.eligible? order
41
41
 
42
- action_taken = false
43
42
  promotion_action_line_items.each do |item|
44
43
  current_quantity = order.quantity_of(item.variant)
45
- if current_quantity < item.quantity && item_available?(item)
46
- line_item = order.contents.add(item.variant, item.quantity - current_quantity)
47
- action_taken = true if line_item.try(:valid?)
44
+ if current_quantity < item.quantity
45
+ order.contents.add(item.variant, item.quantity - current_quantity)
48
46
  end
49
47
  end
50
- action_taken
48
+ true
51
49
  end
52
-
53
- # Checks that there's enough stock to add the line item to the order
54
- def item_available?(item)
55
- quantifier = Spree::Stock::Quantifier.new(item.variant)
56
- quantifier.can_supply? item.quantity
57
- end
58
-
59
50
  end
60
51
  end
61
52
  end
@@ -2,37 +2,17 @@ module Spree
2
2
  class Promotion
3
3
  module Actions
4
4
  class FreeShipping < Spree::PromotionAction
5
+ include Spree::AdjustmentSource
6
+
5
7
  def perform(payload={})
6
8
  order = payload[:order]
7
- results = order.shipments.map do |shipment|
8
- return false if promotion_credit_exists?(shipment)
9
- shipment.adjustments.create!(
10
- order: shipment.order,
11
- amount: compute_amount(shipment),
12
- source: self,
13
- label: label,
14
- )
15
- true
16
- end
17
- # Did we actually end up applying any adjustments?
18
- # If so, then this action should be classed as 'successful'
19
- results.any? { |r| r == true }
20
- end
21
-
22
- def label
23
- "#{Spree.t(:promotion)} (#{promotion.name})"
9
+ create_unique_adjustments(order, order.shipments)
24
10
  end
25
11
 
26
12
  def compute_amount(shipment)
27
13
  shipment.cost * -1
28
14
  end
29
-
30
- private
31
-
32
- def promotion_credit_exists?(shipment)
33
- shipment.adjustments.where(:source_id => self.id).exists?
34
- end
35
15
  end
36
16
  end
37
17
  end
38
- end
18
+ end
@@ -0,0 +1,49 @@
1
+ module Spree
2
+ class Promotion
3
+ module Rules
4
+ class OptionValue < PromotionRule
5
+ MATCH_POLICIES = %w(any)
6
+ preference :match_policy, :string, default: MATCH_POLICIES.first
7
+ preference :eligible_values, :hash
8
+
9
+ def applicable?(promotable)
10
+ promotable.is_a?(Spree::Order)
11
+ end
12
+
13
+ def eligible?(promotable, _options = {})
14
+ case preferred_match_policy
15
+ when 'any'
16
+ promotable.line_items.any? { |item| actionable?(item) }
17
+ end
18
+ end
19
+
20
+ def actionable?(line_item)
21
+ pid = line_item.product.id
22
+ ovids = line_item.variant.option_values.pluck(:id)
23
+
24
+ product_ids.include?(pid) && (value_ids(pid) - ovids).empty?
25
+ end
26
+
27
+ def preferred_eligible_values_with_numerification
28
+ values = preferred_eligible_values_without_numerification || {}
29
+ Hash[values.keys.map(&:to_i).zip(
30
+ values.values.map do |v|
31
+ (v.is_a?(Array) ? v : v.split(",")).map(&:to_i)
32
+ end
33
+ )]
34
+ end
35
+ alias_method_chain :preferred_eligible_values, :numerification
36
+
37
+ private
38
+
39
+ def product_ids
40
+ preferred_eligible_values.keys
41
+ end
42
+
43
+ def value_ids(product_id)
44
+ preferred_eligible_values[product_id]
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -15,5 +15,11 @@ module Spree
15
15
  def perform(options = {})
16
16
  raise 'perform should be implemented in a sub-class of PromotionAction'
17
17
  end
18
+
19
+ protected
20
+
21
+ def label(amount)
22
+ "#{Spree.t(:promotion)} (#{promotion.name})"
23
+ end
18
24
  end
19
25
  end
@@ -29,26 +29,22 @@ module Spree
29
29
  end
30
30
 
31
31
  private
32
+ def promotions
33
+ promo_table = Promotion.arel_table
34
+ join_table = Arel::Table.new(:spree_orders_promotions)
32
35
 
33
- def promotions
34
- # AR cannot bind raw ASTs to prepared statements. There always must be a manager around.
35
- # Also Postgresql requires an aliased table for `SELECT * FROM (subexpression) AS alias`.
36
- # And Sqlite3 cannot work on outher parenthesis from `(left UNION right)`.
37
- # So this construct makes both happy.
38
- select = Arel::SelectManager.new(
39
- Promotion,
40
- Promotion.arel_table.create_table_alias(
41
- order.promotions.active.union(Promotion.active.where(code: nil, path: nil)),
42
- Promotion.table_name
43
- ),
44
- )
45
- select.project(Arel.star)
36
+ join_condition = promo_table.join(join_table, Arel::Nodes::OuterJoin).on(
37
+ promo_table[:id].eq(join_table[:promotion_id])
38
+ ).join_sources
46
39
 
47
- Promotion.find_by_sql(
48
- select,
49
- order.promotions.bind_values
50
- )
51
- end
40
+ Promotion.active.includes(:promotion_rules).
41
+ joins(join_condition).
42
+ where(
43
+ promo_table[:code].eq(nil).and(
44
+ promo_table[:path].eq(nil)
45
+ ).or(join_table[:order_id].eq(order.id))
46
+ ).distinct
47
+ end
52
48
  end
53
49
  end
54
50
  end
@@ -86,7 +86,7 @@ module Spree
86
86
  }
87
87
 
88
88
  # Check for applied adjustments.
89
- discount = order.line_item_adjustments.promotion.eligible.detect(&detector)
89
+ discount = order.line_item_adjustments.promotion.detect(&detector)
90
90
  discount ||= order.shipment_adjustments.promotion.detect(&detector)
91
91
  discount ||= order.adjustments.promotion.detect(&detector)
92
92
 
@@ -5,7 +5,6 @@ module Spree
5
5
 
6
6
  scope :of_type, ->(t) { where(type: t) }
7
7
 
8
- validate :promotion, presence: true
9
8
  validate :unique_per_promotion, on: :create
10
9
 
11
10
  def self.for(promotable)
@@ -11,8 +11,6 @@ module Spree
11
11
 
12
12
  after_touch :touch_all_products
13
13
 
14
- self.whitelisted_ransackable_attributes = ['presentation']
15
-
16
14
  private
17
15
 
18
16
  def touch_all_products
@@ -11,7 +11,6 @@ module Spree
11
11
  validates :transaction_id, presence: true, on: :update # can't require this on create because the before_create needs to run first
12
12
  validates :amount, presence: true, numericality: {greater_than: 0}
13
13
 
14
- validate :check_payment_environment, on: :create, if: :payment
15
14
  validate :amount_is_less_than_or_equal_to_allowed_amount, on: :create
16
15
 
17
16
  after_create :perform!
@@ -47,7 +46,6 @@ module Spree
47
46
 
48
47
  self.transaction_id = @response.authorization
49
48
  update_columns(transaction_id: transaction_id)
50
- update_order
51
49
  end
52
50
 
53
51
  # return an activemerchant response object if successful or else raise an error
@@ -70,15 +68,6 @@ module Spree
70
68
  raise Core::GatewayError.new(Spree.t(:unable_to_connect_to_gateway))
71
69
  end
72
70
 
73
- # Saftey check to make sure we're not accidentally performing operations on a live gateway.
74
- # Ex. When testing in staging environment with a copy of production data.
75
- def check_payment_environment
76
- if payment.payment_method.environment != Rails.env
77
- message = Spree.t(:gateway_config_unavailable) + " - #{Rails.env}"
78
- errors.add(:base, message)
79
- end
80
- end
81
-
82
71
  def create_log_entry
83
72
  log_entries.create!(details: @response.to_yaml)
84
73
  end
@@ -88,9 +77,5 @@ module Spree
88
77
  errors.add(:amount, :greater_than_allowed)
89
78
  end
90
79
  end
91
-
92
- def update_order
93
- payment.order.updater.update
94
- end
95
80
  end
96
81
  end