spree_core 3.3.6 → 3.4.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/helpers/spree/base_helper.rb +17 -18
- data/app/helpers/spree/products_helper.rb +5 -5
- data/app/models/concerns/spree/calculated_adjustments.rb +4 -3
- data/app/models/concerns/spree/default_price.rb +4 -5
- data/app/models/concerns/spree/display_money.rb +1 -1
- data/app/models/concerns/spree/named_type.rb +1 -1
- data/app/models/concerns/spree/ransackable_attributes.rb +5 -6
- data/app/models/concerns/spree/user_address.rb +6 -6
- data/app/models/concerns/spree/user_methods.rb +3 -3
- data/app/models/concerns/spree/user_payment_source.rb +4 -2
- data/app/models/concerns/spree/user_reporting.rb +1 -1
- data/app/models/spree/ability.rb +3 -3
- data/app/models/spree/address.rb +13 -9
- data/app/models/spree/adjustable/adjuster/promotion.rb +1 -1
- data/app/models/spree/adjustable/adjustments_updater.rb +2 -2
- data/app/models/spree/adjustable/promotion_accumulator.rb +6 -4
- data/app/models/spree/adjustment.rb +2 -3
- data/app/models/spree/app_configuration.rb +5 -6
- data/app/models/spree/base.rb +1 -1
- data/app/models/spree/calculator/default_tax.rb +4 -5
- data/app/models/spree/calculator/flat_percent_item_total.rb +1 -1
- data/app/models/spree/calculator/flat_rate.rb +3 -3
- data/app/models/spree/calculator/flexi_rate.rb +5 -5
- data/app/models/spree/calculator/price_sack.rb +9 -9
- data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +1 -1
- data/app/models/spree/calculator/shipping/flat_rate.rb +3 -3
- data/app/models/spree/calculator/shipping/flexi_rate.rb +7 -7
- data/app/models/spree/calculator/shipping/per_item.rb +2 -2
- data/app/models/spree/calculator/shipping/price_sack.rb +4 -4
- data/app/models/spree/calculator/tiered_flat_rate.rb +3 -2
- data/app/models/spree/calculator/tiered_percent.rb +4 -3
- data/app/models/spree/calculator.rb +4 -4
- data/app/models/spree/classification.rb +2 -2
- data/app/models/spree/credit_card.rb +1 -1
- data/app/models/spree/exchange.rb +4 -5
- data/app/models/spree/gateway/bogus.rb +20 -20
- data/app/models/spree/gateway/bogus_simple.rb +2 -4
- data/app/models/spree/gateway.rb +4 -4
- data/app/models/spree/image.rb +3 -3
- data/app/models/spree/inventory_unit.rb +30 -30
- data/app/models/spree/line_item.rb +7 -9
- data/app/models/spree/option_type.rb +1 -1
- data/app/models/spree/order/checkout.rb +5 -5
- data/app/models/spree/order/currency_updater.rb +1 -4
- data/app/models/spree/order/payments.rb +4 -4
- data/app/models/spree/order/store_credit.rb +2 -2
- data/app/models/spree/order.rb +11 -29
- data/app/models/spree/order_contents.rb +6 -5
- data/app/models/spree/order_inventory.rb +3 -4
- data/app/models/spree/order_updater.rb +13 -14
- data/app/models/spree/payment/processing.rb +25 -26
- data/app/models/spree/payment.rb +72 -79
- data/app/models/spree/payment_capture_event.rb +1 -1
- data/app/models/spree/payment_method/check.rb +1 -1
- data/app/models/spree/payment_method/store_credit.rb +5 -5
- data/app/models/spree/payment_method.rb +7 -7
- data/app/models/spree/preferences/configuration.rb +6 -9
- data/app/models/spree/preferences/preferable.rb +11 -11
- data/app/models/spree/preferences/preferable_class_methods.rb +2 -3
- data/app/models/spree/preferences/scoped_store.rb +6 -5
- data/app/models/spree/preferences/store.rb +9 -14
- data/app/models/spree/price.rb +1 -1
- data/app/models/spree/product/scopes.rb +49 -49
- data/app/models/spree/product.rb +16 -16
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +2 -1
- data/app/models/spree/promotion/actions/free_shipping.rb +1 -1
- data/app/models/spree/promotion/rules/first_order.rb +7 -6
- data/app/models/spree/promotion/rules/item_total.rb +3 -5
- data/app/models/spree/promotion/rules/one_use_per_user.rb +1 -2
- data/app/models/spree/promotion/rules/option_value.rb +14 -6
- data/app/models/spree/promotion/rules/product.rb +4 -4
- data/app/models/spree/promotion/rules/taxon.rb +6 -6
- data/app/models/spree/promotion/rules/user.rb +3 -3
- data/app/models/spree/promotion/rules/user_logged_in.rb +1 -1
- data/app/models/spree/promotion.rb +15 -16
- data/app/models/spree/promotion_action.rb +1 -1
- data/app/models/spree/promotion_handler/cart.rb +3 -2
- data/app/models/spree/promotion_handler/free_shipping.rb +1 -3
- data/app/models/spree/promotion_handler/page.rb +3 -3
- data/app/models/spree/promotion_rule.rb +5 -4
- data/app/models/spree/refund.rb +8 -8
- data/app/models/spree/reimbursement/credit.rb +1 -1
- data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -3
- data/app/models/spree/reimbursement.rb +4 -8
- data/app/models/spree/reimbursement_performer.rb +0 -5
- data/app/models/spree/reimbursement_tax_calculator.rb +5 -12
- data/app/models/spree/reimbursement_type.rb +2 -2
- data/app/models/spree/return_authorization.rb +22 -26
- data/app/models/spree/return_item/eligibility_validator/default.rb +3 -3
- data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/order_completed.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/rma_required.rb +2 -3
- data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +2 -2
- data/app/models/spree/return_item.rb +15 -19
- data/app/models/spree/returns_calculator.rb +1 -2
- data/app/models/spree/shipment.rb +14 -35
- data/app/models/spree/shipment_handler.rb +10 -12
- data/app/models/spree/shipping_calculator.rb +5 -6
- data/app/models/spree/shipping_method.rb +3 -3
- data/app/models/spree/shipping_rate.rb +2 -2
- data/app/models/spree/state.rb +2 -2
- data/app/models/spree/stock/availability_validator.rb +1 -1
- data/app/models/spree/stock/content_item.rb +2 -3
- data/app/models/spree/stock/coordinator.rb +3 -2
- data/app/models/spree/stock/differentiator.rb +3 -2
- data/app/models/spree/stock/estimator.rb +7 -5
- data/app/models/spree/stock/package.rb +5 -5
- data/app/models/spree/stock/packer.rb +1 -1
- data/app/models/spree/stock/prioritizer.rb +5 -7
- data/app/models/spree/stock/quantifier.rb +0 -1
- data/app/models/spree/stock/splitter/backordered.rb +2 -4
- data/app/models/spree/stock/splitter/base.rb +3 -2
- data/app/models/spree/stock/splitter/shipping_category.rb +2 -1
- data/app/models/spree/stock_item.rb +1 -1
- data/app/models/spree/stock_location.rb +12 -11
- data/app/models/spree/stock_movement.rb +1 -3
- data/app/models/spree/stock_transfer.rb +1 -1
- data/app/models/spree/store.rb +4 -4
- data/app/models/spree/store_credit.rb +3 -3
- data/app/models/spree/tax_category.rb +1 -1
- data/app/models/spree/tax_rate.rb +10 -10
- data/app/models/spree/taxon.rb +13 -13
- data/app/models/spree/taxonomy.rb +9 -8
- data/app/models/spree/validations/db_maximum_length_validator.rb +2 -3
- data/app/models/spree/variant.rb +30 -41
- data/app/models/spree/zone.rb +10 -10
- data/app/validators/db_maximum_length_validator.rb +5 -5
- data/config/initializers/acts_as_taggable_on.rb +3 -3
- data/config/initializers/assets.rb +1 -1
- data/config/initializers/friendly_id.rb +1 -1
- data/config/initializers/premailer_assets.rb +1 -1
- data/config/locales/en.yml +8 -2
- data/db/default/spree/states.rb +1 -0
- data/lib/generators/spree/custom_user/custom_user_generator.rb +12 -15
- data/lib/generators/spree/install/install_generator.rb +45 -32
- data/lib/spree/core/components.rb +3 -3
- data/lib/spree/core/controller_helpers/auth.rb +5 -10
- data/lib/spree/core/controller_helpers/common.rb +2 -3
- data/lib/spree/core/controller_helpers/order.rb +3 -7
- data/lib/spree/core/controller_helpers/respond_with.rb +4 -4
- data/lib/spree/core/engine.rb +3 -3
- data/lib/spree/core/environment/calculators.rb +0 -1
- data/lib/spree/core/environment_extension.rb +8 -8
- data/lib/spree/core/importer/order.rb +64 -67
- data/lib/spree/core/importer/product.rb +10 -9
- data/lib/spree/core/product_filters.rb +17 -18
- data/lib/spree/core/routes.rb +2 -6
- data/lib/spree/core/search/base.rb +62 -59
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +4 -6
- data/lib/spree/i18n.rb +3 -5
- data/lib/spree/localized_number.rb +0 -2
- data/lib/spree/migrations.rb +8 -7
- data/lib/spree/money.rb +3 -7
- data/lib/spree/permitted_attributes.rb +2 -2
- data/lib/spree/responder.rb +4 -5
- data/lib/spree/testing_support/authorization_helpers.rb +3 -3
- data/lib/spree/testing_support/caching.rb +5 -5
- data/lib/spree/testing_support/capybara_ext.rb +16 -18
- data/lib/spree/testing_support/common_rake.rb +8 -9
- data/lib/spree/testing_support/controller_requests.rb +6 -6
- data/lib/spree/testing_support/extension_rake.rb +2 -3
- data/lib/spree/testing_support/factories/address_factory.rb +1 -1
- data/lib/spree/testing_support/factories/adjustment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/calculator_factory.rb +1 -1
- data/lib/spree/testing_support/factories/country_factory.rb +1 -1
- data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
- data/lib/spree/testing_support/factories/customer_return_factory.rb +1 -3
- data/lib/spree/testing_support/factories/image_factory.rb +2 -2
- data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
- data/lib/spree/testing_support/factories/line_item_factory.rb +2 -2
- data/lib/spree/testing_support/factories/options_factory.rb +1 -1
- data/lib/spree/testing_support/factories/order_factory.rb +1 -1
- data/lib/spree/testing_support/factories/payment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/payment_method_factory.rb +4 -4
- data/lib/spree/testing_support/factories/price_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_option_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_property_factory.rb +1 -1
- data/lib/spree/testing_support/factories/promotion_category_factory.rb +1 -2
- data/lib/spree/testing_support/factories/promotion_factory.rb +1 -2
- data/lib/spree/testing_support/factories/promotion_rule_factory.rb +1 -1
- data/lib/spree/testing_support/factories/property_factory.rb +1 -1
- data/lib/spree/testing_support/factories/prototype_factory.rb +1 -1
- data/lib/spree/testing_support/factories/refund_factory.rb +1 -1
- data/lib/spree/testing_support/factories/reimbursement_factory.rb +2 -2
- data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/return_authorization_factory.rb +1 -1
- data/lib/spree/testing_support/factories/return_item_factory.rb +1 -1
- data/lib/spree/testing_support/factories/role_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipment_factory.rb +2 -2
- data/lib/spree/testing_support/factories/shipping_category_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +3 -3
- data/lib/spree/testing_support/factories/state_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_item_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_location_factory.rb +2 -2
- data/lib/spree/testing_support/factories/stock_movement_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_category_factory.rb +2 -2
- data/lib/spree/testing_support/factories/store_credit_event_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tag_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tax_category_factory.rb +2 -2
- data/lib/spree/testing_support/factories/tax_rate_factory.rb +1 -1
- data/lib/spree/testing_support/factories/taxon_factory.rb +1 -1
- data/lib/spree/testing_support/factories/taxonomy_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tracker_factory.rb +1 -1
- data/lib/spree/testing_support/factories/user_factory.rb +1 -1
- data/lib/spree/testing_support/factories/variant_factory.rb +1 -2
- data/lib/spree/testing_support/factories/zone_factory.rb +1 -1
- data/lib/spree/testing_support/factories/zone_member_factory.rb +1 -1
- data/lib/spree/testing_support/factories.rb +3 -3
- data/lib/spree/testing_support/flash.rb +1 -3
- data/lib/spree/testing_support/i18n.rb +5 -6
- data/lib/spree/testing_support/kernel.rb +1 -2
- data/lib/spree/testing_support/order_walkthrough.rb +12 -15
- data/lib/spree/testing_support/preferences.rb +0 -1
- data/lib/tasks/core.rake +47 -56
- data/lib/tasks/email.rake +2 -2
- data/lib/tasks/exchanges.rake +5 -5
- data/spree_core.gemspec +1 -1
- metadata +5 -9
- data/app/models/spree/calculator/percent_per_item.rb +0 -51
- data/config/initializers/premailer_rails.rb +0 -3
- data/lib/spree/core/delegate_belongs_to.rb +0 -99
- data/lib/spree/testing_support/microdata.rb +0 -192
@@ -4,12 +4,10 @@ module Spree
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
|
8
7
|
def homogenize_line_item_currencies
|
9
8
|
update_line_item_currencies!
|
10
9
|
update_with_updater!
|
11
10
|
end
|
12
|
-
|
13
11
|
end
|
14
12
|
|
15
13
|
# Updates prices of order's line items
|
@@ -31,10 +29,9 @@ module Spree
|
|
31
29
|
if price
|
32
30
|
line_item.update_attributes!(currency: price.currency, price: price.amount)
|
33
31
|
else
|
34
|
-
raise
|
32
|
+
raise "no #{currency} price found for #{line_item.product.name} (#{line_item.variant.sku})"
|
35
33
|
end
|
36
34
|
end
|
37
|
-
|
38
35
|
end
|
39
36
|
end
|
40
37
|
end
|
@@ -32,11 +32,11 @@ module Spree
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def pending_payments
|
35
|
-
payments.select
|
35
|
+
payments.select(&:pending?)
|
36
36
|
end
|
37
37
|
|
38
38
|
def unprocessed_payments
|
39
|
-
payments.select
|
39
|
+
payments.select(&:checkout?)
|
40
40
|
end
|
41
41
|
|
42
42
|
private
|
@@ -45,7 +45,7 @@ module Spree
|
|
45
45
|
# Don't run if there is nothing to pay.
|
46
46
|
return if payment_total >= total
|
47
47
|
# Prevent orders from transitioning to complete without a successfully processed payment.
|
48
|
-
raise Core::GatewayError
|
48
|
+
raise Core::GatewayError, Spree.t(:no_payment_found) if unprocessed_payments.empty?
|
49
49
|
|
50
50
|
unprocessed_payments.each do |payment|
|
51
51
|
break if payment_total >= total
|
@@ -58,7 +58,7 @@ module Spree
|
|
58
58
|
end
|
59
59
|
rescue Core::GatewayError => e
|
60
60
|
result = !!Spree::Config[:allow_checkout_on_gateway_error]
|
61
|
-
errors.add(:base, e.message)
|
61
|
+
errors.add(:base, e.message) && (return result)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -8,7 +8,7 @@ module Spree
|
|
8
8
|
|
9
9
|
if user && user.store_credits.any?
|
10
10
|
payment_method = Spree::PaymentMethod::StoreCredit.available.first
|
11
|
-
raise
|
11
|
+
raise 'Store credit payment method could not be found' unless payment_method
|
12
12
|
|
13
13
|
user.store_credits.order_by_priority.each do |credit|
|
14
14
|
break if remaining_total.zero?
|
@@ -30,7 +30,7 @@ module Spree
|
|
30
30
|
return false unless user
|
31
31
|
user.total_available_store_credit >= total
|
32
32
|
end
|
33
|
-
|
33
|
+
alias covered_by_store_credit covered_by_store_credit?
|
34
34
|
|
35
35
|
def total_available_store_credit
|
36
36
|
return 0.0 unless user
|
data/app/models/spree/order.rb
CHANGED
@@ -20,7 +20,7 @@ module Spree
|
|
20
20
|
:included_tax_total, :additional_tax_total, :tax_total,
|
21
21
|
:shipment_total, :promo_total, :total
|
22
22
|
|
23
|
-
alias
|
23
|
+
alias display_ship_total display_shipment_total
|
24
24
|
alias_attribute :ship_total, :shipment_total
|
25
25
|
|
26
26
|
MONEY_THRESHOLD = 100_000_000
|
@@ -196,7 +196,7 @@ module Spree
|
|
196
196
|
# least one LineItem in the Order. Feel free to override this logic in your
|
197
197
|
# own application if you require additional steps before allowing a checkout.
|
198
198
|
def checkout_allowed?
|
199
|
-
line_items.
|
199
|
+
line_items.exists?
|
200
200
|
end
|
201
201
|
|
202
202
|
# Is this a free order in which case the payment step should be skipped
|
@@ -268,8 +268,8 @@ module Spree
|
|
268
268
|
self.user = user
|
269
269
|
self.email = user.email if override_email
|
270
270
|
self.created_by ||= user
|
271
|
-
self.bill_address ||= user.bill_address
|
272
|
-
self.ship_address ||= user.ship_address
|
271
|
+
self.bill_address ||= user.bill_address
|
272
|
+
self.ship_address ||= user.ship_address
|
273
273
|
|
274
274
|
changes = slice(:user_id, :email, :created_by_id, :bill_address_id, :ship_address_id)
|
275
275
|
|
@@ -486,7 +486,7 @@ module Spree
|
|
486
486
|
all_adjustments.shipping.delete_all
|
487
487
|
|
488
488
|
shipment_ids = shipments.map(&:id)
|
489
|
-
StateChange.where(stateful_type:
|
489
|
+
StateChange.where(stateful_type: 'Spree::Shipment', stateful_id: shipment_ids).delete_all
|
490
490
|
ShippingRate.where(shipment_id: shipment_ids).delete_all
|
491
491
|
|
492
492
|
shipments.delete_all
|
@@ -521,9 +521,9 @@ module Spree
|
|
521
521
|
def restart_checkout_flow
|
522
522
|
update_columns(
|
523
523
|
state: 'cart',
|
524
|
-
updated_at: Time.current
|
524
|
+
updated_at: Time.current
|
525
525
|
)
|
526
|
-
next!
|
526
|
+
next! unless line_items.empty?
|
527
527
|
end
|
528
528
|
|
529
529
|
def refresh_shipment_rates(shipping_method_filter = ShippingMethod::DISPLAY_ON_FRONT_END)
|
@@ -549,7 +549,7 @@ module Spree
|
|
549
549
|
cancel!
|
550
550
|
update_columns(
|
551
551
|
canceler_id: user.id,
|
552
|
-
canceled_at: Time.current
|
552
|
+
canceled_at: Time.current
|
553
553
|
)
|
554
554
|
end
|
555
555
|
end
|
@@ -559,7 +559,7 @@ module Spree
|
|
559
559
|
approve!
|
560
560
|
update_columns(
|
561
561
|
approver_id: user.id,
|
562
|
-
approved_at: Time.current
|
562
|
+
approved_at: Time.current
|
563
563
|
)
|
564
564
|
end
|
565
565
|
end
|
@@ -573,9 +573,7 @@ module Spree
|
|
573
573
|
end
|
574
574
|
|
575
575
|
def consider_risk
|
576
|
-
if is_risky? && !approved?
|
577
|
-
considered_risky!
|
578
|
-
end
|
576
|
+
considered_risky! if is_risky? && !approved?
|
579
577
|
end
|
580
578
|
|
581
579
|
def considered_risky!
|
@@ -616,28 +614,12 @@ module Spree
|
|
616
614
|
def fully_discounted?
|
617
615
|
adjustment_total + line_items.map(&:final_amount).sum == 0.0
|
618
616
|
end
|
619
|
-
|
617
|
+
alias fully_discounted fully_discounted?
|
620
618
|
|
621
619
|
def promo_code
|
622
620
|
promotions.pluck(:code).compact.first
|
623
621
|
end
|
624
622
|
|
625
|
-
def payments_attributes=(attributes)
|
626
|
-
validate_payments_attributes(attributes)
|
627
|
-
super(attributes)
|
628
|
-
end
|
629
|
-
|
630
|
-
def validate_payments_attributes(attributes)
|
631
|
-
# Ensure the payment methods specified are allowed for this user
|
632
|
-
payment_methods = Spree::PaymentMethod.where(id: available_payment_methods.map(&:id))
|
633
|
-
attributes.each do |payment_attributes|
|
634
|
-
payment_method_id = payment_attributes[:payment_method_id]
|
635
|
-
|
636
|
-
# raise RecordNotFound unless it is an allowed payment method
|
637
|
-
payment_methods.find(payment_method_id) if payment_method_id
|
638
|
-
end
|
639
|
-
end
|
640
|
-
|
641
623
|
private
|
642
624
|
|
643
625
|
def link_by_email
|
@@ -81,6 +81,7 @@ module Spree
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def persist_totals
|
84
|
+
order_updater.update_item_count
|
84
85
|
order_updater.update
|
85
86
|
end
|
86
87
|
|
@@ -94,13 +95,13 @@ module Spree
|
|
94
95
|
options_params = options.is_a?(ActionController::Parameters) ? options : ActionController::Parameters.new(options.to_h)
|
95
96
|
opts = options_params.
|
96
97
|
permit(PermittedAttributes.line_item_attributes).to_h.
|
97
|
-
merge(
|
98
|
+
merge(currency: order.currency)
|
98
99
|
|
99
100
|
line_item = order.line_items.new(quantity: quantity,
|
100
|
-
|
101
|
-
|
101
|
+
variant: variant,
|
102
|
+
options: opts)
|
102
103
|
end
|
103
|
-
line_item.target_shipment = options[:shipment] if options.
|
104
|
+
line_item.target_shipment = options[:shipment] if options.key? :shipment
|
104
105
|
line_item.save!
|
105
106
|
line_item
|
106
107
|
end
|
@@ -108,7 +109,7 @@ module Spree
|
|
108
109
|
def remove_from_line_item(variant, quantity, options = {})
|
109
110
|
line_item = grab_line_item_by_variant(variant, true, options)
|
110
111
|
line_item.quantity -= quantity
|
111
|
-
line_item.target_shipment= options[:shipment]
|
112
|
+
line_item.target_shipment = options[:shipment]
|
112
113
|
|
113
114
|
if line_item.quantity.zero?
|
114
115
|
order.line_items.destroy(line_item)
|
@@ -72,10 +72,10 @@ module Spree
|
|
72
72
|
if variant.should_track_inventory?
|
73
73
|
on_hand, back_order = shipment.stock_location.fill_status(variant, quantity)
|
74
74
|
|
75
|
-
shipment.set_up_inventory('on_hand', variant, order, line_item
|
76
|
-
shipment.set_up_inventory('backordered', variant, order, line_item
|
75
|
+
on_hand.times { shipment.set_up_inventory('on_hand', variant, order, line_item) }
|
76
|
+
back_order.times { shipment.set_up_inventory('backordered', variant, order, line_item) }
|
77
77
|
else
|
78
|
-
shipment.set_up_inventory('on_hand', variant, order, line_item
|
78
|
+
quantity.times { shipment.set_up_inventory('on_hand', variant, order, line_item) }
|
79
79
|
end
|
80
80
|
|
81
81
|
# adding to this shipment, and removing from stock_location
|
@@ -103,7 +103,6 @@ module Spree
|
|
103
103
|
end
|
104
104
|
removed_quantity += 1
|
105
105
|
end
|
106
|
-
inventory_unit.save! if inventory_unit.persisted?
|
107
106
|
end
|
108
107
|
|
109
108
|
shipment.destroy if shipment.inventory_units.sum(:quantity).zero?
|
@@ -51,7 +51,6 @@ module Spree
|
|
51
51
|
update_adjustment_total
|
52
52
|
end
|
53
53
|
|
54
|
-
|
55
54
|
# give each of the shipments a chance to update themselves
|
56
55
|
def update_shipments
|
57
56
|
shipments.each do |shipment|
|
@@ -78,14 +77,14 @@ module Spree
|
|
78
77
|
def update_adjustment_total
|
79
78
|
recalculate_adjustments
|
80
79
|
order.adjustment_total = line_items.sum(:adjustment_total) +
|
81
|
-
|
82
|
-
|
80
|
+
shipments.sum(:adjustment_total) +
|
81
|
+
adjustments.eligible.sum(:amount)
|
83
82
|
order.included_tax_total = line_items.sum(:included_tax_total) + shipments.sum(:included_tax_total)
|
84
83
|
order.additional_tax_total = line_items.sum(:additional_tax_total) + shipments.sum(:additional_tax_total)
|
85
84
|
|
86
85
|
order.promo_total = line_items.sum(:promo_total) +
|
87
|
-
|
88
|
-
|
86
|
+
shipments.sum(:promo_total) +
|
87
|
+
adjustments.promotion.eligible.sum(:amount)
|
89
88
|
|
90
89
|
update_order_total
|
91
90
|
end
|
@@ -112,7 +111,7 @@ module Spree
|
|
112
111
|
shipment_total: order.shipment_total,
|
113
112
|
promo_total: order.promo_total,
|
114
113
|
total: order.total,
|
115
|
-
updated_at: Time.current
|
114
|
+
updated_at: Time.current
|
116
115
|
)
|
117
116
|
end
|
118
117
|
|
@@ -132,18 +131,18 @@ module Spree
|
|
132
131
|
else
|
133
132
|
# get all the shipment states for this order
|
134
133
|
shipment_states = shipments.states
|
135
|
-
if shipment_states.size > 1
|
134
|
+
order.shipment_state = if shipment_states.size > 1
|
136
135
|
# multiple shiment states means it's most likely partially shipped
|
137
|
-
|
138
|
-
|
136
|
+
'partial'
|
137
|
+
else
|
139
138
|
# will return nil if no shipments are found
|
140
|
-
|
141
|
-
# TODO inventory unit states?
|
139
|
+
shipment_states.first
|
140
|
+
# TODO: inventory unit states?
|
142
141
|
# if order.shipment_state && order.inventory_units.where(shipment_id: nil).exists?
|
143
142
|
# shipments exist but there are unassigned inventory units
|
144
143
|
# order.shipment_state = 'partial'
|
145
144
|
# end
|
146
|
-
|
145
|
+
end
|
147
146
|
end
|
148
147
|
|
149
148
|
order.state_changed('shipment')
|
@@ -161,14 +160,14 @@ module Spree
|
|
161
160
|
# The +payment_state+ value helps with reporting, etc. since it provides a quick and easy way to locate Orders needing attention.
|
162
161
|
def update_payment_state
|
163
162
|
last_state = order.payment_state
|
164
|
-
if payments.present? && payments.valid.
|
163
|
+
if payments.present? && payments.valid.empty?
|
165
164
|
order.payment_state = 'failed'
|
166
165
|
elsif order.canceled? && order.payment_total == 0
|
167
166
|
order.payment_state = 'void'
|
168
167
|
else
|
169
168
|
order.payment_state = 'balance_due' if order.outstanding_balance > 0
|
170
169
|
order.payment_state = 'credit_owed' if order.outstanding_balance < 0
|
171
|
-
order.payment_state = 'paid'
|
170
|
+
order.payment_state = 'paid' unless order.outstanding_balance?
|
172
171
|
end
|
173
172
|
order.state_changed('payment') if last_state != order.payment_state
|
174
173
|
order.payment_state
|
@@ -29,7 +29,7 @@ module Spree
|
|
29
29
|
# a new pending payment record for the remaining amount to capture later.
|
30
30
|
def capture!(amount = nil)
|
31
31
|
return true if completed?
|
32
|
-
amount ||= money.
|
32
|
+
amount ||= money.money.cents
|
33
33
|
started_processing!
|
34
34
|
protect_from_connection_error do
|
35
35
|
# Standard ActiveMerchant capture usage
|
@@ -48,20 +48,19 @@ module Spree
|
|
48
48
|
def void_transaction!
|
49
49
|
return true if void?
|
50
50
|
protect_from_connection_error do
|
51
|
-
|
52
51
|
if payment_method.payment_profiles_supported?
|
53
52
|
# Gateways supporting payment profiles will need access to credit card object because this stores the payment profile information
|
54
53
|
# so supply the authorization itself as well as the credit card, rather than just the authorization code
|
55
|
-
response = payment_method.void(
|
54
|
+
response = payment_method.void(response_code, source, gateway_options)
|
56
55
|
else
|
57
56
|
# Standard ActiveMerchant void usage
|
58
|
-
response = payment_method.void(
|
57
|
+
response = payment_method.void(response_code, gateway_options)
|
59
58
|
end
|
60
59
|
record_response(response)
|
61
60
|
|
62
61
|
if response.success?
|
63
62
|
self.response_code = response.authorization
|
64
|
-
|
63
|
+
void
|
65
64
|
else
|
66
65
|
gateway_error(response)
|
67
66
|
end
|
@@ -92,30 +91,30 @@ module Spree
|
|
92
91
|
capture_events.create!(amount: amount)
|
93
92
|
end
|
94
93
|
|
95
|
-
def handle_payment_preconditions
|
94
|
+
def handle_payment_preconditions
|
96
95
|
unless block_given?
|
97
|
-
raise ArgumentError
|
96
|
+
raise ArgumentError, 'handle_payment_preconditions must be called with a block'
|
98
97
|
end
|
99
98
|
|
100
99
|
if payment_method && payment_method.source_required?
|
101
100
|
if source
|
102
|
-
|
101
|
+
unless processing?
|
103
102
|
if payment_method.supports?(source) || token_based?
|
104
103
|
yield
|
105
104
|
else
|
106
105
|
invalidate!
|
107
|
-
raise Core::GatewayError
|
106
|
+
raise Core::GatewayError, Spree.t(:payment_method_not_supported)
|
108
107
|
end
|
109
108
|
end
|
110
109
|
else
|
111
|
-
raise Core::GatewayError
|
110
|
+
raise Core::GatewayError, Spree.t(:payment_processing_failed)
|
112
111
|
end
|
113
112
|
end
|
114
113
|
end
|
115
114
|
|
116
115
|
def gateway_action(source, action, success_state)
|
117
116
|
protect_from_connection_error do
|
118
|
-
response = payment_method.send(action, money.
|
117
|
+
response = payment_method.send(action, money.money.cents,
|
119
118
|
source,
|
120
119
|
gateway_options)
|
121
120
|
handle_response(response, success_state, :failure)
|
@@ -135,9 +134,9 @@ module Spree
|
|
135
134
|
self.cvv_response_message = response.cvv_result['message']
|
136
135
|
end
|
137
136
|
end
|
138
|
-
|
137
|
+
send("#{success_state}!")
|
139
138
|
else
|
140
|
-
|
139
|
+
send(failure_state)
|
141
140
|
gateway_error(response)
|
142
141
|
end
|
143
142
|
end
|
@@ -147,24 +146,24 @@ module Spree
|
|
147
146
|
end
|
148
147
|
|
149
148
|
def protect_from_connection_error
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
149
|
+
|
150
|
+
yield
|
151
|
+
rescue ActiveMerchant::ConnectionError => e
|
152
|
+
gateway_error(e)
|
153
|
+
|
155
154
|
end
|
156
155
|
|
157
156
|
def gateway_error(error)
|
158
|
-
if error.is_a? ActiveMerchant::Billing::Response
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
157
|
+
text = if error.is_a? ActiveMerchant::Billing::Response
|
158
|
+
error.params['message'] || error.params['response_reason_text'] || error.message
|
159
|
+
elsif error.is_a? ActiveMerchant::ConnectionError
|
160
|
+
Spree.t(:unable_to_connect_to_gateway)
|
161
|
+
else
|
162
|
+
error.to_s
|
163
|
+
end
|
165
164
|
logger.error(Spree.t(:gateway_error))
|
166
165
|
logger.error(" #{error.to_yaml}")
|
167
|
-
raise Core::GatewayError
|
166
|
+
raise Core::GatewayError, text
|
168
167
|
end
|
169
168
|
|
170
169
|
def token_based?
|
data/app/models/spree/payment.rb
CHANGED
@@ -16,7 +16,7 @@ module Spree
|
|
16
16
|
end
|
17
17
|
belongs_to :source, polymorphic: true
|
18
18
|
|
19
|
-
has_many :offsets, -> { offset_payment }, class_name:
|
19
|
+
has_many :offsets, -> { offset_payment }, class_name: 'Spree::Payment', foreign_key: :source_id
|
20
20
|
has_many :log_entries, as: :source
|
21
21
|
has_many :state_changes, as: :stateful
|
22
22
|
has_many :capture_events, class_name: 'Spree::PaymentCaptureEvent'
|
@@ -103,13 +103,13 @@ module Spree
|
|
103
103
|
payment.state_changes.create!(
|
104
104
|
previous_state: transition.from,
|
105
105
|
next_state: transition.to,
|
106
|
-
name: 'payment'
|
106
|
+
name: 'payment'
|
107
107
|
)
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
111
|
def money
|
112
|
-
Spree::Money.new(amount,
|
112
|
+
Spree::Money.new(amount, currency: currency)
|
113
113
|
end
|
114
114
|
alias display_amount money
|
115
115
|
|
@@ -124,7 +124,7 @@ module Spree
|
|
124
124
|
end
|
125
125
|
|
126
126
|
def offsets_total
|
127
|
-
offsets.
|
127
|
+
offsets.sum(:amount)
|
128
128
|
end
|
129
129
|
|
130
130
|
def credit_allowed
|
@@ -140,14 +140,14 @@ module Spree
|
|
140
140
|
return unless new_record?
|
141
141
|
if source_attributes.present? && source.blank? && payment_method.try(:payment_source_class)
|
142
142
|
self.source = payment_method.payment_source_class.new(source_attributes)
|
143
|
-
|
144
|
-
|
143
|
+
source.payment_method_id = payment_method.id
|
144
|
+
source.user_id = order.user_id if order
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
148
148
|
def actions
|
149
|
-
return [] unless payment_source
|
150
|
-
payment_source.actions.select { |action| !payment_source.respond_to?("can_#{action}?")
|
149
|
+
return [] unless payment_source && payment_source.respond_to?(:actions)
|
150
|
+
payment_source.actions.select { |action| !payment_source.respond_to?("can_#{action}?") || payment_source.send("can_#{action}?", self) }
|
151
151
|
end
|
152
152
|
|
153
153
|
def payment_source
|
@@ -157,14 +157,14 @@ module Spree
|
|
157
157
|
|
158
158
|
def is_avs_risky?
|
159
159
|
return false if avs_response.blank? || NON_RISKY_AVS_CODES.include?(avs_response)
|
160
|
-
|
160
|
+
true
|
161
161
|
end
|
162
162
|
|
163
163
|
def is_cvv_risky?
|
164
|
-
return false if cvv_response_code ==
|
164
|
+
return false if cvv_response_code == 'M'
|
165
165
|
return false if cvv_response_code.nil?
|
166
166
|
return false if cvv_response_message.present?
|
167
|
-
|
167
|
+
true
|
168
168
|
end
|
169
169
|
|
170
170
|
def captured_amount
|
@@ -185,86 +185,79 @@ module Spree
|
|
185
185
|
INVALID_STATES.include?(state)
|
186
186
|
end
|
187
187
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
end
|
188
|
+
def validate_source
|
189
|
+
if source && !source.valid?
|
190
|
+
source.errors.each do |field, error|
|
191
|
+
field_name = I18n.t("activerecord.attributes.#{source.class.to_s.underscore}.#{field}")
|
192
|
+
errors.add(Spree.t(source.class.to_s.demodulize.underscore), "#{field_name} #{error}")
|
194
193
|
end
|
195
|
-
return !errors.present?
|
196
194
|
end
|
195
|
+
!errors.present?
|
196
|
+
end
|
197
197
|
|
198
|
-
|
199
|
-
|
200
|
-
|
198
|
+
def profiles_supported?
|
199
|
+
payment_method.respond_to?(:payment_profiles_supported?) && payment_method.payment_profiles_supported?
|
200
|
+
end
|
201
201
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
202
|
+
def create_payment_profile
|
203
|
+
# Don't attempt to create on bad payments.
|
204
|
+
return if has_invalid_state?
|
205
|
+
# Payment profile cannot be created without source
|
206
|
+
return unless source
|
207
|
+
# Imported payments shouldn't create a payment profile.
|
208
|
+
return if source.imported
|
209
|
+
|
210
|
+
payment_method.create_profile(self)
|
211
|
+
rescue ActiveMerchant::ConnectionError => e
|
212
|
+
gateway_error e
|
213
|
+
end
|
214
214
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
end
|
215
|
+
def split_uncaptured_amount
|
216
|
+
if uncaptured_amount > 0
|
217
|
+
order.payments.create!(
|
218
|
+
amount: uncaptured_amount,
|
219
|
+
payment_method: payment_method,
|
220
|
+
source: source,
|
221
|
+
state: 'pending',
|
222
|
+
capture_on_dispatch: true
|
223
|
+
).authorize!
|
224
|
+
update_attributes(amount: captured_amount)
|
226
225
|
end
|
226
|
+
end
|
227
227
|
|
228
|
-
|
229
|
-
|
230
|
-
order.updater.update_payment_total
|
231
|
-
end
|
232
|
-
|
233
|
-
if order.completed?
|
234
|
-
order.updater.update_payment_state
|
235
|
-
order.updater.update_shipments
|
236
|
-
order.updater.update_shipment_state
|
237
|
-
end
|
228
|
+
def update_order
|
229
|
+
order.updater.update_payment_total if completed? || void?
|
238
230
|
|
239
|
-
|
240
|
-
|
241
|
-
|
231
|
+
if order.completed?
|
232
|
+
order.updater.update_payment_state
|
233
|
+
order.updater.update_shipments
|
234
|
+
order.updater.update_shipment_state
|
242
235
|
end
|
243
236
|
|
244
|
-
|
245
|
-
|
246
|
-
# of the payment total is created to refund the customer. That
|
247
|
-
# payment has a source of itself (Spree::Payment) no matter the
|
248
|
-
# type of payment getting refunded, hence the additional check
|
249
|
-
# if the source is a store credit.
|
250
|
-
return unless store_credit? && source.is_a?(Spree::StoreCredit)
|
251
|
-
|
252
|
-
# creates the store credit event
|
253
|
-
source.update_attributes!({
|
254
|
-
action: Spree::StoreCredit::ELIGIBLE_ACTION,
|
255
|
-
action_amount: amount,
|
256
|
-
action_authorization_code: response_code,
|
257
|
-
})
|
258
|
-
end
|
237
|
+
order.persist_totals if completed? || order.completed?
|
238
|
+
end
|
259
239
|
|
260
|
-
|
261
|
-
|
262
|
-
|
240
|
+
def create_eligible_credit_event
|
241
|
+
# When cancelling an order, a payment with the negative amount
|
242
|
+
# of the payment total is created to refund the customer. That
|
243
|
+
# payment has a source of itself (Spree::Payment) no matter the
|
244
|
+
# type of payment getting refunded, hence the additional check
|
245
|
+
# if the source is a store credit.
|
246
|
+
return unless store_credit? && source.is_a?(Spree::StoreCredit)
|
247
|
+
|
248
|
+
# creates the store credit event
|
249
|
+
source.update_attributes!(action: Spree::StoreCredit::ELIGIBLE_ACTION,
|
250
|
+
action_amount: amount,
|
251
|
+
action_authorization_code: response_code)
|
252
|
+
end
|
263
253
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
end
|
254
|
+
def invalidate_old_payments
|
255
|
+
# invalid payment or store_credit payment shouldn't invalidate other payment types
|
256
|
+
return if has_invalid_state? || store_credit?
|
268
257
|
|
258
|
+
order.payments.with_state('checkout').where.not(id: id).each do |payment|
|
259
|
+
payment.invalidate! unless payment.store_credit?
|
260
|
+
end
|
261
|
+
end
|
269
262
|
end
|
270
263
|
end
|