# Controller for all ordering-actions that are performed by a user who is member of an Ordergroup. # Management actions that require the "orders" role are handled by the OrdersController. class OrderingController < ApplicationController # Security before_filter :ensure_ordergroup_member before_filter :ensure_open_order, :only => [:order, :stock_order, :saveOrder] verify :method => :post, :only => [:saveOrder], :redirect_to => {:action => :index} # Index page. def index end # Edit a current order. def order redirect_to :action => 'stock_order', :id => @order if @order.stockit? # Load order article data... @articles_grouped_by_category = @order.articles_grouped_by_category # save results of earlier orders in array ordered_articles = Array.new @group_order = @order.group_orders.find(:first, :conditions => "ordergroup_id = #{@ordergroup.id}", :include => :group_order_articles) if @group_order # Group has already ordered, so get the results... for goa in @group_order.group_order_articles ordered_articles[goa.order_article_id] = {:quantity => goa.quantity, :tolerance => goa.tolerance, :quantity_result => goa.result(:quantity), :tolerance_result => goa.result(:tolerance)} end @version = @group_order.lock_version @availableFunds = @ordergroup.get_available_funds(@group_order) else @version = 0 @availableFunds = @ordergroup.get_available_funds end # load prices .... @price = Array.new; @unit = Array.new; @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_grouped_by_category.each do |category_name, order_articles| for order_article in order_articles # price/unit size @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) @others_quantity[i] = order_article.quantity - @quantity[i] @used_quantity[i] = (ordered_articles[order_article.id] ? ordered_articles[order_article.id][:quantity_result] : 0) # tolerance @tolerance[i] = (ordered_articles[order_article.id] ? ordered_articles[order_article.id][:tolerance] : 0) @others_tolerance[i] = order_article.tolerance - @tolerance[i] @used_tolerance[i] = (ordered_articles[order_article.id] ? ordered_articles[order_article.id][:tolerance_result] : 0) i += 1 end end end def stock_order # Load order article data... @articles_grouped_by_category = @order.articles_grouped_by_category # save results of earlier orders in array ordered_articles = Array.new @group_order = @order.group_orders.find(:first, :conditions => "ordergroup_id = #{@ordergroup.id}", :include => :group_order_articles) if @group_order # Group has already ordered, so get the results... for goa in @group_order.group_order_articles ordered_articles[goa.order_article_id] = {:quantity => goa.quantity, :tolerance => goa.tolerance, :quantity_result => goa.result(:quantity), :tolerance_result => goa.result(:tolerance)} end @version = @group_order.lock_version @availableFunds = @ordergroup.get_available_funds(@group_order) else @version = 0 @availableFunds = @ordergroup.get_available_funds end # load prices .... @price = Array.new; @quantity_available = Array.new @others_quantity = Array.new; @quantity = Array.new; @quantity_result = Array.new; @used_quantity = Array.new; @unused_quantity = Array.new i = 0; @articles_grouped_by_category.each do |category_name, order_articles| for order_article in order_articles # price/unit size @price[i] = order_article.article.fc_price @quantity_available[i] = order_article.article.quantity_available(@order) # quantity @quantity[i] = (ordered_articles[order_article.id] ? ordered_articles[order_article.id][:quantity] : 0) @others_quantity[i] = order_article.quantity - @quantity[i] @used_quantity[i] = (ordered_articles[order_article.id] ? ordered_articles[order_article.id][:quantity_result] : 0) i += 1 end end end # Update changes to a current order. def saveOrder if (params[:total_balance].to_i < 0) #TODO: Better use a real test on sufficiant funds flash[:error] = 'Der Bestellwert übersteigt das verfügbare Guthaben.' redirect_to :action => 'order' elsif (ordered = params[:ordered]) begin Order.transaction do # Try to find group_order group_order = @order.group_orders.first :conditions => "ordergroup_id = #{@ordergroup.id}", :include => [:group_order_articles] # Create group order if necessary... unless group_order.nil? # check for conflicts well ahead if (params[:version].to_i != group_order.lock_version) raise ActiveRecord::StaleObjectError end else group_order = @ordergroup.group_orders.create!(:order => @order, :updated_by => @current_user, :price => 0) end # Create/update group_order_articles... for order_article in @order.order_articles # Find the group_order_article, create a new one if necessary... group_order_article = group_order.group_order_articles.detect { |v| v.order_article_id == order_article.id } if group_order_article.nil? group_order_article = group_order.group_order_articles.create(:order_article_id => order_article.id) end # Get ordered quantities and update group_order_articles/_quantities... quantities = ordered.fetch(order_article.id.to_s, {:quantity => 0, :tolerance => 0}) group_order_article.update_quantities(quantities[:quantity].to_i, quantities[:tolerance].to_i) # Also update results for the order_article order_article.update_results! end group_order.update_price! group_order.update_attribute(:updated_by, @current_user) end flash[:notice] = 'Die Bestellung wurde gespeichert.' rescue ActiveRecord::StaleObjectError flash[:error] = 'In der Zwischenzeit hat jemand anderes auch bestellt, daher konnte die Bestellung nicht aktualisiert werden.' rescue => exception logger.error('Failed to update order: ' + exception.message) flash[:error] = 'Die Bestellung konnte nicht aktualisiert werden, da ein Fehler auftrat.' end redirect_to :action => 'my_order_result', :id => @order end end # Shows the Result for the Ordergroup the current user belongs to # this method decides between finished and unfinished orders def my_order_result @order= Order.find(params[:id]) @group_order = @order.group_order(@ordergroup) end # Shows all Orders of the Ordergroup # if selected, it shows all orders of the foodcoop def myOrders # 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 { render :partial => "orders", :locals => {:orders => @closed_orders, :pagination => true} } end end # adds a Comment to the 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] = "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 @ordergroup = @current_user.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.open? flash[:notice] = 'Diese Bestellung ist bereits abgeschlossen.' redirect_to :action => 'index' end end end