Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Round calculator values based on order currency #2877

Merged
merged 1 commit into from
Nov 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't be the currency taken from the order where the calculator lives instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I like that better. I'll make the changes.

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