Order-refactoring part II.
This commit is contained in:
parent
f7b9582261
commit
6fd5d825f9
27 changed files with 228 additions and 231 deletions
|
@ -53,7 +53,7 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
def deny_access
|
def deny_access
|
||||||
self.return_to = request.request_uri
|
self.return_to = request.request_uri
|
||||||
redirect_to :controller => 'login', :action => 'denied'
|
redirect_to :controller => '/login', :action => 'denied'
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,6 @@ class HomeController < ApplicationController
|
||||||
def index
|
def index
|
||||||
@currentOrders = Order.open
|
@currentOrders = Order.open
|
||||||
@ordergroup = @current_user.ordergroup
|
@ordergroup = @current_user.ordergroup
|
||||||
if @ordergroup
|
|
||||||
@financial_transactions = @ordergroup.financial_transactions.find(:all, :order => 'created_on desc', :limit => 3)
|
|
||||||
end
|
|
||||||
# unaccepted tasks
|
# unaccepted tasks
|
||||||
@unaccepted_tasks = @current_user.unaccepted_tasks
|
@unaccepted_tasks = @current_user.unaccepted_tasks
|
||||||
# task in next week
|
# task in next week
|
||||||
|
|
|
@ -23,7 +23,7 @@ class OrderingController < ApplicationController
|
||||||
if @group_order
|
if @group_order
|
||||||
# Group has already ordered, so get the results...
|
# Group has already ordered, so get the results...
|
||||||
for article in @group_order.group_order_articles
|
for article in @group_order.group_order_articles
|
||||||
result = article.orderResult
|
result = article.result
|
||||||
ordered_articles[article.order_article_id] = {'quantity' => article.quantity,
|
ordered_articles[article.order_article_id] = {'quantity' => article.quantity,
|
||||||
'tolerance' => article.tolerance,
|
'tolerance' => article.tolerance,
|
||||||
'quantity_result' => result[:quantity],
|
'quantity_result' => result[:quantity],
|
||||||
|
@ -61,44 +61,44 @@ class OrderingController < ApplicationController
|
||||||
|
|
||||||
# Update changes to a current order.
|
# Update changes to a current order.
|
||||||
def saveOrder
|
def saveOrder
|
||||||
order = @order # Get the object through before_filter
|
if (params[:total_balance].to_i < 0) #TODO: Better use a real test on sufficiant funds
|
||||||
if (params[:total_balance].to_i < 0)
|
|
||||||
flash[:error] = 'Der Bestellwert übersteigt das verfügbare Guthaben.'
|
flash[:error] = 'Der Bestellwert übersteigt das verfügbare Guthaben.'
|
||||||
redirect_to :action => 'order'
|
redirect_to :action => 'order'
|
||||||
elsif (ordered = params[:ordered])
|
elsif (ordered = params[:ordered])
|
||||||
begin
|
begin
|
||||||
Order.transaction do
|
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...
|
# Create group order if necessary...
|
||||||
if (groupOrder = order.group_orders.find(:first, :conditions => "ordergroup_id = #{@ordergroup.id}", :include => [:group_order_articles]))
|
unless group_order.nil?
|
||||||
if (params[:version].to_i != groupOrder.lock_version) # check for conflicts well ahead
|
# check for conflicts well ahead
|
||||||
|
if (params[:version].to_i != group_order.lock_version)
|
||||||
raise ActiveRecord::StaleObjectError
|
raise ActiveRecord::StaleObjectError
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
groupOrder = GroupOrder.new(:ordergroup => @ordergroup, :order => order, :updated_by => @current_user, :price => 0)
|
group_order = @ordergroup.group_orders.create!(:order => @order, :updated_by => @current_user, :price => 0)
|
||||||
groupOrder.save!
|
|
||||||
end
|
end
|
||||||
# Create/update GroupOrderArticles...
|
|
||||||
newGroupOrderArticles = Array.new
|
# Create/update group_order_articles...
|
||||||
for article in order.order_articles
|
for order_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 }
|
# Find the group_order_article, create a new one if necessary...
|
||||||
unless (groupOrderArticle = groupOrderArticles[0])
|
group_order_article = group_order.group_order_articles.detect { |v| v.order_article_id == order_article.id }
|
||||||
groupOrderArticle = GroupOrderArticle.create(:group_order => groupOrder, :order_article_id => article.id, :quantity => 0, :tolerance => 0)
|
if group_order_article.nil?
|
||||||
|
group_order_article = group_order.group_order_articles.create(:order_article_id => order_article.id)
|
||||||
end
|
end
|
||||||
# Get ordered quantities and update GroupOrderArticle/-Quantities...
|
|
||||||
unless (quantities = ordered.delete(article.id.to_s)) && (quantity = quantities['quantity']) && (tolerance = quantities['tolerance'])
|
# Get ordered quantities and update group_order_articles/_quantities...
|
||||||
quantity = tolerance = 0
|
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
|
end
|
||||||
groupOrderArticle.update_quantities(quantity.to_i, tolerance.to_i)
|
|
||||||
# Add to new list of GroupOrderArticles:
|
group_order.update_price!
|
||||||
newGroupOrderArticles.push(groupOrderArticle)
|
group_order.update_attribute(:updated_by, @current_user)
|
||||||
end
|
|
||||||
groupOrder.group_order_articles = newGroupOrderArticles
|
|
||||||
groupOrder.update_price!
|
|
||||||
groupOrder.updated_by = @current_user
|
|
||||||
groupOrder.save!
|
|
||||||
order.update_quantities
|
|
||||||
order.save!
|
|
||||||
end
|
end
|
||||||
flash[:notice] = 'Die Bestellung wurde gespeichert.'
|
flash[:notice] = 'Die Bestellung wurde gespeichert.'
|
||||||
rescue ActiveRecord::StaleObjectError
|
rescue ActiveRecord::StaleObjectError
|
||||||
|
@ -107,7 +107,7 @@ class OrderingController < ApplicationController
|
||||||
logger.error('Failed to update order: ' + exception.message)
|
logger.error('Failed to update order: ' + exception.message)
|
||||||
flash[:error] = 'Die Bestellung konnte nicht aktualisiert werden, da ein Fehler auftrat.'
|
flash[:error] = 'Die Bestellung konnte nicht aktualisiert werden, da ein Fehler auftrat.'
|
||||||
end
|
end
|
||||||
redirect_to :action => 'my_order_result', :id => order
|
redirect_to :action => 'my_order_result', :id => @order
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ class OrdersController < ApplicationController
|
||||||
text += "****** " + "Artikel" + "\n\n"
|
text += "****** " + "Artikel" + "\n\n"
|
||||||
text += "Nummer" + " " + "Menge" + " " + "Name" + "\n"
|
text += "Nummer" + " " + "Menge" + " " + "Name" + "\n"
|
||||||
# now display all ordered articles
|
# 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
|
number = oa.article.order_number
|
||||||
(8 - number.size).times { number += " " }
|
(8 - number.size).times { number += " " }
|
||||||
quantity = oa.units_to_order.to_i.to_s
|
quantity = oa.units_to_order.to_i.to_s
|
||||||
|
|
|
@ -76,34 +76,9 @@ class Article < ActiveRecord::Base
|
||||||
updated_at > 2.days.ago
|
updated_at > 2.days.ago
|
||||||
end
|
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.
|
# If the article is used in an open Order, the Order will be returned.
|
||||||
def in_open_order
|
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_articles.detect {|oa| oa.article_id == id }
|
||||||
order_article ? order_article.order : nil
|
order_article ? order_article.order : nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
# Schema version: 20090119155930
|
# Schema version: 20090120184410
|
||||||
#
|
#
|
||||||
# Table name: group_order_articles
|
# Table name: group_order_articles
|
||||||
#
|
#
|
||||||
|
@ -9,12 +9,15 @@
|
||||||
# quantity :integer default(0), not null
|
# quantity :integer default(0), not null
|
||||||
# tolerance :integer default(0), not null
|
# tolerance :integer default(0), not null
|
||||||
# updated_on :datetime 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.
|
# 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
|
# The chronologically order of the Ordergroup - activity are stored in GroupOrderArticleQuantity
|
||||||
#
|
#
|
||||||
class GroupOrderArticle < ActiveRecord::Base
|
class GroupOrderArticle < ActiveRecord::Base
|
||||||
|
extend ActiveSupport::Memoizable # Ability to cache method results. Use memoize :expensive_method
|
||||||
|
|
||||||
belongs_to :group_order
|
belongs_to :group_order
|
||||||
belongs_to :order_article
|
belongs_to :order_article
|
||||||
|
@ -27,6 +30,8 @@ class GroupOrderArticle < ActiveRecord::Base
|
||||||
|
|
||||||
attr_accessor :ordergroup_id # To create an new GroupOrder if neccessary
|
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
|
# Updates the quantity/tolerance for this GroupOrderArticle by updating both GroupOrderArticle properties
|
||||||
# and the associated GroupOrderArticleQuantities chronologically.
|
# and the associated GroupOrderArticleQuantities chronologically.
|
||||||
#
|
#
|
||||||
|
@ -99,25 +104,27 @@ 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 orderResult
|
def calculate_result
|
||||||
quantity = tolerance = 0
|
quantity = tolerance = 0
|
||||||
|
|
||||||
# Get total
|
# Get total
|
||||||
total = order_article.units_to_order * order_article.article.unit_quantity
|
total = order_article.units_to_order * order_article.price.unit_quantity
|
||||||
logger.debug("unitsToOrder => items ordered: #{order_article.units_to_order} => #{total}")
|
logger.debug("<#{order_article.article.name}>.unitsToOrder => items ordered: #{order_article.units_to_order} => #{total}")
|
||||||
|
|
||||||
if (total > 0)
|
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...
|
# 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 }])
|
order_quantities = GroupOrderArticleQuantity.all(
|
||||||
orderQuantities = GroupOrderArticleQuantity.find(:all, :conditions => ['group_order_article_id IN (?)', orderArticles.collect { | i | i.id }], :order => 'created_on')
|
:conditions => ["group_order_article_id IN (?)", order_article.group_order_article_ids], :order => 'created_on')
|
||||||
logger.debug("GroupOrderArticleQuantity records found: #{orderQuantities.size}")
|
logger.debug("GroupOrderArticleQuantity records found: #{order_quantities.size}")
|
||||||
|
|
||||||
# Determine quantities to be ordered...
|
# Determine quantities to be ordered...
|
||||||
totalQuantity = i = 0
|
total_quantity = i = 0
|
||||||
while (i < orderQuantities.size && totalQuantity < total)
|
while (i < order_quantities.size && total_quantity < total)
|
||||||
q = (orderQuantities[i].quantity <= total - totalQuantity ? orderQuantities[i].quantity : total - totalQuantity)
|
q = (order_quantities[i].quantity <= total - total_quantity ? order_quantities[i].quantity : total - total_quantity)
|
||||||
totalQuantity += q
|
total_quantity += q
|
||||||
if (orderQuantities[i].group_order_article_id == self.id)
|
if (order_quantities[i].group_order_article_id == self.id)
|
||||||
logger.debug("increasing quantity by #{q}")
|
logger.debug("increasing quantity by #{q}")
|
||||||
quantity += q
|
quantity += q
|
||||||
end
|
end
|
||||||
|
@ -125,13 +132,13 @@ class GroupOrderArticle < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
# Determine tolerance to be ordered...
|
# Determine tolerance to be ordered...
|
||||||
if (totalQuantity < total)
|
if (total_quantity < total)
|
||||||
logger.debug("determining additional items to be ordered from tolerance")
|
logger.debug("determining additional items to be ordered from tolerance")
|
||||||
i = 0
|
i = 0
|
||||||
while (i < orderQuantities.size && totalQuantity < total)
|
while (i < order_quantities.size && total_quantity < total)
|
||||||
q = (orderQuantities[i].tolerance <= total - totalQuantity ? orderQuantities[i].tolerance : total - totalQuantity)
|
q = (order_quantities[i].tolerance <= total - total_quantity ? order_quantities[i].tolerance : total - total_quantity)
|
||||||
totalQuantity += q
|
total_quantity += q
|
||||||
if (orderQuantities[i].group_order_article_id == self.id)
|
if (order_quantities[i].group_order_article_id == self.id)
|
||||||
logger.debug("increasing tolerance by #{q}")
|
logger.debug("increasing tolerance by #{q}")
|
||||||
tolerance += q
|
tolerance += q
|
||||||
end
|
end
|
||||||
|
@ -139,13 +146,27 @@ class GroupOrderArticle < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# calculate the sum of quantity and tolerance:
|
logger.debug("determined quantity/tolerance/total: #{quantity} / #{tolerance} / #{quantity + tolerance}")
|
||||||
sum = quantity + tolerance
|
|
||||||
|
|
||||||
logger.debug("determined quantity/tolerance/total: #{quantity} / #{tolerance} / #{sum}")
|
|
||||||
end
|
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
|
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
|
end
|
||||||
|
|
|
@ -100,11 +100,11 @@ class Order < ActiveRecord::Base
|
||||||
# :fc, guess what...
|
# :fc, guess what...
|
||||||
def sum(type = :gross)
|
def sum(type = :gross)
|
||||||
total = 0
|
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])
|
for oa in order_articles.ordered.all(:include => [:article,:article_price])
|
||||||
quantity = oa.units_to_order * oa.price.unit_quantity
|
quantity = oa.units_to_order * oa.price.unit_quantity
|
||||||
case type
|
case type
|
||||||
when :clear
|
when :net
|
||||||
total += quantity * oa.price.price
|
total += quantity * oa.price.price
|
||||||
when :gross
|
when :gross
|
||||||
total += quantity * oa.price.gross_price
|
total += quantity * oa.price.gross_price
|
||||||
|
@ -133,14 +133,20 @@ class Order < ActiveRecord::Base
|
||||||
unless finished?
|
unless finished?
|
||||||
Order.transaction do
|
Order.transaction do
|
||||||
# Update order_articles. Save the current article_price to keep price consistency
|
# 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|
|
order_articles.all(:include => :article).each do |oa|
|
||||||
oa.update_attribute(:article_price, oa.article.article_prices.first)
|
oa.update_attribute(:article_price, oa.article.article_prices.first)
|
||||||
|
oa.group_order_articles.each { |goa| goa.save_results! }
|
||||||
end
|
end
|
||||||
# set new order state (needed by notify_order_finished)
|
# set new order state (needed by notify_order_finished)
|
||||||
update_attributes(:state => 'finished', :ends => Time.now, :updated_by => user)
|
update_attributes(:state => 'finished', :ends => Time.now, :updated_by => user)
|
||||||
|
|
||||||
# TODO: delete data, which is no longer required ...
|
# Clean up
|
||||||
# group_order_article_quantities... order_articles with units_to_order == 0 ? ...
|
# 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
|
end
|
||||||
|
|
||||||
# notify order groups
|
# notify order groups
|
||||||
|
@ -148,37 +154,6 @@ class Order < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
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
|
# Sets order.status to 'close' and updates all Ordergroup.account_balances
|
||||||
def close!(user)
|
def close!(user)
|
||||||
raise "Bestellung wurde schon abgerechnet" if closed?
|
raise "Bestellung wurde schon abgerechnet" if closed?
|
||||||
|
|
|
@ -34,8 +34,8 @@ class OrderArticle < ActiveRecord::Base
|
||||||
#
|
#
|
||||||
# before_validation_on_create :create_new_article
|
# before_validation_on_create :create_new_article
|
||||||
|
|
||||||
# This method returns either the Article or the ArticlePrice
|
# This method returns either the ArticlePrice or the Article
|
||||||
# The latter will be set, when the the order is finished
|
# The first will be set, when the the order is finished
|
||||||
def price
|
def price
|
||||||
article_price || article
|
article_price || article
|
||||||
end
|
end
|
||||||
|
@ -47,6 +47,39 @@ class OrderArticle < ActiveRecord::Base
|
||||||
{:quantity => quantity, :price => quantity * price.fc_price}
|
{:quantity => quantity, :price => quantity * price.fc_price}
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
def article_and_price_exist
|
def article_and_price_exist
|
||||||
|
|
|
@ -35,7 +35,7 @@ class Ordergroup < Group
|
||||||
acts_as_paranoid # Avoid deleting the ordergroup for consistency of order-results
|
acts_as_paranoid # Avoid deleting the ordergroup for consistency of order-results
|
||||||
extend ActiveSupport::Memoizable # Ability to cache method results. Use memoize :expensive_method
|
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 :group_orders
|
||||||
has_many :orders, :through => :group_orders
|
has_many :orders, :through => :group_orders
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
|
|
|
|
||||||
= link_to _('Upload articles'), upload_supplier_articles_path(@supplier)
|
= 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_filter
|
||||||
#article_search_form{:style=>"display:inline;"}
|
#article_search_form{:style=>"display:inline;"}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
%table
|
%table
|
||||||
%tr
|
%tr
|
||||||
%td Nettobetrag:
|
%td Nettobetrag:
|
||||||
%td= number_to_currency(order.sum(:clear))
|
%td= number_to_currency(order.sum(:net))
|
||||||
%tr
|
%tr
|
||||||
%td Bruttobetrag:
|
%td Bruttobetrag:
|
||||||
%td= number_to_currency(order.sum(:gross))
|
%td= number_to_currency(order.sum(:gross))
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
%th=_ "Who"
|
%th=_ "Who"
|
||||||
%th=_ "Note"
|
%th=_ "Note"
|
||||||
%th=_ "Amount"
|
%th=_ "Amount"
|
||||||
- for ft in @financial_transactions
|
- for ft in @ordergroup.financial_transactions.all(:limit => 5)
|
||||||
%tr{:class => cycle('even','odd')}
|
%tr{:class => cycle('even','odd')}
|
||||||
%td= format_time(ft.created_on)
|
%td= format_time(ft.created_on)
|
||||||
%td= h(ft.user.nil? ? '?' : ft.user.nick)
|
%td= h(ft.user.nil? ? '?' : ft.user.nick)
|
||||||
|
|
|
@ -20,22 +20,22 @@
|
||||||
:subnav => [
|
:subnav => [
|
||||||
{ :name => "Order", :url => "/ordering" },
|
{ :name => "Order", :url => "/ordering" },
|
||||||
{ :name => "My orders", :url => "/ordering/myOrders" },
|
{ :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",
|
{ :name => "Articles", :url => "/suppliers",
|
||||||
:active => ["articles", "suppliers", "deliveries", "article_categories", "stockit"],
|
: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 => [
|
:subnav => [
|
||||||
{ :name => "Artikel", :url => supplier_articles_path(Supplier.first) },
|
{ :name => "Artikel", :url => supplier_articles_path(Supplier.first) },
|
||||||
{ :name => "Lager", :url => "/stockit" },
|
{ :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 => "Kategorien", :url => "/article_categories"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ :name => "Finance", :url => "/finance",
|
{ :name => "Finance", :url => "/finance",
|
||||||
:active => ["finance/invoices", "finance/transactions", "finance/balancing"],
|
:active => ["finance/invoices", "finance/transactions", "finance/balancing"],
|
||||||
:access? => (u.role_finance?),
|
:access_denied? => (!u.role_finance?),
|
||||||
:subnav => [
|
:subnav => [
|
||||||
{ :name => "Manage accounts", :url => "/finance/transactions" },
|
{ :name => "Manage accounts", :url => "/finance/transactions" },
|
||||||
{ :name => "Balance orders", :url => "/finance/balancing/list" },
|
{ :name => "Balance orders", :url => "/finance/balancing/list" },
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
},
|
},
|
||||||
{ :name => "Administration", :url => "/admin",
|
{ :name => "Administration", :url => "/admin",
|
||||||
:active => ["admin", "admin/users", "admin/ordergroups", "admin/workgroups"],
|
:active => ["admin", "admin/users", "admin/ordergroups", "admin/workgroups"],
|
||||||
:access? => (u.role_admin?),
|
:access_denied? => (!u.role_admin?),
|
||||||
:subnav => [
|
:subnav => [
|
||||||
{ :name => "Users", :url => admin_users_path },
|
{ :name => "Users", :url => admin_users_path },
|
||||||
{ :name => "Ordergroups", :url => admin_ordergroups_path },
|
{ :name => "Ordergroups", :url => admin_ordergroups_path },
|
||||||
|
@ -55,12 +55,12 @@
|
||||||
-%>
|
-%>
|
||||||
<ul>
|
<ul>
|
||||||
<% for tab in tabs -%>
|
<% for tab in tabs -%>
|
||||||
<% unless tab[:access?] and tab[:access?] == false -%>
|
<% unless tab[:access_denied?] -%>
|
||||||
<li class="<%= 'current' if tab_is_active?(tab) %>">
|
<li class="<%= 'current' if tab_is_active?(tab) %>">
|
||||||
<%= link_to tab[:name], tab[:url] %>
|
<%= link_to tab[:name], tab[:url] %>
|
||||||
<ul>
|
<ul>
|
||||||
<% for subtab in tab[:subnav] -%>
|
<% for subtab in tab[:subnav] -%>
|
||||||
<% unless subtab[:access?] and subtab[:access?] == false -%>
|
<% unless subtab[:access_denied?] -%>
|
||||||
<li><%= link_to subtab[:name], subtab[:url] %></li>
|
<li><%= link_to subtab[:name], subtab[:url] %></li>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%p
|
%p
|
||||||
Lieferant:
|
Lieferant:
|
||||||
%b=h @order.supplier.name
|
%b=h @order.supplier.name
|
||||||
- unless @order.note.empty?
|
- unless @order.note.blank?
|
||||||
%p
|
%p
|
||||||
Notiz:
|
Notiz:
|
||||||
=h @order.note
|
=h @order.note
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
- if goa
|
- if goa
|
||||||
- quantity = goa.quantity
|
- quantity = goa.quantity
|
||||||
- tolerance = goa.tolerance
|
- tolerance = goa.tolerance
|
||||||
- result = goa.orderResult[:quantity] + goa.orderResult[:tolerance]
|
- result = goa.result[:total]
|
||||||
- sub_total = oa.price.fc_price * (quantity + tolerance)
|
- sub_total = oa.price.fc_price * (quantity + tolerance)
|
||||||
- else
|
- else
|
||||||
- quantity, tolerance, result, sub_total = 0, 0, 0, 0
|
- quantity, tolerance, result, sub_total = 0, 0, 0, 0
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
%tr{:class => cycle('even', 'odd', :name => 'articles'), :style => "color:#{style}"}
|
%tr{:class => cycle('even', 'odd', :name => 'articles'), :style => "color:#{style}"}
|
||||||
%td{:style => "width:40%"}
|
%td{:style => "width:40%"}
|
||||||
=h oa.article.name
|
=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();"})
|
= 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= "#{oa.price.unit_quantity} x #{oa.article.unit}"
|
||||||
%td= number_to_currency(oa.price.fc_price)
|
%td= number_to_currency(oa.price.fc_price)
|
||||||
|
@ -97,7 +97,7 @@
|
||||||
= "+ #{tolerance}" if oa.price.unit_quantity > 1
|
= "+ #{tolerance}" if oa.price.unit_quantity > 1
|
||||||
%td= result > 0 ? result : "0"
|
%td= result > 0 ? result : "0"
|
||||||
%td= number_to_currency(sub_total)
|
%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"}
|
%tr{:id => "note_#{oa.id}", :class => "note even", :style => "display:none"}
|
||||||
%td{:colspan => "6"}=h oa.article.note
|
%td{:colspan => "6"}=h oa.article.note
|
||||||
%tr{:class => cycle('even', 'odd', :name => 'articles')}
|
%tr{:class => cycle('even', 'odd', :name => 'articles')}
|
||||||
|
|
|
@ -96,14 +96,14 @@
|
||||||
-%>
|
-%>
|
||||||
<tr class="<%= cycle('even', 'odd', :name => 'articles') %>" valign="top">
|
<tr class="<%= cycle('even', 'odd', :name => 'articles') %>" valign="top">
|
||||||
<td class="name">
|
<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();" }%>
|
<%= 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 %>
|
<% else %>
|
||||||
<%= order_article.article.name %>
|
<%= order_article.article.name %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</td>
|
</td>
|
||||||
<td><%=h order_article.article.origin %></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><%= @unit[i] %> * <%=h order_article.article.unit %></td>
|
||||||
<td><%= number_to_currency(@price[i]) %></td>
|
<td><%= number_to_currency(@price[i]) %></td>
|
||||||
<td id="units_<%= i %>"><%= order_article.units_to_order %></td>
|
<td id="units_<%= i %>"><%= order_article.units_to_order %></td>
|
||||||
|
@ -127,7 +127,7 @@
|
||||||
</td>
|
</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>
|
<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>
|
</tr>
|
||||||
<% unless order_article.article.note.empty? -%>
|
<% unless order_article.article.note.blank? -%>
|
||||||
<tr id="note_<%= i %>" class="note" style="display:none">
|
<tr id="note_<%= i %>" class="note" style="display:none">
|
||||||
<td colspan="10"><%=h order_article.article.note %> | <%=h order_article.article.manufacturer %></td>
|
<td colspan="10"><%=h order_article.article.note %> | <%=h order_article.article.manufacturer %></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
%tr
|
%tr
|
||||||
%th Name
|
%th Name
|
||||||
%th Gebinde
|
%th Gebinde
|
||||||
%th Netto/FC-Preis
|
%th Netto-/Bruttopreis
|
||||||
%th Bestellte Einheiten
|
%th Bestellte Einheiten
|
||||||
%th Volle Gebinde
|
%th Volle Gebinde
|
||||||
- total_net, total_gross, counter = 0, 0, 0
|
- total_net, total_gross, counter = 0, 0, 0
|
||||||
|
@ -12,19 +12,19 @@
|
||||||
%td{:colspan => "9"}
|
%td{:colspan => "9"}
|
||||||
- order_articles.each do |order_article|
|
- order_articles.each do |order_article|
|
||||||
- net_price = order_article.price.price
|
- 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
|
- units = order_article.units_to_order
|
||||||
- unit_quantity = order_article.price.unit_quantity
|
- unit_quantity = order_article.price.unit_quantity
|
||||||
- total_net += units * unit_quantity * net_price
|
- 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'}"}
|
%tr{:class => cycle('even', 'odd', :name => 'articles'), :style => "color: #{units > 0 ? 'green' : 'red'}"}
|
||||||
%td=h order_article.article.name
|
%td=h order_article.article.name
|
||||||
%td= "#{unit_quantity} x #{order_article.article.unit}"
|
%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= "#{order_article.quantity} + #{order_article.tolerance}" if unit_quantity > 1
|
||||||
%td= units
|
%td= units
|
||||||
%p
|
%p
|
||||||
Summe (Netto/FC-Preise):
|
Summe (Netto/Brutto-Preise):
|
||||||
= "#{number_to_currency(total_net)} / #{number_to_currency(total_gross)}"
|
= "#{number_to_currency(total_net)} / #{number_to_currency(total_gross)}"
|
||||||
%p
|
%p
|
||||||
Bestellte Artikel.
|
Bestellte Artikel.
|
||||||
|
|
|
@ -41,7 +41,7 @@ pdf.text "Ansprechpartner: " + @order.supplier.contact_person
|
||||||
pdf.move_down 10
|
pdf.move_down 10
|
||||||
|
|
||||||
# Articles
|
# 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.article.order_number, a.units_to_order, a.article.name,
|
||||||
a.price.unit_quantity, a.article.unit, a.price.price]
|
a.price.unit_quantity, a.article.unit, a.price.price]
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,7 +22,7 @@ for group_order in @order.group_orders
|
||||||
|
|
||||||
total = 0
|
total = 0
|
||||||
data = []
|
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
|
price = goa.order_article.price.fc_price
|
||||||
quantity = goa.quantity
|
quantity = goa.quantity
|
||||||
sub_total = price * quantity
|
sub_total = price * quantity
|
||||||
|
|
|
@ -10,7 +10,7 @@ pdf.footer [pdf.margin_box.left, pdf.margin_box.bottom-5] do
|
||||||
end
|
end
|
||||||
|
|
||||||
max_order_articles_per_page = 17 # How many order_articles shoud written on a page
|
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.text "Artikelübersicht", :style => :bold
|
||||||
pdf.move_down 5
|
pdf.move_down 5
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
- title _("Show order")
|
- title _("Show order")
|
||||||
#element_navigation
|
#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 _("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
|
// Order summary
|
||||||
.left_column{:style => "width:65em"}
|
.left_column{:style => "width:65em"}
|
||||||
|
@ -33,18 +33,21 @@
|
||||||
= "[#{@order.group_orders.find(:all, :include => :ordergroup).collect{|g| g.ordergroup.name}.join(', ')}]"
|
= "[#{@order.group_orders.find(:all, :include => :ordergroup).collect{|g| g.ordergroup.name}.join(', ')}]"
|
||||||
|
|
||||||
%p
|
%p
|
||||||
Bruttosummer aller Artikel
|
Netto/Bruttosumme aller Artikel
|
||||||
%b= number_to_currency(@order.sum(:gross))
|
%b= "#{number_to_currency(@order.sum(:net))} / #{number_to_currency(@order.sum(:gross))}"
|
||||||
- if @order.finished?
|
%p
|
||||||
|
|
|
||||||
Bestellte Artikel:
|
Bestellte Artikel:
|
||||||
%b= @order.order_articles.ordered.count
|
%b= @order.order_articles.ordered.count
|
||||||
|
|
||||||
- if @order.open?
|
|
||||||
%p
|
%p
|
||||||
= link_to icon(:edit), edit_order_path(@order)
|
Aktionen:
|
||||||
= link_to icon(:delete), @order, :confirm => "Willst du wirklich die Bestellung löschen?", :method => :delete
|
- if @order.open?
|
||||||
= link_to '[beenden]', finish_order_path(@order), :method => :post
|
= 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?
|
- unless @order.open?
|
||||||
%p
|
%p
|
||||||
|
|
|
@ -4,20 +4,23 @@
|
||||||
%th{:colspan => '3'} Legende
|
%th{:colspan => '3'} Legende
|
||||||
%tr
|
%tr
|
||||||
%th{:style => 'width:70%'} Bestellgruppe
|
%th{:style => 'width:70%'} Bestellgruppe
|
||||||
%th Menge
|
%th Bestellt
|
||||||
|
%th Bekommen
|
||||||
%th Gesamtpreis
|
%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"}
|
%table{:style => "margin-bottom:1em"}
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th{:colspan => "3"}
|
%th{:colspan => "4"}
|
||||||
= order_article.article.name
|
= 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
|
%tbody
|
||||||
- for goa in order_article.group_order_articles
|
- for goa in order_article.group_order_articles
|
||||||
%tr{:class => cycle('even', 'odd', :name => 'groups')}
|
%tr{:class => cycle('even', 'odd', :name => 'groups')}
|
||||||
%td{:style => "width:70%"}=h goa.group_order.ordergroup.name
|
%td{:style => "width:70%"}=h goa.group_order.ordergroup.name
|
||||||
%td= "#{goa.quantity} (#{goa.tolerance})"
|
%td= "#{goa.quantity} (#{goa.tolerance})"
|
||||||
|
%td
|
||||||
|
%b= "#{goa.quantity_result} + #{goa.tolerance_result}"
|
||||||
%td= number_to_currency(order_article.price.fc_price * goa.quantity)
|
%td= number_to_currency(order_article.price.fc_price * goa.quantity)
|
||||||
- reset_cycle('groups')
|
- reset_cycle('groups')
|
|
@ -18,13 +18,13 @@
|
||||||
%th{:colspan => "6"}=h group_order.ordergroup.name
|
%th{:colspan => "6"}=h group_order.ordergroup.name
|
||||||
%tbody
|
%tbody
|
||||||
- total = 0
|
- 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
|
- fc_price = goa.order_article.price.fc_price
|
||||||
- subTotal = fc_price * goa.quantity
|
- subTotal = fc_price * goa.quantity
|
||||||
- total += subTotal
|
- total += subTotal
|
||||||
%tr{:class => cycle('even', 'odd', :name => 'articles')}
|
%tr{:class => cycle('even', 'odd', :name => 'articles')}
|
||||||
%td{:style => "width:40%"}=h goa.order_article.article.name
|
%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= number_to_currency(fc_price)
|
||||||
%td= goa.order_article.price.unit_quantity
|
%td= goa.order_article.price.unit_quantity
|
||||||
%td= goa.order_article.article.unit
|
%td= goa.order_article.article.unit
|
||||||
|
|
|
@ -3,21 +3,21 @@ class RefactorOrderLogic < ActiveRecord::Migration
|
||||||
# TODO: Combine migrations since foodsoft3-development into one file
|
# TODO: Combine migrations since foodsoft3-development into one file
|
||||||
# and try to build a migration path from old data.
|
# and try to build a migration path from old data.
|
||||||
|
|
||||||
# == Ordergroups
|
# # == Ordergroups
|
||||||
add_column :groups, :deleted_at, :datetime # acts_as_paranoid
|
# add_column :groups, :deleted_at, :datetime # acts_as_paranoid
|
||||||
remove_column :groups, :actual_size # Useless, desposits are better stored within a transaction.note
|
# remove_column :groups, :actual_size # Useless, desposits are better stored within a transaction.note
|
||||||
# move contact-infos from users to ordergroups
|
# # move contact-infos from users to ordergroups
|
||||||
add_column :groups, :contact_person, :string
|
# add_column :groups, :contact_person, :string
|
||||||
add_column :groups, :contact_phone, :string
|
# add_column :groups, :contact_phone, :string
|
||||||
add_column :groups, :contact_address, :string
|
# add_column :groups, :contact_address, :string
|
||||||
Ordergroup.all.each do |ordergroup|
|
# Ordergroup.all.each do |ordergroup|
|
||||||
contact = ordergroup.users.first
|
# contact = ordergroup.users.first
|
||||||
if contact
|
# if contact
|
||||||
ordergroup.update_attributes :contact_person => contact.name,
|
# ordergroup.update_attributes :contact_person => contact.name,
|
||||||
:contact_phone => contact.phone, :contact_address => contact.address
|
# :contact_phone => contact.phone, :contact_address => contact.address
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
remove_column :users, :address
|
# remove_column :users, :address
|
||||||
#
|
#
|
||||||
# # == Article
|
# # == Article
|
||||||
# rename_column :articles, :net_price, :price
|
# rename_column :articles, :net_price, :price
|
||||||
|
@ -77,6 +77,11 @@ class RefactorOrderLogic < ActiveRecord::Migration
|
||||||
#
|
#
|
||||||
# # == GroupOrder
|
# # == GroupOrder
|
||||||
# change_column :group_orders, :updated_by_user_id, :integer, :default => nil, :null => true
|
# change_column :group_orders, :updated_by_user_id, :integer, :default => nil, :null => true
|
||||||
|
|
||||||
|
# == GroupOrderArticle
|
||||||
|
# The order result in ordergroup is now saved!
|
||||||
|
add_column :group_order_articles, :quantity_result, :integer, :default => nil
|
||||||
|
add_column :group_order_articles, :tolerance_result, :integer, :default => nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
def self.down
|
||||||
|
|
|
@ -9,7 +9,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 => 20090120184410) do
|
ActiveRecord::Schema.define(:version => 20090119155930) 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
|
||||||
|
|
|
@ -41,7 +41,7 @@ und OrderArticle miteinander verbunden.
|
||||||
Bei jeder Bestellung wird außerdem die Summe der Menge, Toleranz in GroupOrderArticle
|
Bei jeder Bestellung wird außerdem die Summe der Menge, Toleranz in GroupOrderArticle
|
||||||
abgelegt. Allerdings muss jede Aenderung dieser Mengen mit protokolliert werden.
|
abgelegt. Allerdings muss jede Aenderung dieser Mengen mit protokolliert werden.
|
||||||
Dies ist wichtig, weil spaeter die Zuteilung der Einheiten pro bestellten Artikel
|
Dies ist wichtig, weil spaeter die Zuteilung der Einheiten pro bestellten Artikel
|
||||||
nach der chronoligischen Reihenfolge erfolgt. (s.u.)
|
nach der chronologischen Reihenfolge erfolgt. (s.u.)
|
||||||
Das passiert dann in der Tabelle group_order_article_quantities.
|
Das passiert dann in der Tabelle group_order_article_quantities.
|
||||||
(GroupOrderArticleQuantity)
|
(GroupOrderArticleQuantity)
|
||||||
|
|
||||||
|
|
17
test/fixtures/suppliers.yml
vendored
17
test/fixtures/suppliers.yml
vendored
|
@ -3,19 +3,22 @@
|
||||||
#
|
#
|
||||||
# Table name: suppliers
|
# Table name: suppliers
|
||||||
#
|
#
|
||||||
# id :integer(4) not null, primary key
|
# id :integer not null, primary key
|
||||||
# name :string(255) not null
|
# name :string(255) default(""), not null
|
||||||
# address :string(255) not null
|
# address :string(255) default(""), not null
|
||||||
# phone :string(255) not null
|
# phone :string(255) default(""), not null
|
||||||
# phone2 :string(255)
|
# phone2 :string(255)
|
||||||
# fax :string(255)
|
# fax :string(255)
|
||||||
# email :string(255)
|
# email :string(255)
|
||||||
# url :string(255)
|
# url :string(255)
|
||||||
|
# contact_person :string(255)
|
||||||
|
# customer_number :string(255)
|
||||||
# delivery_days :string(255)
|
# delivery_days :string(255)
|
||||||
|
# order_howto :string(255)
|
||||||
# note :string(255)
|
# note :string(255)
|
||||||
# created_on :datetime
|
# shared_supplier_id :integer
|
||||||
# updated_on :datetime
|
# min_order_quantity :string(255)
|
||||||
# lists :string(255)
|
# deleted_at :datetime
|
||||||
#
|
#
|
||||||
|
|
||||||
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
require File.dirname(__FILE__) + '/../test_helper'
|
|
||||||
require 'finance_controller'
|
|
||||||
|
|
||||||
# Re-raise errors caught by the controller.
|
|
||||||
class FinanceController; def rescue_action(e) raise e end; end
|
|
||||||
|
|
||||||
class FinanceControllerTest < Test::Unit::TestCase
|
|
||||||
def setup
|
|
||||||
@controller = FinanceController.new
|
|
||||||
@request = ActionController::TestRequest.new
|
|
||||||
@response = ActionController::TestResponse.new
|
|
||||||
end
|
|
||||||
|
|
||||||
# Replace this with your real tests.
|
|
||||||
def test_truth
|
|
||||||
assert true
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in a new issue