Skip to content

Commit

Permalink
Merge a28c603 into b4dfa50
Browse files Browse the repository at this point in the history
  • Loading branch information
wvengen committed Dec 21, 2013
2 parents b4dfa50 + a28c603 commit 6988671
Show file tree
Hide file tree
Showing 26 changed files with 584 additions and 93 deletions.
Binary file added app/assets/images/package-bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/images/package.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ $(function() {
return false;
});

// Disable action of disabled buttons
$(document).on('click', 'a.disabled', function() {
return false;
});

// Show and hide loader on ajax callbacks
$('*[data-remote]').bind('ajax:beforeSend', function() {
$('#loader').show();
Expand Down
32 changes: 29 additions & 3 deletions app/assets/stylesheets/bootstrap_and_overrides.css.less
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ table {
}

// ordering
span.used {
.used {
color: green;
}
span.unused {
.unused {
color: red;
}

Expand Down Expand Up @@ -216,6 +216,16 @@ tr.unavailable {
}
}

// editable article list can be more compact
.ordered-articles input {
margin-bottom: 0;
}

// entering units
.units_delta {
width: 2em;
}

// ********* Tweaks & fixes

// need more space for supplier&order information (in German, at least)
Expand Down Expand Up @@ -247,6 +257,23 @@ tr.unavailable {
height: inherit;
}

// inline form elements
.inline {
display: inline;
}

// show package icon after amount of package numbers
.package {
background: url(package-bg.png) no-repeat right center;
}
i.package {
width: 18px;
color: transparent; // hide text inside
}
.input-nano {
width: 30px;
}

// get rid of extra space on bottom of dialog with form
.modal form {
margin: 0;
Expand Down Expand Up @@ -287,4 +314,3 @@ tr.unavailable {
.control-text {
margin-top: 5px;
}

59 changes: 57 additions & 2 deletions app/controllers/orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ class OrdersController < ApplicationController

# List orders
def index
@open_orders = Order.open
@open_orders = Order.open.includes(:supplier)
@orders_in_progress = Order.finished_not_closed.includes(:supplier)
@per_page = 15
if params['sort']
sort = case params['sort']
Expand All @@ -20,7 +21,7 @@ def index
else
sort = "ends DESC"
end
@orders = Order.page(params[:page]).per(@per_page).order(sort).where("state != 'open'").includes(:supplier)
@orders = Order.closed.page(params[:page]).per(@per_page).includes(:supplier).order(sort)
end

# Gives a view for the results to a specific order
Expand Down Expand Up @@ -105,6 +106,27 @@ def finish
redirect_to orders_url, alert: I18n.t('errors.general_msg', :msg => error.message)
end

# ajax add article
def add_article
@order = Order.find(params[: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

def receive
@order = Order.find(params[:id])
unless request.post?
@order_articles = @order.order_articles.ordered.includes(:article)
else
flash[:notice] = "Order received: " + update_order_amounts
redirect_to @order
end
end

protected

# Renders the fax-text-file
Expand All @@ -131,4 +153,37 @@ def text_fax_template
end
text
end

def update_order_amounts
# where to leave remainder during redistribution
rest_to = []
rest_to << :tolerance if params[:rest_to_tolerance]
rest_to << :stock if params[:rest_to_stock]
rest_to << nil
# count what happens to the articles
counts = [0] * (rest_to.length+2)
cunits = [0] * (rest_to.length+2)
OrderArticle.transaction do
params[:order_articles].each do |oa_id, oa_params|
unless oa_params.blank?
oa = OrderArticle.find(oa_id)
# update attributes; don't use update_attribute because it calls save
# which makes received_changed? not work anymore
oa.attributes = oa_params
counts[0] += 1 if oa.units_received_changed?
unless oa.units_received.blank?
cunits[0] += oa.units_received * oa.article.unit_quantity
oacounts = oa.redistribute oa.units_received * oa.price.unit_quantity, rest_to
oacounts.each_with_index {|c,i| cunits[i+1]+=c; counts[i+1]+=1 if c>0 }
end
oa.save!
end
end
end
notice = " #{counts.shift} articles (#{cunits.shift} units) updated"
notice += ", #{counts.shift} (#{cunits.shift}) using tolerance" if params[:rest_to_tolerance]
notice += ", #{counts.shift} (#{cunits.shift}) go to stock if foodsoft would support that" if params[:rest_to_stock]
notice += ", #{counts.shift} (#{cunits.shift}) left over"
end

end
13 changes: 9 additions & 4 deletions app/helpers/deliveries_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ def link_to_invoice(delivery)
end
end

def articles_for_select2(supplier)
supplier.articles.undeleted.reorder('articles.name ASC').map {|a| {:id => a.id, :text => "#{a.name} (#{number_to_currency a.price}/#{a.unit})"} }
def articles_for_select2(articles, except = [], &block)
articles = articles.reorder('articles.name ASC')
articles.reject! {|a| not except.index(a.id).nil? } if except
block_given? or block = Proc.new {|a| "#{a.name} (#{number_to_currency a.price}/#{a.unit})" }
articles.map do |a|
{:id => a.id, :text => block.call(a)}
end
end

def stock_articles_for_table(supplier)
supplier.stock_articles.undeleted.reorder('articles.name ASC')
def articles_for_table(articles)
articles.undeleted.reorder('articles.name ASC')
end

def stock_change_remove_link(stock_change_form)
Expand Down
10 changes: 10 additions & 0 deletions app/helpers/orders_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,14 @@ def options_for_suppliers_to_select
options += [[I18n.t('helpers.orders.option_stock'), url_for(action: 'new', supplier_id: 0)]]
options_for_select(options)
end

def units_history_line(order_article)
if order_article.order.open?
nil
else
units_info = "#{order_article.units_to_order} ordered"
units_info += ", #{order_article.units_billed} billed" unless order_article.units_billed.nil?
units_info += ", #{order_article.units_received} received" unless order_article.units_received.nil?
end
end
end
90 changes: 48 additions & 42 deletions app/models/group_order_article.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,57 +99,63 @@ def update_quantities(quantity, tolerance)
# Returns a hash with three keys: :quantity / :tolerance / :total
#
# See description of the ordering algorithm in the general application documentation for details.
def calculate_result
@calculate_result ||= begin
quantity = tolerance = total_quantity = 0

# Get total
if order_article.article.is_a?(StockArticle)
total = order_article.article.quantity
logger.debug "<#{order_article.article.name}> (stock) => #{total}"
else
total = order_article.units_to_order * order_article.price.unit_quantity
logger.debug "<#{order_article.article.name}> units_to_order #{order_article.units_to_order} => #{total}"
end
def calculate_result(total = nil)
# return memoized result unless a total is given
return @calculate_result if total.nil? and not @calculate_result.nil?

quantity = tolerance = total_quantity = 0

# Get total
if not total.nil?
logger.debug "<#{order_article.article.name}> => #{total} (given)"
elsif order_article.article.is_a?(StockArticle)
total = order_article.article.quantity
logger.debug "<#{order_article.article.name}> (stock) => #{total}"
else
total = order_article.units_to_order * order_article.price.unit_quantity
logger.debug "<#{order_article.article.name}> units_to_order #{order_article.units_to_order} => #{total}"
end

if total > 0
# In total there are enough units ordered. Now check the individual result for the ordergroup (group_order).
#
# Get all GroupOrderArticleQuantities for this OrderArticle...
order_quantities = GroupOrderArticleQuantity.all(
:conditions => ["group_order_article_id IN (?)", order_article.group_order_article_ids], :order => 'created_on')
logger.debug "GroupOrderArticleQuantity records found: #{order_quantities.size}"
if total > 0
# In total there are enough units ordered. Now check the individual result for the ordergroup (group_order).
#
# Get all GroupOrderArticleQuantities for this OrderArticle...
order_quantities = GroupOrderArticleQuantity.all(
:conditions => ["group_order_article_id IN (?)", order_article.group_order_article_ids], :order => 'created_on')
logger.debug "GroupOrderArticleQuantity records found: #{order_quantities.size}"

# Determine quantities to be ordered...
order_quantities.each do |goaq|
q = [goaq.quantity, total - total_quantity].min
total_quantity += q
if goaq.group_order_article_id == self.id
logger.debug "increasing quantity by #{q}"
quantity += q
end
break if total_quantity >= total
end

# Determine quantities to be ordered...
# Determine tolerance to be ordered...
if total_quantity < total
logger.debug "determining additional items to be ordered from tolerance"
order_quantities.each do |goaq|
q = [goaq.quantity, total - total_quantity].min
q = [goaq.tolerance, total - total_quantity].min
total_quantity += q
if goaq.group_order_article_id == self.id
logger.debug "increasing quantity by #{q}"
quantity += q
logger.debug "increasing tolerance by #{q}"
tolerance += q
end
break if total_quantity >= total
end

# Determine tolerance to be ordered...
if total_quantity < total
logger.debug "determining additional items to be ordered from tolerance"
order_quantities.each do |goaq|
q = [goaq.tolerance, total - total_quantity].min
total_quantity += q
if goaq.group_order_article_id == self.id
logger.debug "increasing tolerance by #{q}"
tolerance += q
end
break if total_quantity >= total
end
end

logger.debug "determined quantity/tolerance/total: #{quantity} / #{tolerance} / #{quantity + tolerance}"
end

{:quantity => quantity, :tolerance => tolerance, :total => quantity + tolerance}
logger.debug "determined quantity/tolerance/total: #{quantity} / #{tolerance} / #{quantity + tolerance}"
end

# memoize result unless a total is given
r = {:quantity => quantity, :tolerance => tolerance, :total => quantity + tolerance}
@calculate_result = r if total.nil?
r
end

# Returns order result,
Expand All @@ -160,8 +166,8 @@ def result(type = :total)
end

# This is used during order.finish!.
def save_results!
self.update_attribute(:result, calculate_result[:total])
def save_results!(article_total = nil)
self.update_attribute(:result, calculate_result(article_total)[:total])
end

# Returns total price for this individual article
Expand Down
3 changes: 3 additions & 0 deletions app/models/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ def finish!(user)
goa.save_results!
# Delete no longer required order-history (group_order_article_quantities) and
# 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
end
end
Expand Down
Loading

0 comments on commit 6988671

Please sign in to comment.