solidus_core 2.2.2 → 2.3.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.
- checksums.yaml +4 -4
- data/README.md +4 -7
- data/app/assets/javascripts/spree.js.erb +2 -2
- data/app/helpers/spree/base_helper.rb +3 -4
- data/app/models/spree/address.rb +1 -1
- data/app/models/spree/adjustment.rb +3 -1
- data/app/models/spree/app_configuration.rb +43 -0
- data/app/models/spree/billing_integration.rb +2 -2
- data/app/models/spree/calculator/default_tax.rb +3 -1
- data/app/models/spree/calculator/distributed_amount.rb +24 -0
- data/app/models/spree/calculator/free_shipping.rb +0 -1
- data/app/models/spree/calculator/tiered_flat_rate.rb +17 -3
- data/app/models/spree/calculator/tiered_percent.rb +18 -3
- data/app/models/spree/distributed_amounts_handler.rb +43 -0
- data/app/models/spree/gateway/bogus.rb +7 -83
- data/app/models/spree/gateway/bogus_simple.rb +7 -20
- data/app/models/spree/gateway.rb +8 -58
- data/app/models/spree/image.rb +1 -1
- data/app/models/spree/line_item.rb +1 -1
- data/app/models/spree/option_value.rb +1 -1
- data/app/models/spree/order/checkout.rb +1 -4
- data/app/models/spree/order/number_generator.rb +43 -0
- data/app/models/spree/order.rb +33 -38
- data/app/models/spree/order_contents.rb +1 -1
- data/app/models/spree/order_taxation.rb +79 -0
- data/app/models/spree/order_update_attributes.rb +0 -2
- data/app/models/spree/order_updater.rb +55 -33
- data/app/models/spree/payment.rb +0 -1
- data/app/models/spree/payment_method/bogus_credit_card.rb +87 -0
- data/app/models/spree/payment_method/check.rb +14 -6
- data/app/models/spree/payment_method/credit_card.rb +41 -0
- data/app/models/spree/payment_method/simple_bogus_credit_card.rb +24 -0
- data/app/models/spree/payment_method/store_credit.rb +5 -13
- data/app/models/spree/payment_method.rb +126 -40
- data/app/models/spree/preferences/preferable.rb +5 -1
- data/app/models/spree/preferences/store.rb +2 -2
- data/app/models/spree/product/scopes.rb +14 -1
- data/app/models/spree/product.rb +10 -4
- data/app/models/spree/promotion_action.rb +4 -0
- data/app/models/spree/promotion_code/batch_builder.rb +3 -2
- data/app/models/spree/promotion_rule.rb +4 -0
- data/app/models/spree/role.rb +2 -0
- data/app/models/spree/role_user.rb +2 -0
- data/app/models/spree/shipment.rb +4 -2
- data/app/models/spree/shipping_method.rb +3 -1
- data/app/models/spree/shipping_rate.rb +1 -1
- data/app/models/spree/state.rb +10 -2
- data/app/models/spree/stock_item.rb +3 -3
- data/app/models/spree/store.rb +5 -0
- data/app/models/spree/store_credit.rb +2 -2
- data/app/models/spree/store_credit_event.rb +1 -1
- data/app/models/spree/store_selector/by_server_name.rb +30 -0
- data/app/models/spree/store_selector/legacy.rb +48 -0
- data/app/models/spree/tax/item_tax.rb +20 -0
- data/app/models/spree/tax/order_adjuster.rb +2 -14
- data/app/models/spree/tax/order_tax.rb +18 -0
- data/app/models/spree/tax/shipping_rate_taxer.rb +4 -13
- data/app/models/spree/tax/tax_helpers.rb +5 -3
- data/app/models/spree/tax_calculator/default.rb +83 -0
- data/app/models/spree/tax_calculator/shipping_rate.rb +46 -0
- data/app/models/spree/tax_category.rb +9 -1
- data/app/models/spree/tax_rate.rb +31 -7
- data/app/models/spree/tax_rate_tax_category.rb +6 -0
- data/app/models/spree/taxon.rb +1 -1
- data/app/models/spree/variant.rb +1 -1
- data/app/views/spree/{shipment_mailer → carton_mailer}/shipped_email.html.erb +3 -3
- data/app/views/spree/order_mailer/cancel_email.html.erb +3 -3
- data/app/views/spree/order_mailer/confirm_email.html.erb +2 -2
- data/app/views/spree/order_mailer/inventory_cancellation_email.html.erb +26 -0
- data/app/views/spree/reimbursement_mailer/reimbursement_email.html.erb +2 -2
- data/app/views/spree/test_mailer/test_email.html.erb +2 -2
- data/config/locales/en.yml +66 -57
- data/db/default/spree/refund_reasons.rb +1 -0
- data/db/default/spree/shipping_categories.rb +1 -0
- data/db/default/spree/stock_locations.rb +2 -0
- data/db/default/spree/stores.rb +3 -4
- data/db/migrate/20170412103617_transform_tax_rate_category_relation.rb +48 -0
- data/db/migrate/20170422134804_add_roles_unique_constraints.rb +6 -0
- data/db/migrate/20170522143442_add_time_range_to_tax_rate.rb +6 -0
- data/db/migrate/20170608074534_rename_bogus_gateways.rb +13 -0
- data/lib/generators/spree/custom_user/custom_user_generator.rb +1 -1
- data/lib/generators/spree/dummy/dummy_generator.rb +10 -4
- data/lib/generators/spree/dummy/templates/rails/database.yml +12 -12
- data/lib/generators/spree/install/install_generator.rb +5 -5
- data/lib/generators/spree/install/templates/config/initializers/{spree.rb → solidus.rb} +0 -0
- data/lib/solidus/migrations/rename_gateways.rb +39 -0
- data/lib/spree/core/controller_helpers/auth.rb +1 -1
- data/lib/spree/core/controller_helpers/order.rb +10 -5
- data/lib/spree/core/controller_helpers/store.rb +1 -9
- data/lib/spree/core/current_store.rb +6 -14
- data/lib/spree/core/engine.rb +4 -3
- data/lib/spree/core/importer/order.rb +4 -4
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +0 -1
- data/lib/spree/localized_number.rb +2 -1
- data/lib/spree/permitted_attributes.rb +12 -6
- data/lib/spree/testing_support/capybara_ext.rb +0 -1
- data/lib/spree/testing_support/factories/adjustment_factory.rb +5 -1
- data/lib/spree/testing_support/factories/order_factory.rb +26 -24
- data/lib/spree/testing_support/factories/payment_factory.rb +4 -0
- data/lib/spree/testing_support/factories/payment_method_factory.rb +3 -3
- data/lib/spree/testing_support/factories/shipment_factory.rb +7 -3
- data/lib/spree/testing_support/factories/tax_rate_factory.rb +1 -1
- data/lib/spree/testing_support/factories/variant_factory.rb +3 -1
- data/lib/tasks/migrations/copy_order_bill_address_to_credit_card.rake +0 -4
- data/lib/tasks/migrations/migrate_user_addresses.rake +2 -2
- data/lib/tasks/migrations/rename_gateways.rake +19 -0
- data/solidus_core.gemspec +2 -3
- data/spec/lib/spree/core/controller_helpers/order_spec.rb +32 -6
- data/spec/lib/spree/core/controller_helpers/payment_parameters_spec.rb +0 -1
- data/spec/lib/spree/core/current_store_spec.rb +6 -11
- data/spec/lib/spree/core/price_migrator_spec.rb +4 -4
- data/spec/lib/spree/core/testing_support/factories/order_factory_spec.rb +199 -91
- data/spec/lib/spree/core/testing_support/factories/variant_factory_spec.rb +18 -0
- data/spec/lib/spree/localized_number_spec.rb +6 -0
- data/spec/mailers/carton_mailer_spec.rb +3 -3
- data/spec/models/spree/address_spec.rb +3 -3
- data/spec/models/spree/adjustment_spec.rb +71 -27
- data/spec/models/spree/calculator/default_tax_spec.rb +72 -1
- data/spec/models/spree/calculator/distributed_amount_spec.rb +32 -0
- data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +20 -1
- data/spec/models/spree/calculator/tiered_percent_spec.rb +20 -1
- data/spec/models/spree/distributed_amounts_handler_spec.rb +79 -0
- data/spec/models/spree/gateway/bogus_simple.rb +7 -13
- data/spec/models/spree/gateway/bogus_spec.rb +8 -4
- data/spec/models/spree/gateway_spec.rb +6 -105
- data/spec/models/spree/image_spec.rb +23 -0
- data/spec/models/spree/order/checkout_spec.rb +3 -18
- data/spec/models/spree/order/number_generator_spec.rb +45 -0
- data/spec/models/spree/order/outstanding_balance_integration_spec.rb +135 -0
- data/spec/models/spree/order/payment_spec.rb +7 -2
- data/spec/models/spree/order/state_machine_spec.rb +4 -2
- data/spec/models/spree/order_capturing_spec.rb +8 -8
- data/spec/models/spree/order_contents_spec.rb +8 -1
- data/spec/models/spree/order_shipping_spec.rb +5 -1
- data/spec/models/spree/order_spec.rb +156 -83
- data/spec/models/spree/order_taxation_spec.rb +126 -0
- data/spec/models/spree/order_update_attributes_spec.rb +1 -5
- data/spec/models/spree/order_updater_spec.rb +20 -21
- data/spec/models/spree/payment_create_spec.rb +14 -6
- data/spec/models/spree/payment_method/bogus_credit_card_spec.rb +8 -0
- data/spec/models/spree/payment_method/check_spec.rb +78 -0
- data/spec/models/spree/payment_method/credit_card_spec.rb +66 -0
- data/spec/models/spree/payment_method/simple_bogus_credit_card_spec.rb +18 -0
- data/spec/models/spree/payment_method_spec.rb +47 -2
- data/spec/models/spree/payment_spec.rb +6 -8
- data/spec/models/spree/preference_spec.rb +1 -1
- data/spec/models/spree/price_spec.rb +1 -1
- data/spec/models/spree/product/scopes_spec.rb +46 -0
- data/spec/models/spree/promotion_action_spec.rb +4 -0
- data/spec/models/spree/promotion_code/batch_builder_spec.rb +25 -3
- data/spec/models/spree/promotion_code_batch_spec.rb +0 -6
- data/spec/models/spree/promotion_handler/coupon_spec.rb +1 -1
- data/spec/models/spree/promotion_rule_spec.rb +5 -0
- data/spec/models/spree/reimbursement_type/original_payment_spec.rb +1 -1
- data/spec/models/spree/shipment_spec.rb +24 -3
- data/spec/models/spree/shipping_rate_spec.rb +5 -5
- data/spec/models/spree/state_spec.rb +31 -4
- data/spec/models/spree/stock/coordinator_spec.rb +24 -0
- data/spec/models/spree/stock/estimator_spec.rb +1 -1
- data/spec/models/spree/store_selector/by_server_name_spec.rb +26 -0
- data/spec/models/spree/store_selector/legacy_spec.rb +44 -0
- data/spec/models/spree/store_spec.rb +10 -2
- data/spec/models/spree/tax/order_adjuster_spec.rb +11 -21
- data/spec/models/spree/tax/shipping_rate_taxer_spec.rb +10 -3
- data/spec/models/spree/tax/taxation_integration_spec.rb +43 -8
- data/spec/models/spree/tax_calculator/default_spec.rb +54 -0
- data/spec/models/spree/tax_rate_spec.rb +92 -0
- data/spec/models/spree/variant/vat_price_generator_spec.rb +4 -4
- data/spec/models/spree/variant_spec.rb +8 -2
- data/spec/spec_helper.rb +2 -1
- data/spec/support/test_gateway.rb +1 -1
- metadata +45 -24
- data/app/models/spree/tax/item_adjuster.rb +0 -51
- 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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d015fdadf3dd41148e17b69ff2432090071c998
|
|
4
|
+
data.tar.gz: cf60f2cdfa6b33eccb82886b942a23b3253a5557
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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` -
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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 (
|
|
27
|
-
console.warn('Spree.url is deprecated,
|
|
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
|
|
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}: (#{
|
|
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
|
data/app/models/spree/address.rb
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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
|
|
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
|
-
@
|
|
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
|
|
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
|
-
[
|
|
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
|
|
21
|
-
|
|
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
|
-
[
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
#
|
|
3
|
-
class Gateway::BogusSimple <
|
|
4
|
-
def
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
data/app/models/spree/gateway.rb
CHANGED
|
@@ -1,62 +1,12 @@
|
|
|
1
1
|
module Spree
|
|
2
|
-
#
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
data/app/models/spree/image.rb
CHANGED
|
@@ -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 (
|
|
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: :
|
|
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: :
|
|
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
|