Complete refactoring of orders-workflow.

OrderResult tables are removed. Data consistency is now possible through new article.price-history (ArticlePrice).
Balancing-workflow needs to be updated.
This commit is contained in:
Benjamin Meichsner 2009-01-29 01:57:51 +01:00
parent 80287aeea4
commit 9eb2125f15
98 changed files with 1121 additions and 1717 deletions

View file

@ -121,7 +121,7 @@ class ArticlesController < ApplicationController
def destroy
@article = Article.find(params[:id])
@order = @article.inUse # If article is in an active Order, the Order will be returned
@order = @article.in_open_order # If article is in an active Order, the Order will be returned
if @order
render :update do |page|
page.insert_html :after, @article.id.to_s, :partial => 'destroyActiveArticle'
@ -226,7 +226,7 @@ class ArticlesController < ApplicationController
:origin => row[:origin],
:unit => row[:unit],
:article_category => ArticleCategory.find_by_name(row[:category]),
:net_price => row[:price],
:price => row[:price],
:unit_quantity => row[:unit_quantity],
:order_number => row[:number],
:deposit => row[:deposit],
@ -290,7 +290,7 @@ class ArticlesController < ApplicationController
:note => shared_article.note,
:manufacturer => shared_article.manufacturer,
:origin => shared_article.origin,
:net_price => shared_article.price,
:price => shared_article.price,
:tax => shared_article.tax,
:deposit => shared_article.deposit,
:unit_quantity => shared_article.unit_quantity,

View file

@ -39,7 +39,7 @@ class Finance::BalancingController < ApplicationController
render :update do |page|
@article = OrderArticleResult.new(params[:order_article_result])
@article.fc_markup = APP_CONFIG[:price_markup]
@article.make_gross if @article.tax && @article.deposit && @article.net_price
@article.make_gross if @article.tax && @article.deposit && @article.price
if @article.valid?
@article.save
@order = @article.order
@ -121,9 +121,9 @@ class Finance::BalancingController < ApplicationController
page["edit_box"].hide
page.insert_html :after, "groups_results_#{article.id}", :partial => "groupResults"
page["group_order_article_result_#{@result.id}"].visual_effect :highlight, :duration => 2
page["groups_amount"].replace_html number_to_currency(article.order.sumPrice('groups'))
page["fcProfit"].replace_html number_to_currency(article.order.fcProfit)
page["fcProfit"].visual_effect :highlight, :duration => 2
page["groups_amount"].replace_html number_to_currency(article.order.sum('groups'))
page["profit"].replace_html number_to_currency(article.order.profit)
page["profit"].visual_effect :highlight, :duration => 2
# get the new sums for quantity and price and replace it
total = article.total
@ -141,15 +141,15 @@ class Finance::BalancingController < ApplicationController
if params[:group_order_article_result]
if @result.update_attribute(:quantity, params[:group_order_article_result][:quantity])
order = @result.group_order_result.order
groups_amount = order.sumPrice("groups")
groups_amount = order.sum(:groups)
article = @result.order_article_result
total = article.total
page["edit_box"].hide
page["groups_amount"].replace_html number_to_currency(groups_amount)
page["fcProfit"].replace_html number_to_currency(order.fcProfit)
page["profit"].replace_html number_to_currency(order.profit)
page["groups_amount"].visual_effect :highlight, :duration => 2
page["fcProfit"].visual_effect :highlight, :duration => 2
page["profit"].visual_effect :highlight, :duration => 2
page["group_order_article_result_#{@result.id}"].replace_html :partial => "groupResult"
page["group_order_article_result_#{@result.id}"].visual_effect :highlight, :duration => 2
page["totalArticleQuantity_#{article.id}"].replace_html total[:quantity]
@ -169,9 +169,9 @@ class Finance::BalancingController < ApplicationController
render :update do |page|
article = @result.order_article_result
page["group_order_article_result_#{@result.id}"].remove
page["groups_amount"].replace_html number_to_currency(article.order.sumPrice('groups'))
page["fcProfit"].replace_html number_to_currency(article.order.fcProfit)
page["fcProfit"].visual_effect :highlight, :duration => 2
page["groups_amount"].replace_html number_to_currency(article.order.sum('groups'))
page["profit"].replace_html number_to_currency(article.order.profit)
page["profit"].visual_effect :highlight, :duration => 2
total = article.total # get total quantity and price for the ArticleResult
page["totalArticleQuantity_#{article.id}"].replace_html total[:quantity]
page["totalArticleQuantity_#{article.id}"].visual_effect :highlight, :duration => 2

View file

@ -27,7 +27,7 @@ class FoodcoopController < ApplicationController
conditions = "first_name LIKE '%#{params[:query]}%' OR last_name LIKE '%#{params[:query]}%'" unless params[:query].blank?
@total = User.count(:conditions => conditions)
@users = User.paginate(:page => params[:page], :per_page => @per_page, :conditions => conditions, :order => "nick", :include => "groups")
@users = User.paginate(:page => params[:page], :per_page => @per_page, :conditions => conditions, :order => "nick", :include => :groups)
respond_to do |format|
format.html # index.html.erb

View file

@ -2,10 +2,10 @@ class HomeController < ApplicationController
helper :messages
def index
@currentOrders = Order.find_current
@orderGroup = @current_user.find_ordergroup
if @orderGroup
@financial_transactions = @orderGroup.financial_transactions.find(:all, :order => 'created_on desc', :limit => 3)
@currentOrders = Order.open
@ordergroup = @current_user.find_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

View file

@ -8,22 +8,13 @@ class OrderingController < ApplicationController
verify :method => :post, :only => [:saveOrder], :redirect_to => { :action => :index }
# Index page.
def index
@orderGroup = @current_user.find_ordergroup
@currentOrders = Order.find_current
@finishedOrders = @orderGroup.findExpiredOrders + @orderGroup.findFinishedNotBooked
@bookedOrders = @orderGroup.findBookedOrders(5)
# Calculate how much the order group has spent on open or nonbooked orders:
@currentOrdersValue, @nonbookedOrdersValue = 0, 0
@orderGroup.findCurrent.each { |groupOrder| @currentOrdersValue += groupOrder.price}
@finishedOrders.each { |groupOrder| @nonbookedOrdersValue += groupOrder.price}
def index
end
# Edit a current order.
def order
@current_orders = Order.find_current
@other_orders = @current_orders.reject{|order| order == @order}
@open_orders = Order.open
@other_orders = @open_orders.reject{|order| order == @order}
# Load order article data...
@articles_by_category = @order.get_articles
# save results of earlier orders in array
@ -39,10 +30,10 @@ class OrderingController < ApplicationController
'tolerance_result' => result[:tolerance]}
end
@version = @group_order.lock_version
@availableFunds = @ordergroup.getAvailableFunds(@group_order)
@availableFunds = @ordergroup.get_available_funds(@group_order)
else
@version = 0
@availableFunds = @ordergroup.getAvailableFunds
@availableFunds = @ordergroup.get_available_funds
end
# load prices ....
@ -50,10 +41,10 @@ class OrderingController < ApplicationController
@others_quantity = Array.new; @quantity = Array.new; @quantity_result = Array.new; @used_quantity = Array.new; @unused_quantity = Array.new
@others_tolerance = Array.new; @tolerance = Array.new; @tolerance_result = Array.new; @used_tolerance = Array.new; @unused_tolerance = Array.new
i = 0;
@articles_by_category.each do |category, order_articles|
@articles_by_category.each do |category_name, order_articles|
for order_article in order_articles
# price/unit size
@price[i] = order_article.article.gross_price
@price[i] = order_article.article.fc_price
@unit[i] = order_article.article.unit_quantity
# quantity
@quantity[i] = (ordered_articles[order_article.id] ? ordered_articles[order_article.id]['quantity'] : 0)
@ -78,12 +69,12 @@ class OrderingController < ApplicationController
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 (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 = GroupOrder.new(:ordergroup => @ordergroup, :order => order, :updated_by => @current_user, :price => 0)
groupOrder.save!
end
# Create/update GroupOrderArticles...
@ -98,15 +89,15 @@ class OrderingController < ApplicationController
unless (quantities = ordered.delete(article.id.to_s)) && (quantity = quantities['quantity']) && (tolerance = quantities['tolerance'])
quantity = tolerance = 0
end
groupOrderArticle.updateQuantities(quantity.to_i, tolerance.to_i)
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.updatePrice
groupOrder.update_price!
groupOrder.updated_by = @current_user
groupOrder.save!
order.updateQuantities
order.update_quantities
order.save!
end
flash[:notice] = 'Die Bestellung wurde gespeichert.'
@ -124,86 +115,53 @@ class OrderingController < ApplicationController
# this method decides between finished and unfinished orders
def my_order_result
@order= Order.find(params[:id])
@current_orders = Order.find_current #.reject{|order| order == @order}
if @order.finished?
@finished= true
@groupOrderResult= @order.group_order_results.find_by_group_name(@current_user.find_ordergroup.name)
@order_value= @groupOrderResult.price if @groupOrderResult
@comments= @order.comments
else
@group_order = @order.group_orders.find_by_ordergroup_id(@current_user.find_ordergroup.id)
@order_value= @group_order.price if @group_order
end
@group_order = @order.group_order(@ordergroup)
end
# Shows all Orders of the Ordergroup
# if selected, it shows all orders of the foodcoop
def myOrders
@orderGroup = @current_user.find_ordergroup
unless params[:show_all] == "1"
# get only orders belonging to the ordergroup
@finishedOrders = @orderGroup.findExpiredOrders + @orderGroup.findFinishedNotBooked
@bookedOrders = GroupOrderResult.paginate :page => params[:page], :per_page => 10,
:include => :order,
:conditions => ["group_order_results.group_name = ? AND group_order_results.order_id = orders.id AND orders.finished = ? AND orders.booked = ? ", @orderGroup.name, true, true],
:order => "orders.ends DESC"
else
# get all orders, take care of different models in @finishedOrders
@show_all = true
@finishedOrders = Order.find_finished
@bookedOrders = Order.paginate_all_by_booked true, :page => params[:page], :per_page => 10, :order => 'ends desc'
end
# get only orders belonging to the ordergroup
@closed_orders = Order.paginate :page => params[:page], :per_page => 10,
:conditions => { :state => 'closed' }, :order => "orders.ends DESC"
respond_to do |format|
format.html # myOrders.haml
format.js do
render :update do |page|
page.replace_html 'bookedOrders', :partial => "bookedOrders"
end
end
end
end
# sends a form for adding a new comment
def newComment
@order = Order.find(params[:id])
render :update do |page|
page.replace_html 'newComment', :partial => 'shared/newComment', :object => @order
page["newComment"].show
format.js { render :partial => "orders" }
end
end
# adds a Comment to the Order
def addComment
@order = Order.find(params[:id])
@comment = Comment.new(params[:comment])
@comment.user = @current_user
if @comment.title.length > 3 && @order.comments << @comment
flash[:notice] = _("Comment has been created.")
redirect_to :action => 'my_order_result', :id => @order
def add_comment
order = Order.find(params[:id])
comment = order.comments.build(params[:comment])
comment.user = @current_user
if !comment.text.empty? and comment.save
flash[:notice] = "Kommentar wurde erstellt."
else
flash[:error] = _("The comment has not been saved. Check the title and try again.")
redirect_to :action => 'my_order_result', :id => @order
flash[:error] = "Kommentar konnte nicht erstellt werden. Leerer Kommentar?"
end
redirect_to :action => 'my_order_result', :id => order
end
private
# Returns true if @current_user is member of an Ordergroup.
# Used as a :before_filter by OrderingController.
def ensure_ordergroup_member
unless @current_user.find_ordergroup
flash[:notice] = 'Sie gehören keiner Bestellgruppe an.'
redirect_to :controller => root_path
end
# Returns true if @current_user is member of an Ordergroup.
# Used as a :before_filter by OrderingController.
def ensure_ordergroup_member
@ordergroup = @current_user.find_ordergroup
if @ordergroup.nil?
flash[:notice] = 'Sie gehören keiner Bestellgruppe an.'
redirect_to :controller => root_path
end
end
def ensure_open_order
@order = Order.find(params[:id], :include => [:supplier, :order_articles])
unless @order.current?
flash[:notice] = 'Diese Bestellung ist bereits abgeschlossen.'
redirect_to :action => 'index'
end
def ensure_open_order
@order = Order.find(params[:id], :include => [:supplier, :order_articles])
unless @order.open?
flash[:notice] = 'Diese Bestellung ist bereits abgeschlossen.'
redirect_to :action => 'index'
end
end
end

View file

@ -1,9 +1,8 @@
# Controller for managing orders, i.e. all actions that require the "orders" role.
# Normal ordering actions of members of order groups is handled by the OrderingController.
class OrdersController < ApplicationController
# Security
before_filter :authenticate_orders
verify :method => :post, :only => [:finish, :create, :update, :destroy, :setAllBooked], :redirect_to => { :action => :index }
# Define layout exceptions for PDF actions:
layout "application", :except => [:faxPdf, :matrixPdf, :articlesPdf, :groupsPdf]
@ -11,20 +10,20 @@ class OrdersController < ApplicationController
# List orders
def index
@current_orders = Order.find_current
@open_orders = Order.open
@per_page = 15
if params['sort']
sort = case params['sort']
when "supplier" then "suppliers.name, ends DESC"
when "ends" then "ends DESC"
when "supplier_reverse" then "suppliers.name DESC, ends DESC"
when "supplier_reverse" then "suppliers.name DESC"
when "ends_reverse" then "ends"
end
else
sort = "ends DESC"
end
@orders = Order.paginate :page => params[:page], :per_page => @per_page,
:order => sort, :conditions => ['ends < ? OR starts > ? OR finished = ?', Time.now, Time.now, true],
:order => sort, :conditions => "state != 'open'",
:include => :supplier
respond_to do |format|
@ -38,30 +37,25 @@ class OrdersController < ApplicationController
end
# Gives a view for the results to a specific order
# Renders also the pdf
def show
@order= Order.find(params[:id])
unless @order.finished?
@order_articles= @order.get_articles
@group_orders= @order.group_orders
else
@finished= true
@order_articles= @order.order_article_results
@group_orders= @order.group_order_results
@comments= @order.comments
if params[:view] # Articles-list will be replaced
partial = case params[:view]
when 'normal' then "showResult"
when 'groups'then 'showResult_groups'
when 'articles'then 'showResult_articles'
when 'normal' then "articles"
when 'groups'then 'articles_by_groups'
when 'articles'then 'articles_by_articles'
end
render :partial => partial if partial
render :partial => partial, :locals => {:order => @order} if partial
end
end
# Page to create a new order.
def new
@supplier = Supplier.find(params[:id])
@supplier = Supplier.find(params[:supplier_id])
@order = @supplier.orders.build :ends => 4.days.from_now
@template_orders = Order.find_all_by_supplier_id_and_finished(@supplier.id, true, :limit => 3, :order => 'starts DESC', :include => "order_article_results")
@template_orders = @supplier.orders.finished :order => 'starts DESC', :include => "order_article_results"
end
# Save a new order.
@ -69,8 +63,8 @@ class OrdersController < ApplicationController
def create
@order = Order.new(params[:order])
if @order.save
flash[:notice] = _("The order has been created successfully.")
redirect_to :action => 'show', :id => @order
flash[:notice] = "Die Bestellung wurde erstellt."
redirect_to @order
else
render :action => 'new'
end
@ -86,12 +80,11 @@ class OrdersController < ApplicationController
def update
@order = Order.find params[:id]
if @order.update_attributes params[:order]
flash[:notice] = _("The order has been updated.")
flash[:notice] = "Die Bestellung wurde aktualisiert."
redirect_to :action => 'show', :id => @order
else
render :action => 'edit'
end
@order.updateAllGroupOrders #important if ordered articles has been removed
end
# Delete an order.
@ -103,21 +96,21 @@ class OrdersController < ApplicationController
# Finish a current order.
def finish
order = Order.find(params[:id])
order.finish(@current_user)
flash[:notice] = _("The order has been finished successfully.")
redirect_to :action => 'show', :id => order
order.finish!(@current_user)
flash[:notice] = "Die Bestellung wurde beendet."
redirect_to order
end
# Renders the groups-orderd PDF.
def groupsPdf
@order = Order.find(params[:id])
prawnto :filename => "#{Date.today}_#{@order.name}_GruppenSortierung.pdf"
prawnto :filename => "#{Date.today}_#{@order.supplier.name}_GruppenSortierung.pdf"
end
# Renders the articles-orderd PDF.
def articlesPdf
@order = Order.find(params[:id])
prawnto :filename => "#{Date.today}_#{@order.name}_ArtikelSortierung.pdf",
prawnto :filename => "#{Date.today}_#{@order.supplier.name}_ArtikelSortierung.pdf",
:prawn => { :left_margin => 48,
:right_margin => 48,
:top_margin => 48,
@ -127,7 +120,7 @@ class OrdersController < ApplicationController
# Renders the fax PDF.
def faxPdf
@order = Order.find(params[:id])
prawnto :filename => "#{Date.today}_#{@order.name}_FAX.pdf"
prawnto :filename => "#{Date.today}_#{@order.supplier.name}_FAX.pdf"
end
# Renders the fax-text-file
@ -136,51 +129,43 @@ class OrdersController < ApplicationController
order = Order.find(params[:id])
supplier = order.supplier
contact = APP_CONFIG[:contact].symbolize_keys
text = _("Order for") + " #{APP_CONFIG[:name]}"
text += "\n" + _("Customer number") + ": #{supplier.customer_number}" unless supplier.customer_number.blank?
text += "\n" + _("Delivery date") + ": "
text = "Bestellung für" + " #{APP_CONFIG[:name]}"
text += "\n" + "Kundennummer" + ": #{supplier.customer_number}" unless supplier.customer_number.blank?
text += "\n" + "Liefertag" + ": "
text += "\n\n#{supplier.name}\n#{supplier.address}\nFAX: #{supplier.fax}\n\n"
text += "****** " + _("Shipping address") + "\n\n"
text += "****** " + "Versandadresse" + "\n\n"
text += "#{APP_CONFIG[:name]}\n#{contact[:street]}\n#{contact[:zip_code]} #{contact[:city]}\n\n"
text += "****** " + _("Articles") + "\n\n"
text += _("Number") + " " + _("Quantity") + " " + _("Name") + "\n"
text += "****** " + "Artikel" + "\n\n"
text += "Nummer" + " " + "Menge" + " " + "Name" + "\n"
# now display all ordered articles
order.order_article_results.each do |article|
text += article.order_number.blank? ? " " : "#{article.order_number} "
quantity = article.units_to_order.to_i.to_s
order.order_articles.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
quantity = " " + quantity if quantity.size < 2
text += "#{quantity} #{article.name}\n"
text += "#{number} #{quantity} #{oa.article.name}\n"
end
send_data text,
:type => 'text/plain; charset=utf-8; header=present',
:disposition => "attachment; filename=#{order.name}"
:disposition => "attachment; filename=#{order.supplier.name}"
end
# Renders the matrix PDF.
def matrixPdf
@order = Order.find(params[:id])
prawnto :filename => "#{Date.today}_#{@order.name}_Matrix.pdf"
prawnto :filename => "#{Date.today}_#{@order.supplier.name}_Matrix.pdf"
end
# sends a form for adding a new comment
def newComment
@order = Order.find(params[:id])
render :update do |page|
page.replace_html 'newComment', :partial => 'shared/newComment', :object => @order
end
end
# adds a Comment to the Order
def addComment
@order = Order.find(params[:id])
@comment = Comment.new(params[:comment])
@comment.user = @current_user
if @comment.title.length > 3 && @order.comments << @comment
flash[:notice] = _("Comment has been created.")
redirect_to :action => 'show', :id => @order
def add_comment
order = Order.find(params[:id])
comment = order.comments.build(params[:comment])
comment.user = @current_user
if !comment.text.empty? and comment.save
flash[:notice] = "Kommentar wurde erstellt."
else
flash[:error] = _("The comment has not been saved. Check the title and try again.")
redirect_to :action => 'show', :id => @order
flash[:error] = "Kommentar konnte nicht erstellt werden. Leerer Kommentar?"
end
redirect_to order
end
end

View file

@ -1,11 +1,13 @@
module OrdersHelper
require 'iconv'
# This method is needed to convert special characters into UTF-8 for rendering PDF files correctly.
def replace_UTF8(field)
ic_ignore = Iconv.new('ISO-8859-15//IGNORE//TRANSLIT', 'UTF-8')
field = ic_ignore.iconv(field)
ic_ignore.close
field
def update_articles_link(order, text, view)
link_to_remote text, :url => order_path(order, :view => view),
:update => 'articles', :before => "Element.show('loader')", :success => "Element.hide('loader')",
:method => :get
end
def link_to_pdf(order, action)
link_to image_tag("save_pdf.png", :size => "16x16", :border => "0", :alt => "PDF erstellen"),
{ :action => action, :id => order, :format => :pdf }, { :title => "PDF erstellen" }
end
end

View file

@ -1,5 +1,5 @@
# == Schema Information
# Schema version: 20090119155930
# Schema version: 20090120184410
#
# Table name: articles
#
@ -13,8 +13,7 @@
# manufacturer :string(255)
# origin :string(255)
# shared_updated_on :datetime
# net_price :decimal(8, 2)
# gross_price :decimal(8, 2) default(0.0), not null
# price :decimal(8, 2)
# tax :float
# deposit :decimal(8, 2) default(0.0)
# unit_quantity :integer(4) default(1), not null
@ -26,25 +25,30 @@
#
class Article < ActiveRecord::Base
acts_as_paranoid # Avoid deleting the article for consistency of order-results
acts_as_paranoid # Avoid deleting the article for consistency of order-results
extend ActiveSupport::Memoizable # Ability to cache method results. Use memoize :expensive_method
# Associations
belongs_to :supplier
belongs_to :article_category
has_many :article_prices, :order => "created_at"
named_scope :in_stock, :conditions => "quantity > 0", :order => 'suppliers.name', :include => :supplier
validates_presence_of :name, :unit, :net_price, :tax, :deposit, :unit_quantity, :supplier_id
# Validations
validates_presence_of :name, :unit, :price, :tax, :deposit, :unit_quantity, :supplier_id, :article_category_id
validates_length_of :name, :in => 4..60
validates_length_of :unit, :in => 2..15
validates_numericality_of :net_price, :greater_than => 0
validates_numericality_of :price, :greater_than => 0
validates_numericality_of :deposit, :tax
# calculate the gross_price
before_save :calc_gross_price
# Callbacks
before_save :update_price_history
before_destroy :check_article_in_use
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
def net_price=(net_price)
self[:net_price] = String.delocalized_decimal(net_price)
def price=(price)
self[:price] = String.delocalized_decimal(price)
end
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
@ -57,9 +61,14 @@ class Article < ActiveRecord::Base
self[:deposit] = String.delocalized_decimal(deposit)
end
# calculate the fc price and sets the attribute
def calc_gross_price
self.gross_price = ((net_price + deposit) * (tax / 100 + 1)) * (APP_CONFIG[:price_markup] / 100 + 1)
# The financial gross, net plus tax and deposti
def gross_price
((price + deposit) * (tax / 100 + 1)).round(2)
end
# The price for the foodcoop-member.
def fc_price
(gross_price * (APP_CONFIG[:price_markup] / 100 + 1)).round(2)
end
# Returns true if article has been updated at least 2 days ago
@ -75,7 +84,7 @@ class Article < ActiveRecord::Base
#
# Example:
#
# unit_quantity | quantity | tolerance | calculateOrderQuantity
# unit_quantity | quantity | tolerance | calculate_order_quantity
# --------------+----------+-----------+-----------------------
# 4 | 0 | 2 | 0
# 4 | 0 | 5 | 0
@ -85,28 +94,20 @@ class Article < ActiveRecord::Base
# 4 | 5 | 3 | 2
# 4 | 5 | 4 | 2
#
def calculateOrderQuantity(quantity, tolerance = 0)
unitSize = unit_quantity
units = quantity / unitSize
remainder = quantity % unitSize
units += ((remainder > 0) && (remainder + tolerance >= unitSize) ? 1 : 0)
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 active Order, the Order will returned.
def inUse
Order.find(:all, :conditions => 'finished = 0').each do |order|
if order.articles.find_by_id(self)
@order = order
break
end
end
return @order if @order
end
# Checks if the article is in use before it will deleted
def before_destroy
raise self.name.to_s + _(" cannot be deleted. The article is used in a current order!") if self.inUse
# 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_article = order_articles.detect {|oa| oa.article_id == id }
order_article ? order_article.order : nil
end
memoize :in_open_order
# this method checks, if the shared_article has been changed
# unequal attributes will returned in array
@ -132,7 +133,7 @@ class Article < ActiveRecord::Base
:manufacturer => [self.manufacturer, self.shared_article.manufacturer.to_s],
:origin => [self.origin, self.shared_article.origin],
:unit => [self.unit, new_unit],
:net_price => [self.net_price, new_price],
:price => [self.price, new_price],
:tax => [self.tax, self.shared_article.tax],
:deposit => [self.deposit, self.shared_article.deposit],
# take care of different num-objects.
@ -217,4 +218,26 @@ class Article < ActiveRecord::Base
update_attribute :quantity, quantity + amount
end
protected
# Checks if the article is in use before it will deleted
def check_article_in_use
raise self.name.to_s + _(" cannot be deleted. The article is used in a current order!") if self.in_open_order
end
# Create an ArticlePrice, when the price-attr are changed.
def update_price_history
if price_changed?
article_prices.create(
:price => price,
:tax => tax,
:deposit => deposit,
:unit_quantity => unit_quantity
)
end
end
def price_changed?
changed.detect { |attr| attr == 'price' || 'tax' || 'deposit' || 'unit_quantity' } ? true : false
end
end

View file

@ -0,0 +1,29 @@
# == Schema Information
# Schema version: 20090120184410
#
# Table name: article_prices
#
# id :integer(4) not null, primary key
# article_id :integer(4)
# price :decimal(8, 2) default(0.0), not null
# tax :decimal(8, 2) default(0.0), not null
# deposit :decimal(8, 2) default(0.0), not null
# unit_quantity :integer(4)
# created_at :datetime
#
class ArticlePrice < ActiveRecord::Base
belongs_to :article
has_many :order_articles
# The financial gross, net plus tax and deposit.
def gross_price
((price + deposit) * (tax / 100 + 1))
end
# The price for the foodcoop-member.
def fc_price
(gross_price * (APP_CONFIG[:price_markup] / 100 + 1))
end
end

View file

@ -19,7 +19,6 @@ class GroupOrder < ActiveRecord::Base
belongs_to :ordergroup
has_many :group_order_articles, :dependent => :destroy
has_many :order_articles, :through => :group_order_articles
has_many :group_order_article_results
belongs_to :updated_by, :class_name => "User", :foreign_key => "updated_by_user_id"
validates_presence_of :order_id
@ -28,14 +27,17 @@ class GroupOrder < ActiveRecord::Base
validates_numericality_of :price
validates_uniqueness_of :ordergroup_id, :scope => :order_id # order groups can only order once per order
named_scope :open, lambda { {:conditions => ["order_id IN (?)", Order.open.collect{|o| o.id}]} }
named_scope :finished, lambda { {:conditions => ["order_id IN (?)", Order.finished.collect{|o| o.id}]} }
# Updates the "price" attribute.
# This will be the maximum value of a current order
def updatePrice
def update_price!
total = 0
for article in group_order_articles.find(:all, :include => :order_article)
total += article.order_article.article.gross_price * (article.quantity + article.tolerance)
total += article.order_article.article.fc_price * (article.quantity + article.tolerance)
end
self.price = total
update_attribute(:price, total)
end
end

View file

@ -30,8 +30,8 @@ class GroupOrderArticle < ActiveRecord::Base
# and the associated GroupOrderArticleQuantities chronologically.
#
# See description of the ordering algorithm in the general application documentation for details.
def updateQuantities(quantity, tolerance)
logger.debug("GroupOrderArticle[#{id}].updateQuantities(#{quantity}, #{tolerance})")
def update_quantities(quantity, tolerance)
logger.debug("GroupOrderArticle[#{id}].update_quantities(#{quantity}, #{tolerance})")
logger.debug("Current quantity = #{self.quantity}, tolerance = #{self.tolerance}")
# Get quantities ordered with the newest item first.

View file

@ -1,34 +0,0 @@
# == Schema Information
# Schema version: 20090102171850
#
# Table name: group_order_article_results
#
# id :integer(4) not null, primary key
# order_article_result_id :integer(4) default(0), not null
# group_order_result_id :integer(4) default(0), not null
# quantity :decimal(6, 3) default(0.0)
# tolerance :integer(4)
#
# An GroupOrderArticleResult represents a group-order for a single Article and its quantities,
# according to the order quantity/tolerance.
# The GroupOrderArticleResult is part of a finished Order, see OrderArticleResult.
#
class GroupOrderArticleResult < ActiveRecord::Base
belongs_to :order_article_result
belongs_to :group_order_result
validates_presence_of :order_article_result, :group_order_result, :quantity
validates_numericality_of :quantity, :minimum => 0
# updates the price attribute for the appropriate GroupOrderResult
after_update {|result| result.group_order_result.updatePrice }
after_destroy {|result| result.group_order_result.updatePrice }
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
def quantity=(quantity)
self[:quantity] = String.delocalized_decimal(quantity)
end
end

View file

@ -1,26 +0,0 @@
# == Schema Information
# Schema version: 20090102171850
#
# Table name: group_order_results
#
# id :integer(4) not null, primary key
# order_id :integer(4) default(0), not null
# group_name :string(255) default(""), not null
# price :decimal(8, 2) default(0.0), not null
#
# Ordergroups, which participate on a specific order will have a line
class GroupOrderResult < ActiveRecord::Base
belongs_to :order
has_many :group_order_article_results, :dependent => :destroy
# Calculates the Order-Price for the Ordergroup and updates the price-attribute
def updatePrice
total = 0
group_order_article_results.each do |result|
total += result.order_article_result.gross_price * result.quantity
end
update_attribute(:price, total)
end
end

View file

@ -1,24 +1,28 @@
# == Schema Information
# Schema version: 20090113111624
# Schema version: 20090120184410
#
# Table name: invoices
#
# id :integer(4) not null, primary key
# supplier_id :integer(4)
# delivery_id :integer(4)
# number :string(255)
# date :date
# paid_on :date
# note :text
# amount :decimal(8, 2) default(0.0), not null
# created_at :datetime
# updated_at :datetime
# id :integer(4) not null, primary key
# supplier_id :integer(4)
# delivery_id :integer(4)
# number :string(255)
# date :date
# paid_on :date
# note :text
# amount :decimal(8, 2) default(0.0), not null
# created_at :datetime
# updated_at :datetime
# order_id :integer(4)
# deposit :decimal(8, 2) default(0.0), not null
# deposit_credit :decimal(8, 2) default(0.0), not null
#
class Invoice < ActiveRecord::Base
belongs_to :supplier
belongs_to :delivery
belongs_to :order
validates_presence_of :supplier_id
validates_uniqueness_of :date, :scope => [:supplier_id]
@ -29,4 +33,14 @@ class Invoice < ActiveRecord::Base
def amount=(amount)
self[:amount] = String.delocalized_decimal(amount)
end
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
def deposit=(deposit)
self[:deposit] = String.delocalized_decimal(deposit)
end
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
def deposit_credit=(deposit)
self[:deposit_credit] = String.delocalized_decimal(deposit)
end
end

View file

@ -1,69 +1,47 @@
# == Schema Information
# Schema version: 20090102171850
# Schema version: 20090120184410
#
# Table name: orders
#
# id :integer(4) not null, primary key
# name :string(255) default(""), not null
# supplier_id :integer(4) default(0), not null
# starts :datetime not null
# supplier_id :integer(4)
# note :text
# starts :datetime
# ends :datetime
# note :string(255)
# finished :boolean(1) not null
# booked :boolean(1) not null
# state :string(255) default("open")
# lock_version :integer(4) default(0), not null
# updated_by_user_id :integer(4)
# invoice_amount :decimal(8, 2) default(0.0), not null
# deposit :decimal(8, 2) default(0.0)
# deposit_credit :decimal(8, 2) default(0.0)
# invoice_number :string(255)
# invoice_date :string(255)
#
class Order < ActiveRecord::Base
extend ActiveSupport::Memoizable # Ability to cache method results. Use memoize :expensive_method
acts_as_ordered :order => "ends" # easyier find of next or previous model
# Associations
has_many :order_articles, :dependent => :destroy
has_many :articles, :through => :order_articles
has_many :group_orders, :dependent => :destroy
has_many :ordergroups, :through => :group_orders
has_many :order_article_results, :dependent => :destroy
has_many :group_order_results, :dependent => :destroy
has_one :invoice
has_many :comments, :class_name => "OrderComment", :order => "created_at"
belongs_to :supplier
belongs_to :updated_by, :class_name => "User", :foreign_key => "updated_by_user_id"
validates_length_of :name, :in => 2..50
validates_presence_of :starts
validates_presence_of :supplier_id
validates_inclusion_of :finished, :in => [true, false]
validates_numericality_of :invoice_amount, :deposit, :deposit_credit
validate_on_create :include_articles
# attr_accessible :name, :supplier, :starts, :ends, :note, :invoice_amount, :deposit, :deposit_credit, :invoice_number, :invoice_date
#use plugin to make Order commentable
acts_as_commentable
# Validations
validates_presence_of :supplier_id, :starts
validate_on_create :starts_before_ends, :include_articles
# easyier find of next or previous model
acts_as_ordered :order => "ends"
# Callbacks
after_update :update_price_of_group_orders
# Finders
named_scope :finished, :conditions => { :state => 'finished' },
:order => 'ends DESC'
named_scope :open, :conditions => { :state => 'open' },
:order => 'ends DESC'
named_scope :closed, :conditions => { :state => 'closed' },
:order => 'ends DESC'
named_scope :finished, :conditions => { :finished => true },
:order => 'ends DESC', :include => :supplier
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
def invoice_amount=(amount)
self[:invoice_amount] = String.delocalized_decimal(amount)
end
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
def deposit=(deposit)
self[:deposit] = String.delocalized_decimal(deposit)
end
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
def deposit_credit=(deposit)
self[:deposit_credit] = String.delocalized_decimal(deposit)
end
# Create or destroy OrderArticle associations on create/update
def article_ids=(ids)
# fetch selected articles
@ -75,202 +53,123 @@ class Order < ActiveRecord::Base
order_articles.detect { |order_article| order_article.article_id == article.id }.destroy
end
end
# Returns all current orders, i.e. orders that are not finished and the current time is between the order's start and end time.
def self.find_current
find(:all, :conditions => ['finished = ? AND starts < ? AND (ends IS NULL OR ends > ?)', false, Time.now, Time.now], :order => 'ends desc', :include => :supplier)
def open?
state == "open"
end
# Returns true if this is a current order (not finished and current time matches starts/ends).
def current?
!finished? && starts < Time.now && (!ends || ends > Time.now)
def finished?
state == "finished"
end
# Returns all finished or expired orders, exclude booked orders
def self.find_finished
find(:all, :conditions => ['(finished = ? OR ends < ?) AND booked = ?', true, Time.now, false], :order => 'ends desc', :include => :supplier)
end
# Return all booked Orders
def self.find_booked
find :all, :conditions => ['booked = ?', true], :order => 'ends desc', :include => :supplier
def closed?
state == "closed"
end
# search GroupOrder of given Ordergroup
def group_order(ordergroup)
unless finished
return group_orders.detect {|o| o.ordergroup_id == ordergroup.id}
else
return group_order_results.detect {|o| o.group_name == ordergroup.name}
end
group_orders.first :conditions => { :ordergroup_id => ordergroup.id }
end
# Returns OrderArticles in a nested Array, grouped by category and ordered by article name.
# The array has the following form:
# e.g: [["drugs",[teethpaste, toiletpaper]], ["fruits" => [apple, banana, lemon]]]
def get_articles
articles= order_articles.find :all, :include => :article, :order => "articles.name"
articles_by_category= Hash.new
ArticleCategory.find(:all).each do |category|
articles_by_category.merge!(category.name.to_s => articles.select {|order_article| order_article.article.article_category == category})
end
# add articles without a category
articles_by_category.merge!( "--" => articles.select {|order_article| order_article.article.article_category == nil})
# return "clean" hash, sorted by category.name
return articles_by_category.reject {|category, order_articles| order_articles.empty?}.sort
# it could be so easy ... but that doesn't work for empty category-ids...
# order_articles.group_by {|a| a.article.article_category}.sort {|a, b| a[0].name <=> b[0].name}
order_articles.all(:include => [:article, :article_price], :order => 'articles.name').group_by { |a|
a.article.article_category.name
}.sort { |a, b| a[0] <=> b[0] }
end
memoize :get_articles
# Returns the defecit/benefit for the foodcoop
def fcProfit(with_markup = true)
groups_sum = with_markup ? sumPrice("groups") : sumPrice("groups_without_markup")
def profit(with_markup = true)
groups_sum = with_markup ? sum(:groups) : sum(:groups_without_markup)
groups_sum - invoice_amount + deposit - deposit_credit
end
# Returns the all round price of a finished order
# "groups" returns the sum of all GroupOrderResults
# "clear" returns the price without tax, deposit and markup
# "gross" includes tax and deposit. this amount should be equal to suppliers bill
# "fc", guess what...
# for unfinished orders it returns the gross price
def sumPrice(type = "gross")
sum = 0
if finished?
if type == "groups"
for groupResult in group_order_results
for result in groupResult.group_order_article_results
sum += result.order_article_result.gross_price * result.quantity
end
# :groups returns the sum of all GroupOrders
# :clear returns the price without tax, deposit and markup
# :gross includes tax and deposit. this amount should be equal to suppliers bill
# :fc, guess what...
def sum(type = :gross)
total = 0
if type == :clear || 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
total += quantity * oa.price.price
when :gross
total += quantity * oa.price.gross_price
when :fc
total += quantity * oa.price.fc_price
end
elsif type == "groups_without_markup"
for groupResult in group_order_results
for result in groupResult.group_order_article_results
oar = result.order_article_result
sum += (oar.net_price + oar.deposit) * (1 + oar.tax/100) * result.quantity
end
end
else
for article in order_article_results
end
elsif type == :groups || type == :groups_without_markup
for go in group_orders
for goa in go.group_order_articles
case type
when 'clear'
sum += article.units_to_order * article.unit_quantity * article.net_price
when 'gross'
sum += article.units_to_order * article.unit_quantity * (article.net_price + article.deposit) * (article.tax / 100 + 1)
when "fc"
sum += article.units_to_order * article.unit_quantity * article.gross_price
when :groups
total += goa.quantity * goa.order_article.price.fc_price
when :groups_without_markup
total += goa.quantity * goa.order_article.price.gross_price
end
end
end
else
for article in order_articles
sum += article.units_to_order * article.article.gross_price * article.article.unit_quantity
end
end
sum
total
end
# Finishes this order. This will set the finish property to "true" and the end property to the current time.
# Finishes this order. This will set the order state to "finish" and the end property to the current time.
# Ignored if the order is already finished.
# this will also copied the results into OrderArticleResult, GroupOrderArticleResult and GroupOrderResult
def finish(user)
unless finished?
transaction do
#saves ordergroups, which take part in this order
self.group_orders.each do |go|
group_order_result = GroupOrderResult.create!(:order => self,
:group_name => go.ordergroup.name,
:price => go.price)
def finish!(user)
unless finished?
Order.transaction do
# Update order_articles. Save the current article_price to keep price consistency
order_articles.all(:include => :article).each do |oa|
oa.update_attribute(:article_price, oa.article.article_prices.first)
end
# saves every article of the order
self.get_articles.each do |category, articles|
articles.each do |oa|
if oa.units_to_order >= 1 # save only successful ordered articles!
article_result = OrderArticleResult.new(:order => self,
:name => oa.article.name,
:unit => oa.article.unit,
:net_price => oa.article.net_price,
:gross_price => oa.article.gross_price,
:tax => oa.article.tax,
:deposit => oa.article.deposit,
:fc_markup => APP_CONFIG[:price_markup],
:order_number => oa.article.order_number,
:unit_quantity => oa.article.unit_quantity,
:units_to_order => oa.units_to_order)
article_result.save
# saves the ordergroup results, belonging to the saved orderd article
oa.group_order_articles.each do |goa|
result = goa.orderResult
# find appropriate GroupOrderResult
group_order_result = GroupOrderResult.find(:first, :conditions => ['order_id = ? AND group_name = ?', self.id, goa.group_order.ordergroup.name])
group_order_article_result = GroupOrderArticleResult.new(:order_article_result => article_result,
:group_order_result => group_order_result,
:quantity => result[:total],
:tolerance => result[:tolerance])
group_order_article_result.save! if (group_order_article_result.quantity > 0)
end
end
end
end
# set new order state (needed by notifyOrderFinished)
self.finished = true
self.ends = Time.now
self.updated_by = user
# delete data, which is no longer required, because everything is now in the result-tables
self.group_orders.each do |go|
go.destroy
end
self.order_articles.each do |oa|
oa.destroy
end
self.save!
# Update all GroupOrder.price
self.updateAllGroupOrders
# notify order groups
notifyOrderFinished
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 ? ...
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.
def updateQuantities
orderArticles = Hash.new # holds the list of updated OrderArticles indexed by their id
# 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...
articles = GroupOrderArticle.find(:all, :conditions => ['group_order_id IN (?)', group_orders.collect { | o | o.id }], :include => [:order_article])
for article in articles
if (orderArticle = orderArticles[article.order_article.id.to_s])
# OrderArticle has already been fetched, just update...
orderArticle.quantity = orderArticle.quantity + article.quantity
orderArticle.tolerance = orderArticle.tolerance + article.tolerance
orderArticle.units_to_order = orderArticle.article.calculateOrderQuantity(orderArticle.quantity, orderArticle.tolerance)
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...
orderArticle = article.order_article
orderArticle.quantity = article.quantity
orderArticle.tolerance = article.tolerance
orderArticle.units_to_order = orderArticle.article.calculateOrderQuantity(orderArticle.quantity, orderArticle.tolerance)
orderArticles[orderArticle.id.to_s] = orderArticle
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
orderArticles.each_value { | value | value.save! }
end
end
# Updates the "price" attribute of GroupOrders or GroupOrderResults
# This will be either the maximum value of a current order or the actual order value of a finished order.
def updateAllGroupOrders
unless finished?
group_orders.each do |groupOrder|
groupOrder.updatePrice
groupOrder.save
end
else #for finished orders
group_order_results.each do |groupOrderResult|
groupOrderResult.updatePrice
end
indexed_order_articles.each_value { | value | value.save! }
end
end
@ -290,49 +189,40 @@ class Order < ActiveRecord::Base
end
end
# returns the corresponding message for the status
def status
if !self.finished? && self.ends > Time.now
_("running")
elsif !self.finished? && self.ends < Time.now
_("expired")
elsif self.finished? && !self.booked?
_("finished")
else
_("balanced")
end
end
protected
def validate
errors.add(:ends, "muss nach dem Bestellstart liegen (oder leer bleiben)") if (ends && starts && ends <= starts)
end
def include_articles
errors.add(:order_articles, _("There must be at least one article selected")) if order_articles.empty?
end
def starts_before_ends
errors.add(:ends, "muss nach dem Bestellstart liegen (oder leer bleiben)") if (ends && starts && ends <= starts)
end
def include_articles
errors.add(:order_articles, "Es muss mindestens ein Artikel ausgewählt sein") if order_articles.empty?
end
private
# Sends "order finished" messages to users who have participated in this order.
def notifyOrderFinished
# Loop through GroupOrderResults for this order:
for group_order in self.group_order_results
ordergroup = Ordergroup.find_by_name(group_order.group_name)
# Determine group users that want a notification message:
users = ordergroup.users.reject{|u| u.settings["notify.orderFinished"] != '1'}
unless users.empty?
# Assemble the order message text:
results = group_order.group_order_article_results.find(:all, :include => [:order_article_result])
# Create user notification messages:
Message.from_template(
'order_finished',
{:group => ordergroup, :order => self, :results => results, :total => group_order.price},
{:recipients_ids => users.collect(&:id), :subject => "Bestellung beendet: #{self.name}"}
).save!
end
# Updates the "price" attribute of GroupOrders or GroupOrderResults
# This will be either the maximum value of a current order or the actual order value of a finished order.
def update_price_of_group_orders
group_orders.each { |group_order| group_order.update_price! }
end
# Sends "order finished" messages to users who have participated in this order.
def notify_order_finished
for group_order in self.group_orders
ordergroup = group_order.ordergroup
logger.debug("Send 'order finished' message to #{ordergroup.name}")
# Determine users that want a notification message:
users = ordergroup.users.reject{|u| u.settings["notify.orderFinished"] != '1'}
unless users.empty?
# Create user notification messages:
Message.from_template(
'order_finished',
{:group => ordergroup, :order => self, :group_order => group_order},
{:recipients_ids => users.collect(&:id), :subject => "Bestellung beendet: #{supplier.name}"}
).save!
end
end
end
end

View file

@ -1,15 +1,16 @@
# == Schema Information
# Schema version: 20090102171850
# Schema version: 20090120184410
#
# Table name: order_articles
#
# id :integer(4) not null, primary key
# order_id :integer(4) default(0), not null
# article_id :integer(4) default(0), not null
# quantity :integer(4) default(0), not null
# tolerance :integer(4) default(0), not null
# units_to_order :integer(4) default(0), not null
# lock_version :integer(4) default(0), not null
# id :integer(4) not null, primary key
# order_id :integer(4) default(0), not null
# article_id :integer(4) default(0), not null
# quantity :integer(4) default(0), not null
# tolerance :integer(4) default(0), not null
# units_to_order :integer(4) default(0), not null
# lock_version :integer(4) default(0), not null
# article_price_id :integer(4)
#
# An OrderArticle represents a single Article that is part of an Order.
@ -17,16 +18,25 @@ class OrderArticle < ActiveRecord::Base
belongs_to :order
belongs_to :article
belongs_to :article_price
has_many :group_order_articles, :dependent => :destroy
validates_presence_of :order_id
validates_presence_of :article_id
validates_uniqueness_of :article_id, :scope => :order_id # an article can only have one record per order
named_scope :ordered, :conditions => "units_to_order >= 1"
# This method returns either the Article or the ArticlePrice
# The latter will be set, when the the order is finished
def price
article_price || article
end
private
def validate
errors.add(:article, "muss angegeben sein und einen aktuellen Preis haben") if !(article = Article.find(article_id)) || article.gross_price.nil?
errors.add(:article, "muss angegeben sein und einen aktuellen Preis haben") if !(article = Article.find(article_id)) || article.fc_price.nil?
end
end

View file

@ -1,78 +0,0 @@
# == Schema Information
# Schema version: 20090102171850
#
# Table name: order_article_results
#
# id :integer(4) not null, primary key
# order_id :integer(4) default(0), not null
# name :string(255) default(""), not null
# unit :string(255) default(""), not null
# note :string(255)
# net_price :decimal(8, 2) default(0.0)
# gross_price :decimal(8, 2) default(0.0), not null
# tax :float default(0.0), not null
# deposit :decimal(8, 2) default(0.0)
# fc_markup :float default(0.0), not null
# order_number :string(255)
# unit_quantity :integer(4) default(0), not null
# units_to_order :decimal(6, 3) default(0.0), not null
#
# An OrderArticleResult represents a single Article that is part of a *finished* Order.
class OrderArticleResult < ActiveRecord::Base
belongs_to :order
has_many :group_order_article_results, :dependent => :destroy
validates_presence_of :name, :unit, :net_price, :gross_price, :tax, :deposit, :fc_markup, :unit_quantity, :units_to_order
validates_numericality_of :net_price, :gross_price, :deposit, :unit_quantity, :units_to_order
validates_length_of :name, :minimum => 4
def make_gross # calculate the gross price and sets the attribute
self.gross_price = ((net_price + deposit) * (tax / 100 + 1) * (fc_markup / 100 + 1))
end
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
def net_price=(net_price)
self[:net_price] = String.delocalized_decimal(net_price)
end
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
def tax=(tax)
self[:tax] = String.delocalized_decimal(tax)
end
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
def deposit=(deposit)
self[:deposit] = String.delocalized_decimal(deposit)
end
# Custom attribute setter that accepts decimal numbers using localized decimal separator.
def units_to_order=(units_to_order)
self[:units_to_order] = String.delocalized_decimal(units_to_order)
end
# counts from every GroupOrderArticleResult for this ArticleResult
# Return a hash with the total quantity (in Article-units) and the total (FC) price
def total
quantity = 0
price = 0
for result in self.group_order_article_results
quantity += result.quantity
price += result.quantity * self.gross_price
end
return {:quantity => quantity, :price => price}
end
# updates the price attribute for all appropriate GroupOrderResults
def after_update
group_order_article_results.each {|result| result.group_order_result.updatePrice}
end
protected
def validate
errors.add(:net_price, "should be positive") unless net_price.nil? || net_price > 0
end
end

View file

@ -0,0 +1,19 @@
# == Schema Information
# Schema version: 20090120184410
#
# Table name: order_comments
#
# id :integer(4) not null, primary key
# order_id :integer(4)
# user_id :integer(4)
# text :text
# created_at :datetime
#
class OrderComment < ActiveRecord::Base
belongs_to :order
belongs_to :user
validates_presence_of :order_id, :user_id, :text
end

View file

@ -30,46 +30,34 @@
# * account_updated (datetime)
# * actual_size (int) : how many persons are ordering through the Ordergroup
class Ordergroup < Group
has_many :financial_transactions, :dependent => :destroy
has_many :group_orders, :dependent => :destroy
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 :group_orders
has_many :orders, :through => :group_orders
has_many :group_order_article_results, :through => :group_orders # TODO: whats this???
has_many :group_order_results, :finder_sql => 'SELECT * FROM group_order_results as r WHERE r.group_name = "#{name}"'
validates_inclusion_of :actual_size, :in => 1..99
validates_numericality_of :account_balance, :message => 'ist keine gültige Zahl'
attr_accessible :actual_size, :account_updated
# messages
ERR_NAME_IS_USED_IN_ARCHIVE = "Der Name ist von einer ehemaligen Gruppe verwendet worden."
# if the ordergroup.name is changed, group_order_result.name has to be adapted
def before_update
ordergroup = Ordergroup.find(self.id)
unless (ordergroup.name == self.name) || ordergroup.group_order_results.empty?
# rename all finished orders
for result in ordergroup.group_order_results
result.update_attribute(:group_name, self.name)
end
end
end
# Returns the available funds for this order group (the account_balance minus price of all non-booked GroupOrders of this group).
# * excludeGroupOrder (GroupOrder): exclude this GroupOrder from the calculation
def getAvailableFunds(excludeGroupOrder = nil)
funds = account_balance
for order in GroupOrder.find_all_by_ordergroup_id(self.id)
unless order == excludeGroupOrder
funds -= order.price
end
end
for order_result in self.findFinishedNotBooked
funds -= order_result.price
end
return funds
def value_of_open_orders(exclude = nil)
group_orders.open.reject{|go| go == exclude}.collect(&:price).sum
end
def value_of_finished_orders(exclude = nil)
group_orders.finished.reject{|go| go == exclude}.collect(&:price).sum
end
# Returns the available funds for this order group (the account_balance minus price of all non-closed GroupOrders of this group).
# * exclude (GroupOrder): exclude this GroupOrder from the calculation
def get_available_funds(exclude = nil)
account_balance - value_of_open_orders(exclude) - value_of_finished_orders(exclude)
end
memoize :get_available_funds
# Creates a new FinancialTransaction for this Ordergroup and updates the account_balance accordingly.
# Throws an exception if it fails.
def addFinancialTransaction(amount, note, user)
@ -129,13 +117,4 @@ class Ordergroup < Group
end
end
# before create or update, check if the name is already used in GroupOrderResults
def validate_on_create
errors.add(:name, ERR_NAME_IS_USED_IN_ARCHIVE) unless GroupOrderResult.find_all_by_group_name(self.name).empty?
end
def validate_on_update
ordergroup = Ordergroup.find(self.id)
errors.add(:name, ERR_NAME_IS_USED_IN_ARCHIVE) unless ordergroup.name == self.name || GroupOrderResult.find_all_by_group_name(self.name).empty?
end
end

View file

@ -43,7 +43,7 @@ class Supplier < ActiveRecord::Base
# Returns all articles for this supplier that are available and have a valid price, grouped by article category and ordered by name.
def getArticlesAvailableForOrdering
articles = Article.find(:all, :conditions => ['supplier_id = ? AND availability = ?', self.id, true], :order => 'article_categories.name, articles.name', :include => :article_category)
articles.select {|article| article.gross_price}
articles.select {|article| article.fc_price}
end
# sync all articles with the external database
@ -66,10 +66,10 @@ class Supplier < ActiveRecord::Base
# try to convert different units
new_price, new_unit_quantity = article.convert_units
if new_price and new_unit_quantity
article.net_price = new_price
article.price = new_price
article.unit_quantity = new_unit_quantity
else
article.net_price = shared_article.price
article.price = shared_article.price
article.unit_quantity = shared_article.unit_quantity
article.unit = shared_article.unit
end

View file

@ -10,8 +10,8 @@
<td><%= @article.unit_quantity -%></td>
<td class="currency">
<acronym title="zuletzt geändert: <%= format_date(@article.updated_at) -%>
| Brutto: <%= number_to_currency(@article.gross_price) -%>">
<%= number_to_currency(@article.net_price) -%>
| Brutto: <%= number_to_currency(@article.fc_price) -%>">
<%= number_to_currency(@article.price) -%>
</acronym>
</td>
<td><%= number_to_percentage(@article.tax) if @article.tax != 0 -%></td>

View file

@ -31,7 +31,7 @@
%th Pfand
%tbody
%tr
%td= form.text_field :net_price, :size => 5
%td= form.text_field :price, :size => 5
%td= form.text_field :unit_quantity, :size => 5
%td= form.text_field :order_number, :size => 10
%td= form.text_field :tax, :size => 5

View file

@ -44,7 +44,7 @@
<%= form.text_field 'name', :size => 0 -%>
</td>
<td><%= form.text_field 'unit', :size => 5 -%></td>
<td><%= form.text_field 'net_price', :size => 4 -%></td>
<td><%= form.text_field 'price', :size => 4 -%></td>
<td><%= form.text_field 'unit_quantity', :size => 4 -%></td>
<td><%= form.text_field 'order_number', :size => 6 -%></td>
<td><%= form.text_field 'note', :size => 15 -%></td>

View file

@ -28,7 +28,7 @@
%td= form.text_field 'manufacturer', :size => 6
%td= form.text_field 'origin', :size => 6
%td= form.text_field 'unit', :size => 5
%td= form.text_field 'net_price', :size => 4
%td= form.text_field 'price', :size => 4
%td= form.text_field 'tax', :size => 4
%td= form.text_field 'deposit', :size => 4
%td= form.text_field 'unit_quantity', :size => 4

View file

@ -46,7 +46,7 @@
%td= article.origin
%td= article.unit
%td= article.unit_quantity
%td= article.net_price
%td= article.price
%td= article.tax
%td= article.deposit
%td= article.article_category.name if article.article_category
@ -60,7 +60,7 @@
%td{:style => highlight_new(unequal_attributes, :origin)}= form.text_field 'origin', :size => 5
%td{:style => highlight_new(unequal_attributes, :unit)}= form.text_field 'unit', :size => 5
%td{:style => highlight_new(unequal_attributes, :unit_quantity)}= form.text_field 'unit_quantity', :size => 5
%td{:style => highlight_new(unequal_attributes, :net_price)}= form.text_field 'net_price', :size => 5
%td{:style => highlight_new(unequal_attributes, :price)}= form.text_field 'price', :size => 5
%td{:style => highlight_new(unequal_attributes, :tax)}= form.text_field 'tax', :size => 4
%td{:style => highlight_new(unequal_attributes, :deposit)}= form.text_field 'deposit', :size => 4
%td= select 'article[]', 'article_category_id', ArticleCategory.find(:all).collect {|a| [ a.name, a.id ] }, { :include_blank => true }

View file

@ -3,8 +3,8 @@
%td= @article.order_number
%td= @article.units_to_order
%td= @article.unit_quantity.to_s + ' * ' + @article.unit.to_s
%td= number_to_currency(@article.net_price)
%td= number_to_currency(@article.gross_price)
%td= number_to_currency(@article.price)
%td= number_to_currency(@article.fc_price)
%td= @article.tax
%td= @article.deposit
%td

View file

@ -19,7 +19,7 @@
%td= @form.text_field 'units_to_order', :size => 5
%td= @form.text_field 'unit_quantity', :size => 3
%td= @form.text_field 'unit', :size => 5
%td= @form.text_field 'net_price', :size => 3
%td= @form.text_field 'price', :size => 3
%td= @form.text_field 'tax', :size => 3
%td= @form.text_field 'deposit', :size => 3
= @form.hidden_field "order_id"

View file

@ -6,12 +6,12 @@
%table{:style=> "margin-bottom:1em; width:40em;"}[article]
%thead
%tr
%th{:colspan => "3"}= article.name + " (" + article.unit + " | " + article.unit_quantity.to_s + " | " + article.gross_price.to_s + ")"
%th{:colspan => "3"}= article.name + " (" + article.unit + " | " + article.unit_quantity.to_s + " | " + article.fc_price.to_s + ")"
%tbody
- for result in article.group_order_article_results
%tr{ :class => cycle('even', 'odd', :name => 'group')}
%td{:style=>"width:70%"}= result.group_order_result.group_name
%td= result.quantity
%td= article.gross_price * result.quantity
%td= article.fc_price * result.quantity
- reset_cycle("group")

View file

@ -1,7 +1,7 @@
%td
%td{:style=>"width:50%"}= @result.group_order_result.group_name
%td{:id => "group_order_article_result_#{@result.id}_quantity"}= @result.quantity
%td{:class => "currency"}= number_to_currency(@result.order_article_result.gross_price * @result.quantity)
%td{:class => "currency"}= number_to_currency(@result.order_article_result.fc_price * @result.quantity)
%td{:style=>"width:1em", :class => "actions"}
= link_to_remote image_tag('b_edit.png', :size => "16x16", :border => 0, :alt => 'Menge ändern'), |
:url => {:action => 'updateGroupResult', :id => @result}, |

View file

@ -11,7 +11,7 @@
%tbody
- total = 0
- for result in groupOrderResult.group_order_article_results
- price = result.order_article_result.gross_price
- price = result.order_article_result.fc_price
- quantity = result.quantity
- subTotal = price * quantity
- total += subTotal

View file

@ -18,7 +18,7 @@
%tr
%td
%abbr{:title => "gelieferten Artikel x Nettopreis"} Nettobetrag:
%td= number_to_currency(@order.sumPrice("clear"))
%td= number_to_currency(@order.sum(:clear))
%td
Rechnungsbetrag
%small (incl. Pfand/Gutschriften)
@ -26,7 +26,7 @@
%tr
%td
%abbr{:title => "Nettobetrag mit Pfand und MwSt."} Bruttobetrag:
%td= number_to_currency(@order.sumPrice("gross"))
%td= number_to_currency(@order.sum(:gross))
%td
%span - extra Pfand
%small (Kistenpfand etc.)
@ -34,7 +34,7 @@
%tr
%td
%abbr{:title => "Bruttobetrag mit Foodcoop Aufschlag"} FC Summe:
%td= number_to_currency(@order.sumPrice("fc"))
%td= number_to_currency(@order.sum(:fc))
%td{:style => "border-bottom: 1px solid grey"}
+ Pfandgutschriften
%td{:style => "border-bottom: 1px solid grey"}
@ -42,7 +42,7 @@
%tr
%td
%abbr{:title => "Zugeteilte Mengen x Bruttopreise (inkl. Aufschlag)"} Gruppenbeträge:
%td#groups_amount= number_to_currency(@order.sumPrice("groups"))
%td#groups_amount= number_to_currency(@order.sum(:groups))
%td
Summe
%small (Rechungsbetrag ohne Pfand)
@ -51,10 +51,10 @@
%td{:colspan => "4"}
%abbr{:title => "Gruppenbeträge ohne Aufschlag minus Rechnung ohne Pfand. |
Im Idealfall sollte hier 0.00 stehen."} Differenz ohne Aufschlag: |
%span#fcProfit= number_to_currency(@order.fcProfit(false))
%span#profit= number_to_currency(@order.profit(false))
%tr
%td{:colspan => "4"}
%b
%abbr{:title => "= Gruppenbeträge - Rechnung ohne Pfand"} Differenz mit Aufschlag
= "(#{number_to_percentage(APP_CONFIG[:price_markup])}):"
%span#fcProfit= number_to_currency(@order.fcProfit)
%span#profit= number_to_currency(@order.profit)

View file

@ -55,9 +55,9 @@
%tbody
- @orders.each do |order|
%tr{:class => cycle("even","odd", :name => "order")}
%td= order.name
%td= order.supplier.name
%td= format_date(order.ends)
%td{:class => "currency"}= number_to_currency(order.sumPrice("fc"))
%td{:class => "currency"}= number_to_currency(order.sum(:fc))
%td= link_to "abrechnen", :action => "editOrder", :id => order
- else
Super, alles schon abgerechnet...

View file

@ -23,13 +23,13 @@
%tbody
- @orders.each do |order|
%tr{:class => cycle("even","odd", :name => "order")}
%td= link_to truncate(order.name), :action => "new", :id => order
%td= link_to truncate(order.supplier.name), :action => "new", :id => order
%td=h order.supplier ? order.supplier.name : _('nonexistent')
%td=h format_time(order.ends) unless order.ends.nil?
%td= order.booked ? "abgerechnet (#{number_to_currency order.fcProfit})" : "beendet"
%td= order.closed? ? "abgerechnet (#{number_to_currency order.profit})" : "beendet"
%td= order.updated_by.nil? ? '??' : order.updated_by.nick
%td
- unless order.booked
- unless order.closed?
= link_to "abrechnen", :action => "new", :id => order
|
= link_to 'auf "gebucht" setzen', {:action => 'setAllBooked', :id => order}, :confirm => 'Wirklich alle Gruppenbestellungen für diese Bestellung auf "gebucht" setzen?', :method => "post"

View file

@ -1,12 +1,12 @@
%h1 Bestellung abrechnen
- if @order.booked
- if @order.closed?
%p
%b Achtung, Bestellung wurde schon abgerechnet!
.left_column{:style => 'width: 50em'}
.box_title
%h2
= @order.name + " | " + format_date(@order.starts) + ' --> ' + format_date(@order.ends)
= @order.supplier.name + " | " + format_date(@order.starts) + ' --> ' + format_date(@order.ends)
.column_content#summary
#order_summary
= render :partial => "summary"
@ -15,7 +15,7 @@
%h2 Aktionen
.column_content
%ul
- unless @order.booked
- unless @order.closed?
%li= link_to "Bestellung abschließen", :action => "confirm", :id => @order
.right_column{:style => 'clear:both;width: 28%'}

View file

@ -27,7 +27,7 @@
= _("There are") + " #{@unassigned_tasks_number} " + link_to(_("unassigned task(s)"), :controller => "tasks")
%p{:style => "clear:both"}= link_to _("My tasks"), :controller => "tasks", :action => "myTasks"
- if @orderGroup
- if @ordergroup
// Current orders
= render :partial => 'ordering/currentOrders'
@ -42,13 +42,13 @@
%h2=_ "My ordergroup"
.column_content
%p
%b= @orderGroup.name
%b= @ordergroup.name
|
=_ "Account balance:"
= number_to_currency(@orderGroup.account_balance)
= number_to_currency(@ordergroup.account_balance)
%span{:style => "color:grey"}
(zuletzt aktualisiert vor
= distance_of_time_in_words(Time.now, @orderGroup.account_updated) + ")"
= distance_of_time_in_words(Time.now, @ordergroup.account_updated) + ")"
%h3=_ "Last transactions"
%table
%tr

View file

@ -1,13 +1,13 @@
Liebe <%= group.name %>,
die Bestellung "<%= order.name %>" wurde am <%= order.ends.strftime('%d.%m.%Y um %H:%M') %> von <%= order.updated_by.nick %> beendet.
die Bestellung für "<%= order.supplier.name %>" wurde am <%= order.ends.strftime('%d.%m.%Y um %H:%M') %> von <%= order.updated_by.nick %> beendet.
Für Euch wurden die folgenden Artikel bestellt:
<% for result in results
article = result.order_article_result -%>
<%= article.name %>: <%= result.quantity %> x <%= article.unit %> = <%= result.quantity * article.gross_price %>
<% for group_order_article in group_order.group_order_articles.all(:include => :order_article)
article = group_order_article.order_article.article -%>
<%= article.name %>: <%= group_order_article.quantity %> x <%= article.unit %> = <%= group_order_article.quantity * article.fc_price %>
<% end -%>
Gesamtpreis: <%= total %>
Gesamtpreis: <%= group_order.price %>
Bestellung online einsehen: <%= ApplicationController.current.url_for(:controller => 'ordering', :action => 'my_order_result', :id => order.id) %>

View file

@ -1,31 +0,0 @@
- if controller.action_name == 'myOrders'
= pagination_links_remote @bookedOrders, :per_page => 10, :params => {:show_all => params[:show_all]}
%table.list
%thead
%tr
%th=_ 'Name'
%th=_ 'Supplier'
%th=_ 'End'
%th=_ 'Sum'
%tbody
- @bookedOrders.each do |order|
- if order.is_a?(GroupOrder) || order.is_a?(GroupOrderResult)
%tr{:class=> cycle('even', 'odd', :name => 'bookedOrders')}
%td= link_to order.order.name, :action => 'my_order_result', :id => order.order
%td=h order.order.supplier ? order.order.supplier.name : _("nonexistent")
%td= format_time(order.order.ends)
%td{:class => "currency"}= number_to_currency(order.price)
- else
// check if the Ordergroup has ordered
- if groupOrder = order.group_order(@orderGroup)
%tr{:class=> cycle('even', 'odd', :name => 'bookedOrders')}
%td= link_to order.name, :action => 'my_order_result', :id => order
%td=h order.supplier ? order.supplier.name : _("nonexistent")
%td= format_time(order.ends)
%td{:class => "currency"}= number_to_currency(groupOrder.price)
- else
%tr{:class=> cycle('even', 'odd', :name => 'bookedOrders'), :style => "color:grey"}
%td= link_to truncate(order.name), {:action => "my_order_result", :id => order}, :style => "color:grey"
%td= order.supplier ? order.supplier.name : _("nonexistent")
%td= format_time(order.ends)
%td{:class => "currency"} --

View file

@ -1,32 +0,0 @@
.box_title
%h2=_ "Running orders"
.column_content
- unless @currentOrders.empty?
%table.list
%thead
%tr
%th=_ "Name"
%th=_ "Supplier"
%th=_ "End"
%th=_ "Who ordered?"
%th=_ "Sum"
%tbody
- total = 0
- @currentOrders.each do |order|
%tr{:class => cycle('even', 'odd', :name => 'current_orders')}
%td= link_to order.name, :controller => 'ordering', :action => 'order', :id => order
%td=h order.supplier.name
%td=h format_time(order.ends) unless order.ends.nil?
- if (groupOrder = order.group_orders.find(:first, :conditions => ["ordergroup_id = ?", @orderGroup.id]))
- total += groupOrder.price
%td=h groupOrder.updated_by.nil? ? '??' : "#{groupOrder.updated_by.nick} (#{format_time(groupOrder.updated_on)})"
%td= number_to_currency(groupOrder.price)
- else
%td
%td
- if total > 0
%p
=_ "Total sum"
%b= number_to_currency(total)
- else
%i=_ "There aren't current orders at the moment."

View file

@ -1,30 +0,0 @@
%table.list
%thead
%tr
%th=_ 'Name'
%th=_ 'Supplier'
%th=_ 'End'
%th=_ 'Sum'
%tbody
- @finishedOrders.each do |order|
- if order.is_a?(GroupOrder) or order.is_a?(GroupOrderResult)
%tr{:class=> cycle('even', 'odd', :name => 'bookedOrders')}
%td= link_to order.order.name, :action => 'my_order_result', :id => order.order
%td=h order.order.supplier ? order.order.supplier.name : _("nonexistent")
%td= format_time(order.order.ends)
%td{:class => "currency"}= number_to_currency(order.price)
- else
// check if the Ordergroup has ordered
- if groupOrder = order.group_order(@orderGroup)
%tr{:class=> cycle('even', 'odd', :name => 'finishedOrders')}
%td= link_to order.name, :action => 'my_order_result', :id => order
%td=h order.supplier ? order.supplier.name : _("nonexistent")
%td= format_time(order.ends)
%td{:class => "currency"}= number_to_currency(groupOrder.price)
- else
%tr{:class=> cycle('even', 'odd', :name => 'finishedOrders'), :style => "color:grey"}
%td= link_to truncate(order.name), {:action => "my_order_result", :id => order}, :style => "color:grey"
%td= order.supplier ? order.supplier.name : _("nonexistent")
%td= format_time(order.ends)
%td{:class => "currency"} --

View file

@ -1,33 +0,0 @@
%table.list
%thead
%tr
%th{:style => "width:40%"}=_ "Name"
%th=_ "Unit quantity"
%th=_ "Unit price"
%th=_ "Received"
%th=_ "Total price"
%tbody
- for article in @groupOrderResult.group_order_article_results
- price = article.order_article_result.gross_price
- quantity = article.quantity
%tr{:class => cycle('even', 'odd', :name => 'articles')}
%td{:style=>"width:40%"}
=h article.order_article_result.name
- unless article.order_article_result.note.nil?
= image_tag "lamp_grey.png", {:alt => "Notiz anzeigen", :size => "15x16", :border => "0", :onmouseover => "$('note_#{article.id}').show();", :onmouseout => "$('note_#{article.id}').hide();" }
%td
= article.order_article_result.unit_quantity
x
= article.order_article_result.unit
%td= number_to_currency(price)
%td= quantity
%td= number_to_currency(quantity * price)
- unless article.order_article_result.note.nil?
%tr{:id => "note_#{article.id}", :style => "display:none"}
%td{:colspan => "5"}
Notiz:
=h article.order_article_result.note
%tr{:class => cycle('even', 'odd', :name => 'articles')}
%th{:colspan => "4"}=_ "Sum"
%th= number_to_currency(@groupOrderResult.price)

View file

@ -0,0 +1,30 @@
.box_title
%h2 Laufende Bestellungen
.column_content
- unless Order.open.empty?
%table.list
%thead
%tr
%th Lieferant
%th Ende
%th Wer hat bestellt?
%th Summe
%tbody
- total = 0
- Order.open.each do |order|
%tr{:class => cycle('even', 'odd', :name => 'open_orders')}
%td= link_to h(order.supplier.name), :controller => 'ordering', :action => 'order', :id => order
%td=h format_time(order.ends) unless order.ends.nil?
- if group_order = order.group_order(@ordergroup)
- total += group_order.price
%td=h "#{group_order.updated_by.nick} (#{format_time(group_order.updated_on)})"
%td= number_to_currency(group_order.price)
- else
%td
%td
- if total > 0
%p
Gesamtsumme:
%b= number_to_currency(total)
- else
%i Derzeit gibt es keine laufenden Bestellungen

View file

@ -0,0 +1,17 @@
- if controller.action_name == 'myOrders'
= pagination_links_remote @closed_orders, :per_page => 10, :update => 'closed_orders'
%table.list
%thead
%tr
%th Lieferant
%th Ende
%th Summe
%tbody
- for order in orders
- group_order = order.group_order(@ordergroup) # Get GroupOrder if possible
- order_class = group_order ? "" : "color:grey"
%tr{:class=> cycle('even', 'odd', :name => 'orders'), :style => order_class}
%td= link_to order.supplier.name, :action => 'my_order_result', :id => order
%td= format_time(order.ends)
%td{:class => "currency"}= group_order ? number_to_currency(group_order.price) : "--"

View file

@ -1,54 +0,0 @@
%table.list
%thead
%tr
%th{:style => "width:40%"} Name
%th Gebinde
%th Einzelpreis
%th
%abbr{:title => "Menge + Toleranz"} Bestellt
%th
%abbr{:title => "Unter Berücksichtigung der anderen Gruppen"} Zugeteilt
%th Gesamtpreis
%tbody
- total = 0 #set counter for order-sum
- for category, order_articles in @order.get_articles
%tr{:style => "background-color:#EFEFEF"}
%td{:style => "text-align:left;"}=h category
%td{:colspan => "9"}
- for order_article in order_articles
- article = order_article.article
- # get the order-results for the ordergroup
- group_order_article = GroupOrderArticle.find_by_group_order_id_and_order_article_id @group_order.id, order_article.id
- if group_order_article
- quantity = group_order_article.quantity
- tolerance = group_order_article.tolerance
- result = group_order_article.orderResult[:quantity] + group_order_article.orderResult[:tolerance]
- sub_total = article.gross_price * (quantity + tolerance)
- else
- quantity, tolerance, result, sub_total = 0, 0, 0, 0
- total += sub_total
- # give the article different colors, dependent on order-result
- style = "grey"
- if (quantity > 0)
- style = result > 0 ? 'green' : 'red'
%tr{:class => cycle('even', 'odd', :name => 'articles'), :style => "color:#{style}"}
%td{:style => "width:40%"}
=h order_article.article.name
- unless order_article.article.note.empty?
= image_tag("lamp_grey.png", {:alt => "Notiz anzeigen", :size => "15x16", :border => "0", :onmouseover => "$('note_#{order_article.id}').show();", :onmouseout => "$('note_#{order_article.id}').hide();"})
%td= "#{article.unit_quantity} x #{order_article.article.unit}"
%td= number_to_currency(article.gross_price)
%td
= quantity
= "+ #{tolerance}" if article.unit_quantity > 1
%td= result > 0 ? result : "0"
%td= number_to_currency(sub_total)
- unless order_article.article.note.empty?
%tr{:id => "note_#{order_article.id}", :class => "note even", :style => "display:none"}
%td{:colspan => "6"}=h order_article.article.note
%tr{:class => cycle('even', 'odd', :name => 'articles')}
%th{:colspan => "5"} Summe
%th= number_to_currency(total)

View file

@ -1,45 +1,44 @@
%h1= _('Order Overview')
- title "Bestellüberblick"
// Ordergroups Account Balance
.left_column{:style => "width:26%"}
.box_title
%h2=h @orderGroup.name
%h2=h @ordergroup.name
.column_content
%table
%tr
%td= _('Account balance')
%td{:class => "currency", :style => "width:5em"}= number_to_currency(@orderGroup.account_balance)
%td Kontostand:
%td{:class => "currency", :style => "width:5em"}= number_to_currency(@ordergroup.account_balance)
%tr
%td= "- " + _('Current orders')
%td{:class => "currency"}= number_to_currency(@currentOrdersValue)
%td - laufende Bestellungen:
%td{:class => "currency"}= number_to_currency(@ordergroup.value_of_open_orders)
%tr
%td= "- " +_('Unrecorded orders')
%td{:class => "currency"}= number_to_currency(@nonbookedOrdersValue)
%td - nicht abgerechnete Bestellungen:
%td{:class => "currency"}= number_to_currency(@ordergroup.value_of_finished_orders)
%tr
%th= _('Available')
%th{:class => "currency"}= number_to_currency(@orderGroup.account_balance - @currentOrdersValue - @nonbookedOrdersValue)
%th verfügbares Guthaben:
%th{:class => "currency"}= number_to_currency(@ordergroup.get_available_funds)
.right_column{:style => "width:70%"}
// Current Orders
- if @orderGroup
= render :partial => "currentOrders"
// open orders
= render :partial => "open_orders"
// finished, nonbooked Orders
- unless @finishedOrders.empty?
// finished orders
- unless Order.finished.empty?
.box_title
%h2= _('unrecorded orders')
%h2 Nicht abgerechnete Bestellungen
.column_content
= render :partial => "finishedOrders"
- if @nonbookedOrdersValue > 0
= render :partial => "orders", :locals => {:orders => Order.finished}
- if @ordergroup.value_of_finished_orders > 0
%p
= _('total order value')
%b= number_to_currency(@nonbookedOrdersValue)
Gesamtsumme:
%b= number_to_currency(@ordergroup.value_of_finished_orders)
// bookedOrders
- unless @bookedOrders.empty?
// closed orders
- unless Order.closed.empty?
.box_title
%h2= _('balanced orders')
%h2 Abgerechnete Bestellungen
.column_content
= render :partial => "bookedOrders"
= render :partial => "orders", :locals => {:orders => Order.closed.all(:limit => 5)}
%br/
= link_to _('more...'), :action => "myOrders"
= link_to "mehr...", :action => "myOrders"

View file

@ -1,27 +1,17 @@
%h1
=_ "Orders of"
= @orderGroup.name
- title "Bestellungen der #{@ordergroup.name}"
%p
%i
=_ "See current orders in"
= link_to _("Overview"), :action => "index"
%p
%i{:style => "float:left"}=_ "Also show orders, your ordergroup haven't participated:"
- form_tag({:action => "myOrders"}, :method => "get") do
-unless @show_all
%input{:type => "checkbox", :name => :show_all, :value => "1", :onclick => "submit();"}
-else
%input{:type => "checkbox", :name => :show_all, :value => "0", :checked => "checked", :onclick => "submit();"}
Siehe hier alle
= link_to "laufenden Bestellungen.", :action => "index"
.single_column{:style => "width:50em"}
.box_title
%h2=_ "finished/not balanced"
%h2 beendet/nicht abgerechnet
.column_content
= render :partial => "finishedOrders"
= render :partial => "orders", :locals => {:orders => Order.finished}
.single_column{:style => "width:50em"}
.box_title
%h2=_ "balanced"
%h2 abgerechnet
.column_content
#bookedOrders
= render :partial => "bookedOrders"
#closed_orders
= render :partial => "orders", :locals => {:orders => @closed_orders}

View file

@ -1,86 +1,126 @@
%h1= _("Your result for") + " #{@order.name}"
- title "Dein Bestellergebnis für #{@order.supplier.name}"
#element_navigation
= link_to_unless @order.previous == @order, _("Previous order"), :action => "my_order_result", :id => @order.previous
= link_to_unless @order.previous == @order, "<< #{@order.previous.supplier.name}", :action => "my_order_result", :id => @order.previous
|
= link_to _("Overview"), :controller => 'ordering'
|
= link_to_unless @order.next == @order, _("Next order"), :action => "my_order_result", :id => @order.next
= link_to_unless @order.next == @order, "#{@order.next.supplier.name} >>", :action => "my_order_result", :id => @order.next
// Order summary
.left_column{:style => "width:45em"}
.box_title
%h2=_ "Summary"
%h2 Zusammenfassung
.column_content
%table
%tr{:valign => "top"}
%td{:style => "width:50%"}
%p
= _("Name") + ":"
%b=h @order.name
|
= _("Supplier") + ":"
%b=h @order.supplier ? @order.supplier.name : _("nonexistent")
Lieferant:
%b=h @order.supplier.name
- unless @order.note.empty?
%p
= _("Note") + ":"
Notiz:
=h @order.note
%p
= _("End") + ":"
Ende:
%b=h format_time(@order.ends)
%p
= _("Order value") + ":"
- if @order_value
%b=h number_to_currency(@order_value)
Bestellsumme:
- if @group_order
%b=h number_to_currency(@group_order.price)
- else
%b --
%b Du hast nicht bestellt.
%p
- if @finished
= @order.booked ? _("Cleared by") + " #{@order.updated_by.nick}" : "<b>" + _("Order isn't balanced yet") + "</b>"
= link_to _("read/add comments"), "#comments"
= "Abgerechnet von #{@order.updated_by.nick}" if @order.finished?
= "<b>Bestellung</b>" if @order.closed?
= link_to "Kommentare lesen/schreiben", "#comments"
// directly switch to active orders
.right_column{:style => "width:23em;"}
.box_title
%h2= _("Running orders")
%h2 Laufende Bestellungen
.column_content
%table
- @current_orders.each do |order|
- for order in Order.open
%tr
%td= link_to order.name, :action => 'order', :id => order
%td= "("+ time_ago_in_words(order.ends) + ")" if @order.ends
%td= link_to order.supplier.name, :action => 'order', :id => order
%td= "("+ time_ago_in_words(order.ends) + ")" if order.ends
// Article box
// Article box
.single_column{:style => "clear:both; width:70em;"}
.box_title
%h2=_ "Overview of articles"
%h2 Artikelübersicht
.column_content#result
- if @finished
// order is finished, show results ...
- unless @groupOrderResult.nil?
= render :partial => "finished_order_result"
- else
=_ "You haven't ordered"
- if @group_order
%p= link_to("Bestellung ändern", :action => "order", :id => @order) if @order.open?
%table.list
%thead
%tr
%th{:style => "width:40%"} Name
%th Gebinde
%th Einzelpreis
%th
%abbr{:title => "Menge + Toleranz"} Bestellt
%th
%abbr{:title => "Unter Berücksichtigung der anderen Gruppen"} Zugeteilt
%th Gesamtpreis
%tbody
- total = 0 #set counter for order-sum
- for category_name, order_articles in @order.get_articles
%tr{:style => "background-color:#EFEFEF"}
%td{:style => "text-align:left;"}=h category_name
%td{:colspan => "9"}
- for oa in order_articles
- # get the order-results for the ordergroup
- goa = oa.group_order_articles.first :conditions => {:group_order_id => @group_order.id}
- if goa
- quantity = goa.quantity
- tolerance = goa.tolerance
- result = goa.orderResult[:quantity] + goa.orderResult[:tolerance]
- sub_total = oa.price.fc_price * (quantity + tolerance)
- else
- quantity, tolerance, result, sub_total = 0, 0, 0, 0
- total += sub_total
- # give the article different colors, dependent on order-result
- style = "grey"
- if (quantity > 0)
- style = result > 0 ? 'green' : 'red'
%tr{:class => cycle('even', 'odd', :name => 'articles'), :style => "color:#{style}"}
%td{:style => "width:40%"}
=h oa.article.name
- unless oa.article.note.empty?
= 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)
%td
= quantity
= "+ #{tolerance}" if oa.price.unit_quantity > 1
%td= result > 0 ? result : "0"
%td= number_to_currency(sub_total)
- unless oa.article.note.empty?
%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')}
%th{:colspan => "5"} Summe
%th= number_to_currency(total)
%br/
= link_to_top
- else
// order isn't finished yet, show ordered articles
- if @group_order
%p= link_to("Bestellung ändern", :action => "order", :id => @order) if @order.current?
= render :partial => 'unfinished_order_result'
%br/
= link_to_top
- else
= _("You haven't ordered yet.")
= link_to _("Order now"), :action => "order", :id => @order
Du hast noch nicht bestellt.
= link_to "Das ist Deine Chance!", :action => "order", :id => @order
// Comments box
- if @finished
.single_column{:style => "width:70em;"}
.box_title
%h2=_ "Comments"
.column_content#comments
= render :partial => 'shared/comments'
.single_column{:style => "width:70em;"}
.box_title
%h2=_ "Comments"
.column_content#comments
= render :partial => 'shared/comments', :locals => { :comments => @order.comments }
%p
- form_for :comment, :url => { :action => :add_comment, :id => @order } do |form|
%p
= link_to_remote _("New comment"), :url => {:action => 'newComment', :id => @order}, |
:before => "Element.show('loader')", |
:success => "Element.hide('loader')" |
#newComment
= link_to_top
%b Neuen Kommentar hinzufügen:
%br/
= form.text_area :text, :cols => 50, :rows => 6
%br/
= submit_tag "Kommentar hinzufügen"
= link_to_top

View file

@ -1,7 +1,7 @@
<h1>Bestellen</h1>
<div class="left_column" style="width:49em">
<div class="box_title"><h2><%=h @order.name %></h2></div>
<div class="box_title"><h2><%=h @order.supplier.name %></h2></div>
<div class="column_content">
<table>
<tr valign="top">
@ -28,7 +28,7 @@
<% end %>
<p>
<b><%=_ "Order quanitity so far" %>:</b>
<%= number_to_currency @order.sumPrice %>
<%= number_to_currency @order.sum %>
</p>
</td>
</tr>
@ -46,7 +46,7 @@
<% for order in @other_orders -%>
<tr>
<td>
<%= link_to_function order.name, "if (confirmSwitchOrder()) (window.location = '#{ url_for(:action => 'order', :id => order) }' )" %>
<%= link_to_function order.supplier.name, "if (confirmSwitchOrder()) (window.location = '#{ url_for(:action => 'order', :id => order) }' )" %>
</td>
<td>noch <%= time_ago_in_words(order.ends) if order.ends -%></td>
</tr>
@ -125,7 +125,7 @@
<%= button_to_function('-', "decreaseTolerance(#{i})") %>
<% end -%>
</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> <%= L18n.number.currency.format.unit %></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? -%>
<tr id="note_<%= i %>" class="note" style="display:none">
@ -139,7 +139,7 @@
<tfoot>
<tr>
<td colspan="6"></td>
<td colspan="3" class="currency"><%=_ "Total amount" %>: <span id="total_price"><%= total %></span> <%= L18n.number.currency.format.unit %></td>
<td colspan="3" class="currency"><%=_ "Total amount" %>: <span id="total_price"><%= total %></span> </td>
</tr>
<tr>
<td colspan="6"></td>
@ -147,7 +147,7 @@
</tr>
<tr>
<td colspan="6"></td>
<td colspan="3" class="currency"><%=_ "New account balance"%>: <strong><span id="new_balance"><%= @ordergroup.account_balance - total %></span> <%= L18n.number.currency.format.unit %></strong></td>
<td colspan="3" class="currency"><%=_ "New account balance"%>: <strong><span id="new_balance"><%= @ordergroup.account_balance - total %></span> </strong></td>
</tr>
<tr>
<td style="text-align:left;"><%= link_to_top %></td>
@ -171,7 +171,7 @@
setGroupBalance(<%= @availableFunds %>);
// localization
setDecimalSeparator("<%= L18n.number.currency.format.separator %>");
setDecimalSeparator(",");
// initialize javascript
updateBalance();

View file

@ -0,0 +1,31 @@
%table
%tr
%th Name
%th Gebinde
%th Netto/FC-Preis
%th Bestellte Einheiten
%th Volle Gebinde
- total_net, total_gross, counter = 0, 0, 0
- order.get_articles.each do |category_name, order_articles|
%tr{:style => "background-color:#EFEFEF"}
%td{:style => "text-align:left; color: grey;"}=h category_name
%td{:colspan => "9"}
- order_articles.each do |order_article|
- net_price = order_article.price.price
- fc_price = order_article.price.fc_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
%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= "#{order_article.quantity} + #{order_article.tolerance}" if unit_quantity > 1
%td= units
%p
Summe (Netto/FC-Preise):
= "#{number_to_currency(total_net)} / #{number_to_currency(total_gross)}"
%p
Bestellte Artikel.
= order.order_articles.ordered.count

View file

@ -0,0 +1,23 @@
.legend
%table.legend{:style => "margin-bottom:1em"}
%tr
%th{:colspan => '3'} Legende
%tr
%th{:style => 'width:70%'} Bestellgruppe
%th Menge
%th Gesamtpreis
- for order_article in order.order_articles.all(:include => [:article, :article_price])
%table{:style => "margin-bottom:1em"}
%thead
%tr
%th{:colspan => "3"}
= order_article.article.name
= "(#{order_article.article.unit} | #{order_article.price.unit_quantity} | #{number_to_currency(order_article.price.fc_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= number_to_currency(order_article.price.fc_price * goa.quantity)
- reset_cycle('groups')

View file

@ -0,0 +1,36 @@
.legend
%table.legend{:style => "margin-bottom:1em"}
%tr
%th{:style => "width:40%"} Name
%th
%acronym{:title => "zugeteilte Einheiten (davon aus Toleranzmenge)"} Menge
%th
%acronym{:title => "Preis incl. MwSt, Pfand und Foodcoop-Aufschlag"} FC-Preis
%th
%acronym{:title => "Gebindegröße"} GebGr
%th Einheit
%th Gesamtpreis
- for group_order in order.group_orders.all
%table{:style => "margin-bottom:1em"}
%thead
%tr
%th{:colspan => "6"}=h group_order.ordergroup.name
%tbody
- total = 0
- for goa in group_order.group_order_articles.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= number_to_currency(fc_price)
%td= goa.order_article.price.unit_quantity
%td= goa.order_article.article.unit
%td= number_to_currency(subTotal)
%tr{:class => cycle('even', 'odd', :name => 'articles')}
%th{:colspan => "5"} Summe
%th= number_to_currency(total)
- reset_cycle("articles")

View file

@ -1,31 +1,28 @@
= error_messages_for 'order'
= form.error_messages
.single_column
.box_title
%h2=_ "Order"
%h2 Bestellung
.column_content
= hidden_field 'order', 'supplier_id'
= form.hidden_field :supplier_id
%p
=h _("Supplier") + ": #{@order.supplier.name}"
Lieferant:
= @order.supplier.name
%p
%label{:for => 'order_name'}=_ "Name"
Notiz
%br/
= text_field 'order', 'name'
= form.text_area :note, :cols => 50, :rows => 5
%p
%label{:for => 'order_note'}=_ "Note"
Start
%br/
= text_area 'order', 'note', :cols => 50, :rows => 5
= form.datetime_select :starts, :start_year => Time.now.year - 1
%p
%label{:for => 'order_starts'}=_ "Start"
Ende
%br/
= datetime_select 'order', 'starts', :start_year => Time.now.year - 1
%p
%label{:for => 'order_ends'}=_ "End"
%br/
= datetime_select 'order', 'ends', :start_year => Time.now.year - 1, :include_blank => true
= form.datetime_select :ends, :start_year => Time.now.year - 1, :include_blank => true
.box_title
%h2=_ "Articles"
%h2 Artikel
.column_content
- if (@template_orders && !@template_orders.empty?)
%p
@ -34,7 +31,7 @@
%option{:value => "-1", :selected => "selected"}=_ "Choose an order..."
- i = -1
- for order in @template_orders
%option{:value => (i += 1)}=h order.name
%option{:value => (i += 1)}=h order.supplier.name
%table.list
%tr
%th= check_box_tag 'checkall', "1", false, { :onclick => "checkUncheckAll(this)" }
@ -52,14 +49,15 @@
- for article in articles
/ check if the article is selected
- included = @order.order_articles.detect { |order_article| order_article.article_id == article.id }
%tr{:class => cycle('even', 'odd') + (included ? ' selected' : ''), :id => article.id.to_s, :onclick => "checkRow('#{article.id}')"}
%td= check_box_tag "order[article_ids][]", article.id.to_s, included, { :id => "checkbox_#{article.id}", :onclick => "checkRow('#{article.id}')" }
- included_class = included ? ' selected' : ''
%tr{:class => cycle('even', 'odd') + ' click-me' + included_class, :id => article.id.to_s, :onclick => "checkRow('#{article.id}')"}
%td= check_box_tag "order[article_ids][]", article.id, included, { :id => "checkbox_#{article.id}", :onclick => "checkRow('#{article.id}')" }
%td=h article.name
%td=h truncate article.note, 25
%td=h truncate article.origin, 15
%td=h truncate article.manufacturer, 15
%td=h truncate article.note, :length => 25
%td=h truncate article.origin, :length => 15
%td=h truncate article.manufacturer, :length => 15
%td= "#{article.unit_quantity} x #{article.unit}"
%td= "#{number_to_currency(article.net_price)} / #{number_to_currency(article.gross_price)}"
%td= "#{number_to_currency(article.price)} / #{number_to_currency(article.fc_price)}"
%tr
%td{:colspan => "6"}
= check_box_tag 'checkall', "1", false, { :onclick => "checkUncheckAll(this)" }

View file

@ -1,22 +0,0 @@
= pagination_links_remote @orders, :params => {:sort => params[:sort]}
%table.list{:style => "width: 100%"}
%thead
%tr
%th=_ "Name"
%th[sort_td_class_helper "supplier"]
= sort_link_helper _("Supplier"), "supplier"
%th=_ "Start"
%th[sort_td_class_helper "ends"]
= sort_link_helper _("End"), "ends"
%th=_ "Status"
%th{:colspan => "2"}
%tbody
- @orders.each do |order|
%tr{:class => cycle('even', 'odd', :name => 'orders') + ((!order.finished? and order.ends < Time.now) ? " active" : "")}
%td= link_to order.name, :action => "show", :id => order
%td=h order.supplier ? order.supplier.name : _("nonexistent")
%td=h format_time(order.starts)
%td=h format_time(order.ends)
%td= order.status == _("expired") ? link_to( _("finish now") + (" !!"), {:action => 'finish', :id => order}, :confirm => _("Are you really sure to finish the order?"), :method => "post") : order.status
%td= link_to(image_tag('b_edit.png', :size => "16x16", :border => "0", :alt => _('Edit')), :action => 'edit', :id => order) unless order.finished?
%td= link_to image_tag('b_drop.png', :size => "16x16", :border => "0", :alt => _("Destroy")), { :action => 'destroy', :id => order }, :confirm => _("Are you really sure you want to destroy the order?"), :method => "post"

View file

@ -0,0 +1,19 @@
= pagination_links_remote @orders, :params => {:sort => params[:sort]}
%table.list{:style => "width: 100%"}
%thead
%tr
%th[sort_td_class_helper "supplier"]
= sort_link_helper "Lieferant", "supplier"
%th Start
%th[sort_td_class_helper "ends"]
= sort_link_helper "Ende", "ends"
%th Status
%th{:colspan => "2"}
%tbody
- @orders.each do |order|
%tr{:class => cycle('even', 'odd', :name => 'orders')}
%td=h order.supplier.name
%td=h format_time(order.starts)
%td=h format_time(order.ends)
%td= order.state
%td= link_to "Anzeigen", order

View file

@ -1,30 +0,0 @@
<table class="list">
<thead>
<tr>
<th><acronym title="Bestellnummer">Nr.</acronym></th>
<th><acronym title="Gebinde insgesamt">Menge</acronym></th>
<th>Artikel</th>
<th><acronym title="Gebindegröße">GebGr</acronym></th>
<th>Einheit</th>
<th>Notiz</th>
<th><acronym title="Bruttopreis inkl. MwSt, Aufschlag, Pfand">Preis</acronym></th>
<th>MwSt</th>
<th>Pfand</th>
</tr>
</thead>
<tbody>
<% for article in @order_articles %>
<tr class="<%= cycle('even', 'odd', :name => 'articles') %>">
<td><%=h article.order_number %></td>
<td><%=h article.units_to_order %></td>
<td><%=h article.name %></td>
<td><%=h article.unit_quantity %></td>
<td><%=h article.unit %></td>
<td><%=h article.note %></td>
<td><%= number_to_currency(article.gross_price) %></td>
<td><%=h article.tax %></td>
<td><%=h article.deposit %></td>
</tr>
<% end %>
</tbody>
</table>

View file

@ -1,31 +0,0 @@
<div class="legend">
<table style="margin-bottom:1em" class="legend">
<tr>
<th colspan="3">Legende</th>
</tr>
<tr>
<td style="width:70%">Bestellgruppe</td>
<td>Menge</td>
<td>Gesamtpreis</td>
</tr>
</table>
</div>
<% for article in @order_articles %>
<table style="margin-bottom:1em">
<thead>
<tr>
<th colspan="3"><%= article.name %> (<%= article.unit %> | <%= article.unit_quantity %> | <%= number_to_currency(article.gross_price) %>)</th>
</tr>
</thead>
<tbody>
<% for result in article.group_order_article_results %>
<tr class="<%= cycle('even', 'odd', :name => 'groups') %>">
<td style="width:70%"><%=h result.group_order_result.group_name %></td>
<td><%=h result.quantity %> (<%=h result.tolerance %>)</td>
<td><%= number_to_currency(article.gross_price * result.quantity) %></td>
</tr>
<% end %>
</tbody>
</table>
<%- reset_cycle("groups") -%>
<% end %>

View file

@ -1,45 +0,0 @@
<div class="legend">
<table style="margin-bottom:1em" class="legend">
<tr>
<th style="width:40%">Name</th>
<th><acronym title="zugeteilte Einheiten (davon aus Toleranzmenge)">Menge</acronym></th>
<th><acronym title="Bruttopreis incl. MwSt, Aufschlag, Pfand">Preis</acronym></th>
<th><acronym title="Gebindegröße">GebGr</acronym></th>
<th>Einheit</th>
<th>Gesamtpreis</th>
</tr>
</table>
</div>
<% for groupOrderResult in @order.group_order_results %>
<table style="margin-bottom:1em">
<thead>
<tr>
<th colspan="6"><%=h groupOrderResult.group_name %></th>
</tr>
</thead>
<tbody>
<%
total = 0
for result in groupOrderResult.group_order_article_results
price = result.order_article_result.gross_price
quantity = result.quantity
subTotal = price * quantity
total += subTotal
%>
<tr class="<%= cycle('even', 'odd', :name => 'articles') %>">
<td style="width:40%"><%=h result.order_article_result.name %></td>
<td><%=h quantity %> (<%=h result.tolerance %>)</td>
<td><%= number_to_currency(price) %></td>
<td><%=h result.order_article_result.unit_quantity %></td>
<td><%=h result.order_article_result.unit %></td>
<td><%= number_to_currency(subTotal) %></td>
</tr>
<% end %>
<tr class="<%= cycle('even', 'odd', :name => 'articles') %>">
<th colspan="5">Summe</th>
<th><%= number_to_currency(total) %></th>
</tr>
</tbody>
</table>
<%- reset_cycle("articles") -%>
<% end %>

View file

@ -1,33 +0,0 @@
%table
%tr
%th=_ "Name"
%th=_ "Unit quantity"
%th=_ "Price"
%th=_ "Units ordered"
%th=_ "Result/Unit quantity"
- totalNetto, totalBrutto, counter = 0, 0, 0
- @order_articles.each do |category, order_articles|
%tr{:style => "background-color:#EFEFEF"}
%td{:style => "text-align:left; color: grey;"}=h category
%td{:colspan => "9"}
- order_articles.each do |order_article|
- nettoPrice = order_article.article.net_price
- bruttoPrice = order_article.article.gross_price
- units = order_article.units_to_order
- unitQuantity = order_article.article.unit_quantity
- totalNetto += units * unitQuantity * nettoPrice
- totalBrutto += units * unitQuantity * bruttoPrice
- counter += 1 if units > 0
%tr{:class => cycle('even', 'odd', :name => 'articles'), :style => "color: #{units > 0 ? 'green' : 'red'}"}
%td=h order_article.article.name
%td= "#{unitQuantity} x #{order_article.article.unit}"
%td= "#{number_to_currency(nettoPrice)} / #{number_to_currency(bruttoPrice)}"
%td= "#{order_article.quantity} + #{order_article.tolerance}" if unitQuantity > 1
%td= units
%p
=_ "Total value"
=_ "(net/gross)"
= "#{number_to_currency(totalNetto)} / #{number_to_currency(totalBrutto)}"
%p
=_ "Ordered articles:"
= counter

View file

@ -1,7 +1,5 @@
# Get ActiveRecord objects
order_articles = @order.order_article_results
end_date = @order.ends.strftime('%d.%m.%Y')
title = "#{@order.name} | beendet am #{end_date}"
title = "#{@order.supplier.name} | beendet am #{end_date}"
# Define header and footer
pdf.header [pdf.margin_box.left,pdf.margin_box.top+30] do
@ -14,15 +12,16 @@ end
# Start rendering
for article in order_articles
pdf.text "#{article.name} (#{article.unit} | #{article.unit_quantity.to_s} | #{number_to_currency(article.gross_price)})",
for order_article in @order.order_articles.ordered
pdf.text "#{order_article.article.name} (#{order_article.article.unit} |\
#{order_article.price.unit_quantity.to_s} | #{number_to_currency(order_article.price.fc_price)})",
:style => :bold, :size => 10
pdf.move_down 5
data = []
for result in article.group_order_article_results
data << [result.group_order_result.group_name,
result.quantity,
article.gross_price * result.quantity]
for goa in order_article.group_order_articles
data << [goa.group_order.ordergroup.name,
goa.quantity,
number_with_precision(order_article.price.fc_price * goa.quantity)]
end
pdf.table data,
@ -31,6 +30,7 @@ for article in order_articles
:widths => { 0 => 200, 1 => 40, 2 => 40 },
:border_style => :grid,
:row_colors => ['ffffff','ececec'],
:vertical_padding => 3
:vertical_padding => 3,
:align => { 2 => :right }
pdf.move_down 10
end

View file

@ -1,7 +1,7 @@
- title _("Edit order")
- form_tag :action => 'update', :id => @order do
= render :partial => 'form'
- form_for @order do |form|
= render :partial => 'form', :locals => { :form => form }
= submit_tag _("Save")
|
= link_to _("Cancel"), :action => 'show', :id => @order

View file

@ -41,12 +41,13 @@ pdf.text "Ansprechpartner: " + @order.supplier.contact_person
pdf.move_down 10
# Articles
data = @order.order_article_results.collect do |a|
[a.order_number, a.units_to_order, a.name,
a.unit_quantity, a.unit, a.net_price]
data = @order.order_articles.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
pdf.table data,
:font_size => 8,
:vertical_padding => 3,
:border_style => :grid,
:headers => ["BestellNr.", "Menge","Name", "Gebinde", "Einheit","Preis/Einheit"]
:headers => ["BestellNr.", "Menge","Name", "Gebinde", "Einheit","Preis/Einheit"],
:align => {0 => :left}

View file

@ -1,5 +1,5 @@
end_date = @order.ends.strftime('%d.%m.%Y')
title = "Gruppensortierung für #{@order.name}, beendet am #{end_date}"
title = "Gruppensortierung für #{@order.supplier.name}, beendet am #{end_date}"
# Define header and footer
pdf.header [pdf.margin_box.left,pdf.margin_box.top+20] do
@ -12,28 +12,28 @@ end
# Start rendering
groups = @order.group_order_results.size
groups = @order.group_orders.size
counter = 1
for group_result in @order.group_order_results
pdf.text group_result.group_name, :style => :bold
for group_order in @order.group_orders
pdf.text group_order.ordergroup.name, :style => :bold
pdf.move_down 5
pdf.text "Gruppe #{counter.to_s}/#{groups.to_s}", :size => 8
pdf.move_down 5
total = 0
data = []
group_result.group_order_article_results.each do |result|
price = result.order_article_result.gross_price
quantity = result.quantity
group_order.group_order_articles.each do |goa|
price = goa.order_article.price.fc_price
quantity = goa.quantity
sub_total = price * quantity
total += sub_total
data << [result.order_article_result.name,
quantity, price,
result.order_article_result.unit_quantity,
result.order_article_result.unit,
sub_total]
data << [goa.order_article.article.name,
quantity, number_with_precision(price),
goa.order_article.price.unit_quantity,
goa.order_article.article.unit,
number_with_precision(sub_total)]
end
data << [ {:text => "Summe", :colspan => 5}, total]
data << [ {:text => "Summe", :colspan => 5}, number_with_precision(total)]
pdf.table data,
:font_size => 8,
@ -41,7 +41,8 @@ for group_result in @order.group_order_results
:vertical_padding => 3,
:headers => ["Artikel", "Menge", "Preis", "GebGr", "Einheit", "Summe"],
:widths => { 0 => 250 },
:row_colors => ['ffffff','ececec']
:row_colors => ['ffffff','ececec'],
:align => { 0 => :right, 5 => :right }
counter += 1
pdf.move_down 10

View file

@ -3,39 +3,40 @@
- if @current_user.role_orders?
%p
- form_tag do
=_ "New Order"
=_ "for"
Neue Bestellung anlegen für
%select{:onchange => "redirectTo(this)", :style => "font-size: 0.9em;margin-left:1em;"}
%option{:selected => 'selected'}=_ "Choose a supplier..."
= options_for_select(Supplier.find(:all).collect {|s| [ s.name, url_for(:action => "new", :id => s)] })
= options_for_select(Supplier.find(:all).collect {|s| [ s.name, url_for(:action => "new", :supplier_id => s)] })
%br/
.left_column{:style => "width:55em"}
.box_title
%h2=_ "Running orders"
%h2 Laufende Bestellungen
.column_content
- if (@current_orders.length > 0)
- unless @open_orders.empty?
%table.list
%thead
%tr
%th=_ "Name"
%th=_ "Supplier"
%th=_ "End"
%th Lieferant
%th Ende
%th Notiz
%th{:colspan => "2"}
%tbody
- for order in @current_orders
%tr{:class => cycle('even', 'odd', :name => 'current_orders')}
%td= link_to order.name, :controller => 'orders', :action => 'show', :id => order
- for order in @open_orders
- active = (order.open? and order.ends < Time.now) ? " active" : ""
%tr{:class => cycle('even', 'odd', :name => 'open_orders') + active}
%td=h order.supplier.name
%td=h format_time(order.ends) unless order.ends.nil?
%td= link_to _("finish"), {:action => 'finish', :id => order}, :confirm => _("Are you really sure to finish the order?"), :method => "post"
%td=h truncate(order.note)
%td= link_to "Beenden", finish_order_path(order), :confirm => _("Are you really sure to finish the order?"), :method => :post
%td
= link_to image_tag('b_edit.png', :size => "16x16", :border => 0, :alt => _("Edit")), :action => 'edit', :id => order
= link_to image_tag('b_drop.png', :size => "16x16", :border => 0, :alt => _("Destroy")), { :action => 'destroy', :id => order }, :confirm => _("Are you really sure you want to destroy the order?"), :method => "post"
= link_to "Anzeigen", order
= link_to icon(:edit), edit_order_path(order)
= link_to icon(:delete), order, :confirm => _("Are you really sure you want to destroy the order?"), :method => :delete
- else
=_ "There aren't current orders at the moment."
=_ "There aren't open orders at the moment."
.left_column{:style => "width:75em"}
.box_title
%h2=_ "Expired/finished orders"
%h2 Beendete Bestellungen
.column_content#orders_table
= render :partial => 'list'
= render :partial => 'orders'

View file

@ -1,4 +1,4 @@
title = "#{@order.name}, beendet am #{@order.ends.strftime('%d.%m.%Y')}"
title = "#{@order.supplier.name}, beendet am #{@order.ends.strftime('%d.%m.%Y')}"
# Define header and footer
pdf.header [pdf.margin_box.left,pdf.margin_box.top+20] do
@ -9,64 +9,64 @@ pdf.footer [pdf.margin_box.left, pdf.margin_box.bottom-5] do
pdf.text "Seite #{pdf.page_count}", :size => 8
end
max_articles_per_page = 17 # How many articles shoud written on a page
articles = @order.order_article_results
max_order_articles_per_page = 17 # How many order_articles shoud written on a page
order_articles = @order.order_articles
pdf.text "Artikelübersicht", :style => :bold
pdf.move_down 5
pdf.text "Insgesamt #{articles.size} Artikel", :size => 8
pdf.text "Insgesamt #{order_articles.size} Artikel", :size => 8
pdf.move_down 10
articles_data = articles.collect do |a|
[a.name, a.unit, a.unit_quantity, a.gross_price, a.units_to_order]
order_articles_data = order_articles.collect do |a|
[a.article.name, a.article.unit, a.price.unit_quantity, a.price.fc_price, a.units_to_order]
end
pdf.table articles_data,
pdf.table order_articles_data,
:font_size => 8,
:border_style => :grid,
:vertical_padding => 3,
:headers => ["Artikel", "Einheit", "Gebinde", "Preis", "Menge"]
:headers => ["Artikel", "Einheit", "Gebinde", "Preis", "Menge"],
:align => { 3 => :right }
page_number = 0
total_num_articles = articles.size
total_num_order_articles = order_articles.size
while (page_number * max_articles_per_page < total_num_articles) do # Start page generating
while (page_number * max_order_articles_per_page < total_num_order_articles) do # Start page generating
page_number += 1
pdf.start_new_page(:layout => :landscape)
# Collect articles for this page
current_articles = articles.select do |a|
articles.index(a) >= (page_number-1) * max_articles_per_page and
articles.index(a) < page_number * max_articles_per_page
# Collect order_articles for this page
current_order_articles = order_articles.select do |a|
order_articles.index(a) >= (page_number-1) * max_order_articles_per_page and
order_articles.index(a) < page_number * max_order_articles_per_page
end
# Make articles header
# Make order_articles header
header = [""]
for header_article in current_articles
name = header_article.name.split("-").join(" ").split(".").join(". ").split("/").join(" ")
for header_article in current_order_articles
name = header_article.article.name.split("-").join(" ").split(".").join(". ").split("/").join(" ")
name = name.split.collect { |w| truncate(w, 8, "..") }.join(" ")
header << truncate(name, 30, " ..")
end
# Collect group results
groups_data = []
for group_order_result in @order.group_order_results
for group_order in @order.group_orders.all(:include => :ordergroup)
group_result = [truncate(group_order_result.group_name, 20)]
group_result = [truncate(group_order.ordergroup.name, 20)]
for article in current_articles
# get the OrdergroupResult for this article
result = GroupOrderArticleResult.find(:first,
:conditions => ['order_article_result_id = ? AND group_order_result_id = ?', article.id, group_order_result.id])
group_result << ((result.nil? || result == 0) ? "" : result.quantity.to_i)
for order_article in current_order_articles
# get the Ordergroup result for this order_article
goa = order_article.group_order_articles.first :conditions => { :group_order_id => group_order.id }
group_result << ((goa.nil? || goa == 0) ? "" : goa.quantity.to_i)
end
groups_data << group_result
end
# Make table
widths = { }
(max_articles_per_page + 1).times { |i| widths.merge!({ i => 40 }) unless i == 0 }
widths = { } # Generate widths-hash for table layout
(max_order_articles_per_page + 1).times { |i| widths.merge!({ i => 40 }) unless i == 0 }
pdf.table groups_data,
:font_size => 8,
:border_style => :grid,

View file

@ -1,7 +1,7 @@
- title _("New order")
- form_tag :action => 'create' do
= render :partial => 'form'
- form_for @order do |form|
= render :partial => 'form', :locals => { :form => form }
= submit_tag _("Put the order online")
|
= link_to _("Cancel"), :action => 'index'
= link_to "Abbrechen", orders_path

View file

@ -1,90 +1,88 @@
- title _("Show order")
#element_navigation
= link_to_unless @order.previous == @order, _("Previous order"), :action => "show", :id => @order.previous
= link_to_unless @order.previous == @order, _("Previous order"), @order.previous
|
= link_to _("Overview"), :controller => 'orders'
= link_to _("Overview"), orders_path
|
= link_to_unless @order.next == @order, _("Next order"), :action => "show", :id => @order.next
= link_to_unless @order.next == @order, _("Next order"), @order.next
// Order summary
.left_column{:style => "width:55em"}
.left_column{:style => "width:65em"}
.box_title
%h2=_ "Summary"
%h2 Zusammenfassung
.column_content
- if !@order.booked? and @finished
- if @order.finished? and !@order.closed?
%p
%b{:style => "color:red"}=_ "Order isn't balanced yet"
%b{:style => "color:red"}=_ "Order isn't closed yet"
%p
= _("Name") + ":"
%b=h @order.name
|
= _("Supplier") + ":"
%b=h @order.supplier ? @order.supplier.name : _('nonexistent')
Lieferant:
%b=h @order.supplier.name
- unless @order.note.empty?
%p
= _("Note") + ":"
Notiz:
=h @order.note
%p
= _("Begin") + ":"
Beginn:
%b=h format_time(@order.starts)
|
= _("End") + ":"
Ende:
%b=h format_time(@order.ends)
%p
= _("Groups ordered") + ":"
%b= @group_orders.size
- unless @finished
= "[#{@group_orders.collect{|g| g.ordergroup.name}.join(', ')}]" unless @group_orders.empty?
- else
= "[#{@group_orders.collect{|g| g.group_name}.join(', ')}]" unless @group_orders.empty?
Gruppenbestellungen:
%b= @order.group_orders.count
= "[#{@order.group_orders.find(:all, :include => :ordergroup).collect{|g| g.ordergroup.name}.join(', ')}]"
%p
=_ "Total price"
%b= number_to_currency(@order.sumPrice('gross'))
- if @order.finished
Bruttosummer aller Artikel
%b= number_to_currency(@order.sum(:gross))
- if @order.finished?
|
=_ "Ordered articles:"
%b= @order_articles.size
- unless @finished
= link_to(image_tag('b_edit.png', :size => "16x16", :border => "0", :alt => 'Edit'), :action => 'edit', :id => @order)
= link_to(image_tag('b_drop.png', :size => "16x16", :border => "0", :alt => 'Delete'), { :action => 'destroy', :id => @order }, :confirm => "Willst du wirklich die Bestellung '#{@order.name}' löschen?", :method => "post")
= link_to('[beenden]', {:action => 'finish', :id => @order}, :confirm => "Willst du wirklich die Bestellung '#{@order.name}' beenden?", :method => "post")
- else
Bestellte Artikel:
%b= @order.order_articles.ordered.count
- if @order.open?
%p
= link_to_remote _("All articles"), :update => 'result', :url => {:action => 'show', :id => @order, :view => 'normal'}, :before => "Element.show('loader')", :success => "Element.hide('loader')"
= 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
- unless @order.open?
%p
= update_articles_link(@order, "Artikelübersicht", :normal)
|
= link_to_remote _("Sort by groups"), :update => 'result', :url => {:action => 'show', :id => @order, :view => 'groups'}, :before => "Element.show('loader')", :success => "Element.hide('loader')"
= link_to image_tag("save_pdf.png", :size => "16x16", :border => "0", :alt => "PDF erstellen"), { :action => 'groupsPdf', :id => @order, :format => :pdf }, { :title => _("Download file") }
= update_articles_link(@order, "Sortiert nach Gruppen", :groups)
= link_to_pdf(@order, 'groupsPdf')
|
= link_to_remote _("Sort by articles"), :update => 'result', :url => {:action => 'show', :id => @order, :view => 'articles'}, :before => "Element.show('loader')", :success => "Element.hide('loader')"
= link_to image_tag("save_pdf.png", :size => "16x16", :border => "0", :alt => "PDF erstellen"), { :action => 'articlesPdf', :id => @order, :format => :pdf}, { :title => _("Download file") }
= update_articles_link(@order, "Sortiert nach Artikeln", :articles)
= link_to_pdf(@order, 'articlesPdf')
|
=_ "Matrix" + ":"
= link_to image_tag("save_pdf.png", :size => "16x16", :border => "0", :alt => "PDF erstellen"), { :action => 'matrixPdf', :id => @order, :format => :pdf }, { :title => _("Download file") }
Matrix:
= link_to_pdf(@order, 'matrixPdf')
|
=_ "FAX-template" + ":"
= link_to image_tag("save_pdf.png", :size => "16x16", :border => "0", :alt => "PDF erstellen"), { :action => 'faxPdf', :id => @order, :format => :pdf }, { :title => _("Download file") }
Faxvorlage:
= link_to_pdf(@order, 'faxPdf')
= link_to image_tag("text_file.png", :size => "16x16", :border => "0", :alt => "Textdatei erstellen"), { :action => 'text_fax_template', :id => @order }, { :title => _("Download file") }
|
= link_to 'Kommentare', '#comments'
// Ordered articles
.single_column{:style => "clear:both; width:70em;"}
.box_title
%h2=_ "Articles"
.column_content#result
- unless @finished
= render :partial => "show_unfinished"
- else
= render :partial => "showResult"
%h2 Artikel
.column_content#articles
= render :partial => 'articles', :locals => { :order => @order }
// comments
- if @finished
.single_column{:style => "width:70em;"}
.box_title
%h2=_ "Comments"
.column_content#comments
= render :partial => "/shared/comments"
%p
= link_to_remote "neuer Kommentar", :url => {:action => 'newComment', :id => @order}
#newComment
= link_to_top
.single_column{:style => "width:70em;"}
.box_title
%h2 Kommentare
.column_content#comments
= render :partial => "/shared/comments", :locals => { :comments => @order.comments }
%p
- form_for :comment, :url => add_comment_order_path(@order) do |form|
%p
%b Neuen Kommentar hinzufügen:
%br/
= form.text_area :comment, :cols => 50, :rows => 6
%br/
= submit_tag "Kommentar hinzufügen"
= link_to_top

View file

@ -1,10 +1,9 @@
- unless @comments.empty?
- @comments.each do |comment|
- unless comments.empty?
- comments.each do |comment|
.comment[comment]
%h3
= "#{comment.user.find_ordergroup.name} :" if comment.user.find_ordergroup
=h comment.title
= simple_format(comment.comment)
= simple_format(comment.text)
.timestamp
Erstellt am
= format_time(comment.created_at)

View file

@ -1,12 +0,0 @@
- form_for :comment, :url => {:action => 'addComment', :id => @order } do |form|
%p
Titel:
%br/
= form.text_field :title, :cols => 40
%p
Kommentar:
%br/
= form.text_area :comment, :cols => 60, :rows => 8
= submit_tag "Speichern"
|
= link_to_function "Abbrechen", "Element.hide('newComment')"

View file

@ -23,5 +23,5 @@
%td=h article.name
%td= article.quantity
%td= article.unit
%td= article.net_price
%td= article.price
%td= link_to article.supplier.name, article.supplier