Add calculation for percentage voucher

It include calculation for order with taxes included in the price
This commit is contained in:
Gaetan Craig-Riou
2023-05-09 14:37:47 +10:00
parent cc9069e9c6
commit cdb33aa0d0
4 changed files with 32 additions and 11 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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