Order-refactoring part II.

This commit is contained in:
Benjamin Meichsner 2009-02-03 21:14:48 +01:00
parent f7b9582261
commit 6fd5d825f9
27 changed files with 228 additions and 231 deletions

View file

@ -53,7 +53,7 @@ class ApplicationController < ActionController::Base
def deny_access
self.return_to = request.request_uri
redirect_to :controller => 'login', :action => 'denied'
redirect_to :controller => '/login', :action => 'denied'
return false
end

View file

@ -4,9 +4,6 @@ class HomeController < ApplicationController
def index
@currentOrders = Order.open
@ordergroup = @current_user.ordergroup
if @ordergroup
@financial_transactions = @ordergroup.financial_transactions.find(:all, :order => 'created_on desc', :limit => 3)
end
# unaccepted tasks
@unaccepted_tasks = @current_user.unaccepted_tasks
# task in next week

View file

@ -5,7 +5,7 @@ class OrderingController < ApplicationController
before_filter :ensure_ordergroup_member
before_filter :ensure_open_order, :only => [:order, :saveOrder]
verify :method => :post, :only => [:saveOrder], :redirect_to => { :action => :index }
verify :method => :post, :only => [:saveOrder], :redirect_to => {:action => :index}
# Index page.
def index
@ -23,8 +23,8 @@ class OrderingController < ApplicationController
if @group_order
# Group has already ordered, so get the results...
for article in @group_order.group_order_articles
result = article.orderResult
ordered_articles[article.order_article_id] = { 'quantity' => article.quantity,
result = article.result
ordered_articles[article.order_article_id] = {'quantity' => article.quantity,
'tolerance' => article.tolerance,
'quantity_result' => result[:quantity],
'tolerance_result' => result[:tolerance]}
@ -61,53 +61,53 @@ class OrderingController < ApplicationController
# Update changes to a current order.
def saveOrder
order = @order # Get the object through before_filter
if (params[:total_balance].to_i < 0)
if (params[:total_balance].to_i < 0) #TODO: Better use a real test on sufficiant funds
flash[:error] = 'Der Bestellwert übersteigt das verfügbare Guthaben.'
redirect_to :action => 'order'
elsif (ordered = params[:ordered])
begin
Order.transaction do
# Create group order if necessary...
if (groupOrder = order.group_orders.find(:first, :conditions => "ordergroup_id = #{@ordergroup.id}", :include => [:group_order_articles]))
if (params[:version].to_i != groupOrder.lock_version) # check for conflicts well ahead
raise ActiveRecord::StaleObjectError
end
else
groupOrder = GroupOrder.new(:ordergroup => @ordergroup, :order => order, :updated_by => @current_user, :price => 0)
groupOrder.save!
end
# Create/update GroupOrderArticles...
newGroupOrderArticles = Array.new
for article in order.order_articles
# Find the GroupOrderArticle, create a new one if necessary...
groupOrderArticles = groupOrder.group_order_articles.select{ |v| v.order_article_id == article.id }
unless (groupOrderArticle = groupOrderArticles[0])
groupOrderArticle = GroupOrderArticle.create(:group_order => groupOrder, :order_article_id => article.id, :quantity => 0, :tolerance => 0)
end
# Get ordered quantities and update GroupOrderArticle/-Quantities...
unless (quantities = ordered.delete(article.id.to_s)) && (quantity = quantities['quantity']) && (tolerance = quantities['tolerance'])
quantity = tolerance = 0
end
groupOrderArticle.update_quantities(quantity.to_i, tolerance.to_i)
# Add to new list of GroupOrderArticles:
newGroupOrderArticles.push(groupOrderArticle)
end
groupOrder.group_order_articles = newGroupOrderArticles
groupOrder.update_price!
groupOrder.updated_by = @current_user
groupOrder.save!
order.update_quantities
order.save!
end
flash[:notice] = 'Die Bestellung wurde gespeichert.'
rescue ActiveRecord::StaleObjectError
flash[:error] = 'In der Zwischenzeit hat jemand anderes auch bestellt, daher konnte die Bestellung nicht aktualisiert werden.'
rescue => exception
logger.error('Failed to update order: ' + exception.message)
flash[:error] = 'Die Bestellung konnte nicht aktualisiert werden, da ein Fehler auftrat.'
end
redirect_to :action => 'my_order_result', :id => order
begin
Order.transaction do
# Try to find group_order
group_order = @order.group_orders.first :conditions => "ordergroup_id = #{@ordergroup.id}",
:include => [:group_order_articles]
# Create group order if necessary...
unless group_order.nil?
# check for conflicts well ahead
if (params[:version].to_i != group_order.lock_version)
raise ActiveRecord::StaleObjectError
end
else
group_order = @ordergroup.group_orders.create!(:order => @order, :updated_by => @current_user, :price => 0)
end
# Create/update group_order_articles...
for order_article in @order.order_articles
# Find the group_order_article, create a new one if necessary...
group_order_article = group_order.group_order_articles.detect { |v| v.order_article_id == order_article.id }
if group_order_article.nil?
group_order_article = group_order.group_order_articles.create(:order_article_id => order_article.id)
end
# Get ordered quantities and update group_order_articles/_quantities...
quantities = ordered.fetch(order_article.id.to_s, {'quantity' => 0, 'tolerance' => 0})
group_order_article.update_quantities(quantities['quantity'].to_i, quantities['tolerance'].to_i)
# Also update results for the order_article
order_article.update_results!
end
group_order.update_price!
group_order.update_attribute(:updated_by, @current_user)
end
flash[:notice] = 'Die Bestellung wurde gespeichert.'
rescue ActiveRecord::StaleObjectError
flash[:error] = 'In der Zwischenzeit hat jemand anderes auch bestellt, daher konnte die Bestellung nicht aktualisiert werden.'
rescue => exception
logger.error('Failed to update order: ' + exception.message)
flash[:error] = 'Die Bestellung konnte nicht aktualisiert werden, da ein Fehler auftrat.'
end
redirect_to :action => 'my_order_result', :id => @order
end
end

View file

@ -138,7 +138,7 @@ class OrdersController < ApplicationController
text += "****** " + "Artikel" + "\n\n"
text += "Nummer" + " " + "Menge" + " " + "Name" + "\n"
# now display all ordered articles
order.order_articles.all(:include => [:article, :article_price]).each do |oa|
order.order_articles.ordered.all(:include => [:article, :article_price]).each do |oa|
number = oa.article.order_number
(8 - number.size).times { number += " " }
quantity = oa.units_to_order.to_i.to_s

View file

@ -76,34 +76,9 @@ class Article < ActiveRecord::Base
updated_at > 2.days.ago
end
# Returns how many units of this article need to be ordered given the specified order quantity and tolerance.
# This is determined by calculating how many units can be ordered from the given order quantity, using
# the tolerance to order an additional unit if the order quantity is not quiet sufficient.
# There must always be at least one item in a unit that is an ordered quantity (no units are ever entirely
# filled by tolerance items only).
#
# Example:
#
# unit_quantity | quantity | tolerance | calculate_order_quantity
# --------------+----------+-----------+-----------------------
# 4 | 0 | 2 | 0
# 4 | 0 | 5 | 0
# 4 | 2 | 2 | 1
# 4 | 4 | 2 | 1
# 4 | 4 | 4 | 1
# 4 | 5 | 3 | 2
# 4 | 5 | 4 | 2
#
def calculate_order_quantity(quantity, tolerance = 0)
unit_size = unit_quantity
units = quantity / unit_size
remainder = quantity % unit_size
units += ((remainder > 0) && (remainder + tolerance >= unit_size) ? 1 : 0)
end
# If the article is used in an open Order, the Order will be returned.
def in_open_order
order_articles = OrderArticle.all(:conditions => ['order_id IN (?)', Order.open.collect {|o| o.id }])
order_articles = OrderArticle.all(:conditions => ['order_id IN (?)', Order.open.collect(&:id)])
order_article = order_articles.detect {|oa| oa.article_id == id }
order_article ? order_article.order : nil
end

View file

@ -1,5 +1,5 @@
# == Schema Information
# Schema version: 20090119155930
# Schema version: 20090120184410
#
# Table name: group_order_articles
#
@ -9,13 +9,16 @@
# quantity :integer default(0), not null
# tolerance :integer default(0), not null
# updated_on :datetime not null
# quantity_result :integer
# tolerance_result :integer
#
# A GroupOrderArticle stores the sum of how many items of an OrderArticle are ordered as part of a GroupOrder.
# The chronologically order of the Ordergroup - activity are stored in GroupOrderArticleQuantity
#
class GroupOrderArticle < ActiveRecord::Base
extend ActiveSupport::Memoizable # Ability to cache method results. Use memoize :expensive_method
belongs_to :group_order
belongs_to :order_article
has_many :group_order_article_quantities, :dependent => :destroy
@ -27,6 +30,8 @@ class GroupOrderArticle < ActiveRecord::Base
attr_accessor :ordergroup_id # To create an new GroupOrder if neccessary
named_scope :ordered, :conditions => 'quantity_result > 0 OR tolerance_result > 0'
# Updates the quantity/tolerance for this GroupOrderArticle by updating both GroupOrderArticle properties
# and the associated GroupOrderArticleQuantities chronologically.
#
@ -99,25 +104,27 @@ class GroupOrderArticle < ActiveRecord::Base
# Returns a hash with three keys: :quantity / :tolerance / :total
#
# See description of the ordering algorithm in the general application documentation for details.
def orderResult
def calculate_result
quantity = tolerance = 0
# Get total
total = order_article.units_to_order * order_article.article.unit_quantity
logger.debug("unitsToOrder => items ordered: #{order_article.units_to_order} => #{total}")
total = order_article.units_to_order * order_article.price.unit_quantity
logger.debug("<#{order_article.article.name}>.unitsToOrder => items ordered: #{order_article.units_to_order} => #{total}")
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...
orderArticles = GroupOrderArticle.find(:all, :conditions => ['order_article_id = ? AND group_order_id IN (?)', order_article.id, group_order.order.group_orders.collect { | o | o.id }])
orderQuantities = GroupOrderArticleQuantity.find(:all, :conditions => ['group_order_article_id IN (?)', orderArticles.collect { | i | i.id }], :order => 'created_on')
logger.debug("GroupOrderArticleQuantity records found: #{orderQuantities.size}")
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...
totalQuantity = i = 0
while (i < orderQuantities.size && totalQuantity < total)
q = (orderQuantities[i].quantity <= total - totalQuantity ? orderQuantities[i].quantity : total - totalQuantity)
totalQuantity += q
if (orderQuantities[i].group_order_article_id == self.id)
total_quantity = i = 0
while (i < order_quantities.size && total_quantity < total)
q = (order_quantities[i].quantity <= total - total_quantity ? order_quantities[i].quantity : total - total_quantity)
total_quantity += q
if (order_quantities[i].group_order_article_id == self.id)
logger.debug("increasing quantity by #{q}")
quantity += q
end
@ -125,13 +132,13 @@ class GroupOrderArticle < ActiveRecord::Base
end
# Determine tolerance to be ordered...
if (totalQuantity < total)
if (total_quantity < total)
logger.debug("determining additional items to be ordered from tolerance")
i = 0
while (i < orderQuantities.size && totalQuantity < total)
q = (orderQuantities[i].tolerance <= total - totalQuantity ? orderQuantities[i].tolerance : total - totalQuantity)
totalQuantity += q
if (orderQuantities[i].group_order_article_id == self.id)
while (i < order_quantities.size && total_quantity < total)
q = (order_quantities[i].tolerance <= total - total_quantity ? order_quantities[i].tolerance : total - total_quantity)
total_quantity += q
if (order_quantities[i].group_order_article_id == self.id)
logger.debug("increasing tolerance by #{q}")
tolerance += q
end
@ -139,13 +146,27 @@ class GroupOrderArticle < ActiveRecord::Base
end
end
# calculate the sum of quantity and tolerance:
sum = quantity + tolerance
logger.debug("determined quantity/tolerance/total: #{quantity} / #{tolerance} / #{sum}")
logger.debug("determined quantity/tolerance/total: #{quantity} / #{tolerance} / #{quantity + tolerance}")
end
{:quantity => quantity, :tolerance => tolerance, :total => sum}
{:quantity => quantity, :tolerance => tolerance, :total => quantity + tolerance}
end
memoize :calculate_result
# Returns order result,
# either calcualted on the fly or fetched from quantity_/tolerance_result
def result
if quantity_result.nil?
calculate_result
else
{:quantity => quantity_result, :tolerance => tolerance_result, :total => quantity_result + tolerance_result}
end
end
# This is used when finishing the order.
def save_results!
self.quantity_result = calculate_result[:quantity]
self.tolerance_result = calculate_result[:tolerance]
save!
end
end

View file

@ -100,11 +100,11 @@ class Order < ActiveRecord::Base
# :fc, guess what...
def sum(type = :gross)
total = 0
if type == :clear || type == :gross || type == :fc
if type == :net || type == :gross || type == :fc
for oa in order_articles.ordered.all(:include => [:article,:article_price])
quantity = oa.units_to_order * oa.price.unit_quantity
case type
when :clear
when :net
total += quantity * oa.price.price
when :gross
total += quantity * oa.price.gross_price
@ -133,51 +133,26 @@ class Order < ActiveRecord::Base
unless finished?
Order.transaction do
# Update order_articles. Save the current article_price to keep price consistency
# Also save results for each group_order_result
order_articles.all(:include => :article).each do |oa|
oa.update_attribute(:article_price, oa.article.article_prices.first)
oa.group_order_articles.each { |goa| goa.save_results! }
end
# set new order state (needed by notify_order_finished)
update_attributes(:state => 'finished', :ends => Time.now, :updated_by => user)
# TODO: delete data, which is no longer required ...
# group_order_article_quantities... order_articles with units_to_order == 0 ? ...
# Clean up
# Delete no longer required order-history (group_order_article_quantities) and
# TODO: Do we need articles, which aren't ordered? (units_to_order == 0 ?)
order_articles.each do |oa|
oa.group_order_articles.each { |goa| goa.group_order_article_quantities.clear }
end
end
# notify order groups
notify_order_finished
end
end
# TODO: I can't understand, why its going out from the group_order_articles perspective.
# Why we can't just iterate through the order_articles?
#
# Updates the ordered quantites of all OrderArticles from the GroupOrderArticles.
# This method is fired after an ordergroup has saved/updated his order.
def update_quantities
indexed_order_articles = {} # holds the list of updated OrderArticles indexed by their id
# Get all GroupOrderArticles for this order and update OrderArticle.quantity/.tolerance/.units_to_order from them...
group_order_articles = GroupOrderArticle.all(:conditions => ['group_order_id IN (?)', group_order_ids],
:include => [:order_article])
for goa in group_order_articles
if (order_article = indexed_order_articles[goa.order_article.id.to_s])
# order_article has already been fetched, just update...
order_article.quantity = order_article.quantity + goa.quantity
order_article.tolerance = order_article.tolerance + goa.tolerance
order_article.units_to_order = order_article.article.calculate_order_quantity(order_article.quantity, order_article.tolerance)
else
# First update to OrderArticle, need to store in orderArticle hash...
order_article = goa.order_article
order_article.quantity = goa.quantity
order_article.tolerance = goa.tolerance
order_article.units_to_order = order_article.article.calculate_order_quantity(order_article.quantity, order_article.tolerance)
indexed_order_articles[order_article.id.to_s] = order_article
end
end
# Commit changes to database...
OrderArticle.transaction do
indexed_order_articles.each_value { | value | value.save! }
end
end
# Sets order.status to 'close' and updates all Ordergroup.account_balances
def close!(user)

View file

@ -34,8 +34,8 @@ class OrderArticle < ActiveRecord::Base
#
# before_validation_on_create :create_new_article
# This method returns either the Article or the ArticlePrice
# The latter will be set, when the the order is finished
# This method returns either the ArticlePrice or the Article
# The first will be set, when the the order is finished
def price
article_price || article
end
@ -47,6 +47,39 @@ class OrderArticle < ActiveRecord::Base
{:quantity => quantity, :price => quantity * price.fc_price}
end
# Update quantity/tolerance/units_to_order from group_order_articles
def update_results!
quantity = group_order_articles.collect(&:quantity).sum
tolerance = group_order_articles.collect(&:tolerance).sum
update_attributes(:quantity => quantity, :tolerance => tolerance,
:units_to_order => calculate_units_to_order(quantity, tolerance))
end
# Returns how many units of the belonging article need to be ordered given the specified order quantity and tolerance.
# This is determined by calculating how many units can be ordered from the given order quantity, using
# the tolerance to order an additional unit if the order quantity is not quiet sufficient.
# There must always be at least one item in a unit that is an ordered quantity (no units are ever entirely
# filled by tolerance items only).
#
# Example:
#
# unit_quantity | quantity | tolerance | calculate_units_to_order
# --------------+----------+-----------+-----------------------
# 4 | 0 | 2 | 0
# 4 | 0 | 5 | 0
# 4 | 2 | 2 | 1
# 4 | 4 | 2 | 1
# 4 | 4 | 4 | 1
# 4 | 5 | 3 | 2
# 4 | 5 | 4 | 2
#
def calculate_units_to_order(quantity, tolerance = 0)
unit_size = price.unit_quantity
units = quantity / unit_size
remainder = quantity % unit_size
units += ((remainder > 0) && (remainder + tolerance >= unit_size) ? 1 : 0)
end
private
def article_and_price_exist

View file

@ -35,7 +35,7 @@ class Ordergroup < Group
acts_as_paranoid # Avoid deleting the ordergroup for consistency of order-results
extend ActiveSupport::Memoizable # Ability to cache method results. Use memoize :expensive_method
has_many :financial_transactions
has_many :financial_transactions, :order => "created_on DESC"
has_many :group_orders
has_many :orders, :through => :group_orders

View file

@ -54,7 +54,7 @@
|
= link_to _('Upload articles'), upload_supplier_articles_path(@supplier)
|
= link_to_if @current_user.role_orders?, _('Create order'), {:controller => 'orders', :action => 'new', :id => @supplier }
= link_to_if @current_user.role_orders?, _('Create order'), {:controller => 'orders', :action => 'new', :supplier_id => @supplier }
#article_filter
#article_search_form{:style=>"display:inline;"}

View file

@ -5,7 +5,7 @@
%table
%tr
%td Nettobetrag:
%td= number_to_currency(order.sum(:clear))
%td= number_to_currency(order.sum(:net))
%tr
%td Bruttobetrag:
%td= number_to_currency(order.sum(:gross))

View file

@ -57,7 +57,7 @@
%th=_ "Who"
%th=_ "Note"
%th=_ "Amount"
- for ft in @financial_transactions
- for ft in @ordergroup.financial_transactions.all(:limit => 5)
%tr{:class => cycle('even','odd')}
%td= format_time(ft.created_on)
%td= h(ft.user.nil? ? '?' : ft.user.nick)

View file

@ -20,22 +20,22 @@
:subnav => [
{ :name => "Order", :url => "/ordering" },
{ :name => "My orders", :url => "/ordering/myOrders" },
{ :name => "Manage orders", :url => "/orders", :access? => (u.role_orders?) }
{ :name => "Manage orders", :url => "/orders", :access_denied? => (!u.role_orders?) }
]
},
{ :name => "Articles", :url => "/suppliers",
:active => ["articles", "suppliers", "deliveries", "article_categories", "stockit"],
:access? => (u.role_article_meta? || u.role_suppliers?),
:access_denied? => (!u.role_article_meta? && !u.role_suppliers?),
:subnav => [
{ :name => "Artikel", :url => supplier_articles_path(Supplier.first) },
{ :name => "Lager", :url => "/stockit" },
{ :name => "Lieferantinnen", :url => suppliers_path, :access? => (u.role_suppliers?) },
{ :name => "Lieferantinnen", :url => suppliers_path, :access_denied? => (!u.role_suppliers?) },
{ :name => "Kategorien", :url => "/article_categories"}
]
},
{ :name => "Finance", :url => "/finance",
:active => ["finance/invoices", "finance/transactions", "finance/balancing"],
:access? => (u.role_finance?),
:access_denied? => (!u.role_finance?),
:subnav => [
{ :name => "Manage accounts", :url => "/finance/transactions" },
{ :name => "Balance orders", :url => "/finance/balancing/list" },
@ -44,7 +44,7 @@
},
{ :name => "Administration", :url => "/admin",
:active => ["admin", "admin/users", "admin/ordergroups", "admin/workgroups"],
:access? => (u.role_admin?),
:access_denied? => (!u.role_admin?),
:subnav => [
{ :name => "Users", :url => admin_users_path },
{ :name => "Ordergroups", :url => admin_ordergroups_path },
@ -55,12 +55,12 @@
-%>
<ul>
<% for tab in tabs -%>
<% unless tab[:access?] and tab[:access?] == false -%>
<% unless tab[:access_denied?] -%>
<li class="<%= 'current' if tab_is_active?(tab) %>">
<%= link_to tab[:name], tab[:url] %>
<ul>
<% for subtab in tab[:subnav] -%>
<% unless subtab[:access?] and subtab[:access?] == false -%>
<% unless subtab[:access_denied?] -%>
<li><%= link_to subtab[:name], subtab[:url] %></li>
<% end -%>
<% end -%>

View file

@ -17,7 +17,7 @@
%p
Lieferant:
%b=h @order.supplier.name
- unless @order.note.empty?
- unless @order.note.blank?
%p
Notiz:
=h @order.note
@ -76,7 +76,7 @@
- if goa
- quantity = goa.quantity
- tolerance = goa.tolerance
- result = goa.orderResult[:quantity] + goa.orderResult[:tolerance]
- result = goa.result[:total]
- sub_total = oa.price.fc_price * (quantity + tolerance)
- else
- quantity, tolerance, result, sub_total = 0, 0, 0, 0
@ -88,7 +88,7 @@
%tr{:class => cycle('even', 'odd', :name => 'articles'), :style => "color:#{style}"}
%td{:style => "width:40%"}
=h oa.article.name
- unless oa.article.note.empty?
- unless oa.article.note.blank?
= image_tag("lamp_grey.png", {:alt => "Notiz anzeigen", :size => "15x16", :border => "0", :onmouseover => "$('note_#{oa.id}').show();", :onmouseout => "$('note_#{oa.id}').hide();"})
%td= "#{oa.price.unit_quantity} x #{oa.article.unit}"
%td= number_to_currency(oa.price.fc_price)
@ -97,7 +97,7 @@
= "+ #{tolerance}" if oa.price.unit_quantity > 1
%td= result > 0 ? result : "0"
%td= number_to_currency(sub_total)
- unless oa.article.note.empty?
- unless oa.article.note.blank?
%tr{:id => "note_#{oa.id}", :class => "note even", :style => "display:none"}
%td{:colspan => "6"}=h oa.article.note
%tr{:class => cycle('even', 'odd', :name => 'articles')}

View file

@ -96,14 +96,14 @@
-%>
<tr class="<%= cycle('even', 'odd', :name => 'articles') %>" valign="top">
<td class="name">
<% unless order_article.article.note.empty? %>
<% unless order_article.article.note.blank? %>
<%= order_article.article.name %> <%= image_tag "lamp_grey.png", {:alt => _("Show note"), :size => "15x16", :border => "0", :onmouseover => "$('note_#{i}').show();", :onmouseout => "$('note_#{i}').hide();" }%>
<% else %>
<%= order_article.article.name %>
<% end %>
</td>
<td><%=h order_article.article.origin %></td>
<td><%=h truncate order_article.article.manufacturer, 11 %></td>
<td><%=h truncate order_article.article.manufacturer, :length => 11 %></td>
<td><%= @unit[i] %> * <%=h order_article.article.unit %></td>
<td><%= number_to_currency(@price[i]) %></td>
<td id="units_<%= i %>"><%= order_article.units_to_order %></td>
@ -127,7 +127,7 @@
</td>
<td id="td_price_<%= i %>" style="text-align:right; padding-right:10px; width:4em"><span id="price_<%= i %>_display"><%= number_to_currency(article_total, :unit => "") %></span> €</td>
</tr>
<% unless order_article.article.note.empty? -%>
<% unless order_article.article.note.blank? -%>
<tr id="note_<%= i %>" class="note" style="display:none">
<td colspan="10"><%=h order_article.article.note %> | <%=h order_article.article.manufacturer %></td>
</tr>

View file

@ -2,7 +2,7 @@
%tr
%th Name
%th Gebinde
%th Netto/FC-Preis
%th Netto-/Bruttopreis
%th Bestellte Einheiten
%th Volle Gebinde
- total_net, total_gross, counter = 0, 0, 0
@ -12,19 +12,19 @@
%td{:colspan => "9"}
- order_articles.each do |order_article|
- net_price = order_article.price.price
- fc_price = order_article.price.fc_price
- gross_price = order_article.price.gross_price
- units = order_article.units_to_order
- unit_quantity = order_article.price.unit_quantity
- total_net += units * unit_quantity * net_price
- total_gross += units * unit_quantity * fc_price
- total_gross += units * unit_quantity * gross_price
%tr{:class => cycle('even', 'odd', :name => 'articles'), :style => "color: #{units > 0 ? 'green' : 'red'}"}
%td=h order_article.article.name
%td= "#{unit_quantity} x #{order_article.article.unit}"
%td= "#{number_to_currency(net_price)} / #{number_to_currency(fc_price)}"
%td= "#{number_to_currency(net_price)} / #{number_to_currency(gross_price)}"
%td= "#{order_article.quantity} + #{order_article.tolerance}" if unit_quantity > 1
%td= units
%p
Summe (Netto/FC-Preise):
Summe (Netto/Brutto-Preise):
= "#{number_to_currency(total_net)} / #{number_to_currency(total_gross)}"
%p
Bestellte Artikel.

View file

@ -41,7 +41,7 @@ pdf.text "Ansprechpartner: " + @order.supplier.contact_person
pdf.move_down 10
# Articles
data = @order.order_articles.all(:include => :article).collect do |a|
data = @order.order_articles.ordered.all(:include => :article).collect do |a|
[a.article.order_number, a.units_to_order, a.article.name,
a.price.unit_quantity, a.article.unit, a.price.price]
end

View file

@ -22,7 +22,7 @@ for group_order in @order.group_orders
total = 0
data = []
group_order.group_order_articles.each do |goa|
group_order.group_order_articles.ordered.each do |goa|
price = goa.order_article.price.fc_price
quantity = goa.quantity
sub_total = price * quantity

View file

@ -10,7 +10,7 @@ pdf.footer [pdf.margin_box.left, pdf.margin_box.bottom-5] do
end
max_order_articles_per_page = 17 # How many order_articles shoud written on a page
order_articles = @order.order_articles
order_articles = @order.order_articles.ordered
pdf.text "Artikelübersicht", :style => :bold
pdf.move_down 5

View file

@ -1,10 +1,10 @@
- title _("Show order")
#element_navigation
= link_to_unless @order.previous == @order, _("Previous order"), @order.previous
= link_to_unless @order.previous == @order, "<< #{@order.previous.supplier.name}", @order.previous
|
= link_to _("Overview"), orders_path
|
= link_to_unless @order.next == @order, _("Next order"), @order.next
= link_to_unless @order.next == @order, "#{@order.next.supplier.name} >>", @order.next
// Order summary
.left_column{:style => "width:65em"}
@ -33,18 +33,21 @@
= "[#{@order.group_orders.find(:all, :include => :ordergroup).collect{|g| g.ordergroup.name}.join(', ')}]"
%p
Bruttosummer aller Artikel
%b= number_to_currency(@order.sum(:gross))
- if @order.finished?
|
Bestellte Artikel:
%b= @order.order_articles.ordered.count
Netto/Bruttosumme aller Artikel
%b= "#{number_to_currency(@order.sum(:net))} / #{number_to_currency(@order.sum(:gross))}"
%p
Bestellte Artikel:
%b= @order.order_articles.ordered.count
- if @order.open?
%p
= link_to icon(:edit), edit_order_path(@order)
= link_to icon(:delete), @order, :confirm => "Willst du wirklich die Bestellung löschen?", :method => :delete
= link_to '[beenden]', finish_order_path(@order), :method => :post
%p
Aktionen:
- if @order.open?
= link_to "Bearbeiten", edit_order_path(@order)
= link_to 'Beenden!', finish_order_path(@order), :method => :post, :confirm => "Willst Du wirklich die Bestellung beenden?\nEs gibt kein zurück.."
- unless @order.closed?
= link_to "Löschen", @order, :confirm => "Willst du wirklich die Bestellung löschen?", :method => :delete
- unless @order.open?
%p

View file

@ -4,20 +4,23 @@
%th{:colspan => '3'} Legende
%tr
%th{:style => 'width:70%'} Bestellgruppe
%th Menge
%th Bestellt
%th Bekommen
%th Gesamtpreis
- for order_article in order.order_articles.all(:include => [:article, :article_price])
- for order_article in order.order_articles.ordered.all(:include => [:article, :article_price])
%table{:style => "margin-bottom:1em"}
%thead
%tr
%th{:colspan => "3"}
%th{:colspan => "4"}
= order_article.article.name
= "(#{order_article.article.unit} | #{order_article.price.unit_quantity} | #{number_to_currency(order_article.price.fc_price)})"
= "(#{order_article.article.unit} | #{order_article.price.unit_quantity} | #{number_to_currency(order_article.price.gross_price)})"
%tbody
- for goa in order_article.group_order_articles
%tr{:class => cycle('even', 'odd', :name => 'groups')}
%td{:style => "width:70%"}=h goa.group_order.ordergroup.name
%td= "#{goa.quantity} (#{goa.tolerance})"
%td
%b= "#{goa.quantity_result} + #{goa.tolerance_result}"
%td= number_to_currency(order_article.price.fc_price * goa.quantity)
- reset_cycle('groups')

View file

@ -18,13 +18,13 @@
%th{:colspan => "6"}=h group_order.ordergroup.name
%tbody
- total = 0
- for goa in group_order.group_order_articles.all(:include => :order_article)
- for goa in group_order.group_order_articles.ordered.all(:include => :order_article)
- fc_price = goa.order_article.price.fc_price
- subTotal = fc_price * goa.quantity
- total += subTotal
%tr{:class => cycle('even', 'odd', :name => 'articles')}
%td{:style => "width:40%"}=h goa.order_article.article.name
%td= "#{goa.quantity} (#{goa.tolerance})"
%td= "#{goa.result[:quantity]} (#{goa.result[:tolerance]})"
%td= number_to_currency(fc_price)
%td= goa.order_article.price.unit_quantity
%td= goa.order_article.article.unit