solidus_core 2.0.3 → 2.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of solidus_core might be problematic. Click here for more details.

Files changed (187) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +62 -3
  3. data/app/assets/javascripts/spree.js.coffee.erb +4 -1
  4. data/app/helpers/spree/base_helper.rb +7 -48
  5. data/app/models/spree/address.rb +5 -1
  6. data/app/models/spree/adjustment.rb +3 -3
  7. data/app/models/spree/app_configuration.rb +13 -0
  8. data/app/models/spree/calculator.rb +3 -2
  9. data/app/models/spree/calculator/default_tax.rb +6 -10
  10. data/app/models/spree/calculator/flat_percent_item_total.rb +0 -4
  11. data/app/models/spree/calculator/flat_rate.rb +0 -4
  12. data/app/models/spree/calculator/flexi_rate.rb +0 -4
  13. data/app/models/spree/calculator/free_shipping.rb +0 -3
  14. data/app/models/spree/calculator/percent_on_line_item.rb +0 -4
  15. data/app/models/spree/calculator/percent_per_item.rb +0 -4
  16. data/app/models/spree/calculator/price_sack.rb +0 -4
  17. data/app/models/spree/calculator/returns/default_refund_amount.rb +0 -3
  18. data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +0 -4
  19. data/app/models/spree/calculator/shipping/flat_rate.rb +0 -4
  20. data/app/models/spree/calculator/shipping/flexi_rate.rb +0 -4
  21. data/app/models/spree/calculator/shipping/per_item.rb +0 -4
  22. data/app/models/spree/calculator/shipping/price_sack.rb +0 -4
  23. data/app/models/spree/calculator/tiered_flat_rate.rb +0 -4
  24. data/app/models/spree/calculator/tiered_percent.rb +0 -4
  25. data/app/models/spree/credit_card.rb +27 -14
  26. data/app/models/spree/gateway.rb +4 -0
  27. data/app/models/spree/inventory_unit.rb +2 -0
  28. data/app/models/spree/line_item.rb +31 -26
  29. data/app/models/spree/option_type.rb +0 -3
  30. data/app/models/spree/order.rb +28 -31
  31. data/app/models/spree/order/checkout.rb +0 -2
  32. data/app/models/spree/order_contents.rb +0 -45
  33. data/app/models/spree/order_merger.rb +6 -6
  34. data/app/models/spree/order_update_attributes.rb +0 -2
  35. data/app/models/spree/order_updater.rb +91 -13
  36. data/app/models/spree/payment.rb +9 -2
  37. data/app/models/spree/payment/processing.rb +15 -9
  38. data/app/models/spree/payment_method.rb +48 -5
  39. data/app/models/spree/price.rb +7 -9
  40. data/app/models/spree/product.rb +1 -25
  41. data/app/models/spree/promotion.rb +22 -14
  42. data/app/models/spree/promotion/actions/create_adjustment.rb +12 -1
  43. data/app/models/spree/promotion/actions/create_item_adjustments.rb +15 -1
  44. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +5 -3
  45. data/app/models/spree/promotion/actions/free_shipping.rb +14 -0
  46. data/app/models/spree/promotion/rules/taxon.rb +7 -2
  47. data/app/models/spree/promotion/rules/user_role.rb +43 -0
  48. data/app/models/spree/promotion_action.rb +19 -2
  49. data/app/models/spree/promotion_handler/coupon.rb +1 -4
  50. data/app/models/spree/promotion_handler/free_shipping.rb +22 -17
  51. data/app/models/spree/promotion_rule_role.rb +6 -0
  52. data/app/models/spree/property.rb +0 -3
  53. data/app/models/spree/return_authorization.rb +2 -0
  54. data/app/models/spree/shipment.rb +5 -21
  55. data/app/models/spree/shipping_method.rb +23 -2
  56. data/app/models/spree/shipping_rate.rb +3 -0
  57. data/app/models/spree/stock/estimator.rb +1 -1
  58. data/app/models/spree/stock_location.rb +3 -0
  59. data/app/models/spree/store.rb +7 -0
  60. data/app/models/spree/tax/item_adjuster.rb +27 -12
  61. data/app/models/spree/tax/order_adjuster.rb +2 -5
  62. data/app/models/spree/tax/tax_helpers.rb +4 -8
  63. data/app/models/spree/tax_rate.rb +1 -15
  64. data/app/models/spree/taxon.rb +0 -3
  65. data/app/models/spree/transfer_item.rb +1 -1
  66. data/app/models/spree/user_class_handle.rb +14 -9
  67. data/app/models/spree/variant/pricing_options.rb +1 -1
  68. data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +1 -1
  69. data/app/models/spree/zone.rb +20 -13
  70. data/config/locales/en.yml +144 -62
  71. data/db/migrate/20120831092320_spree_one_two.rb +0 -7
  72. data/db/migrate/20150723224133_remove_unnecessary_indexes.rb +0 -2
  73. data/db/migrate/20160924135758_remove_is_default_from_prices.rb +5 -0
  74. data/db/migrate/20161009141333_remove_currency_from_line_items.rb +5 -0
  75. data/db/migrate/20161014221052_add_available_to_columns_and_remove_display_on_from_payment_methods.rb +28 -0
  76. data/db/migrate/20161123154034_add_available_to_users_and_remove_display_on_from_shipping_methods.rb +20 -0
  77. data/lib/generators/spree/custom_user/templates/authentication_helpers.rb.tt +4 -0
  78. data/lib/generators/spree/dummy/dummy_generator.rb +0 -2
  79. data/lib/spree/core.rb +0 -5
  80. data/lib/spree/core/controller_helpers/pricing.rb +2 -1
  81. data/lib/spree/core/engine.rb +14 -0
  82. data/lib/spree/core/version.rb +1 -1
  83. data/lib/spree/deprecation.rb +1 -1
  84. data/lib/spree/localized_number.rb +3 -2
  85. data/lib/spree/permission_sets/configuration_display.rb +0 -1
  86. data/lib/spree/permission_sets/configuration_management.rb +0 -1
  87. data/lib/spree/permission_sets/product_display.rb +0 -1
  88. data/lib/spree/permission_sets/product_management.rb +0 -1
  89. data/lib/spree/permission_sets/user_management.rb +2 -4
  90. data/lib/spree/permitted_attributes.rb +3 -2
  91. data/lib/spree/testing_support/capybara_ext.rb +0 -12
  92. data/lib/spree/testing_support/factories/address_factory.rb +1 -1
  93. data/lib/spree/testing_support/factories/line_item_factory.rb +0 -1
  94. data/lib/spree/testing_support/factories/payment_factory.rb +4 -0
  95. data/lib/spree/testing_support/factories/payment_method_factory.rb +8 -1
  96. data/lib/spree/testing_support/factories/user_factory.rb +2 -2
  97. data/solidus_core.gemspec +4 -3
  98. data/spec/helpers/base_helper_spec.rb +0 -40
  99. data/spec/lib/spree/core/controller_helpers/pricing_spec.rb +16 -0
  100. data/spec/lib/spree/core/importer/order_spec.rb +27 -18
  101. data/spec/lib/spree/core/price_migrator_spec.rb +3 -1
  102. data/spec/lib/spree/core/testing_support/factories/order_factory_spec.rb +16 -0
  103. data/spec/lib/spree/core/unreturned_item_charger_spec.rb +0 -2
  104. data/spec/lib/tasks/exchanges_spec.rb +4 -2
  105. data/spec/lib/tasks/migrations/create_vat_prices_spec.rb +5 -3
  106. data/spec/models/spree/adjustment_spec.rb +136 -0
  107. data/spec/models/spree/calculator/default_tax_spec.rb +13 -7
  108. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +3 -0
  109. data/spec/models/spree/calculator/flat_rate_spec.rb +3 -0
  110. data/spec/models/spree/calculator/flexi_rate_spec.rb +3 -0
  111. data/spec/models/spree/calculator/free_shipping_spec.rb +6 -0
  112. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +9 -4
  113. data/spec/models/spree/calculator/percent_per_item_spec.rb +10 -0
  114. data/spec/models/spree/calculator/price_sack_spec.rb +3 -0
  115. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +3 -0
  116. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +3 -0
  117. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +3 -0
  118. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +3 -0
  119. data/spec/models/spree/calculator/shipping/per_item_spec.rb +3 -0
  120. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +4 -1
  121. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +3 -0
  122. data/spec/models/spree/calculator/tiered_percent_spec.rb +3 -0
  123. data/spec/models/spree/credit_card_spec.rb +27 -1
  124. data/spec/models/spree/line_item_spec.rb +58 -65
  125. data/spec/models/spree/order/checkout_spec.rb +2 -1
  126. data/spec/models/spree/order/payment_spec.rb +9 -10
  127. data/spec/models/spree/order/tax_spec.rb +22 -7
  128. data/spec/models/spree/order/updating_spec.rb +1 -3
  129. data/spec/models/spree/order_cancellations_spec.rb +6 -4
  130. data/spec/models/spree/order_contents_spec.rb +34 -50
  131. data/spec/models/spree/order_inventory_spec.rb +3 -5
  132. data/spec/models/spree/order_merger_spec.rb +20 -0
  133. data/spec/models/spree/order_spec.rb +28 -64
  134. data/spec/models/spree/order_update_attributes_spec.rb +1 -5
  135. data/spec/models/spree/order_updater_spec.rb +251 -0
  136. data/spec/models/spree/payment_method_spec.rb +178 -28
  137. data/spec/models/spree/payment_spec.rb +35 -19
  138. data/spec/models/spree/permission_sets/configuration_display.rb +0 -4
  139. data/spec/models/spree/permission_sets/configuration_management_spec.rb +0 -2
  140. data/spec/models/spree/permission_sets/product_display_spec.rb +0 -4
  141. data/spec/models/spree/permission_sets/product_management_spec.rb +0 -2
  142. data/spec/models/spree/permission_sets/user_management_spec.rb +9 -2
  143. data/spec/models/spree/price_spec.rb +16 -1
  144. data/spec/models/spree/product_spec.rb +0 -75
  145. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +20 -0
  146. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +39 -15
  147. data/spec/models/spree/promotion/actions/create_quantity_adjustments_spec.rb +203 -22
  148. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +22 -3
  149. data/spec/models/spree/promotion/rules/taxon_spec.rb +26 -0
  150. data/spec/models/spree/promotion/rules/user_role_spec.rb +86 -0
  151. data/spec/models/spree/promotion_action_spec.rb +38 -0
  152. data/spec/models/spree/promotion_handler/coupon_spec.rb +36 -33
  153. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +21 -22
  154. data/spec/models/spree/promotion_spec.rb +46 -6
  155. data/spec/models/spree/reimbursement_spec.rb +1 -1
  156. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +2 -2
  157. data/spec/models/spree/shipment_spec.rb +68 -50
  158. data/spec/models/spree/shipping_method_spec.rb +41 -0
  159. data/spec/models/spree/shipping_rate_spec.rb +9 -3
  160. data/spec/models/spree/stock/estimator_spec.rb +4 -2
  161. data/spec/models/spree/store_credit_spec.rb +3 -3
  162. data/spec/models/spree/tax/item_adjuster_spec.rb +31 -21
  163. data/spec/models/spree/tax/order_adjuster_spec.rb +6 -10
  164. data/spec/models/spree/tax/taxation_integration_spec.rb +19 -0
  165. data/spec/models/spree/tax_rate_spec.rb +5 -26
  166. data/spec/models/spree/transfer_item_spec.rb +11 -0
  167. data/spec/models/spree/variant/pricing_options_spec.rb +7 -17
  168. data/spec/models/spree/variant_spec.rb +2 -4
  169. data/spec/models/spree/zone_spec.rb +60 -20
  170. data/spec/shared_examples/calculator_shared_examples.rb +8 -0
  171. metadata +19 -24
  172. data/app/models/spree/item_adjustments.rb +0 -89
  173. data/app/models/spree/option_type_prototype.rb +0 -6
  174. data/app/models/spree/property_prototype.rb +0 -6
  175. data/app/models/spree/prototype.rb +0 -14
  176. data/app/models/spree/prototype_taxon.rb +0 -6
  177. data/app/models/spree/tracker.rb +0 -8
  178. data/db/migrate/20150128032538_remove_environment_from_tracker.rb +0 -6
  179. data/lib/generators/spree/dummy/templates/initializers/custom_user.rb +0 -1
  180. data/lib/spree/core/delegate_belongs_to.rb +0 -94
  181. data/lib/spree/testing_support/factories/prototype_factory.rb +0 -8
  182. data/lib/spree/testing_support/factories/tracker_factory.rb +0 -6
  183. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +0 -24
  184. data/spec/lib/spree/core/testing_support/factories/prototype_factory_spec.rb +0 -12
  185. data/spec/lib/spree/core/testing_support/factories/tracker_factory_spec.rb +0 -12
  186. data/spec/models/spree/item_adjustments_spec.rb +0 -306
  187. data/spec/models/spree/tracker_spec.rb +0 -21
@@ -26,7 +26,7 @@ module Spree
26
26
  #
27
27
  # The line items from `other_order` will be merged in to the `order` for
28
28
  # this OrderMerger object. If the line items are for the same variant, it
29
- # will the quantity of the incoming line item to the existing line item.
29
+ # will add the quantity of the incoming line item to the existing line item.
30
30
  # Otherwise, it will assign the line item to the new order.
31
31
  #
32
32
  # After the orders have been merged the `other_order` will be destroyed.
@@ -46,11 +46,11 @@ module Spree
46
46
  # specified, the order user association will not be changed.
47
47
  # @return [void]
48
48
  def merge!(other_order, user = nil)
49
- other_order.line_items.each do |other_order_line_item|
50
- next unless other_order_line_item.currency == order.currency
51
-
52
- current_line_item = find_matching_line_item(other_order_line_item)
53
- handle_merge(current_line_item, other_order_line_item)
49
+ if other_order.currency == order.currency
50
+ other_order.line_items.each do |other_order_line_item|
51
+ current_line_item = find_matching_line_item(other_order_line_item)
52
+ handle_merge(current_line_item, other_order_line_item)
53
+ end
54
54
  end
55
55
 
56
56
  set_user(user)
@@ -14,8 +14,6 @@ module Spree
14
14
  # Assign the attributes to the order and save the order
15
15
  # @return true if saved, otherwise false and errors will be set on the order
16
16
  def apply
17
- order.validate_payments_attributes(@payments_attributes)
18
-
19
17
  assign_order_attributes
20
18
  assign_payments_attributes
21
19
 
@@ -15,27 +15,39 @@ module Spree
15
15
  # object with callbacks (otherwise you will end up in an infinite recursion as the
16
16
  # associations try to save and then in turn try to call +update!+ again.)
17
17
  def update
18
- update_item_count
19
- update_totals
20
- if order.completed?
21
- update_payment_state
22
- update_shipments
23
- update_shipment_state
18
+ @order.transaction do
19
+ update_item_count
20
+ update_totals
21
+ if order.completed?
22
+ update_payment_state
23
+ update_shipments
24
+ update_shipment_state
25
+ end
26
+ run_hooks
27
+ persist_totals
24
28
  end
25
- run_hooks
26
- persist_totals
27
29
  end
28
30
 
29
31
  def run_hooks
30
32
  update_hooks.each { |hook| order.send hook }
31
33
  end
32
34
 
35
+ # This will update and select the best promotion adjustment, update tax
36
+ # adjustments, update cancellation adjustments, and then update the total
37
+ # fields (promo_total, included_tax_total, additional_tax_total, and
38
+ # adjustment_total) on the item.
39
+ # @return [void]
33
40
  def recalculate_adjustments
34
- adjustables = [*line_items, *shipments, order]
35
-
36
- adjustables.each do |adjustable|
37
- Spree::ItemAdjustments.new(adjustable).update
38
- end
41
+ # Promotion adjustments must be applied first, then tax adjustments.
42
+ # This fits the criteria for VAT tax as outlined here:
43
+ # http://www.hmrc.gov.uk/vat/managing/charging/discounts-etc.htm#1
44
+ # It also fits the criteria for sales tax as outlined here:
45
+ # http://www.boe.ca.gov/formspubs/pub113/
46
+ update_item_promotions
47
+ update_order_promotions
48
+ update_taxes
49
+ update_cancellations
50
+ update_item_totals
39
51
  end
40
52
 
41
53
  # Updates the following Order total values:
@@ -164,5 +176,71 @@ module Spree
164
176
  def round_money(n)
165
177
  (n * 100).round / 100.0
166
178
  end
179
+
180
+ def update_item_promotions
181
+ [*line_items, *shipments].each do |item|
182
+ promotion_adjustments = item.adjustments.select(&:promotion?)
183
+
184
+ promotion_adjustments.each(&:update!)
185
+ Spree::Config.promotion_chooser_class.new(promotion_adjustments).update
186
+
187
+ item.promo_total = promotion_adjustments.select(&:eligible?).sum(&:amount)
188
+ end
189
+ end
190
+
191
+ # Update and select the best promotion adjustment for the order.
192
+ # We don't update the order.promo_total yet. Order totals are updated later
193
+ # in #update_adjustment_total since they include the totals from the order's
194
+ # line items and/or shipments.
195
+ def update_order_promotions
196
+ promotion_adjustments = order.adjustments.select(&:promotion?)
197
+ promotion_adjustments.each(&:update!)
198
+ Spree::Config.promotion_chooser_class.new(promotion_adjustments).update
199
+ end
200
+
201
+ def update_taxes
202
+ Spree::Config.tax_adjuster_class.new(order).adjust!
203
+
204
+ [*line_items, *shipments].each do |item|
205
+ tax_adjustments = item.adjustments.select(&:tax?)
206
+ # Tax adjustments come in not one but *two* exciting flavours:
207
+ # Included & additional
208
+
209
+ # Included tax adjustments are those which are included in the price.
210
+ # These ones should not affect the eventual total price.
211
+ #
212
+ # Additional tax adjustments are the opposite, affecting the final total.
213
+ item.included_tax_total = tax_adjustments.select(&:included?).sum(&:amount)
214
+ item.additional_tax_total = tax_adjustments.reject(&:included?).sum(&:amount)
215
+ end
216
+ end
217
+
218
+ def update_cancellations
219
+ line_items.each do |line_item|
220
+ line_item.adjustments.select(&:cancellation?).each(&:update!)
221
+ end
222
+ end
223
+
224
+ def update_item_totals
225
+ [*line_items, *shipments].each do |item|
226
+ # The cancellation_total isn't persisted anywhere but is included in
227
+ # the adjustment_total
228
+ item_cancellation_total = item.adjustments.select(&:cancellation?).sum(&:amount)
229
+
230
+ item.adjustment_total = item.promo_total +
231
+ item.additional_tax_total +
232
+ item_cancellation_total
233
+
234
+ if item.changed?
235
+ item.update_columns(
236
+ promo_total: item.promo_total,
237
+ included_tax_total: item.included_tax_total,
238
+ additional_tax_total: item.additional_tax_total,
239
+ adjustment_total: item.adjustment_total,
240
+ updated_at: Time.current,
241
+ )
242
+ end
243
+ end
244
+ end
167
245
  end
168
246
  end
@@ -1,4 +1,8 @@
1
1
  module Spree
2
+ # Manage and process a payment for an order, from a specific
3
+ # source (e.g. `Spree::CreditCard`) using a specific payment method (e.g
4
+ # `Solidus::Gateway::Braintree`).
5
+ #
2
6
  class Payment < Spree::Base
3
7
  include Spree::Payment::Processing
4
8
 
@@ -39,7 +43,6 @@ module Spree
39
43
 
40
44
  validates :amount, numericality: true
41
45
  validates :source, presence: true, if: :source_required?
42
- validates :payment_method, presence: true
43
46
 
44
47
  default_scope -> { order(:created_at) }
45
48
 
@@ -249,7 +252,11 @@ WARN
249
252
 
250
253
  def invalidate_old_payments
251
254
  if !store_credit? && !['invalid', 'failed'].include?(state)
252
- order.payments.checkout.where(payment_method: payment_method).where("id != ?", id).each(&:invalidate!)
255
+ order.payments.select do |payment|
256
+ payment.state == 'checkout' &&
257
+ payment.payment_method_id == payment_method.try!(:id) &&
258
+ payment.id != id
259
+ end.each(&:invalidate!)
253
260
  end
254
261
  end
255
262
 
@@ -85,15 +85,21 @@ module Spree
85
85
 
86
86
  def gateway_options
87
87
  order.reload
88
- options = { email: order.email,
89
- customer: order.email,
90
- customer_id: order.user_id,
91
- ip: order.last_ip_address,
92
- # Need to pass in a unique identifier here to make some
93
- # payment gateways happy.
94
- #
95
- # For more information, please see Spree::Payment#set_unique_identifier
96
- order_id: gateway_order_id }
88
+ options = {
89
+ email: order.email,
90
+ customer: order.email,
91
+ customer_id: order.user_id,
92
+ ip: order.last_ip_address,
93
+ # Need to pass in a unique identifier here to make some
94
+ # payment gateways happy.
95
+ #
96
+ # For more information, please see Spree::Payment#set_unique_identifier
97
+ order_id: gateway_order_id,
98
+ # The originator is passed to options used by the payment method.
99
+ # One example of a place that it is used is in:
100
+ # app/models/spree/payment_method/store_credit.rb
101
+ originator: self
102
+ }
97
103
 
98
104
  options[:shipping] = order.ship_total * 100
99
105
  options[:tax] = order.additional_tax_total * 100
@@ -1,4 +1,6 @@
1
1
  module Spree
2
+ # An abstract class which is implemented most commonly as a `Spree::Gateway`.
3
+ #
2
4
  class PaymentMethod < Spree::Base
3
5
  acts_as_paranoid
4
6
  acts_as_list
@@ -12,6 +14,10 @@ module Spree
12
14
  has_many :stores, through: :store_payment_methods
13
15
 
14
16
  scope :ordered_by_position, -> { order(:position) }
17
+ scope :active, -> { where(active: true) }
18
+ scope :available_to_users, -> { where(available_to_users: true) }
19
+ scope :available_to_admin, -> { where(available_to_admin: true) }
20
+ scope :available_to_store, -> (store) { (store.present? && store.payment_methods.empty?) ? self : store.payment_methods }
15
21
 
16
22
  include Spree::Preferences::StaticallyConfigurable
17
23
 
@@ -30,11 +36,48 @@ module Spree
30
36
  raise ::NotImplementedError, "You must implement payment_source_class method for #{self.class}."
31
37
  end
32
38
 
33
- def self.available(display_on = 'both', store: nil)
34
- all.select do |p|
35
- p.active &&
36
- (p.display_on == display_on.to_s || p.display_on.blank?) &&
37
- (store.nil? || store.payment_methods.empty? || store.payment_methods.include?(p))
39
+ # @deprecated Use {#available_to_users=} and {#available_to_admin=} instead
40
+ def display_on=(value)
41
+ Spree::Deprecation.warn "Spree::PaymentMethod#display_on= is deprecated."\
42
+ "Please use #available_to_users= and #available_to_admin= instead."
43
+ self.available_to_users = value.blank? || value == 'front_end'
44
+ self.available_to_admin = value.blank? || value == 'back_end'
45
+ end
46
+
47
+ # @deprecated Use {#available_to_users} and {#available_to_admin} instead
48
+ def display_on
49
+ Spree::Deprecation.warn "Spree::PaymentMethod#display_on is deprecated."\
50
+ "Please use #available_to_users and #available_to_admin instead."
51
+ if available_to_users? && available_to_admin?
52
+ ''
53
+ elsif available_to_users?
54
+ 'front_end'
55
+ elsif available_to_admin?
56
+ 'back_end'
57
+ else
58
+ 'none'
59
+ end
60
+ end
61
+
62
+ def self.available(display_on=nil, store: nil)
63
+ Spree::Deprecation.warn "Spree::PaymentMethod.available is deprecated."\
64
+ "Please use .active, .available_to_users, and .available_to_admin scopes instead."\
65
+ "For payment methods associated with a specific store, use Spree::PaymentMethod.available_to_store(your_store)"\
66
+ " as the base applying any further filtering"
67
+
68
+ display_on = display_on.to_s
69
+
70
+ available_payment_methods =
71
+ case display_on
72
+ when 'front_end'
73
+ active.available_to_users
74
+ when 'back_end'
75
+ active.available_to_admin
76
+ else
77
+ active.available_to_users.available_to_admin
78
+ end
79
+ available_payment_methods.select do |p|
80
+ store.nil? || store.payment_methods.empty? || store.payment_methods.include?(p)
38
81
  end
39
82
  end
40
83
 
@@ -18,10 +18,11 @@ module Spree
18
18
  validates :currency, inclusion: { in: ::Money::Currency.all.map(&:iso_code), message: :invalid_code }
19
19
  validates :country, presence: true, unless: -> { for_any_country? }
20
20
 
21
- scope :currently_valid, -> { where(is_default: true).order("country_iso IS NULL") }
21
+ scope :currently_valid, -> { order("country_iso IS NULL, updated_at DESC") }
22
+ scope :for_master, -> { joins(:variant).where(spree_variants: { is_master: true }) }
23
+ scope :for_variant, -> { joins(:variant).where(spree_variants: { is_master: false }) }
22
24
  scope :for_any_country, -> { where(country: nil) }
23
25
  scope :with_default_attributes, -> { where(Spree::Config.default_pricing_options.desired_attributes) }
24
- after_save :set_default_price
25
26
 
26
27
  extend DisplayMoney
27
28
  money_methods :amount, :price
@@ -58,6 +59,10 @@ module Spree
58
59
  end
59
60
  end
60
61
 
62
+ def country_iso=(country_iso)
63
+ self[:country_iso] = country_iso.presence
64
+ end
65
+
61
66
  private
62
67
 
63
68
  def sum_of_vat_amounts
@@ -69,13 +74,6 @@ module Spree
69
74
  self.currency ||= Spree::Config[:currency]
70
75
  end
71
76
 
72
- def set_default_price
73
- if is_default?
74
- other_default_prices = variant.prices.currently_valid.where(pricing_options.desired_attributes).where.not(id: id)
75
- other_default_prices.update_all(is_default: false)
76
- end
77
- end
78
-
79
77
  def pricing_options
80
78
  Spree::Config.pricing_options_class.from_price(self)
81
79
  end
@@ -74,7 +74,6 @@ module Spree
74
74
 
75
75
  has_many :variant_images, -> { order(:position) }, source: :images, through: :variants_including_master
76
76
 
77
- after_create :add_associations_from_prototype
78
77
  after_create :build_variants_from_option_values_hash, if: :option_values_hash
79
78
 
80
79
  after_destroy :punch_slug
@@ -114,17 +113,6 @@ module Spree
114
113
  super || TaxCategory.find_by(is_default: true)
115
114
  end
116
115
 
117
- # Overrides the prototype_id setter in order to ensure it is cast to an
118
- # integer.
119
- #
120
- # @param value [#to_i] the intended new value
121
- # @!attribute [rw] prototype_id
122
- # @return [Fixnum]
123
- attr_reader :prototype_id
124
- def prototype_id=(value)
125
- @prototype_id = value.to_i
126
- end
127
-
128
116
  # Ensures option_types and product_option_types exist for keys in
129
117
  # option_values_hash.
130
118
  #
@@ -227,9 +215,7 @@ module Spree
227
215
 
228
216
  # @return [Boolean] true if there are no option values
229
217
  def empty_option_values?
230
- options.empty? || options.any? do |opt|
231
- opt.option_type.option_values.empty?
232
- end
218
+ options.empty? || !option_types.left_joins(:option_values).where('spree_option_values.id IS NULL').empty?
233
219
  end
234
220
 
235
221
  # @param property_name [String] the name of the property to find
@@ -292,16 +278,6 @@ module Spree
292
278
 
293
279
  private
294
280
 
295
- def add_associations_from_prototype
296
- if prototype_id && prototype = Spree::Prototype.find_by(id: prototype_id)
297
- prototype.properties.each do |property|
298
- product_properties.create(property: property)
299
- end
300
- self.option_types = prototype.option_types
301
- self.taxons = prototype.taxons
302
- end
303
- end
304
-
305
281
  def any_variants_not_track_inventory?
306
282
  if variants_including_master.loaded?
307
283
  variants_including_master.any? { |v| !v.should_track_inventory? }
@@ -7,10 +7,10 @@ module Spree
7
7
 
8
8
  belongs_to :promotion_category
9
9
 
10
- has_many :promotion_rules, autosave: true, dependent: :destroy
10
+ has_many :promotion_rules, autosave: true, dependent: :destroy, inverse_of: :promotion
11
11
  alias_method :rules, :promotion_rules
12
12
 
13
- has_many :promotion_actions, autosave: true, dependent: :destroy
13
+ has_many :promotion_actions, autosave: true, dependent: :destroy, inverse_of: :promotion
14
14
  alias_method :actions, :promotion_actions
15
15
 
16
16
  has_many :order_promotions, class_name: "Spree::OrderPromotion"
@@ -82,15 +82,6 @@ module Spree
82
82
  !active?
83
83
  end
84
84
 
85
- def expired?
86
- Spree::Deprecation.warn <<-WARN.squish, caller
87
- #expired? is deprecated, and will be removed in Solidus 2.0.
88
- Please use #inactive? instead.
89
- WARN
90
-
91
- inactive?
92
- end
93
-
94
85
  def activate(order:, line_item: nil, user: nil, path: nil, promotion_code: nil)
95
86
  return unless self.class.order_activatable?(order)
96
87
 
@@ -114,10 +105,13 @@ module Spree
114
105
 
115
106
  if action_taken
116
107
  # connect to the order
117
- order_promotions.find_or_create_by!(
118
- order_id: order.id,
119
- promotion_code_id: promotion_code.try!(:id)
108
+ order.order_promotions.find_or_create_by!(
109
+ promotion: self,
110
+ promotion_code: promotion_code,
120
111
  )
112
+ order.promotions.reset
113
+ order_promotions.reset
114
+ orders.reset
121
115
  end
122
116
 
123
117
  action_taken
@@ -220,6 +214,20 @@ module Spree
220
214
  end
221
215
  end
222
216
 
217
+ # Removes a promotion and any adjustments or other side effects from an
218
+ # order.
219
+ # @param order [Spree::Order] the order to remove the promotion from.
220
+ # @return [void]
221
+ def remove_from(order)
222
+ actions.each do |action|
223
+ action.remove_from(order)
224
+ end
225
+ # note: this destroys the join table entry, not the promotion itself
226
+ order.promotions.destroy(self)
227
+ order.order_promotions.reset
228
+ order_promotions.reset
229
+ end
230
+
223
231
  private
224
232
 
225
233
  def blacklisted?(promotable)