Add a per-pound calculator and a spec for it

This commit is contained in:
Andy Brett
2020-09-06 09:03:06 -07:00
parent 8256a20aea
commit e8eadcbf39
6 changed files with 96 additions and 3 deletions

View File

@@ -88,7 +88,8 @@ module Spree
:require_ship_address, :tag_list, :calculator_type,
distributor_ids: [],
calculator_attributes: [
:id, :preferred_currency, :preferred_amount, :preferred_per_kg, :preferred_flat_percent,
:id, :preferred_currency, :preferred_amount, :preferred_per_kg,
:preferred_per_lb, :preferred_flat_percent,
:preferred_first_item, :preferred_additional_item, :preferred_max_items,
:preferred_minimal_amount, :preferred_normal_amount, :preferred_discount_amount
]

View File

@@ -0,0 +1,75 @@
require 'spree/localized_number'
module Calculator
class WeightLb < Spree::Calculator
extend Spree::LocalizedNumber
preference :per_lb, :decimal, default: 0.0
localize_number :preferred_per_lb
def self.description
I18n.t('spree.weight_lb')
end
def compute(object)
line_items = line_items_for object
(total_weight(line_items) * preferred_per_lb).round(2)
end
private
def total_weight(line_items)
line_items.sum do |line_item|
line_item_weight(line_item)
end
end
def line_item_weight(line_item)
if final_weight_volume_present?(line_item)
weight_per_final_weight_volume(line_item)
else
weight_per_variant(line_item) * line_item.quantity
end
end
def weight_per_variant(line_item)
if variant_unit(line_item) == 'weight'
# The calculator price is per_lb so we need to convert unit_value to lb
convert_g_to_lb(line_item.variant.andand.unit_value)
else
line_item.variant.andand.weight || 0
end
end
def weight_per_final_weight_volume(line_item)
if variant_unit(line_item) == 'weight'
# The calculator price is per_lb so we need to convert final_weight_volume to lb
convert_g_to_lb(line_item.final_weight_volume)
else
weight_per_variant(line_item) * quantity_implied_in_final_weight_volume(line_item)
end
end
# Example: 2 (line_item.quantity) wine glasses of 125mL (line_item.variant.unit_value)
# Customer ends up getting 350mL (line_item.final_weight_volume) of wine
# that represent 2.8 (quantity_implied_in_final_weight_volume) glasses of wine
def quantity_implied_in_final_weight_volume(line_item)
return line_item.quantity if line_item.variant.unit_value.to_f.zero?
(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_lb(value)
return 0 unless value
value / 453.6
end
end
end

View File

@@ -54,7 +54,8 @@ module Openfoodnetwork
Calculator::FlexiRate,
Calculator::PerItem,
Calculator::PriceSack,
Calculator::Weight
Calculator::Weight,
Calculator::WeightLb
]
app.config.spree.calculators.add_class('enterprise_fees')
@@ -64,7 +65,8 @@ module Openfoodnetwork
Calculator::FlexiRate,
Calculator::PerItem,
Calculator::PriceSack,
Calculator::Weight
Calculator::Weight,
Calculator::WeightLb
]
app.config.spree.calculators.add_class('payment_methods')

View File

@@ -3127,6 +3127,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
inventory: Inventory
zipcode: Postcode
weight: Weight (per kg)
weight_lb: Weight (per lb)
error_user_destroy_with_orders: "Users with completed orders may not be deleted"
cannot_create_payment_without_payment_methods: "You cannot create a payment for an order without any payment methods defined."
please_define_payment_methods: "Please define some payment methods first."

View File

@@ -38,6 +38,15 @@ describe Spree::Admin::ShippingMethodsController, type: :controller do
expect(shipping_method.reload.calculator.preferred_per_kg).to eq 10
end
it "updates preferred_per_lb of a Weight (Lb) calculator" do
shipping_method.calculator = create(:weight_lb_calculator, calculable: shipping_method)
params[:shipping_method][:calculator_attributes][:preferred_per_lb] = 10
spree_post :update, params
expect(shipping_method.reload.calculator.preferred_per_lb).to eq 10
end
it "updates preferred_flat_percent of a FlatPercentPerItem calculator" do
shipping_method.calculator = Calculator::FlatPercentPerItem.new(preferred_flat_percent: 20,

View File

@@ -16,4 +16,9 @@ FactoryBot.define do
after(:build) { |c| c.set_preference(:per_kg, 0.5) }
after(:create) { |c| c.set_preference(:per_kg, 0.5); c.save! }
end
factory :weight_lb_calculator, class: Calculator::WeightLb do
after(:build) { |c| c.set_preference(:per_lb, 0.5) }
after(:create) { |c| c.set_preference(:per_lb, 0.5); c.save! }
end
end