Skip to content

Commit

Permalink
Add calculation for percentage voucher
Browse files Browse the repository at this point in the history
It include calculation for order with taxes included in the price
  • Loading branch information
rioug committed May 9, 2023
1 parent cc65d3a commit b7df2e9
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 100 deletions.
5 changes: 4 additions & 1 deletion app/models/voucher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def create_adjustment(label, order)
# 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.total)
return -amount.clamp(0, order.total) if voucher_type == FLAT_RATE

percentage = amount / 100
-percentage * order.total
end
end
20 changes: 15 additions & 5 deletions app/services/voucher_adjustments_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ def self.calculate(order)
adjustment = order.voucher_adjustments.first

# Recalculate 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.
Expand All @@ -20,7 +22,7 @@ def self.calculate(order)
if order.additional_tax_total.positive?
handle_tax_excluded_from_price(order, amount)
else
handle_tax_included_in_price(order, amount)
handle_tax_included_in_price(order, voucher)
end

# Move to closed state
Expand Down Expand Up @@ -55,9 +57,17 @@ def self.handle_tax_excluded_from_price(order, amount)
)
end

def self.handle_tax_included_in_price(order, amount)
voucher_rate = amount / order.total
included_tax = voucher_rate * order.included_tax_total
def self.handle_tax_included_in_price(order, voucher)
amount = voucher.compute_amount(order)

if voucher.voucher_type == Voucher::FLAT_RATE
# Flat rate tax calulation
voucher_rate = amount / order.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
Expand Down
30 changes: 21 additions & 9 deletions spec/models/voucher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,32 @@
end

describe '#compute_amount' do
subject { create(:voucher_flat_rate, code: 'new_code', enterprise: enterprise, amount: 10) }

let(:order) { create(:order_with_totals) }

it 'returns -10' do
expect(subject.compute_amount(order).to_f).to eq(-10)
context "with flat rate voucher" do
subject { create(:voucher_flat_rate, code: 'new_code', enterprise: enterprise, amount: 10) }

it 'returns -amount' do
expect(subject.compute_amount(order).to_f).to eq(-10)
end

context 'when order total is smaller than voucher amount' do
it 'returns minus the order total' do
order.total = 6
order.save!

expect(subject.compute_amount(order).to_f).to eq(-6)
end
end
end

context 'when order total is smaller than 10' do
it 'returns minus the order total' do
order.total = 6
order.save!
context "with percentage rate voucher" do
subject { create(:voucher_percentage, code: 'new_code', enterprise: enterprise, amount: 10) }

expect(subject.compute_amount(order).to_f).to eq(-6)
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
Expand Down
Loading

0 comments on commit b7df2e9

Please sign in to comment.