solidus_core 2.0.3 → 2.1.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)