add receive screen, quantities for model, redistribution
This commit is contained in:
parent
ed9a6cca39
commit
bd1b932775
17 changed files with 365 additions and 49 deletions
|
@ -212,6 +212,16 @@ tr.unavailable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// editable article list can be more compact
|
||||||
|
.ordered-articles input {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// entering units
|
||||||
|
.units_delta {
|
||||||
|
width: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
// ********* Tweaks & fixes
|
// ********* Tweaks & fixes
|
||||||
|
|
||||||
// need more space for supplier&order information (in German, at least)
|
// need more space for supplier&order information (in German, at least)
|
||||||
|
|
37
app/controllers/finance/receive_controller.rb
Normal file
37
app/controllers/finance/receive_controller.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
class Finance::ReceiveController < Finance::BaseController
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@order = Order.find(params[:id])
|
||||||
|
@order_articles = @order.order_articles.ordered.includes(:article)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
OrderArticle.transaction do
|
||||||
|
params[:order_articles].each do |oa_id, oa_params|
|
||||||
|
unless oa_params.blank?
|
||||||
|
oa = OrderArticle.find(oa_id)
|
||||||
|
# update attributes
|
||||||
|
oa.update_attributes!(oa_params)
|
||||||
|
# and process consequences
|
||||||
|
oa.redistribute(oa.units_received * oa.price.unit_quantity) unless oa.units_received.blank?
|
||||||
|
oa.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
flash[:notice] = I18n.t('receive.update.notice')
|
||||||
|
redirect_to finance_order_index_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# ajax add article
|
||||||
|
def add_article
|
||||||
|
@order = Order.find(params[:receive_id])
|
||||||
|
@order_article = @order.order_articles.where(:article_id => params[:article_id]).includes(:article).first
|
||||||
|
# we need to create the order article if it's not part of the current order
|
||||||
|
if @order_article.nil?
|
||||||
|
@order_article = @order.order_articles.build({order: @order, article_id: params[:article_id]})
|
||||||
|
@order_article.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
9
app/helpers/finance/receive_helper.rb
Normal file
9
app/helpers/finance/receive_helper.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# :encoding:utf-8:
|
||||||
|
module Finance::ReceiveHelper
|
||||||
|
# TODO currently duplicate a bit of DeliveriesHelper.articles_for_select2
|
||||||
|
def articles_for_select2(supplier)
|
||||||
|
supplier.articles.undeleted.reorder('articles.name ASC').map do |a|
|
||||||
|
{:id => a.id, :text => "#{a.name} (#{a.unit_quantity}⨯#{a.unit})"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -99,12 +99,16 @@ class GroupOrderArticle < ActiveRecord::Base
|
||||||
# Returns a hash with three keys: :quantity / :tolerance / :total
|
# Returns a hash with three keys: :quantity / :tolerance / :total
|
||||||
#
|
#
|
||||||
# See description of the ordering algorithm in the general application documentation for details.
|
# See description of the ordering algorithm in the general application documentation for details.
|
||||||
def calculate_result
|
def calculate_result(total = nil)
|
||||||
@calculate_result ||= begin
|
# return memoized result unless a total is given
|
||||||
|
return @calculate_result if total.nil? and not @calculate_result.nil?
|
||||||
|
|
||||||
quantity = tolerance = total_quantity = 0
|
quantity = tolerance = total_quantity = 0
|
||||||
|
|
||||||
# Get total
|
# Get total
|
||||||
if order_article.article.is_a?(StockArticle)
|
if not total.nil?
|
||||||
|
logger.debug "<#{order_article.article.name}> => #{total} (given)"
|
||||||
|
elsif order_article.article.is_a?(StockArticle)
|
||||||
total = order_article.article.quantity
|
total = order_article.article.quantity
|
||||||
logger.debug "<#{order_article.article.name}> (stock) => #{total}"
|
logger.debug "<#{order_article.article.name}> (stock) => #{total}"
|
||||||
else
|
else
|
||||||
|
@ -148,8 +152,10 @@ class GroupOrderArticle < ActiveRecord::Base
|
||||||
logger.debug "determined quantity/tolerance/total: #{quantity} / #{tolerance} / #{quantity + tolerance}"
|
logger.debug "determined quantity/tolerance/total: #{quantity} / #{tolerance} / #{quantity + tolerance}"
|
||||||
end
|
end
|
||||||
|
|
||||||
{:quantity => quantity, :tolerance => tolerance, :total => quantity + tolerance}
|
# memoize result unless a total is given
|
||||||
end
|
r = {:quantity => quantity, :tolerance => tolerance, :total => quantity + tolerance}
|
||||||
|
@calculate_result = r if total.nil?
|
||||||
|
r
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns order result,
|
# Returns order result,
|
||||||
|
@ -160,8 +166,8 @@ class GroupOrderArticle < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
# This is used during order.finish!.
|
# This is used during order.finish!.
|
||||||
def save_results!
|
def save_results!(article_total = nil)
|
||||||
self.update_attribute(:result, calculate_result[:total])
|
self.update_attribute(:result, calculate_result(article_total)[:total])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns total price for this individual article
|
# Returns total price for this individual article
|
||||||
|
|
|
@ -166,6 +166,9 @@ class Order < ActiveRecord::Base
|
||||||
goa.save_results!
|
goa.save_results!
|
||||||
# Delete no longer required order-history (group_order_article_quantities) and
|
# Delete no longer required order-history (group_order_article_quantities) and
|
||||||
# TODO: Do we need articles, which aren't ordered? (units_to_order == 0 ?)
|
# TODO: Do we need articles, which aren't ordered? (units_to_order == 0 ?)
|
||||||
|
# A: Yes, we do - for redistributing articles when the number of articles
|
||||||
|
# delivered changes, and for statistics on popular articles. Records
|
||||||
|
# with both tolerance and quantity zero can be deleted.
|
||||||
#goa.group_order_article_quantities.clear
|
#goa.group_order_article_quantities.clear
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,8 +12,8 @@ class OrderArticle < ActiveRecord::Base
|
||||||
validate :article_and_price_exist
|
validate :article_and_price_exist
|
||||||
validates_uniqueness_of :article_id, scope: :order_id
|
validates_uniqueness_of :article_id, scope: :order_id
|
||||||
|
|
||||||
scope :ordered, :conditions => "units_to_order > 0"
|
scope :ordered, -> { where("units_to_order > 0 OR units_billed > 0 OR units_received > 0") }
|
||||||
scope :ordered_or_member, -> { includes(:group_order_articles).where("units_to_order > 0 OR group_order_articles.result > 0") }
|
scope :ordered_or_member, -> { includes(:group_order_articles).where("units_to_order > 0 OR units_billed > 0 OR units_received > 0 OR group_order_articles.result > 0") }
|
||||||
|
|
||||||
before_create :init_from_balancing
|
before_create :init_from_balancing
|
||||||
after_destroy :update_ordergroup_prices
|
after_destroy :update_ordergroup_prices
|
||||||
|
@ -35,6 +35,13 @@ class OrderArticle < ActiveRecord::Base
|
||||||
article_price || article
|
article_price || article
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# latest information on available units
|
||||||
|
def units
|
||||||
|
return units_received unless units_received.nil?
|
||||||
|
return units_billed unless units_billed.nil?
|
||||||
|
units_to_order
|
||||||
|
end
|
||||||
|
|
||||||
# Count quantities of belonging group_orders.
|
# Count quantities of belonging group_orders.
|
||||||
# In balancing this can differ from ordered (by supplier) quantity for this article.
|
# In balancing this can differ from ordered (by supplier) quantity for this article.
|
||||||
def group_orders_sum
|
def group_orders_sum
|
||||||
|
@ -94,6 +101,18 @@ class OrderArticle < ActiveRecord::Base
|
||||||
(units_to_order * price.unit_quantity) == group_orders_sum[:quantity] rescue false
|
(units_to_order * price.unit_quantity) == group_orders_sum[:quantity] rescue false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def redistribute(quantity)
|
||||||
|
# recompute
|
||||||
|
group_order_articles.each {|goa| goa.save_results! quantity }
|
||||||
|
|
||||||
|
# Update GroupOrder prices & Ordergroup stats
|
||||||
|
# TODO only affected group_orders, and once after redistributing all articles
|
||||||
|
order.group_orders.each(&:update_price!)
|
||||||
|
order.ordergroups.each(&:update_stats!)
|
||||||
|
|
||||||
|
# TODO notifications
|
||||||
|
end
|
||||||
|
|
||||||
# Updates order_article and belongings during balancing process
|
# Updates order_article and belongings during balancing process
|
||||||
def update_article_and_price!(order_article_attributes, article_attributes, price_attributes = nil)
|
def update_article_and_price!(order_article_attributes, article_attributes, price_attributes = nil)
|
||||||
OrderArticle.transaction do
|
OrderArticle.transaction do
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
%td= show_user(order.updated_by)
|
%td= show_user(order.updated_by)
|
||||||
%td
|
%td
|
||||||
- unless order.closed?
|
- unless order.closed?
|
||||||
|
= link_to t('.receive'), edit_finance_receive_path(order), class: 'btn btn-mini'
|
||||||
= link_to t('.clear'), new_finance_order_path(order_id: order.id), class: 'btn btn-mini btn-primary'
|
= link_to t('.clear'), new_finance_order_path(order_id: order.id), class: 'btn btn-mini btn-primary'
|
||||||
= link_to t('.close'), close_direct_finance_order_path(order),
|
= link_to t('.close'), close_direct_finance_order_path(order),
|
||||||
:confirm => t('.confirm'), :method => :put, class: 'btn btn-mini'
|
:confirm => t('.confirm'), :method => :put, class: 'btn btn-mini'
|
||||||
|
|
16
app/views/finance/receive/_edit_article.html.haml
Normal file
16
app/views/finance/receive/_edit_article.html.haml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
= fields_for 'order_articles', order_article, index: order_article.id do |form|
|
||||||
|
%tr{class: "#{cycle('even', 'odd', name: 'articles')} order-article", valign: "top"}
|
||||||
|
- order_title = []
|
||||||
|
- order_title.append t('.manufacturer')+': ' + order_article.article.manufacturer unless order_article.article.manufacturer.to_s.empty?
|
||||||
|
- order_title.append t('.note')+': ' + order_article.article.note unless order_article.article.note.to_s.empty?
|
||||||
|
- units_expected = (order_article.units_billed or order_article.units_to_order)
|
||||||
|
%td= order_article.article.order_number
|
||||||
|
%td.name{title: order_title.join("\n")}= order_article.article.name
|
||||||
|
%td #{order_article.article.unit_quantity} × #{order_article.article.unit}
|
||||||
|
%td #{order_article.quantity} + #{order_article.tolerance}
|
||||||
|
%td= order_article.units_to_order
|
||||||
|
%td= order_article.units_billed
|
||||||
|
%td
|
||||||
|
= form.text_field :units_received, class: 'input-mini', data: {'units-expected' => units_expected}
|
||||||
|
/ TODO add almost invisible text_field for entering single units
|
||||||
|
%td.units_delta
|
76
app/views/finance/receive/_edit_articles.html.haml
Normal file
76
app/views/finance/receive/_edit_articles.html.haml
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
- content_for :javascript do
|
||||||
|
:javascript
|
||||||
|
|
||||||
|
function update_delta(input) {
|
||||||
|
var units = $(input).val();
|
||||||
|
var expected = $(input).data('units-expected');
|
||||||
|
var html;
|
||||||
|
|
||||||
|
if (units.replace(/\s/g,"")=="") {
|
||||||
|
// no value
|
||||||
|
html = '';
|
||||||
|
} else if (isNaN(units)) {
|
||||||
|
html = '<i class="icon-remove" style="color: red"></i>';
|
||||||
|
} else if (units == expected) {
|
||||||
|
// equal value
|
||||||
|
html = '<i class="icon-ok" style="color: green"></i>';
|
||||||
|
} else if (units < expected) {
|
||||||
|
html = '<span style="color: red">- '+(expected-units)+'</span>';
|
||||||
|
} else /*if (units> expected)*/ {
|
||||||
|
html = '<span style="color: green">+ '+(units-expected)+'</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$(input).closest('tr').find('.units_delta').html(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).on('change', 'input[data-units-expected]', function() {
|
||||||
|
update_delta(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$('input[data-units-expected]').each(function() {
|
||||||
|
update_delta(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#add_article').removeAttr('disabled').select2({
|
||||||
|
placeholder: '#{t '.add_article'}',
|
||||||
|
data: #{articles_for_select2(@order).to_json},
|
||||||
|
// TODO implement adding a new article, like in deliveries
|
||||||
|
}).on('change', function(e) {
|
||||||
|
var selectedArticle = $(e.currentTarget).select2('data');
|
||||||
|
if(!selectedArticle) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: '#{finance_receive_add_article_path(@order)}',
|
||||||
|
type: 'get',
|
||||||
|
data: {article_id: selectedArticle.id},
|
||||||
|
contentType: 'application/json; charset=UTF-8'
|
||||||
|
});
|
||||||
|
$('#add_article').select2('data', null);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
%table.ordered-articles.table.table-striped.stupidtable
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th.sort{:data => {:sort => 'string'}}= t('.number')
|
||||||
|
%th.sort{:data => {:sort => 'string'}}= t('.article')
|
||||||
|
%th= heading_helper GroupOrderArticle, :units
|
||||||
|
%th Members
|
||||||
|
%th Ordered
|
||||||
|
%th Invoice
|
||||||
|
%th Received
|
||||||
|
%th
|
||||||
|
%tbody#result_table
|
||||||
|
- @order_articles.each do |order_article|
|
||||||
|
= render :partial => 'edit_article', :locals => {:order_article => order_article}
|
||||||
|
%tfoot
|
||||||
|
%tr
|
||||||
|
%th{:colspan => 8}
|
||||||
|
%input#add_article{:style => 'width: 500px;'}
|
||||||
|
|
14
app/views/finance/receive/add_article.js.erb
Normal file
14
app/views/finance/receive/add_article.js.erb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
$('div.container-fluid').prepend(
|
||||||
|
'<%= j(render(:partial => 'shared/alert_success', :locals => {:alert_message => t('.notice', :name => @order_article.article.name)})) %>'
|
||||||
|
);
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
$('.ordered-articles tr').removeClass('success');
|
||||||
|
|
||||||
|
var article_for_adding = $(
|
||||||
|
'<%= j(render(:partial => 'edit_article', :locals => {:order_article => @order_article})) %>'
|
||||||
|
).addClass('success');
|
||||||
|
|
||||||
|
$('.ordered-articles tbody').append(article_for_adding);
|
||||||
|
updateSort('.ordered-articles');
|
||||||
|
})();
|
10
app/views/finance/receive/edit.html.haml
Normal file
10
app/views/finance/receive/edit.html.haml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
- title "Receiving #{@order.name}"
|
||||||
|
|
||||||
|
= form_tag(finance_receive_path(@order), :method => :put) do
|
||||||
|
%section#results
|
||||||
|
= render 'edit_articles'
|
||||||
|
.form-actions
|
||||||
|
= submit_tag t('.submit'), class: 'btn btn-primary'
|
||||||
|
= link_to t('ui.or_cancel'), finance_order_index_path
|
||||||
|
|
||||||
|
%p= link_to_top
|
|
@ -560,6 +560,7 @@ en:
|
||||||
last_edited_by: Last edited by
|
last_edited_by: Last edited by
|
||||||
name: Supplier
|
name: Supplier
|
||||||
no_closed_orders: At the moment there are no closed orders.
|
no_closed_orders: At the moment there are no closed orders.
|
||||||
|
receive: receive
|
||||||
state: State
|
state: State
|
||||||
summary:
|
summary:
|
||||||
changed: Data was changed!
|
changed: Data was changed!
|
||||||
|
|
|
@ -144,6 +144,10 @@ Foodsoft::Application.routes.draw do
|
||||||
resources :order_articles
|
resources :order_articles
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resources :receive do
|
||||||
|
get :add_article
|
||||||
|
end
|
||||||
|
|
||||||
resources :group_order_articles do
|
resources :group_order_articles do
|
||||||
member do
|
member do
|
||||||
put :update_result
|
put :update_result
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
class AddQuantitiesToOrderArticle < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :order_articles, :units_billed, :integer
|
||||||
|
add_column :order_articles, :units_received, :integer
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20130920201529) do
|
ActiveRecord::Schema.define(:version => 20130930132511) do
|
||||||
|
|
||||||
create_table "article_categories", :force => true do |t|
|
create_table "article_categories", :force => true do |t|
|
||||||
t.string "name", :default => "", :null => false
|
t.string "name", :default => "", :null => false
|
||||||
|
@ -195,6 +195,8 @@ ActiveRecord::Schema.define(:version => 20130920201529) do
|
||||||
t.integer "units_to_order", :default => 0, :null => false
|
t.integer "units_to_order", :default => 0, :null => false
|
||||||
t.integer "lock_version", :default => 0, :null => false
|
t.integer "lock_version", :default => 0, :null => false
|
||||||
t.integer "article_price_id"
|
t.integer "article_price_id"
|
||||||
|
t.integer "units_billed"
|
||||||
|
t.integer "units_received"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "order_articles", ["order_id", "article_id"], :name => "index_order_articles_on_order_id_and_article_id", :unique => true
|
add_index "order_articles", ["order_id", "article_id"], :name => "index_order_articles_on_order_id_and_article_id", :unique => true
|
||||||
|
|
|
@ -24,8 +24,4 @@ FactoryGirl.define do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# requires order and article
|
|
||||||
factory :order_article do
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
106
spec/models/order_article_spec.rb
Normal file
106
spec/models/order_article_spec.rb
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe OrderArticle do
|
||||||
|
let(:order) { FactoryGirl.create :order, article_count: 1 }
|
||||||
|
let(:oa) { order.order_articles.first }
|
||||||
|
|
||||||
|
it 'is not ordered by default' do
|
||||||
|
expect(OrderArticle.ordered.count).to eq 0
|
||||||
|
end
|
||||||
|
|
||||||
|
[:units_to_order, :units_billed, :units_received].each do |units|
|
||||||
|
|
||||||
|
it "is ordered when there are #{units.to_s.gsub '_', ' '}" do
|
||||||
|
oa.update_attribute units, rand(1..99)
|
||||||
|
expect(OrderArticle.ordered.count).to eq 1
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'knows how many items there are' do
|
||||||
|
oa.units_to_order = rand(1..99)
|
||||||
|
expect(oa.units).to eq oa.units_to_order
|
||||||
|
oa.units_billed = rand(1..99)
|
||||||
|
expect(oa.units).to eq oa.units_billed
|
||||||
|
oa.units_received = rand(1..99)
|
||||||
|
expect(oa.units).to eq oa.units_received
|
||||||
|
|
||||||
|
oa.units_billed = rand(1..99)
|
||||||
|
expect(oa.units).to eq oa.units_received
|
||||||
|
oa.units_to_order = rand(1..99)
|
||||||
|
expect(oa.units).to eq oa.units_received
|
||||||
|
oa.units_received = rand(1..99)
|
||||||
|
expect(oa.units).to eq oa.units_received
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'redistribution' do
|
||||||
|
let(:admin) { FactoryGirl.create :user, groups:[FactoryGirl.create(:workgroup, role_finance: true)] }
|
||||||
|
let(:article) { FactoryGirl.create :article, unit_quantity: 3 }
|
||||||
|
let(:order) { FactoryGirl.create :order, article_ids: [article.id] }
|
||||||
|
let(:go1) { FactoryGirl.create :group_order, order: order }
|
||||||
|
let(:go2) { FactoryGirl.create :group_order, order: order }
|
||||||
|
let(:go3) { FactoryGirl.create :group_order, order: order }
|
||||||
|
let(:goa1) { FactoryGirl.create :group_order_article, group_order: go1, order_article: oa }
|
||||||
|
let(:goa2) { FactoryGirl.create :group_order_article, group_order: go2, order_article: oa }
|
||||||
|
let(:goa3) { FactoryGirl.create :group_order_article, group_order: go3, order_article: oa }
|
||||||
|
|
||||||
|
# set quantities of group_order_articles
|
||||||
|
def set_quantities(q1, q2, q3)
|
||||||
|
goa1.update_quantities(*q1)
|
||||||
|
goa2.update_quantities(*q2)
|
||||||
|
goa3.update_quantities(*q3)
|
||||||
|
oa.update_results!
|
||||||
|
order.finish!(admin)
|
||||||
|
goa_reload
|
||||||
|
end
|
||||||
|
|
||||||
|
# reload all group_order_articles
|
||||||
|
def goa_reload
|
||||||
|
[goa1, goa2, goa3].map(&:reload)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has expected units_to_order' do
|
||||||
|
set_quantities [3,2], [1,3], [1,0]
|
||||||
|
expect(oa.units*oa.article.unit_quantity).to eq 6
|
||||||
|
expect([goa1, goa2, goa3].map(&:result)).to eq [4, 1, 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does nothing when nothing has changed' do
|
||||||
|
set_quantities [3,2], [1,3], [1,0]
|
||||||
|
oa.redistribute 6
|
||||||
|
goa_reload
|
||||||
|
expect([goa1, goa2, goa3].map(&:result).map(&:to_i)).to eq [4, 1, 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'works when there is nothing to distribute' do
|
||||||
|
set_quantities [3,2], [1,3], [1,0]
|
||||||
|
oa.redistribute 0
|
||||||
|
goa_reload
|
||||||
|
expect([goa1, goa2, goa3].map(&:result)).to eq [0, 0, 0]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'works when quantity needs to be reduced' do
|
||||||
|
set_quantities [3,2], [1,3], [1,0]
|
||||||
|
oa.redistribute 4
|
||||||
|
goa_reload
|
||||||
|
expect([goa1, goa2, goa3].map(&:result)).to eq [3, 1, 0]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'works when quantity is increased within quantity' do
|
||||||
|
set_quantities [3,0], [2,0], [2,0]
|
||||||
|
expect([goa1, goa2, goa3].map(&:result)).to eq [3, 2, 1]
|
||||||
|
oa.redistribute 7
|
||||||
|
goa_reload
|
||||||
|
expect([goa1, goa2, goa3].map(&:result).map(&:to_i)).to eq [3, 2, 2]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'works when there is just one for the first' do
|
||||||
|
set_quantities [3,2], [1,3], [1,0]
|
||||||
|
oa.redistribute 1
|
||||||
|
goa_reload
|
||||||
|
expect([goa1, goa2, goa3].map(&:result)).to eq [1, 0, 0]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in a new issue