mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Fix VoucherAdjustmentsService.calculate so we can call it mutiple time
It now uses `order.pre_discount_total` to make any calculation, that means you can call it multiple time and you will still get the same adjustment amount, included_tax and tax adjustment when needed. This is assuming nothing changed on the order.
This commit is contained in:
@@ -10,7 +10,7 @@ class VoucherAdjustmentsService
|
||||
# We only support one voucher per order right now, we could just loop on voucher_adjustments
|
||||
adjustment = order.voucher_adjustments.first
|
||||
|
||||
# Recalculate value
|
||||
# Calculate value
|
||||
amount = adjustment.originator.compute_amount(order)
|
||||
|
||||
# It is quite possible to have an order with both tax included in and tax excluded from price.
|
||||
@@ -23,33 +23,35 @@ class VoucherAdjustmentsService
|
||||
handle_tax_included_in_price(order, amount)
|
||||
else
|
||||
adjustment.amount = amount
|
||||
adjustment.save
|
||||
end
|
||||
|
||||
# Move to closed state
|
||||
adjustment.close
|
||||
end
|
||||
|
||||
def self.handle_tax_excluded_from_price(order, amount)
|
||||
voucher_rate = amount / order.total
|
||||
voucher_rate = amount / order.pre_discount_total
|
||||
|
||||
adjustment = order.voucher_adjustments.first
|
||||
|
||||
# Adding the voucher tax part
|
||||
tax_amount = voucher_rate * order.additional_tax_total
|
||||
|
||||
adjustment = order.voucher_adjustments.first
|
||||
adjustment_attributes = {
|
||||
amount: tax_amount,
|
||||
originator: adjustment.originator,
|
||||
order: order,
|
||||
label: "Tax #{adjustment.label}",
|
||||
mandatory: false,
|
||||
state: 'closed',
|
||||
state: 'open',
|
||||
tax_category: nil,
|
||||
included_tax: 0
|
||||
}
|
||||
order.adjustments.create(adjustment_attributes)
|
||||
|
||||
# Update the amount if tax adjustment already exist, create if not
|
||||
tax_adjustment = order.adjustments.find_or_initialize_by(adjustment_attributes)
|
||||
tax_adjustment.amount = tax_amount
|
||||
tax_adjustment.save
|
||||
|
||||
# Update the adjustment amount
|
||||
amount = voucher_rate * (order.total - order.additional_tax_total)
|
||||
amount = voucher_rate * (order.pre_discount_total - order.additional_tax_total)
|
||||
|
||||
adjustment.update_columns(
|
||||
amount: amount,
|
||||
@@ -58,7 +60,7 @@ class VoucherAdjustmentsService
|
||||
end
|
||||
|
||||
def self.handle_tax_included_in_price(order, amount)
|
||||
voucher_rate = amount / order.total
|
||||
voucher_rate = amount / order.pre_discount_total
|
||||
included_tax = voucher_rate * order.included_tax_total
|
||||
|
||||
# Update Adjustment
|
||||
|
||||
@@ -22,7 +22,7 @@ describe VoucherAdjustmentsService do
|
||||
end
|
||||
end
|
||||
|
||||
context 'with price included in order price' do
|
||||
context 'with tax included in order price' do
|
||||
subject { order.voucher_adjustments.first }
|
||||
|
||||
let(:order) do
|
||||
@@ -51,18 +51,14 @@ describe VoucherAdjustmentsService do
|
||||
|
||||
it 'updates the adjustment included_tax' do
|
||||
# voucher_rate = amount / order.total
|
||||
# -10 / 150 = -0.066666667
|
||||
# -10 / 160 = -0.0625
|
||||
# included_tax = voucher_rate * order.included_tax_total
|
||||
# -0.66666666 * 10 = -0.67
|
||||
expect(subject.included_tax.to_f).to eq(-0.67)
|
||||
end
|
||||
|
||||
it 'moves the adjustment state to closed' do
|
||||
expect(subject.state).to eq('closed')
|
||||
# -0.0625 * 10 = -0.625
|
||||
expect(subject.included_tax.to_f).to eq(-0.63)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with price not included in order price' do
|
||||
context 'with tax not included in order price' do
|
||||
let(:order) do
|
||||
create(
|
||||
:order_with_taxes,
|
||||
@@ -87,28 +83,34 @@ describe VoucherAdjustmentsService do
|
||||
VoucherAdjustmentsService.calculate(order)
|
||||
end
|
||||
|
||||
it 'includes amount withou tax' do
|
||||
it 'includes amount without tax' do
|
||||
adjustment = order.voucher_adjustments.first
|
||||
# voucher_rate = amount / order.total
|
||||
# -10 / 161 = -0.062111801
|
||||
# -10 / 171 = -0.058479532
|
||||
# amount = voucher_rate * (order.total - order.additional_tax_total)
|
||||
# -0.062111801 * (161 -11) = -9.32
|
||||
expect(adjustment.amount.to_f).to eq(-9.32)
|
||||
# -0.058479532 * (171 -11) = -9.36
|
||||
expect(adjustment.amount.to_f).to eq(-9.36)
|
||||
end
|
||||
|
||||
it 'creates a tax adjustment' do
|
||||
# voucher_rate = amount / order.total
|
||||
# -10 / 161 = -0.062111801
|
||||
# -10 / 171 = -0.058479532
|
||||
# amount = voucher_rate * order.additional_tax_total
|
||||
# -0.0585 * 11 = -0.68
|
||||
# -0.058479532 * 11 = -0.64
|
||||
tax_adjustment = order.voucher_adjustments.second
|
||||
expect(tax_adjustment.amount.to_f).to eq(-0.68)
|
||||
expect(tax_adjustment.amount.to_f).to eq(-0.64)
|
||||
expect(tax_adjustment.label).to match("Tax")
|
||||
end
|
||||
|
||||
it 'moves the adjustment state to closed' do
|
||||
adjustment = order.voucher_adjustments.first
|
||||
expect(adjustment.state).to eq('closed')
|
||||
context "when re calculating" do
|
||||
it "updates the tax adjustment" do
|
||||
order.update_columns(item_total: 200)
|
||||
tax_adjustment = order.voucher_adjustments.second
|
||||
|
||||
expect do
|
||||
VoucherAdjustmentsService.calculate(order)
|
||||
end.to change { tax_adjustment.reload.amount }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user