diff --git a/app/models/spree/payment.rb b/app/models/spree/payment.rb index b185795f3e..1c331fcd28 100644 --- a/app/models/spree/payment.rb +++ b/app/models/spree/payment.rb @@ -89,6 +89,8 @@ module Spree event :complete_authorization do transition from: [:requires_authorization], to: :completed end + + after_transition to: :completed, do: :set_captured_at end def money @@ -219,6 +221,10 @@ module Spree OrderManagement::Order::Updater.new(order).after_payment_update(self) end + def set_captured_at + update_column(:captured_at, Time.zone.now) + end + # Necessary because some payment gateways will refuse payments with # duplicate IDs. We *were* using the Order number, but that's set once and # is unchanging. What we need is a unique identifier on a per-payment basis, diff --git a/db/migrate/20211217094141_add_captured_at_to_spree_payments.rb b/db/migrate/20211217094141_add_captured_at_to_spree_payments.rb new file mode 100644 index 0000000000..11d5ab3b44 --- /dev/null +++ b/db/migrate/20211217094141_add_captured_at_to_spree_payments.rb @@ -0,0 +1,5 @@ +class AddCapturedAtToSpreePayments < ActiveRecord::Migration[6.1] + def change + add_column :spree_payments, :captured_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index fa328fbf16..831200e2f8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_10_29_174211) do +ActiveRecord::Schema.define(version: 2021_12_17_094141) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -597,6 +597,7 @@ ActiveRecord::Schema.define(version: 2021_10_29_174211) do t.string "identifier", limit: 255 t.string "cvv_response_code", limit: 255 t.text "cvv_response_message" + t.datetime "captured_at" t.index ["order_id"], name: "index_spree_payments_on_order_id" end diff --git a/engines/order_management/spec/services/order_management/order/updater_spec.rb b/engines/order_management/spec/services/order_management/order/updater_spec.rb index 2d11b16753..23827e1c85 100644 --- a/engines/order_management/spec/services/order_management/order/updater_spec.rb +++ b/engines/order_management/spec/services/order_management/order/updater_spec.rb @@ -162,7 +162,7 @@ module OrderManagement context "when the order has a payment that requires authorization and a completed payment" do let!(:payment) { create(:payment, order: order, state: "requires_authorization") } - let!(:completed_payment) { create(:payment, order: order, state: "completed") } + let!(:completed_payment) { create(:payment, :completed, order: order) } it "returns paid" do updater.update_payment_state diff --git a/spec/controllers/line_items_controller_spec.rb b/spec/controllers/line_items_controller_spec.rb index 9d1f230f57..28f446b4f1 100644 --- a/spec/controllers/line_items_controller_spec.rb +++ b/spec/controllers/line_items_controller_spec.rb @@ -91,7 +91,7 @@ describe LineItemsController, type: :controller do context "after a payment is captured" do let(:payment) { - create(:check_payment, amount: order.total, order: order, state: 'completed') + create(:check_payment, :completed, amount: order.total, order: order) } before { payment.capture! } diff --git a/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb b/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb index 9d9f1ce373..62400b8392 100644 --- a/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb +++ b/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb @@ -26,8 +26,8 @@ describe Spree::Admin::PaymentsController, type: :controller do context "that was processed by stripe" do let!(:payment_method) { create(:stripe_connect_payment_method, distributors: [shop]) } let!(:payment) do - create(:payment, order: order, state: 'completed', payment_method: payment_method, - response_code: 'ch_1a2b3c', amount: order.total) + create(:payment, :completed, order: order, payment_method: payment_method, + response_code: 'ch_1a2b3c', amount: order.total) end before do @@ -85,8 +85,8 @@ describe Spree::Admin::PaymentsController, type: :controller do context "that was processed by stripe" do let!(:payment_method) { create(:stripe_connect_payment_method, distributors: [shop]) } let!(:payment) do - create(:payment, order: order, state: 'completed', payment_method: payment_method, - response_code: 'ch_1a2b3c', amount: order.total + 5) + create(:payment, :completed, order: order, payment_method: payment_method, + response_code: 'ch_1a2b3c', amount: order.total + 5) end before do @@ -146,8 +146,8 @@ describe Spree::Admin::PaymentsController, type: :controller do context "that was processed by stripe" do let!(:payment_method) { create(:stripe_sca_payment_method, distributors: [shop]) } let!(:payment) do - create(:payment, order: order, state: 'completed', payment_method: payment_method, - response_code: 'pi_123', amount: order.total) + create(:payment, :completed, order: order, payment_method: payment_method, + response_code: 'pi_123', amount: order.total) end let(:stripe_account) { create(:stripe_account, enterprise: shop) } @@ -256,8 +256,8 @@ describe Spree::Admin::PaymentsController, type: :controller do context "that was processed by stripe" do let!(:payment_method) { create(:stripe_sca_payment_method, distributors: [shop]) } let!(:payment) do - create(:payment, order: order, state: 'completed', payment_method: payment_method, - response_code: 'pi_123', amount: order.total + 5) + create(:payment, :completed, order: order, payment_method: payment_method, + response_code: 'pi_123', amount: order.total + 5) end before do diff --git a/spec/factories/order_factory.rb b/spec/factories/order_factory.rb index bde16360c1..0bd6a8c718 100644 --- a/spec/factories/order_factory.rb +++ b/spec/factories/order_factory.rb @@ -48,7 +48,8 @@ FactoryBot.define do payment_state { 'paid' } shipment_state { 'ready' } after(:create) do |order| - create(:payment, amount: order.total, order: order, state: 'completed') + create(:payment, :completed, amount: order.total, order: order) + order.shipments.each do |shipment| shipment.inventory_units.each { |u| u.update_column('state', 'on_hand') } shipment.update_column('state', 'ready') @@ -174,8 +175,8 @@ FactoryBot.define do end after(:create) do |order, evaluator| - create(:payment, amount: order.total + evaluator.credit_amount, order: order, - state: "completed") + create(:payment, :completed, amount: order.total + evaluator.credit_amount, order: order) + order.reload end end diff --git a/spec/factories/payment_factory.rb b/spec/factories/payment_factory.rb index 2919b00c7c..f8c6ab6d45 100644 --- a/spec/factories/payment_factory.rb +++ b/spec/factories/payment_factory.rb @@ -19,6 +19,11 @@ FactoryBot.define do payment_method { FactoryBot.create(:payment_method, distributors: [distributor]) } end + trait :completed do + state { 'completed' } + captured_at { Time.zone.now } + end + factory :check_payment, class: Spree::Payment do amount { 45.75 } payment_method diff --git a/spec/features/admin/invoice_print_spec.rb b/spec/features/admin/invoice_print_spec.rb index 90535c6ad2..0a1b82c2b0 100644 --- a/spec/features/admin/invoice_print_spec.rb +++ b/spec/features/admin/invoice_print_spec.rb @@ -41,7 +41,7 @@ describe ' context "with one payment" do let!(:payment1) do - create(:payment, order: order, state: 'completed', payment_method: payment_method1) + create(:payment, :completed, order: order, payment_method: payment_method1) end before do order.save! @@ -58,8 +58,9 @@ describe ' context "with two payments, and one that failed" do before do order.update payments: [] - order.payments << create(:payment, order: order, state: 'completed', - payment_method: payment_method1, created_at: 1.day.ago) + order.payments << create(:payment, :completed, order: order, + payment_method: payment_method1, + created_at: 1.day.ago) order.payments << create(:payment, order: order, state: 'failed', payment_method: payment_method2, created_at: 2.days.ago) order.save! @@ -76,10 +77,12 @@ describe ' context "with two completed payments" do before do order.update payments: [] - order.payments << create(:payment, order: order, state: 'completed', - payment_method: payment_method1, created_at: 2.days.ago) - order.payments << create(:payment, order: order, state: 'completed', - payment_method: payment_method2, created_at: 1.day.ago) + order.payments << create(:payment, :completed, order: order, + payment_method: payment_method1, + created_at: 2.days.ago) + order.payments << create(:payment, :completed, order: order, + payment_method: payment_method2, + created_at: 1.day.ago) order.save! end diff --git a/spec/models/spree/payment_spec.rb b/spec/models/spree/payment_spec.rb index 8ae18a4611..5f9d36315c 100644 --- a/spec/models/spree/payment_spec.rb +++ b/spec/models/spree/payment_spec.rb @@ -286,7 +286,7 @@ describe Spree::Payment do # Regression test for #2119 context "when payment is completed" do it "should do nothing" do - payment = build_stubbed(:payment, state: 'completed') + payment = build_stubbed(:payment, :completed) expect(payment).to_not receive(:complete) expect(payment.payment_method).to_not receive(:capture) expect(payment.log_entries).to_not receive(:create) @@ -569,7 +569,7 @@ describe Spree::Payment do context "#save" do context "completed payments" do it "updates order payment total" do - payment = create(:payment, amount: 100, order: order, state: "completed") + payment = create(:payment, :completed, amount: 100, order: order) expect(order.payment_total).to eq payment.amount end end @@ -583,7 +583,7 @@ describe Spree::Payment do end context 'when the payment was completed but now void' do - let(:payment) { create(:payment, amount: 100, order: order, state: 'completed') } + let(:payment) { create(:payment, :completed, amount: 100, order: order) } it 'updates order payment total' do payment.void @@ -672,7 +672,7 @@ describe Spree::Payment do end context 'when the payment was completed but now void' do - let(:payment) { create(:payment, amount: 100, order: order, state: 'completed') } + let(:payment) { create(:payment, :completed, amount: 100, order: order) } it 'updates order payment total' do payment.void @@ -1009,4 +1009,13 @@ describe Spree::Payment do expect(payment.cvv_response_message).to eq(nil) end end + + describe "#complete" do + let(:payment) { build(:payment, state: "processing") } + + it "sets :captured_at to the current time" do + payment.complete + expect(payment.captured_at).to be_present + end + end end diff --git a/spec/serializers/api/order_serializer_spec.rb b/spec/serializers/api/order_serializer_spec.rb index 7bad390442..94a462298b 100644 --- a/spec/serializers/api/order_serializer_spec.rb +++ b/spec/serializers/api/order_serializer_spec.rb @@ -12,7 +12,7 @@ describe Api::OrderSerializer do describe '#serializable_hash' do let!(:completed_payment) do - create(:payment, order: order, state: 'completed', amount: order.total - 1) + create(:payment, :completed, order: order, amount: order.total - 1) end let!(:payment) { create(:payment, order: order, state: 'checkout', amount: 123.45) } diff --git a/spec/services/order_payment_finder_spec.rb b/spec/services/order_payment_finder_spec.rb index 3d71d9a706..3d154a2785 100644 --- a/spec/services/order_payment_finder_spec.rb +++ b/spec/services/order_payment_finder_spec.rb @@ -8,7 +8,7 @@ describe OrderPaymentFinder do context "when order has several non pending payments" do let!(:failed_payment) { create(:payment, order: order, state: 'failed') } - let!(:complete_payment) { create(:payment, order: order, state: 'completed') } + let!(:complete_payment) { create(:payment, :completed, order: order) } it "#last_payment returns the last payment" do expect(finder.last_payment).to eq complete_payment diff --git a/spec/system/admin/customers_spec.rb b/spec/system/admin/customers_spec.rb index 0b85f63ed4..9ad56ceb77 100644 --- a/spec/system/admin/customers_spec.rb +++ b/spec/system/admin/customers_spec.rb @@ -119,8 +119,8 @@ describe 'Customers' do create(:stripe_sca_payment_method, distributors: [managed_distributor1]) } let!(:payment1) { - create(:payment, order: order1, state: 'completed', payment_method: payment_method, - response_code: 'pi_123', amount: 88.00) + create(:payment, :completed, order: order1, payment_method: payment_method, + response_code: 'pi_123', amount: 88.00) } before do @@ -149,8 +149,8 @@ describe 'Customers' do context "with an additional negative payment (or refund)" do let!(:payment2) { - create(:payment, order: order1, state: 'completed', payment_method: payment_method, - response_code: 'pi_123', amount: -25.00) + create(:payment, :completed, order: order1, payment_method: payment_method, + response_code: 'pi_123', amount: -25.00) } before do