Make weight calculator work for SubscriptionLineItems by making it test if line_item responds to final_weight_volume field (final_weight_volume_present?)

We also add logic to weight_per_variant so that we use variant.unit_value if final_weight_volume is not available but variant_unit is weight
Adapt some test case to test unit_value (in grams) instead of weight (in kgs)
This commit is contained in:
luisramos0
2019-12-06 18:14:35 +00:00
parent 52dc288470
commit e9e6aa77d8
2 changed files with 47 additions and 27 deletions

View File

@@ -25,7 +25,7 @@ module Calculator
end
def line_item_weight(line_item)
if line_item.final_weight_volume.present?
if final_weight_volume_present?(line_item)
weight_per_final_weight_volume(line_item)
else
weight_per_variant(line_item) * line_item.quantity
@@ -33,13 +33,18 @@ module Calculator
end
def weight_per_variant(line_item)
line_item.variant.andand.weight || 0
if variant_unit(line_item) == 'weight'
# The calculator price is per_kg so we need to convert unit_value to kg
convert_g_to_kg(line_item.variant.andand.unit_value)
else
line_item.variant.andand.weight || 0
end
end
def weight_per_final_weight_volume(line_item)
if line_item.variant.product.andand.variant_unit == 'weight'
# Divided by 1000 because grams is the base weight unit and the calculator price is per_kg
line_item.final_weight_volume / 1000.0
if variant_unit(line_item) == 'weight'
# The calculator price is per_kg so we need to convert final_weight_volume to kg
convert_g_to_kg(line_item.final_weight_volume)
else
weight_per_variant(line_item) * quantity_implied_in_final_weight_volume(line_item)
end
@@ -51,5 +56,19 @@ module Calculator
def quantity_implied_in_final_weight_volume(line_item)
(1.0 * line_item.final_weight_volume / line_item.variant.unit_value).round(3)
end
def final_weight_volume_present?(line_item)
line_item.respond_to?(:final_weight_volume) && line_item.final_weight_volume.present?
end
def variant_unit(line_item)
line_item.variant.product.andand.variant_unit
end
def convert_g_to_kg(value)
return 0 unless value
value / 1000
end
end
end

View File

@@ -4,9 +4,9 @@ describe Calculator::Weight do
it_behaves_like "a model using the LocalizedNumber module", [:preferred_per_kg]
it "computes shipping cost for an order by total weight" do
variant1 = build(:variant, weight: 10)
variant2 = build(:variant, weight: 20)
variant3 = build(:variant, weight: nil)
variant1 = build(:variant, unit_value: 10_000)
variant2 = build(:variant, unit_value: 20_000)
variant3 = build(:variant, unit_value: nil)
line_item1 = build(:line_item, variant: variant1, quantity: 1)
line_item2 = build(:line_item, variant: variant2, quantity: 3)
@@ -14,39 +14,40 @@ describe Calculator::Weight do
order = double(:order, line_items: [line_item1, line_item2, line_item3])
subject.set_preference(:per_kg, 10)
expect(subject.compute(order)).to eq((10 * 1 + 20 * 3) * 10)
subject.set_preference(:per_kg, 5)
expect(subject.compute(order)).to eq(350) # (10 * 1 + 20 * 3) * 5
end
describe "line item with variant weight" do
let(:variant) { build(:variant, weight: 10) }
describe "line item with variant_unit weight and variant unit_value" do
let(:variant) { build(:variant, unit_value: 10_000) }
let(:line_item) { build(:line_item, variant: variant, quantity: 2) }
before { subject.set_preference(:per_kg, 10) }
before { subject.set_preference(:per_kg, 5) }
it "computes shipping cost for a line item" do
expect(subject.compute(line_item)).to eq(10 * 2 * 10)
expect(subject.compute(line_item)).to eq(100) # 10 * 2 * 5
end
describe "and with final_weight_volume defined" do
before { line_item.update_attribute :final_weight_volume, '18000' }
it "computes fee using final_weight_volume, not the variant weight" do
expect(subject.compute(line_item)).to eq(10 * 18)
expect(subject.compute(line_item)).to eq(90) # 18 * 5
end
context "where variant unit is not weight" do
it "uses both final_weight_volume and weight to calculate fee" do
line_item.variant.update_attribute :weight, 7
line_item.variant.product.update_attribute :variant_unit, 'items'
expect(subject.compute(line_item)).to eq(180)
expect(subject.compute(line_item)).to eq(63) # 7 * (18000/10000) * 5
end
end
end
end
it "computes shipping cost for an object with an order" do
variant1 = build(:variant, weight: 10)
variant2 = build(:variant, weight: 5)
variant1 = build(:variant, unit_value: 10_000)
variant2 = build(:variant, unit_value: 20_000)
line_item1 = build(:line_item, variant: variant1, quantity: 1)
line_item2 = build(:line_item, variant: variant2, quantity: 2)
@@ -54,8 +55,8 @@ describe Calculator::Weight do
order = double(:order, line_items: [line_item1, line_item2])
object_with_order = double(:object_with_order, order: order)
subject.set_preference(:per_kg, 10)
expect(subject.compute(object_with_order)).to eq((10 * 1 + 5 * 2) * 10)
subject.set_preference(:per_kg, 5)
expect(subject.compute(object_with_order)).to eq(250) # (10 * 1 + 20 * 2) * 5
end
context "when line item final_weight_volume is set" do
@@ -77,7 +78,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(600) # 600g
line_item.final_weight_volume = 700 # 700g
expect(calculator.compute(line_item)).to eq(4.2)
expect(calculator.compute(line_item)).to eq(4.2) # 0.7 * 6
end
end
@@ -88,7 +89,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(6_000) # 6kg
line_item.final_weight_volume = 7_000 # 7kg
expect(calculator.compute(line_item)).to eq(42)
expect(calculator.compute(line_item)).to eq(42) # 7 * 6
end
end
@@ -99,7 +100,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(6_000_000) # 6T
line_item.final_weight_volume = 7_000_000 # 7T
expect(calculator.compute(line_item)).to eq(42_000)
expect(calculator.compute(line_item)).to eq(42_000) # 7000 * 6
end
end
end
@@ -112,7 +113,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(0.6) # 600mL
line_item.final_weight_volume = 0.7 # 700mL
expect(calculator.compute(line_item)).to eq(3.50)
expect(calculator.compute(line_item)).to eq(3.50) # 0.25 * (0.7/0.3) * 6
end
end
@@ -123,7 +124,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(6) # 6L
line_item.final_weight_volume = 7 # 7L
expect(calculator.compute(line_item)).to eq(35.00)
expect(calculator.compute(line_item)).to eq(35.00) # 2.5 * (7/3) * 6
end
end
@@ -134,7 +135,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(6_000) # 6kL
line_item.final_weight_volume = 7_000 # 7kL
expect(calculator.compute(line_item)).to eq(34_995)
expect(calculator.compute(line_item)).to eq(34_995) # 2_500 * round(7_000/3_000) * 6
end
end
end
@@ -146,7 +147,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(6) # 6 pcs
line_item.final_weight_volume = 7 # 7 pcs
expect(calculator.compute(line_item)).to eq(35.0)
expect(calculator.compute(line_item)).to eq(35.0) # 2.5 * (7/3) * 6
end
end
end