diff --git a/app/models/voucher.rb b/app/models/voucher.rb index 2d74167b72..30065e8c10 100644 --- a/app/models/voucher.rb +++ b/app/models/voucher.rb @@ -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 diff --git a/app/services/voucher_adjustments_service.rb b/app/services/voucher_adjustments_service.rb index 355058b9d6..b699851af6 100644 --- a/app/services/voucher_adjustments_service.rb +++ b/app/services/voucher_adjustments_service.rb @@ -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 diff --git a/spec/models/voucher_spec.rb b/spec/models/voucher_spec.rb index 8af6daa029..67ba57dcff 100644 --- a/spec/models/voucher_spec.rb +++ b/spec/models/voucher_spec.rb @@ -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 diff --git a/spec/services/voucher_adjustments_service_spec.rb b/spec/services/voucher_adjustments_service_spec.rb index dc91347b7f..4d710943c1 100644 --- a/spec/services/voucher_adjustments_service_spec.rb +++ b/spec/services/voucher_adjustments_service_spec.rb @@ -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