solidus_core 2.2.2 → 2.3.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 (175) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -7
  3. data/app/assets/javascripts/spree.js.erb +2 -2
  4. data/app/helpers/spree/base_helper.rb +3 -4
  5. data/app/models/spree/address.rb +1 -1
  6. data/app/models/spree/adjustment.rb +3 -1
  7. data/app/models/spree/app_configuration.rb +43 -0
  8. data/app/models/spree/billing_integration.rb +2 -2
  9. data/app/models/spree/calculator/default_tax.rb +3 -1
  10. data/app/models/spree/calculator/distributed_amount.rb +24 -0
  11. data/app/models/spree/calculator/free_shipping.rb +0 -1
  12. data/app/models/spree/calculator/tiered_flat_rate.rb +17 -3
  13. data/app/models/spree/calculator/tiered_percent.rb +18 -3
  14. data/app/models/spree/distributed_amounts_handler.rb +43 -0
  15. data/app/models/spree/gateway/bogus.rb +7 -83
  16. data/app/models/spree/gateway/bogus_simple.rb +7 -20
  17. data/app/models/spree/gateway.rb +8 -58
  18. data/app/models/spree/image.rb +1 -1
  19. data/app/models/spree/line_item.rb +1 -1
  20. data/app/models/spree/option_value.rb +1 -1
  21. data/app/models/spree/order/checkout.rb +1 -4
  22. data/app/models/spree/order/number_generator.rb +43 -0
  23. data/app/models/spree/order.rb +33 -38
  24. data/app/models/spree/order_contents.rb +1 -1
  25. data/app/models/spree/order_taxation.rb +79 -0
  26. data/app/models/spree/order_update_attributes.rb +0 -2
  27. data/app/models/spree/order_updater.rb +55 -33
  28. data/app/models/spree/payment.rb +0 -1
  29. data/app/models/spree/payment_method/bogus_credit_card.rb +87 -0
  30. data/app/models/spree/payment_method/check.rb +14 -6
  31. data/app/models/spree/payment_method/credit_card.rb +41 -0
  32. data/app/models/spree/payment_method/simple_bogus_credit_card.rb +24 -0
  33. data/app/models/spree/payment_method/store_credit.rb +5 -13
  34. data/app/models/spree/payment_method.rb +126 -40
  35. data/app/models/spree/preferences/preferable.rb +5 -1
  36. data/app/models/spree/preferences/store.rb +2 -2
  37. data/app/models/spree/product/scopes.rb +14 -1
  38. data/app/models/spree/product.rb +10 -4
  39. data/app/models/spree/promotion_action.rb +4 -0
  40. data/app/models/spree/promotion_code/batch_builder.rb +3 -2
  41. data/app/models/spree/promotion_rule.rb +4 -0
  42. data/app/models/spree/role.rb +2 -0
  43. data/app/models/spree/role_user.rb +2 -0
  44. data/app/models/spree/shipment.rb +4 -2
  45. data/app/models/spree/shipping_method.rb +3 -1
  46. data/app/models/spree/shipping_rate.rb +1 -1
  47. data/app/models/spree/state.rb +10 -2
  48. data/app/models/spree/stock_item.rb +3 -3
  49. data/app/models/spree/store.rb +5 -0
  50. data/app/models/spree/store_credit.rb +2 -2
  51. data/app/models/spree/store_credit_event.rb +1 -1
  52. data/app/models/spree/store_selector/by_server_name.rb +30 -0
  53. data/app/models/spree/store_selector/legacy.rb +48 -0
  54. data/app/models/spree/tax/item_tax.rb +20 -0
  55. data/app/models/spree/tax/order_adjuster.rb +2 -14
  56. data/app/models/spree/tax/order_tax.rb +18 -0
  57. data/app/models/spree/tax/shipping_rate_taxer.rb +4 -13
  58. data/app/models/spree/tax/tax_helpers.rb +5 -3
  59. data/app/models/spree/tax_calculator/default.rb +83 -0
  60. data/app/models/spree/tax_calculator/shipping_rate.rb +46 -0
  61. data/app/models/spree/tax_category.rb +9 -1
  62. data/app/models/spree/tax_rate.rb +31 -7
  63. data/app/models/spree/tax_rate_tax_category.rb +6 -0
  64. data/app/models/spree/taxon.rb +1 -1
  65. data/app/models/spree/variant.rb +1 -1
  66. data/app/views/spree/{shipment_mailer → carton_mailer}/shipped_email.html.erb +3 -3
  67. data/app/views/spree/order_mailer/cancel_email.html.erb +3 -3
  68. data/app/views/spree/order_mailer/confirm_email.html.erb +2 -2
  69. data/app/views/spree/order_mailer/inventory_cancellation_email.html.erb +26 -0
  70. data/app/views/spree/reimbursement_mailer/reimbursement_email.html.erb +2 -2
  71. data/app/views/spree/test_mailer/test_email.html.erb +2 -2
  72. data/config/locales/en.yml +66 -57
  73. data/db/default/spree/refund_reasons.rb +1 -0
  74. data/db/default/spree/shipping_categories.rb +1 -0
  75. data/db/default/spree/stock_locations.rb +2 -0
  76. data/db/default/spree/stores.rb +3 -4
  77. data/db/migrate/20170412103617_transform_tax_rate_category_relation.rb +48 -0
  78. data/db/migrate/20170422134804_add_roles_unique_constraints.rb +6 -0
  79. data/db/migrate/20170522143442_add_time_range_to_tax_rate.rb +6 -0
  80. data/db/migrate/20170608074534_rename_bogus_gateways.rb +13 -0
  81. data/lib/generators/spree/custom_user/custom_user_generator.rb +1 -1
  82. data/lib/generators/spree/dummy/dummy_generator.rb +10 -4
  83. data/lib/generators/spree/dummy/templates/rails/database.yml +12 -12
  84. data/lib/generators/spree/install/install_generator.rb +5 -5
  85. data/lib/generators/spree/install/templates/config/initializers/{spree.rb → solidus.rb} +0 -0
  86. data/lib/solidus/migrations/rename_gateways.rb +39 -0
  87. data/lib/spree/core/controller_helpers/auth.rb +1 -1
  88. data/lib/spree/core/controller_helpers/order.rb +10 -5
  89. data/lib/spree/core/controller_helpers/store.rb +1 -9
  90. data/lib/spree/core/current_store.rb +6 -14
  91. data/lib/spree/core/engine.rb +4 -3
  92. data/lib/spree/core/importer/order.rb +4 -4
  93. data/lib/spree/core/version.rb +1 -1
  94. data/lib/spree/core.rb +0 -1
  95. data/lib/spree/localized_number.rb +2 -1
  96. data/lib/spree/permitted_attributes.rb +12 -6
  97. data/lib/spree/testing_support/capybara_ext.rb +0 -1
  98. data/lib/spree/testing_support/factories/adjustment_factory.rb +5 -1
  99. data/lib/spree/testing_support/factories/order_factory.rb +26 -24
  100. data/lib/spree/testing_support/factories/payment_factory.rb +4 -0
  101. data/lib/spree/testing_support/factories/payment_method_factory.rb +3 -3
  102. data/lib/spree/testing_support/factories/shipment_factory.rb +7 -3
  103. data/lib/spree/testing_support/factories/tax_rate_factory.rb +1 -1
  104. data/lib/spree/testing_support/factories/variant_factory.rb +3 -1
  105. data/lib/tasks/migrations/copy_order_bill_address_to_credit_card.rake +0 -4
  106. data/lib/tasks/migrations/migrate_user_addresses.rake +2 -2
  107. data/lib/tasks/migrations/rename_gateways.rake +19 -0
  108. data/solidus_core.gemspec +2 -3
  109. data/spec/lib/spree/core/controller_helpers/order_spec.rb +32 -6
  110. data/spec/lib/spree/core/controller_helpers/payment_parameters_spec.rb +0 -1
  111. data/spec/lib/spree/core/current_store_spec.rb +6 -11
  112. data/spec/lib/spree/core/price_migrator_spec.rb +4 -4
  113. data/spec/lib/spree/core/testing_support/factories/order_factory_spec.rb +199 -91
  114. data/spec/lib/spree/core/testing_support/factories/variant_factory_spec.rb +18 -0
  115. data/spec/lib/spree/localized_number_spec.rb +6 -0
  116. data/spec/mailers/carton_mailer_spec.rb +3 -3
  117. data/spec/models/spree/address_spec.rb +3 -3
  118. data/spec/models/spree/adjustment_spec.rb +71 -27
  119. data/spec/models/spree/calculator/default_tax_spec.rb +72 -1
  120. data/spec/models/spree/calculator/distributed_amount_spec.rb +32 -0
  121. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +20 -1
  122. data/spec/models/spree/calculator/tiered_percent_spec.rb +20 -1
  123. data/spec/models/spree/distributed_amounts_handler_spec.rb +79 -0
  124. data/spec/models/spree/gateway/bogus_simple.rb +7 -13
  125. data/spec/models/spree/gateway/bogus_spec.rb +8 -4
  126. data/spec/models/spree/gateway_spec.rb +6 -105
  127. data/spec/models/spree/image_spec.rb +23 -0
  128. data/spec/models/spree/order/checkout_spec.rb +3 -18
  129. data/spec/models/spree/order/number_generator_spec.rb +45 -0
  130. data/spec/models/spree/order/outstanding_balance_integration_spec.rb +135 -0
  131. data/spec/models/spree/order/payment_spec.rb +7 -2
  132. data/spec/models/spree/order/state_machine_spec.rb +4 -2
  133. data/spec/models/spree/order_capturing_spec.rb +8 -8
  134. data/spec/models/spree/order_contents_spec.rb +8 -1
  135. data/spec/models/spree/order_shipping_spec.rb +5 -1
  136. data/spec/models/spree/order_spec.rb +156 -83
  137. data/spec/models/spree/order_taxation_spec.rb +126 -0
  138. data/spec/models/spree/order_update_attributes_spec.rb +1 -5
  139. data/spec/models/spree/order_updater_spec.rb +20 -21
  140. data/spec/models/spree/payment_create_spec.rb +14 -6
  141. data/spec/models/spree/payment_method/bogus_credit_card_spec.rb +8 -0
  142. data/spec/models/spree/payment_method/check_spec.rb +78 -0
  143. data/spec/models/spree/payment_method/credit_card_spec.rb +66 -0
  144. data/spec/models/spree/payment_method/simple_bogus_credit_card_spec.rb +18 -0
  145. data/spec/models/spree/payment_method_spec.rb +47 -2
  146. data/spec/models/spree/payment_spec.rb +6 -8
  147. data/spec/models/spree/preference_spec.rb +1 -1
  148. data/spec/models/spree/price_spec.rb +1 -1
  149. data/spec/models/spree/product/scopes_spec.rb +46 -0
  150. data/spec/models/spree/promotion_action_spec.rb +4 -0
  151. data/spec/models/spree/promotion_code/batch_builder_spec.rb +25 -3
  152. data/spec/models/spree/promotion_code_batch_spec.rb +0 -6
  153. data/spec/models/spree/promotion_handler/coupon_spec.rb +1 -1
  154. data/spec/models/spree/promotion_rule_spec.rb +5 -0
  155. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +1 -1
  156. data/spec/models/spree/shipment_spec.rb +24 -3
  157. data/spec/models/spree/shipping_rate_spec.rb +5 -5
  158. data/spec/models/spree/state_spec.rb +31 -4
  159. data/spec/models/spree/stock/coordinator_spec.rb +24 -0
  160. data/spec/models/spree/stock/estimator_spec.rb +1 -1
  161. data/spec/models/spree/store_selector/by_server_name_spec.rb +26 -0
  162. data/spec/models/spree/store_selector/legacy_spec.rb +44 -0
  163. data/spec/models/spree/store_spec.rb +10 -2
  164. data/spec/models/spree/tax/order_adjuster_spec.rb +11 -21
  165. data/spec/models/spree/tax/shipping_rate_taxer_spec.rb +10 -3
  166. data/spec/models/spree/tax/taxation_integration_spec.rb +43 -8
  167. data/spec/models/spree/tax_calculator/default_spec.rb +54 -0
  168. data/spec/models/spree/tax_rate_spec.rb +92 -0
  169. data/spec/models/spree/variant/vat_price_generator_spec.rb +4 -4
  170. data/spec/models/spree/variant_spec.rb +8 -2
  171. data/spec/spec_helper.rb +2 -1
  172. data/spec/support/test_gateway.rb +1 -1
  173. metadata +45 -24
  174. data/app/models/spree/tax/item_adjuster.rb +0 -51
  175. data/spec/models/spree/tax/item_adjuster_spec.rb +0 -82
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a2dec32c7e551a4cccda16f58059e05cbb507ea
4
- data.tar.gz: 0f1687d7691c96cb0a0aae2b13cc53c1e4f90692
3
+ metadata.gz: 9d015fdadf3dd41148e17b69ff2432090071c998
4
+ data.tar.gz: cf60f2cdfa6b33eccb82886b942a23b3253a5557
5
5
  SHA512:
6
- metadata.gz: 9215d5df94bc2bb98df3f74e33b670af7fa9a7f00edec4ee4367e9f28da1d386cde1982f3f770c6eba3676e29253dd7c3b1c2c2d1640dec5fd6fd9a4eff31242
7
- data.tar.gz: d2b86bb28e9673ddf3f32d98a67d274bf580f057f812e662d4c4f43e7f9cb6cd67dbe0628d58fc839e78ba15636f8528c4b416caeeece6dd5ca98a9046e677e6
6
+ metadata.gz: dbd5d9fc8a47b9470a406e28e8f7427ab0c005893c6179e908d50e6310f375216a2c933a4d56a26b5695beb8a5a46ed2e2996ec34caeccceb9c8d41eb44affc9
7
+ data.tar.gz: 2d86cd376c2341b82ca020ed126c4633151d99918775863c2223bcb4e6da88259f9e5dcf80d5ed8a18cb02fcc50949e8bb4a0800c0929d0d34b441e3457bbe95
data/README.md CHANGED
@@ -38,13 +38,10 @@ integration.
38
38
  * `Spree::Payment` - Manage and process a payment for an order, from a specific
39
39
  source (e.g. `Spree::CreditCard`) using a specific payment method (e.g
40
40
  `Solidus::Gateway::Braintree`).
41
- * `Spree::PaymentMethod` - An abstract class which is implemented most commonly
42
- as a `Spree::Gateway`.
43
- * `Spree::Gateway` - A concrete implementation of `Spree::PaymentMethod`
44
- intended to provide a base for extension. See
45
- https://github.com/solidusio/solidus_gateway/ for offically supported payment
46
- gateway implementations.
47
- * `Spree::CreditCard` - The default `source` of a `Spree::Payment`.
41
+ * `Spree::PaymentMethod` - A base class which is used for implementing payment methods.
42
+ * `Spree::PaymentMethod::CreditCard` - An implementation of a `Spree::PaymentMethod` for credit card payments.
43
+ See https://github.com/solidusio/solidus_gateway/ for officially supported payment method implementations.
44
+ * `Spree::CreditCard` - The `source` of a `Spree::Payment` using `Spree::PaymentMethod::CreditCard` as payment method.
48
45
 
49
46
  ## The Inventory Sub-System
50
47
  * `Spree::ReturnAuthorization` - Models the return of Inventory Units to
@@ -23,8 +23,8 @@ Spree.pathFor = function(path) {
23
23
  };
24
24
 
25
25
  Spree.url = function(uri, query) {
26
- if (Spree.env === 'development' || Spree.env === 'test') {
27
- console.warn('Spree.url is deprecated, please use Spree.ajax for your request instead.');
26
+ if (console && console.warn) {
27
+ console.warn('Spree.url is deprecated, and will be removed from a future Solidus version.');
28
28
  }
29
29
  if (uri.path === undefined) {
30
30
  uri = new Uri(uri);
@@ -4,11 +4,11 @@ module Spree
4
4
  text = text ? h(text) : Spree.t(:cart)
5
5
  css_class = nil
6
6
 
7
- if simple_current_order.nil? || simple_current_order.item_count.zero?
7
+ if current_order.nil? || current_order.item_count.zero?
8
8
  text = "#{text}: (#{Spree.t(:empty)})"
9
9
  css_class = 'empty'
10
10
  else
11
- text = "#{text}: (#{simple_current_order.item_count}) <span class='amount'>#{simple_current_order.display_total.to_html}</span>"
11
+ text = "#{text}: (#{current_order.item_count}) <span class='amount'>#{current_order.display_total.to_html}</span>"
12
12
  css_class = 'full'
13
13
  end
14
14
 
@@ -84,7 +84,7 @@ module Spree
84
84
  items = crumbs.each_with_index.collect do |crumb, i|
85
85
  content_tag(:li, itemprop: 'itemListElement', itemscope: '', itemtype: 'https://schema.org/ListItem') do
86
86
  link_to(crumb.last, itemprop: 'item') do
87
- content_tag(:span, crumb.first, itemprop: 'name') + tag('meta', { itemprop: 'position', content: (i+1).to_s }, false, false)
87
+ content_tag(:span, crumb.first, itemprop: 'name') + tag('meta', { itemprop: 'position', content: (i + 1).to_s }, false, false)
88
88
  end + (crumb == crumbs.last ? '' : separator)
89
89
  end
90
90
  end
@@ -147,6 +147,5 @@ module Spree
147
147
  def plural_resource_name(resource_class)
148
148
  resource_class.model_name.human(count: Spree::I18N_GENERIC_PLURAL)
149
149
  end
150
-
151
150
  end
152
151
  end
@@ -193,7 +193,7 @@ module Spree
193
193
  # ensure state_name belongs to country without states, or that it matches a predefined state name/abbr
194
194
  if state_name.present?
195
195
  if country.states.present?
196
- states = country.states.find_all_by_name_or_abbr(state_name)
196
+ states = country.states.with_name_or_abbr(state_name)
197
197
 
198
198
  if states.size == 1
199
199
  self.state = states.first
@@ -97,7 +97,9 @@ module Spree
97
97
  #
98
98
  # @return [BigDecimal] New amount of this adjustment
99
99
  def update!
100
- return amount if finalized?
100
+ if finalized? && !tax?
101
+ return amount
102
+ end
101
103
 
102
104
  # If the adjustment has no source, do not attempt to re-calculate the amount.
103
105
  # Chances are likely that this was a manually created adjustment in the admin backend.
@@ -309,6 +309,17 @@ module Spree
309
309
  @shipping_rate_taxer_class ||= Spree::Tax::ShippingRateTaxer
310
310
  end
311
311
 
312
+ # Allows providing your own class for calculating taxes on a shipping rate.
313
+ #
314
+ # @!attribute [rw] shipping_rate_tax_calculator_class
315
+ # @return [Class] a class with the same public interfaces as
316
+ # Spree::TaxCalculator::ShippingRate
317
+ # @api experimental
318
+ attr_writer :shipping_rate_tax_calculator_class
319
+ def shipping_rate_tax_calculator_class
320
+ @shipping_rate_tax_calculator_class ||= Spree::TaxCalculator::ShippingRate
321
+ end
322
+
312
323
  # Allows providing your own Mailer for shipped cartons.
313
324
  #
314
325
  # @!attribute [rw] carton_shipped_email_class
@@ -365,6 +376,38 @@ module Spree
365
376
  @tax_adjuster_class ||= Spree::Tax::OrderAdjuster
366
377
  end
367
378
 
379
+ # Allows providing your own class for calculating taxes on an order.
380
+ #
381
+ # @!attribute [rw] tax_calculator_class
382
+ # @return [Class] a class with the same public interfaces as
383
+ # Spree::TaxCalculator::Default
384
+ # @api experimental
385
+ attr_writer :tax_calculator_class
386
+ def tax_calculator_class
387
+ @tax_calculator_class ||= Spree::TaxCalculator::Default
388
+ end
389
+
390
+ # Allows providing your own class for choosing which store to use.
391
+ #
392
+ # @!attribute [rw] current_store_selector_class
393
+ # @return [Class] a class with the same public interfaces as
394
+ # Spree::CurrentStoreSelector
395
+ attr_writer :current_store_selector_class
396
+ def current_store_selector_class
397
+ @current_store_selector_class ||= Spree::StoreSelector::ByServerName
398
+ end
399
+
400
+ # Allows providing your own class instance for generating order numbers.
401
+ #
402
+ # @!attribute [rw] order_number_generator
403
+ # @return [Class] a class instance with the same public interfaces as
404
+ # Spree::Order::NumberGenerator
405
+ # @api experimental
406
+ attr_writer :order_number_generator
407
+ def order_number_generator
408
+ @order_number_generator ||= Spree::Order::NumberGenerator.new
409
+ end
410
+
368
411
  def static_model_preferences
369
412
  @static_model_preferences ||= Spree::Preferences::StaticModelPreferences.new
370
413
  end
@@ -5,11 +5,11 @@ module Spree
5
5
  preference :server, :string, default: 'test'
6
6
  preference :test_mode, :boolean, default: true
7
7
 
8
- def provider
8
+ def gateway
9
9
  integration_options = options
10
10
  ActiveMerchant::Billing::Base.integration_mode = integration_options[:server].to_sym
11
11
  integration_options[:test] = true if integration_options[:test_mode]
12
- @provider ||= provider_class.new(integration_options)
12
+ @gateway ||= gateway_class.new(integration_options)
13
13
  end
14
14
 
15
15
  def options
@@ -8,8 +8,9 @@ module Spree
8
8
  # Orders created before Spree 2.1 had tax adjustments applied to the order, as a whole.
9
9
  # Orders created with Spree 2.2 and after, have them applied to the line items individually.
10
10
  def compute_order(order)
11
+ return 0 unless rate.active?
11
12
  matched_line_items = order.line_items.select do |line_item|
12
- line_item.tax_category == rate.tax_category
13
+ rate.tax_categories.include?(line_item.tax_category)
13
14
  end
14
15
 
15
16
  line_items_total = matched_line_items.sum(&:discounted_amount)
@@ -23,6 +24,7 @@ module Spree
23
24
 
24
25
  # When it comes to computing shipments or line items: same same.
25
26
  def compute_item(item)
27
+ return 0 unless rate.active?
26
28
  if rate.included_in_price
27
29
  deduced_total_by_rate(item, rate)
28
30
  else
@@ -0,0 +1,24 @@
1
+ require_dependency 'spree/calculator'
2
+
3
+ # This is a calculator for line item adjustment actions. It accepts a line item
4
+ # and calculates its weighted adjustment amount based on the value of the
5
+ # preferred amount and the price of the other line items. More expensive line
6
+ # items will receive a greater share of the preferred amount.
7
+
8
+ module Spree
9
+ class Calculator::DistributedAmount < Calculator
10
+ preference :amount, :decimal, default: 0
11
+ preference :currency, :string, default: -> { Spree::Config[:currency] }
12
+
13
+ def compute_line_item(line_item)
14
+ if line_item && preferred_currency.casecmp(line_item.currency).zero?
15
+ Spree::DistributedAmountsHandler.new(
16
+ line_item,
17
+ preferred_amount
18
+ ).amount
19
+ else
20
+ 0
21
+ end
22
+ end
23
+ end
24
+ end
@@ -3,7 +3,6 @@ module Spree
3
3
  # The only case where it was used was for Free Shipping Promotions. There is
4
4
  # now a Promotion Action which deals with these types of promotions instead.
5
5
  class Calculator::FreeShipping < Calculator
6
-
7
6
  def compute(object)
8
7
  if object.is_a?(Array)
9
8
  return if object.empty?
@@ -4,12 +4,13 @@ module Spree
4
4
  class Calculator::TieredFlatRate < Calculator
5
5
  preference :base_amount, :decimal, default: 0
6
6
  preference :tiers, :hash, default: {}
7
+ preference :currency, :string, default: -> { Spree::Config[:currency] }
7
8
 
8
9
  before_validation do
9
10
  # Convert tier values to decimals. Strings don't do us much good.
10
11
  if preferred_tiers.is_a?(Hash)
11
12
  self.preferred_tiers = preferred_tiers.map do |k, v|
12
- [BigDecimal.new(k.to_s), BigDecimal.new(v.to_s)]
13
+ [cast_to_d(k.to_s), cast_to_d(v.to_s)]
13
14
  end.to_h
14
15
  end
15
16
  end
@@ -17,12 +18,25 @@ module Spree
17
18
  validate :preferred_tiers_content
18
19
 
19
20
  def compute(object)
20
- _base, amount = preferred_tiers.sort.reverse.detect{ |b, _| object.amount >= b }
21
- amount || preferred_base_amount
21
+ _base, amount = preferred_tiers.sort.reverse.detect do |b, _|
22
+ object.amount >= b
23
+ end
24
+
25
+ if preferred_currency.casecmp(object.currency).zero?
26
+ amount || preferred_base_amount
27
+ else
28
+ 0
29
+ end
22
30
  end
23
31
 
24
32
  private
25
33
 
34
+ def cast_to_d(value)
35
+ value.to_s.to_d
36
+ rescue ArgumentError
37
+ BigDecimal.new(0)
38
+ end
39
+
26
40
  def preferred_tiers_content
27
41
  if preferred_tiers.is_a? Hash
28
42
  unless preferred_tiers.keys.all?{ |k| k.is_a?(Numeric) && k > 0 }
@@ -4,12 +4,13 @@ module Spree
4
4
  class Calculator::TieredPercent < Calculator
5
5
  preference :base_percent, :decimal, default: 0
6
6
  preference :tiers, :hash, default: {}
7
+ preference :currency, :string, default: -> { Spree::Config[:currency] }
7
8
 
8
9
  before_validation do
9
10
  # Convert tier values to decimals. Strings don't do us much good.
10
11
  if preferred_tiers.is_a?(Hash)
11
12
  self.preferred_tiers = preferred_tiers.map do |k, v|
12
- [BigDecimal.new(k.to_s), BigDecimal.new(v.to_s)]
13
+ [cast_to_d(k.to_s), cast_to_d(v.to_s)]
13
14
  end.to_h
14
15
  end
15
16
  end
@@ -22,12 +23,26 @@ module Spree
22
23
 
23
24
  def compute(object)
24
25
  order = object.is_a?(Order) ? object : object.order
25
- _base, percent = preferred_tiers.sort.reverse.detect{ |b, _| order.item_total >= b }
26
- (object.amount * (percent || preferred_base_percent) / 100).round(2)
26
+
27
+ _base, percent = preferred_tiers.sort.reverse.detect do |b, _|
28
+ order.item_total >= b
29
+ end
30
+
31
+ if preferred_currency.casecmp(order.currency).zero?
32
+ (object.amount * (percent || preferred_base_percent) / 100).round(2)
33
+ else
34
+ 0
35
+ end
27
36
  end
28
37
 
29
38
  private
30
39
 
40
+ def cast_to_d(value)
41
+ value.to_s.to_d
42
+ rescue ArgumentError
43
+ BigDecimal.new(0)
44
+ end
45
+
31
46
  def preferred_tiers_content
32
47
  if preferred_tiers.is_a? Hash
33
48
  unless preferred_tiers.keys.all?{ |k| k.is_a?(Numeric) && k > 0 }
@@ -0,0 +1,43 @@
1
+ module Spree
2
+ class DistributedAmountsHandler
3
+ attr_reader :line_item, :order, :total_amount
4
+
5
+ def initialize(line_item, total_amount)
6
+ @line_item = line_item
7
+ @order = line_item.order
8
+ @total_amount = total_amount
9
+ end
10
+
11
+ # @return [Float] the weighted adjustment for the initialized line item
12
+ def amount
13
+ distributed_amounts[@line_item.id].to_f
14
+ end
15
+
16
+ private
17
+
18
+ # @private
19
+ # @return [Hash<Integer, BigDecimal>] a hash of line item IDs and their
20
+ # corresponding weighted adjustments
21
+ def distributed_amounts
22
+ remaining_amount = @total_amount
23
+
24
+ @order.line_items.each_with_index.map do |line_item, i|
25
+ if i == @order.line_items.length - 1
26
+ # If this is the last line item on the order we want to use the
27
+ # remaining preferred amount to ensure our total adjustment is what
28
+ # has been set as the preferred amount.
29
+ [line_item.id, remaining_amount]
30
+ else
31
+ # Calculate the weighted amount by getting this line item's share of
32
+ # the order's total and multiplying it with the preferred amount.
33
+ weighted_amount = ((line_item.amount / @order.item_total) * total_amount).round(2)
34
+
35
+ # Subtract this line item's weighted amount from the total.
36
+ remaining_amount -= weighted_amount
37
+
38
+ [line_item.id, weighted_amount]
39
+ end
40
+ end.to_h
41
+ end
42
+ end
43
+ end
@@ -1,87 +1,11 @@
1
1
  module Spree
2
- class Gateway::Bogus < Gateway
3
- TEST_VISA = ['4111111111111111', '4012888888881881', '4222222222222']
4
- TEST_MC = ['5500000000000004', '5555555555554444', '5105105105105100']
5
- TEST_AMEX = ['378282246310005', '371449635398431', '378734493671000', '340000000000009']
6
- TEST_DISC = ['6011000000000004', '6011111111111117', '6011000990139424']
7
-
8
- VALID_CCS = ['1', TEST_VISA, TEST_MC, TEST_AMEX, TEST_DISC].flatten
9
-
10
- attr_accessor :test
11
-
12
- def provider_class
13
- self.class
14
- end
15
-
16
- def create_profile(payment)
17
- return if payment.source.has_payment_profile?
18
- # simulate the storage of credit card profile using remote service
19
- if success = VALID_CCS.include?(payment.source.number)
20
- payment.source.update_attributes(gateway_customer_profile_id: generate_profile_id(success))
21
- end
22
- end
23
-
24
- def authorize(_money, credit_card, _options = {})
25
- profile_id = credit_card.gateway_customer_profile_id
26
- if VALID_CCS.include?(credit_card.number) || (profile_id && profile_id.starts_with?('BGS-'))
27
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'D' })
28
- else
29
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', { message: 'Bogus Gateway: Forced failure' }, test: true)
30
- end
31
- end
32
-
33
- def purchase(_money, credit_card, _options = {})
34
- profile_id = credit_card.gateway_customer_profile_id
35
- if VALID_CCS.include?(credit_card.number) || (profile_id && profile_id.starts_with?('BGS-'))
36
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'M' })
37
- else
38
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', message: 'Bogus Gateway: Forced failure', test: true)
39
- end
40
- end
41
-
42
- def credit(_money, _credit_card, _response_code, _options = {})
43
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
44
- end
45
-
46
- def capture(_money, authorization, _gateway_options)
47
- if authorization == '12345'
48
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true)
49
- else
50
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', error: 'Bogus Gateway: Forced failure', test: true)
51
- end
52
- end
53
-
54
- def void(_response_code, _credit_card, _options = {})
55
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
56
- end
57
-
58
- def cancel(_response_code)
59
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
60
- end
61
-
62
- def test?
63
- # Test mode is not really relevant with bogus gateway (no such thing as live server)
64
- true
65
- end
66
-
67
- def payment_profiles_supported?
68
- true
69
- end
70
-
71
- def actions
72
- %w(capture void credit)
73
- end
74
-
75
- private
76
-
77
- def generate_profile_id(success)
78
- record = true
79
- prefix = success ? 'BGS' : 'FAIL'
80
- while record
81
- random = "#{prefix}-#{Array.new(6){ rand(6) }.join}"
82
- record = Spree::CreditCard.where(gateway_customer_profile_id: random).first
83
- end
84
- random
2
+ # @deprecated Use Spree::PaymentMethod::BogusCreditCard instead
3
+ class Gateway::Bogus < PaymentMethod::BogusCreditCard
4
+ def initialize(*args)
5
+ Spree::Deprecation.warn \
6
+ 'Spree::Gateway::Bogus is deprecated. ' \
7
+ 'Please use Spree::PaymentMethod::BogusCreditCard instead'
8
+ super
85
9
  end
86
10
  end
87
11
  end
@@ -1,24 +1,11 @@
1
1
  module Spree
2
- # Bogus Gateway that doesn't support payment profiles.
3
- class Gateway::BogusSimple < Gateway::Bogus
4
- def payment_profiles_supported?
5
- false
6
- end
7
-
8
- def authorize(_money, credit_card, _options = {})
9
- if VALID_CCS.include? credit_card.number
10
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'A' })
11
- else
12
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', { message: 'Bogus Gateway: Forced failure' }, test: true)
13
- end
14
- end
15
-
16
- def purchase(_money, credit_card, _options = {})
17
- if VALID_CCS.include? credit_card.number
18
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'A' })
19
- else
20
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', message: 'Bogus Gateway: Forced failure', test: true)
21
- end
2
+ # @deprecated Use Spree::PaymentMethod::SimpleBogusCreditCard instead
3
+ class Gateway::BogusSimple < Spree::PaymentMethod::SimpleBogusCreditCard
4
+ def initialize(*args)
5
+ Spree::Deprecation.warn \
6
+ 'Spree::Gateway::BogusSimple is deprecated. ' \
7
+ 'Please use Spree::PaymentMethod::SimpleBogusCreditCard instead'
8
+ super
22
9
  end
23
10
  end
24
11
  end
@@ -1,62 +1,12 @@
1
1
  module Spree
2
- # A concrete implementation of `Spree::PaymentMethod` intended to provide a
3
- # base for extension. See https://github.com/solidusio/solidus_gateway/ for
4
- # offically supported payment gateway implementations.
5
- #
6
- class Gateway < PaymentMethod
7
- delegate :authorize, :purchase, :capture, :void, :credit, to: :provider
8
-
9
- validates :name, :type, presence: true
10
-
11
- preference :server, :string, default: 'test'
12
- preference :test_mode, :boolean, default: true
13
-
14
- def payment_source_class
15
- CreditCard
16
- end
17
-
18
- def provider
19
- gateway_options = options
20
- gateway_options.delete :login if gateway_options.key?(:login) && gateway_options[:login].nil?
21
- if gateway_options[:server]
22
- ActiveMerchant::Billing::Base.mode = gateway_options[:server].to_sym
23
- end
24
- @provider ||= provider_class.new(gateway_options)
25
- end
26
-
27
- def options
28
- preferences.to_hash
29
- end
30
-
31
- def payment_profiles_supported?
32
- false
33
- end
34
-
35
- def method_type
36
- 'gateway'
37
- end
38
-
39
- def supports?(source)
40
- return true unless provider_class.respond_to? :supports?
41
- return true if source.brand && provider_class.supports?(source.brand)
42
- source.has_payment_profile?
43
- end
44
-
45
- def reusable_sources_by_order(order)
46
- source_ids = order.payments.where(payment_method_id: id).pluck(:source_id).uniq
47
- payment_source_class.where(id: source_ids).select(&:reusable?)
48
- end
49
- alias_method :sources_by_order, :reusable_sources_by_order
50
- deprecate sources_by_order: :reusable_sources_by_order, deprecator: Spree::Deprecation
51
-
52
- def reusable_sources(order)
53
- if order.completed?
54
- reusable_sources_by_order(order)
55
- elsif order.user_id
56
- order.user.wallet.wallet_payment_sources.map(&:payment_source).select(&:reusable?)
57
- else
58
- []
59
- end
2
+ # @deprecated Use Spree::PaymentMethod::CreditCard or Spree::PaymentMethod instead
3
+ class Gateway < PaymentMethod::CreditCard
4
+ def initialize(*args)
5
+ Spree::Deprecation.warn \
6
+ "Using Spree::Gateway as parent class of payment methods is deprecated. " \
7
+ "Please use Spree::PaymentMethod::CreditCard for credit card based payment methods " \
8
+ "or Spree::PaymentMethod for non credit card payment methods instead."
9
+ super
60
10
  end
61
11
  end
62
12
  end
@@ -15,7 +15,7 @@ module Spree
15
15
 
16
16
  # save the w,h of the original image (from which others can be calculated)
17
17
  # we need to look at the write-queue for images which have not been saved yet
18
- after_post_process :find_dimensions
18
+ after_post_process :find_dimensions, if: :valid?
19
19
 
20
20
  # used by admin products autocomplete
21
21
  def mini_url
@@ -175,7 +175,7 @@ module Spree
175
175
  end
176
176
 
177
177
  def update_inventory
178
- if (changed? || target_shipment.present?) && order.has_checkout_step?("delivery")
178
+ if (saved_changes? || target_shipment.present?) && order.has_checkout_step?("delivery")
179
179
  Spree::OrderInventory.new(order, self).verify(target_shipment)
180
180
  end
181
181
  end
@@ -9,7 +9,7 @@ module Spree
9
9
  validates :name, presence: true, uniqueness: { scope: :option_type_id, allow_blank: true }
10
10
  validates :presentation, presence: true
11
11
 
12
- after_save :touch, if: :changed?
12
+ after_save :touch, if: :saved_changes?
13
13
  after_touch :touch_all_variants
14
14
 
15
15
  delegate :name, :presentation, to: :option_type, prefix: :option_type
@@ -90,7 +90,7 @@ module Spree
90
90
  before_transition from: :cart, do: :ensure_line_items_present
91
91
 
92
92
  if states[:address]
93
- before_transition to: :address, do: :assign_default_addresses!
93
+ before_transition to: :address, do: :assign_default_user_addresses
94
94
  before_transition from: :address, do: :persist_user_address!
95
95
  end
96
96
 
@@ -108,9 +108,6 @@ module Spree
108
108
  # calls matter so that we do not process payments
109
109
  # until validations have passed
110
110
  before_transition to: :complete, do: :validate_line_item_availability
111
- if states[:delivery]
112
- before_transition to: :complete, do: :ensure_available_shipping_rates
113
- end
114
111
  before_transition to: :complete, do: :ensure_promotions_eligible
115
112
  before_transition to: :complete, do: :ensure_line_item_variants_are_not_deleted
116
113
  before_transition to: :complete, do: :ensure_inventory_units
@@ -0,0 +1,43 @@
1
+ module Spree
2
+ # Generates order numbers
3
+ #
4
+ # In order to change the way your order numbers get generated you can either
5
+ # set your own instance of this class in your stores configuration with different options:
6
+ #
7
+ # Spree::Config.order_number_generator = Spree::Order::NumberGenerator.new(
8
+ # prefix: 'B',
9
+ # lenght: 8,
10
+ # letters: false
11
+ # )
12
+ #
13
+ # or create your own class:
14
+ #
15
+ # Spree::Config.order_number_generator = My::OrderNumberGenerator.new
16
+ #
17
+ class Order::NumberGenerator
18
+ attr_reader :letters, :prefix
19
+
20
+ def initialize(options = {})
21
+ @length = options[:length] || Spree::Order::ORDER_NUMBER_LENGTH
22
+ @letters = options[:letters] || Spree::Order::ORDER_NUMBER_LETTERS
23
+ @prefix = options[:prefix] || Spree::Order::ORDER_NUMBER_PREFIX
24
+ end
25
+
26
+ def generate
27
+ possible = (0..9).to_a
28
+ possible += ('A'..'Z').to_a if letters
29
+
30
+ loop do
31
+ # Make a random number.
32
+ random = "#{prefix}#{(0...@length).map { possible.sample }.join}"
33
+ # Use the random number if no other order exists with it.
34
+ if Spree::Order.exists?(number: random)
35
+ # If over half of all possible options are taken add another digit.
36
+ @length += 1 if Spree::Order.count > (10**@length / 2)
37
+ else
38
+ break random
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end