mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-02 02:11:33 +00:00
Move adjustments logic from decorator into model
This commit is contained in:
@@ -15,6 +15,8 @@ module Spree
|
||||
class_name: "Spree::Payment", foreign_key: :source_id
|
||||
has_many :log_entries, as: :source
|
||||
|
||||
has_one :adjustment, as: :source, dependent: :destroy
|
||||
|
||||
before_validation :validate_source
|
||||
before_save :set_unique_identifier
|
||||
|
||||
@@ -125,8 +127,38 @@ module Spree
|
||||
res || payment_method
|
||||
end
|
||||
|
||||
def ensure_correct_adjustment
|
||||
revoke_adjustment_eligibility if ['failed', 'invalid'].include?(state)
|
||||
return if adjustment.try(:finalized?)
|
||||
|
||||
if adjustment
|
||||
adjustment.originator = payment_method
|
||||
adjustment.label = adjustment_label
|
||||
adjustment.save
|
||||
else
|
||||
payment_method.create_adjustment(adjustment_label, order, self, true)
|
||||
association(:adjustment).reload
|
||||
end
|
||||
end
|
||||
|
||||
def adjustment_label
|
||||
I18n.t('payment_method_fee')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Don't charge fees for invalid or failed payments.
|
||||
# This is called twice for failed payments, because the persistence of the 'failed'
|
||||
# state is acheived through some trickery using an after_rollback callback on the
|
||||
# payment model. See Spree::Payment#persist_invalid
|
||||
def revoke_adjustment_eligibility
|
||||
return unless adjustment.try(:reload)
|
||||
return if adjustment.finalized?
|
||||
|
||||
adjustment.update_attribute(:eligible, false)
|
||||
adjustment.finalize!
|
||||
end
|
||||
|
||||
def validate_source
|
||||
if source && !source.valid?
|
||||
source.errors.each do |field, error|
|
||||
|
||||
@@ -4,31 +4,11 @@ module Spree
|
||||
Payment.class_eval do
|
||||
delegate :line_items, to: :order
|
||||
|
||||
has_one :adjustment, as: :source, dependent: :destroy
|
||||
|
||||
# We bypass this after_rollback callback that is setup in Spree::Payment
|
||||
# The issues the callback fixes are not experienced in OFN:
|
||||
# if a payment fails on checkout the state "failed" is persisted correctly
|
||||
def persist_invalid; end
|
||||
|
||||
def ensure_correct_adjustment
|
||||
revoke_adjustment_eligibility if ['failed', 'invalid'].include?(state)
|
||||
return if adjustment.try(:finalized?)
|
||||
|
||||
if adjustment
|
||||
adjustment.originator = payment_method
|
||||
adjustment.label = adjustment_label
|
||||
adjustment.save
|
||||
else
|
||||
payment_method.create_adjustment(adjustment_label, order, self, true)
|
||||
association(:adjustment).reload
|
||||
end
|
||||
end
|
||||
|
||||
def adjustment_label
|
||||
I18n.t('payment_method_fee')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_payment_profile
|
||||
@@ -41,17 +21,5 @@ module Spree
|
||||
rescue ActiveMerchant::ConnectionError => e
|
||||
gateway_error e
|
||||
end
|
||||
|
||||
# Don't charge fees for invalid or failed payments.
|
||||
# This is called twice for failed payments, because the persistence of the 'failed'
|
||||
# state is acheived through some trickery using an after_rollback callback on the
|
||||
# payment model. See Spree::Payment#persist_invalid
|
||||
def revoke_adjustment_eligibility
|
||||
return unless adjustment.try(:reload)
|
||||
return if adjustment.finalized?
|
||||
|
||||
adjustment.update_attribute(:eligible, false)
|
||||
adjustment.finalize!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -787,4 +787,35 @@ describe Spree::Payment do
|
||||
payment.refund!
|
||||
end
|
||||
end
|
||||
|
||||
describe "applying transaction fees" do
|
||||
let!(:order) { create(:order) }
|
||||
let!(:line_item) { create(:line_item, order: order, quantity: 3, price: 5.00) }
|
||||
|
||||
before do
|
||||
order.reload.update!
|
||||
end
|
||||
|
||||
context "when order-based calculator" do
|
||||
let!(:shop) { create(:enterprise) }
|
||||
let!(:payment_method) { create(:payment_method, calculator: calculator) }
|
||||
|
||||
let!(:calculator) do
|
||||
Spree::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10)
|
||||
end
|
||||
|
||||
context "when order complete and inventory tracking enabled" do
|
||||
let!(:order) { create(:completed_order_with_totals, distributor: shop) }
|
||||
let!(:variant) { order.line_items.first.variant }
|
||||
let!(:inventory_item) { create(:inventory_item, enterprise: shop, variant: variant) }
|
||||
|
||||
it "creates adjustment" do
|
||||
payment = create(:payment, order: order, payment_method: payment_method,
|
||||
amount: order.total)
|
||||
expect(payment.adjustment).to be_present
|
||||
expect(payment.adjustment.amount).not_to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,28 +11,6 @@ module Spree
|
||||
order.reload.update!
|
||||
end
|
||||
|
||||
context "when order-based calculator" do
|
||||
let!(:shop) { create(:enterprise) }
|
||||
let!(:payment_method) { create(:payment_method, calculator: calculator) }
|
||||
|
||||
let!(:calculator) do
|
||||
Spree::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10)
|
||||
end
|
||||
|
||||
context "when order complete and inventory tracking enabled" do
|
||||
let!(:order) { create(:completed_order_with_totals, distributor: shop) }
|
||||
let!(:variant) { order.line_items.first.variant }
|
||||
let!(:inventory_item) { create(:inventory_item, enterprise: shop, variant: variant) }
|
||||
|
||||
it "creates adjustment" do
|
||||
payment = create(:payment, order: order, payment_method: payment_method,
|
||||
amount: order.total)
|
||||
expect(payment.adjustment).to be_present
|
||||
expect(payment.adjustment.amount).not_to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "to Stripe payments" do
|
||||
let(:shop) { create(:enterprise) }
|
||||
let(:payment_method) { create(:stripe_payment_method, distributor_ids: [create(:distributor_enterprise).id], preferred_enterprise_id: shop.id) }
|
||||
|
||||
Reference in New Issue
Block a user