Adding 'Total Units' field to supplier report

This commit is contained in:
Rob H
2014-08-07 14:21:01 +10:00
parent bb09236468
commit 30a14edb06
3 changed files with 51 additions and 33 deletions

View File

@@ -386,12 +386,23 @@ Spree::Admin::ReportsController.class_eval do
table_items = @line_items
@include_blank = 'All'
header = ["Producer", "Product", "Variant", "Amount", "Curr. Cost per Unit", "Total Cost", "Status", "Incoming Transport"]
header = ["Producer", "Product", "Variant", "Amount", "Total Units", "Curr. Cost per Unit", "Total Cost", "Status", "Incoming Transport"]
ovn = OpenFoodNetwork::OptionValueNamer.new()
columns = [ proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.full_name },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| ovn.name(OpenStruct.new({
unit_value: ( line_items.map{ |li| li.variant.unit_value.nil? }.any? ? 0 : line_items.sum { |li| li.quantity * li.variant.unit_value } ),
unit_description: line_items.first.variant.unit_description,
product: OpenStruct.new({
variant_unit: line_items.first.product.variant_unit,
variant_unit_scale: line_items.first.product.variant_unit_scale,
variant_unit_name: line_items.first.product.variant_unit_name
})
}))},
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.price } },
proc { |line_items| "" },

View File

@@ -1,27 +1,34 @@
module OpenFoodNetwork
class OptionValueNamer < Struct.new(:variant)
def name
value, unit = self.option_value_value_unit
separator = self.value_scaled? ? '' : ' '
class OptionValueNamer
def initialize(variant = nil)
@variant = variant
end
def name(obj = nil)
@variant = obj unless obj.nil?
value, unit = option_value_value_unit
separator = value_scaled? ? '' : ' '
name_fields = []
name_fields << "#{value}#{separator}#{unit}" if value.present? && unit.present?
name_fields << variant.unit_description if variant.unit_description.present?
name_fields << @variant.unit_description if @variant.unit_description.present?
name_fields.join ' '
end
private
def value_scaled?
variant.product.variant_unit_scale.present?
@variant.product.variant_unit_scale.present?
end
def option_value_value_unit
if variant.unit_value.present?
if %w(weight volume).include? variant.product.variant_unit
value, unit_name = self.option_value_value_unit_scaled
if @variant.unit_value.present?
if %w(weight volume).include? @variant.product.variant_unit
value, unit_name = option_value_value_unit_scaled
else
value = variant.unit_value
unit_name = variant.product.variant_unit_name
value = @variant.unit_value
unit_name = @variant.product.variant_unit_name
unit_name = unit_name.pluralize if value > 1
end
@@ -35,9 +42,9 @@ module OpenFoodNetwork
end
def option_value_value_unit_scaled
unit_scale, unit_name = self.scale_for_unit_value
unit_scale, unit_name = scale_for_unit_value
value = variant.unit_value / unit_scale
value = @variant.unit_value / unit_scale
[value, unit_name]
end
@@ -48,10 +55,10 @@ module OpenFoodNetwork
# Find the largest available unit where unit_value comes to >= 1 when expressed in it.
# If there is none available where this is true, use the smallest available unit.
unit = units[variant.product.variant_unit].select { |scale, unit_name|
variant.unit_value / scale >= 1
unit = units[@variant.product.variant_unit].select { |scale, unit_name|
@variant.unit_value / scale >= 1
}.to_a.last
unit = units[variant.product.variant_unit].first if unit.nil?
unit = units[@variant.product.variant_unit].first if unit.nil?
unit
end

View File

@@ -4,34 +4,34 @@ module OpenFoodNetwork
describe OptionValueNamer do
describe "generating option value name" do
let(:v) { Spree::Variant.new }
let(:subject) { OptionValueNamer.new v }
let(:subject) { OptionValueNamer.new }
it "when description is blank" do
v.stub(:unit_description) { nil }
subject.stub(:value_scaled?) { true }
subject.stub(:option_value_value_unit) { %w(value unit) }
subject.name.should == "valueunit"
subject.name(v).should == "valueunit"
end
it "when description is present" do
v.stub(:unit_description) { 'desc' }
subject.stub(:option_value_value_unit) { %w(value unit) }
subject.stub(:value_scaled?) { true }
subject.name.should == "valueunit desc"
subject.name(v).should == "valueunit desc"
end
it "when value is blank and description is present" do
v.stub(:unit_description) { 'desc' }
subject.stub(:option_value_value_unit) { [nil, nil] }
subject.stub(:value_scaled?) { true }
subject.name.should == "desc"
subject.name(v).should == "desc"
end
it "spaces value and unit when value is unscaled" do
v.stub(:unit_description) { nil }
subject.stub(:option_value_value_unit) { %w(value unit) }
subject.stub(:value_scaled?) { false }
subject.name.should == "value unit"
subject.name(v).should == "value unit"
end
end
@@ -42,7 +42,7 @@ module OpenFoodNetwork
v.stub(:product) { p }
subject = OptionValueNamer.new v
subject.value_scaled?.should be_true
expect(subject.send(:value_scaled?)).to be_true
end
it "returns false otherwise" do
@@ -51,7 +51,7 @@ module OpenFoodNetwork
v.stub(:product) { p }
subject = OptionValueNamer.new v
subject.value_scaled?.should be_false
expect(subject.send(:value_scaled?)).to be_false
end
end
@@ -65,7 +65,7 @@ module OpenFoodNetwork
v.stub(:unit_value) { 100 }
subject.option_value_value_unit.should == [100, 'g']
expect(subject.send(:option_value_value_unit)).to eq [100, 'g']
end
it "generates values when unit value is non-integer" do
@@ -73,7 +73,7 @@ module OpenFoodNetwork
v.stub(:product) { p }
v.stub(:unit_value) { 123.45 }
subject.option_value_value_unit.should == [123.45, 'g']
expect(subject.send(:option_value_value_unit)).to eq [123.45, 'g']
end
it "returns a value of 1 when unit value equals the scale" do
@@ -81,7 +81,7 @@ module OpenFoodNetwork
v.stub(:product) { p }
v.stub(:unit_value) { 1000.0 }
subject.option_value_value_unit.should == [1, 'kg']
expect(subject.send(:option_value_value_unit)).to eq [1, 'kg']
end
it "generates values for all weight scales" do
@@ -89,7 +89,7 @@ module OpenFoodNetwork
p = double(:product, variant_unit: 'weight', variant_unit_scale: scale)
v.stub(:product) { p }
v.stub(:unit_value) { 100 * scale }
subject.option_value_value_unit.should == [100, unit]
expect(subject.send(:option_value_value_unit)).to eq [100, unit]
end
end
@@ -98,7 +98,7 @@ module OpenFoodNetwork
p = double(:product, variant_unit: 'volume', variant_unit_scale: scale)
v.stub(:product) { p }
v.stub(:unit_value) { 100 * scale }
subject.option_value_value_unit.should == [100, unit]
expect(subject.send(:option_value_value_unit)).to eq [100, unit]
end
end
@@ -106,7 +106,7 @@ module OpenFoodNetwork
p = double(:product, variant_unit: 'volume', variant_unit_scale: 0.001)
v.stub(:product) { p }
v.stub(:unit_value) { 0.0001 }
subject.option_value_value_unit.should == [0.1, 'mL']
expect(subject.send(:option_value_value_unit)).to eq [0.1, 'mL']
end
it "generates values for item units" do
@@ -114,7 +114,7 @@ module OpenFoodNetwork
p = double(:product, variant_unit: 'items', variant_unit_scale: nil, variant_unit_name: unit)
v.stub(:product) { p }
v.stub(:unit_value) { 100 }
subject.option_value_value_unit.should == [100, unit.pluralize]
expect(subject.send(:option_value_value_unit)).to eq [100, unit.pluralize]
end
end
@@ -122,14 +122,14 @@ module OpenFoodNetwork
p = double(:product, variant_unit: 'items', variant_unit_scale: nil, variant_unit_name: 'packet')
v.stub(:product) { p }
v.stub(:unit_value) { 1 }
subject.option_value_value_unit.should == [1, 'packet']
expect(subject.send(:option_value_value_unit)).to eq [1, 'packet']
end
it "returns [nil, nil] when unit value is not set" do
p = double(:product, variant_unit: 'items', variant_unit_scale: nil, variant_unit_name: 'foo')
v.stub(:product) { p }
v.stub(:unit_value) { nil }
subject.option_value_value_unit.should == [nil, nil]
expect(subject.send(:option_value_value_unit)).to eq [nil, nil]
end
end
end