mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-31 21:37:16 +00:00
Add calculation for percentage voucher
It include calculation for order with taxes included in the price
This commit is contained in:
@@ -62,6 +62,9 @@ class Voucher < ApplicationRecord
|
||||
# We limit adjustment to the maximum amount needed to cover the order, ie if the voucher
|
||||
# covers more than the order.total we only need to create an adjustment covering the order.total
|
||||
def compute_amount(order)
|
||||
-amount.clamp(0, order.pre_discount_total)
|
||||
return -amount.clamp(0, order.pre_discount_total) if voucher_type == FLAT_RATE
|
||||
|
||||
percentage = amount / 100
|
||||
-percentage * order.pre_discount_total
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,7 +15,9 @@ class VoucherAdjustmentsService
|
||||
adjustment = @order.voucher_adjustments.first
|
||||
|
||||
# Calculate value
|
||||
amount = adjustment.originator.compute_amount(@order)
|
||||
voucher = adjustment.originator
|
||||
# TODO: see if we can remove this and do it in handle_tax_excluded_from_price
|
||||
amount = voucher.compute_amount(@order)
|
||||
|
||||
# It is quite possible to have an order with both tax included in and tax excluded from price.
|
||||
# We should be able to caculate the relevant amount apply the current calculation.
|
||||
@@ -24,7 +26,7 @@ class VoucherAdjustmentsService
|
||||
if @order.additional_tax_total.positive?
|
||||
handle_tax_excluded_from_price(amount)
|
||||
elsif @order.included_tax_total.positive?
|
||||
handle_tax_included_in_price(amount)
|
||||
handle_tax_included_in_price(amount, voucher)
|
||||
else
|
||||
adjustment.amount = amount
|
||||
adjustment.save
|
||||
@@ -69,9 +71,15 @@ class VoucherAdjustmentsService
|
||||
tax_adjustment.save
|
||||
end
|
||||
|
||||
def handle_tax_included_in_price(amount)
|
||||
voucher_rate = amount / @order.pre_discount_total
|
||||
included_tax = voucher_rate * @order.included_tax_total
|
||||
def handle_tax_included_in_price(amount, voucher)
|
||||
if voucher.voucher_type == Voucher::FLAT_RATE
|
||||
# Flat rate tax calulation
|
||||
voucher_rate = amount / @order.pre_discount_total
|
||||
included_tax = voucher_rate * @order.included_tax_total
|
||||
else
|
||||
# Percentage rate tax calculation
|
||||
included_tax = -voucher.amount / 100 * @order.included_tax_total
|
||||
end
|
||||
|
||||
# Update Adjustment
|
||||
adjustment = @order.voucher_adjustments.first
|
||||
|
||||
@@ -42,12 +42,10 @@ describe Voucher do
|
||||
end
|
||||
|
||||
describe '#compute_amount' do
|
||||
subject { create(:voucher_flat_rate, code: 'new_code', enterprise: enterprise, amount: 10) }
|
||||
|
||||
let(:order) { create(:order_with_totals) }
|
||||
|
||||
context 'when order total is more than the voucher' do
|
||||
subject { create(:voucher, code: 'new_code', enterprise: enterprise, amount: 5) }
|
||||
subject { create(:voucher_flat_rate, code: 'new_code', enterprise: enterprise, amount: 5) }
|
||||
|
||||
it 'uses the voucher total' do
|
||||
expect(subject.compute_amount(order).to_f).to eq(-5)
|
||||
@@ -55,12 +53,22 @@ describe Voucher do
|
||||
end
|
||||
|
||||
context 'when order total is less than the voucher' do
|
||||
subject { create(:voucher, code: 'new_code', enterprise: enterprise, amount: 20) }
|
||||
subject { create(:voucher_flat_rate, code: 'new_code', enterprise: enterprise, amount: 20) }
|
||||
|
||||
it 'matches the order total' do
|
||||
expect(subject.compute_amount(order).to_f).to eq(-10)
|
||||
end
|
||||
end
|
||||
|
||||
context "with percentage rate voucher" do
|
||||
subject { create(:voucher_percentage, code: 'new_code', enterprise: enterprise, amount: 10) }
|
||||
|
||||
it 'returns calculated anount based on the percentage' do
|
||||
# -0.1 (10%) * $10 = $1
|
||||
expected_amount = -0.1 * order.total
|
||||
expect(subject.compute_amount(order).to_f).to eq(expected_amount.to_f)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#create_adjustment' do
|
||||
|
||||
@@ -117,6 +117,8 @@ describe VoucherAdjustmentsService do
|
||||
order.create_tax_charge!
|
||||
order.update_shipping_fees!
|
||||
order.update_order!
|
||||
|
||||
VoucherAdjustmentsService.new(order).update
|
||||
end
|
||||
|
||||
it 'includes amount without tax' do
|
||||
@@ -206,7 +208,7 @@ describe VoucherAdjustmentsService do
|
||||
ship_address: create(:address),
|
||||
product_price: 110,
|
||||
tax_rate_amount: 0.10,
|
||||
included_in_price: false,
|
||||
included_in_price: true,
|
||||
tax_rate_name: "Tax 1"
|
||||
)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user