Storing estimated prices for standing line items in the database

This commit is contained in:
Rob Harrington
2016-11-30 12:48:34 +11:00
parent 9baaf1efc9
commit f4cbd90400
6 changed files with 93 additions and 11 deletions

View File

@@ -9,7 +9,6 @@ module Admin
respond_to :json
def index
respond_to do |format|
format.html do
@payment_methods = Spree::PaymentMethod.managed_by(spree_current_user)
@@ -25,7 +24,7 @@ module Admin
end
def create
form = StandingOrderForm.new(@standing_order, params[:standing_order])
form = StandingOrderForm.new(@standing_order, params[:standing_order], fee_calculator)
if form.save
render_as_json @standing_order, fee_calculator: fee_calculator
else
@@ -34,7 +33,7 @@ module Admin
end
def update
form = StandingOrderForm.new(@standing_order, params[:standing_order])
form = StandingOrderForm.new(@standing_order, params[:standing_order], fee_calculator)
if form.save
render_as_json @standing_order, ams_prefix: params[:ams_prefix], fee_calculator: fee_calculator
else

View File

@@ -3,20 +3,22 @@ class StandingOrderForm
include ActiveModel::Conversion
include ActiveModel::Validations
attr_accessor :standing_order, :params
attr_accessor :standing_order, :params, :fee_calculator
delegate :orders, :order_cycles, :bill_address, :ship_address, :standing_line_items, to: :standing_order
delegate :shop, :shop_id, :customer, :customer_id, :begins_at, :ends_at, :standing_order_orders, to: :standing_order
delegate :shipping_method, :shipping_method_id, :payment_method, :payment_method_id, to: :standing_order
delegate :shipping_method_id_changed?, :shipping_method_id_was, :payment_method_id_changed?, :payment_method_id_was, to: :standing_order
def initialize(standing_order, params={})
def initialize(standing_order, params={}, fee_calculator=nil)
@standing_order = standing_order
@params = params
@fee_calculator = fee_calculator
end
def save
@standing_order.transaction do
validate_price_estimates
@standing_order.assign_attributes(params)
initialise_orders!
@@ -129,4 +131,25 @@ class StandingOrderForm
def line_items_from_future_and_undated_orders(variant_id)
Spree::LineItem.where(order_id: future_and_undated_orders, variant_id: variant_id)
end
def validate_price_estimates
item_attributes = params[:standing_line_items_attributes]
return unless item_attributes.present?
if fee_calculator
item_attributes.each do |item_attrs|
if variant = Spree::Variant.find_by_id(item_attrs[:variant_id])
item_attrs[:price_estimate] = price_estimate_for(variant)
else
item_attrs.delete(:price_estimate)
end
end
else
item_attributes.each { |item_attrs| item_attrs.delete(:price_estimate) }
end
end
def price_estimate_for(variant)
fees = fee_calculator.indexed_fees_for(variant)
(variant.price + fees).to_d
end
end

View File

@@ -6,7 +6,9 @@ class Api::Admin::StandingLineItemSerializer < ActiveModel::Serializer
end
def price_estimate
if options[:fee_calculator]
if object.price_estimate
object.price_estimate
elsif options[:fee_calculator]
(object.variant.price + options[:fee_calculator].indexed_fees_for(object.variant)).to_f
else
"?"

View File

@@ -0,0 +1,5 @@
class AddPriceEstimateToStandingLineItems < ActiveRecord::Migration
def change
add_column :standing_line_items, :price_estimate, :decimal, :precision => 8, :scale => 2
end
end

View File

@@ -1065,11 +1065,12 @@ ActiveRecord::Schema.define(:version => 20170921065259) do
end
create_table "standing_line_items", :force => true do |t|
t.integer "standing_order_id", :null => false
t.integer "variant_id", :null => false
t.integer "quantity", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "standing_order_id", :null => false
t.integer "variant_id", :null => false
t.integer "quantity", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.decimal "price_estimate", :precision => 8, :scale => 2
end
add_index "standing_line_items", ["standing_order_id"], :name => "index_standing_line_items_on_standing_order_id"

View File

@@ -217,5 +217,57 @@ module OpenFoodNetwork
expect(line_items.map(&:quantity)).to eq [4]
end
end
describe "validating price_estimates on standing line items" do
let(:params) { { } }
let(:form) { StandingOrderForm.new(nil, params) }
context "when line_item params are present" do
before { allow(form).to receive(:price_estimate_for) }
it "does nothing" do
form.send(:validate_price_estimates)
expect(form.params[:standing_line_items_attributes]).to be nil
end
end
context "when line_item params are present" do
before do
params[:standing_line_items_attributes] = [ { id: 1, price_estimate: 2.50 }, { id: 2, price_estimate: 3.50 }]
end
context "when no fee calculator is present" do
before { allow(form).to receive(:price_estimate_for) }
it "clears price estimates on all standing line item attributes" do
form.send(:validate_price_estimates)
attrs = form.params[:standing_line_items_attributes]
expect(attrs.first.keys).to_not include :price_estimate
expect(attrs.last.keys).to_not include :price_estimate
expect(form).to_not have_received(:price_estimate_for)
end
end
context "when a fee calculator is present" do
let(:variant) { create(:variant) }
let(:fee_calculator) { double(:fee_calculator) }
before do
allow(form).to receive(:fee_calculator) { fee_calculator }
allow(form).to receive(:price_estimate_for) { 5.30 }
params[:standing_line_items_attributes].first[:variant_id] = variant.id
end
it "clears price estimates on standing line item attributes without variant ids" do
form.send(:validate_price_estimates)
attrs = form.params[:standing_line_items_attributes]
expect(attrs.first.keys).to include :price_estimate
expect(attrs.last.keys).to_not include :price_estimate
expect(attrs.first[:price_estimate]).to eq 5.30
expect(form).to have_received(:price_estimate_for).with(variant)
end
end
end
end
end
end