spree_core 3.3.6 → 3.4.0.rc1
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/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
|