Skip to content

Commit

Permalink
Merge pull request #2877 from ericsaupe/order-currency-rounding
Browse files Browse the repository at this point in the history
Round calculator values based on order currency
  • Loading branch information
kennyadsl authored Nov 23, 2018
2 parents 95bf58a + 0e08301 commit 5707a64
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 7 deletions.
5 changes: 4 additions & 1 deletion core/app/models/spree/calculator/flat_percent_item_total.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ class Calculator::FlatPercentItemTotal < Calculator
preference :flat_percent, :decimal, default: 0

def compute(object)
computed_amount = (object.amount * preferred_flat_percent / 100).round(2)
order = object.is_a?(Order) ? object : object.order
preferred_currency = order.currency
currency_exponent = ::Money::Currency.find(preferred_currency).exponent
computed_amount = (object.amount * preferred_flat_percent / 100).round(currency_exponent)

# We don't want to cause the promotion adjustments to push the order into a negative total.
if computed_amount > object.amount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ class FlatPercentItemTotal < ShippingCalculator
preference :flat_percent, :decimal, default: 0

def compute_package(package)
compute_from_price(total(package.contents))
value = compute_from_price(total(package.contents))
preferred_currency = package.order.currency
currency_exponent = ::Money::Currency.find(preferred_currency).exponent
value.round(currency_exponent)
end

def compute_from_price(price)
value = price * BigDecimal(preferred_flat_percent.to_s) / 100.0
value.round(2)
price * BigDecimal(preferred_flat_percent.to_s) / 100.0
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion core/app/models/spree/calculator/tiered_percent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ def compute(object)
end

if preferred_currency.casecmp(order.currency).zero?
(object.amount * (percent || preferred_base_percent) / 100).round(2)
currency_exponent = ::Money::Currency.find(preferred_currency).exponent
(object.amount * (percent || preferred_base_percent) / 100).round(currency_exponent)
else
0
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

RSpec.describe Spree::Calculator::FlatPercentItemTotal, type: :model do
let(:calculator) { Spree::Calculator::FlatPercentItemTotal.new }
let(:line_item) { mock_model Spree::LineItem }
let(:line_item) { create(:line_item) }

it_behaves_like 'a calculator with a description'

Expand All @@ -20,6 +20,15 @@
expect(calculator.compute(line_item)).to eq 3.10
end

it "should round result based on order currency" do
line_item.order.currency = 'JPY'
allow(line_item).to receive_messages amount: 31.08
expect(calculator.compute(line_item)).to eq 3

allow(line_item).to receive_messages amount: 31.00
expect(calculator.compute(line_item)).to eq 3
end

it 'returns object.amount if computed amount is greater' do
allow(calculator).to receive_messages preferred_flat_percent: 110
allow(line_item).to receive_messages amount: 30.00
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ module Calculator::Shipping
expect(subject.compute(package)).to eq(4.04)
end

it "should round result based on order currency" do
package.order.currency = 'JPY'
expect(subject.compute(package)).to eq(4)
end

it "should return a bigdecimal" do
expect(subject.compute(package)).to be_a(BigDecimal)
end
Expand Down
8 changes: 7 additions & 1 deletion core/spec/models/spree/calculator/tiered_percent_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,15 @@
end

context "when the order's currency does not match the calculator" do
let(:preferred_currency) { "CAD" }
let(:preferred_currency) { "JPY" }
let(:line_item_count) { 1 }
let(:price) { 15 }
it { is_expected.to eq 0 }

it "rounds based on currency" do
allow(order).to receive_messages currency: "JPY"
expect(subject).to eq(2)
end
end
end

Expand Down

0 comments on commit 5707a64

Please sign in to comment.