2012-04-16 08:48:01 +02:00
|
|
|
#
|
2009-01-06 11:49:19 +01:00
|
|
|
# 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
|
2018-12-19 22:27:47 +01:00
|
|
|
include Concerns::SendOrderPdf
|
2015-01-16 15:49:31 +01:00
|
|
|
|
2019-10-28 21:11:35 +01:00
|
|
|
before_action :authenticate_pickups_or_orders
|
2023-05-12 13:01:12 +02:00
|
|
|
before_action :authenticate_orders,
|
|
|
|
except: %i[receive receive_on_order_article_create receive_on_order_article_update show]
|
|
|
|
before_action :remove_empty_article, only: %i[create update]
|
2015-01-16 15:49:31 +01:00
|
|
|
|
2009-01-06 11:49:19 +01:00
|
|
|
# List orders
|
|
|
|
def index
|
2013-12-18 19:21:39 +01:00
|
|
|
@open_orders = Order.open.includes(:supplier)
|
2014-01-13 23:21:03 +01:00
|
|
|
@finished_orders = Order.finished_not_closed.includes(:supplier)
|
2009-01-06 11:49:19 +01:00
|
|
|
@per_page = 15
|
2023-05-12 13:01:12 +02:00
|
|
|
sort = if params['sort']
|
|
|
|
case params['sort']
|
|
|
|
when 'supplier' then 'suppliers.name, ends DESC'
|
|
|
|
when 'pickup' then 'pickup DESC'
|
|
|
|
when 'ends' then 'ends DESC'
|
|
|
|
when 'supplier_reverse' then 'suppliers.name DESC'
|
|
|
|
when 'ends_reverse' then 'ends'
|
2021-03-01 15:27:26 +01:00
|
|
|
end
|
2023-05-12 13:01:12 +02:00
|
|
|
else
|
|
|
|
'ends DESC'
|
|
|
|
end
|
2015-02-18 23:46:50 +01:00
|
|
|
@suppliers = Supplier.having_articles.order('suppliers.name')
|
2014-03-08 17:15:09 +01:00
|
|
|
@orders = Order.closed.includes(:supplier).reorder(sort).page(params[:page]).per(@per_page)
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
# Gives a view for the results to a specific order
|
2009-01-29 01:57:51 +01:00
|
|
|
# Renders also the pdf
|
2009-01-06 11:49:19 +01:00
|
|
|
def show
|
2021-03-01 15:27:26 +01:00
|
|
|
@order = Order.find(params[:id])
|
2015-01-14 22:56:32 +01:00
|
|
|
@view = (params[:view] || 'default').gsub(/[^-_a-zA-Z0-9]/, '')
|
2014-01-27 14:58:39 +01:00
|
|
|
@partial = case @view
|
2021-03-01 15:27:26 +01:00
|
|
|
when 'default' then 'articles'
|
|
|
|
when 'groups' then 'shared/articles_by/groups'
|
|
|
|
when 'articles' then 'shared/articles_by/articles'
|
|
|
|
else 'articles'
|
2014-01-27 14:58:39 +01:00
|
|
|
end
|
2009-01-29 01:57:51 +01:00
|
|
|
|
2012-10-02 02:50:48 +02:00
|
|
|
respond_to do |format|
|
|
|
|
format.html
|
|
|
|
format.js do
|
2023-05-12 13:01:12 +02:00
|
|
|
render layout: false
|
2012-10-02 02:50:48 +02:00
|
|
|
end
|
|
|
|
format.pdf do
|
2018-12-19 22:27:47 +01:00
|
|
|
send_order_pdf @order, params[:document]
|
2012-10-02 02:50:48 +02:00
|
|
|
end
|
2014-03-06 16:26:16 +01:00
|
|
|
format.csv do
|
2023-02-14 16:51:22 +01:00
|
|
|
send_data OrderCsv.new(@order, options= {custom_csv: params[:custom_csv]}).to_csv, filename: @order.name + '.csv', type: 'text/csv'
|
2014-03-06 16:26:16 +01:00
|
|
|
end
|
2013-10-30 01:56:23 +01:00
|
|
|
format.text do
|
2021-03-01 15:27:26 +01:00
|
|
|
send_data OrderTxt.new(@order).to_txt, filename: @order.name + '.txt', type: 'text/plain'
|
2013-10-30 01:56:23 +01:00
|
|
|
end
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-02-14 16:51:22 +01:00
|
|
|
def custom_csv
|
|
|
|
@order = Order.find(params[:id])
|
|
|
|
@view = (params[:view] || 'default').gsub(/[^-_a-zA-Z0-9]/, '')
|
|
|
|
@partial = case @view
|
|
|
|
when 'default' then 'articles'
|
|
|
|
when 'groups' then 'shared/articles_by/groups'
|
|
|
|
when 'articles' then 'shared/articles_by/articles'
|
|
|
|
else 'articles'
|
|
|
|
end
|
|
|
|
|
|
|
|
render :layout => false
|
|
|
|
end
|
|
|
|
|
2009-01-06 11:49:19 +01:00
|
|
|
# Page to create a new order.
|
|
|
|
def new
|
2019-11-11 11:32:23 +01:00
|
|
|
if params[:order_id]
|
|
|
|
old_order = Order.find(params[:order_id])
|
|
|
|
@order = Order.new(supplier_id: old_order.supplier_id).init_dates
|
|
|
|
@order.article_ids = old_order.article_ids
|
|
|
|
else
|
|
|
|
@order = Order.new(supplier_id: params[:supplier_id]).init_dates
|
|
|
|
end
|
2023-05-12 13:01:12 +02:00
|
|
|
rescue StandardError => e
|
|
|
|
redirect_to orders_url, alert: t('errors.general_msg', msg: e.message)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Page to edit an exsiting order.
|
|
|
|
# editing finished orders is done in FinanceController
|
|
|
|
def edit
|
|
|
|
@order = Order.includes(:articles).find(params[:id])
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
# Save a new order.
|
|
|
|
# order_articles will be saved in Order.article_ids=()
|
|
|
|
def create
|
|
|
|
@order = Order.new(params[:order])
|
2013-01-26 16:24:45 +01:00
|
|
|
@order.created_by = current_user
|
2020-08-01 02:49:15 +02:00
|
|
|
@order.updated_by = current_user
|
2009-01-06 11:49:19 +01:00
|
|
|
if @order.save
|
2013-02-08 01:52:20 +01:00
|
|
|
flash[:notice] = I18n.t('orders.create.notice')
|
2009-01-29 01:57:51 +01:00
|
|
|
redirect_to @order
|
2009-01-06 11:49:19 +01:00
|
|
|
else
|
2012-10-30 00:20:47 +01:00
|
|
|
logger.debug "[debug] order errors: #{@order.errors.messages}"
|
2023-05-12 13:01:12 +02:00
|
|
|
render action: 'new'
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Update an existing order.
|
|
|
|
def update
|
|
|
|
@order = Order.find params[:id]
|
2022-10-13 18:25:52 +02:00
|
|
|
if @order.update(params[:order].merge(updated_by: current_user))
|
2013-02-08 01:52:20 +01:00
|
|
|
flash[:notice] = I18n.t('orders.update.notice')
|
2023-05-12 13:01:12 +02:00
|
|
|
redirect_to action: 'show', id: @order
|
2009-01-06 11:49:19 +01:00
|
|
|
else
|
2023-05-12 13:01:12 +02:00
|
|
|
render action: 'edit'
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Delete an order.
|
|
|
|
def destroy
|
|
|
|
Order.find(params[:id]).destroy
|
2023-05-12 13:01:12 +02:00
|
|
|
redirect_to action: 'index'
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
2015-01-16 15:49:31 +01:00
|
|
|
|
2009-01-06 11:49:19 +01:00
|
|
|
# Finish a current order.
|
|
|
|
def finish
|
|
|
|
order = Order.find(params[:id])
|
2009-01-29 01:57:51 +01:00
|
|
|
order.finish!(@current_user)
|
2013-04-04 00:56:45 +02:00
|
|
|
redirect_to order, notice: I18n.t('orders.finish.notice')
|
2023-05-12 13:01:12 +02:00
|
|
|
rescue StandardError => e
|
|
|
|
redirect_to orders_url, alert: I18n.t('errors.general_msg', msg: e.message)
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
2013-10-30 01:56:23 +01:00
|
|
|
|
2017-08-11 20:58:51 +02:00
|
|
|
# Send a order to the supplier.
|
|
|
|
def send_result_to_supplier
|
|
|
|
order = Order.find(params[:id])
|
2017-10-12 00:20:30 +02:00
|
|
|
order.send_to_supplier!(@current_user)
|
2017-08-11 20:58:51 +02:00
|
|
|
redirect_to order, notice: I18n.t('orders.send_to_supplier.notice')
|
2023-05-12 13:01:12 +02:00
|
|
|
rescue StandardError => e
|
|
|
|
redirect_to order, alert: I18n.t('errors.general_msg', msg: e.message)
|
2017-08-11 20:58:51 +02:00
|
|
|
end
|
|
|
|
|
2013-12-18 21:06:05 +01:00
|
|
|
def receive
|
|
|
|
@order = Order.find(params[:id])
|
2023-05-12 13:01:12 +02:00
|
|
|
if request.post?
|
2021-02-03 20:57:53 +01:00
|
|
|
Order.transaction do
|
|
|
|
s = update_order_amounts
|
|
|
|
@order.update_attribute(:state, 'received') if @order.state != 'received'
|
|
|
|
|
2023-05-12 13:01:12 +02:00
|
|
|
flash[:notice] = (s ? I18n.t('orders.receive.notice', msg: s) : I18n.t('orders.receive.notice_none'))
|
2021-02-03 20:57:53 +01:00
|
|
|
end
|
2020-07-31 14:09:45 +02:00
|
|
|
NotifyReceivedOrderJob.perform_later(@order)
|
2021-01-30 11:21:00 +01:00
|
|
|
if current_user.role_orders? || current_user.role_finance?
|
|
|
|
redirect_to @order
|
2021-03-05 12:14:20 +01:00
|
|
|
elsif current_user.role_pickups?
|
2021-01-30 11:21:00 +01:00
|
|
|
redirect_to pickups_path
|
|
|
|
else
|
|
|
|
redirect_to receive_order_path(@order)
|
|
|
|
end
|
2023-05-12 13:01:12 +02:00
|
|
|
else
|
|
|
|
@order_articles = @order.order_articles.ordered_or_member.includes(:article).order('articles.order_number, articles.name')
|
2013-12-18 21:06:05 +01:00
|
|
|
end
|
|
|
|
end
|
2015-01-16 15:49:31 +01:00
|
|
|
|
2013-12-31 13:46:25 +01:00
|
|
|
def receive_on_order_article_create # See publish/subscribe design pattern in /doc.
|
|
|
|
@order_article = OrderArticle.find(params[:order_article_id])
|
2023-05-12 13:01:12 +02:00
|
|
|
render layout: false
|
2013-12-31 13:46:25 +01:00
|
|
|
end
|
2015-01-16 15:49:31 +01:00
|
|
|
|
2013-12-30 14:34:26 +01:00
|
|
|
def receive_on_order_article_update # See publish/subscribe design pattern in /doc.
|
|
|
|
@order_article = OrderArticle.find(params[:order_article_id])
|
2023-05-12 13:01:12 +02:00
|
|
|
render layout: false
|
2013-12-30 14:34:26 +01:00
|
|
|
end
|
2013-12-18 21:06:05 +01:00
|
|
|
|
2013-10-30 01:56:23 +01:00
|
|
|
protected
|
2015-01-16 15:49:31 +01:00
|
|
|
|
2013-12-18 21:06:05 +01:00
|
|
|
def update_order_amounts
|
2023-05-12 13:01:12 +02:00
|
|
|
return unless params[:order_articles]
|
2021-03-01 15:27:26 +01:00
|
|
|
|
2013-12-18 21:06:05 +01:00
|
|
|
# where to leave remainder during redistribution
|
|
|
|
rest_to = []
|
|
|
|
rest_to << :tolerance if params[:rest_to_tolerance]
|
|
|
|
rest_to << :stock if params[:rest_to_stock]
|
|
|
|
rest_to << nil
|
2014-01-13 11:48:43 +01:00
|
|
|
# count what happens to the articles:
|
|
|
|
# changed, rest_to_tolerance, rest_to_stock, left_over
|
|
|
|
counts = [0] * 4
|
|
|
|
cunits = [0] * 4
|
2014-08-22 09:35:05 +02:00
|
|
|
# This was once wrapped in a transaction, but caused
|
|
|
|
# "MySQL lock timeout exceeded" errors. It's ok to do
|
|
|
|
# this article-by-article anway.
|
|
|
|
params[:order_articles].each do |oa_id, oa_params|
|
2023-05-12 13:01:12 +02:00
|
|
|
next if oa_params.blank?
|
|
|
|
|
|
|
|
oa = OrderArticle.find(oa_id)
|
|
|
|
# update attributes; don't use update_attribute because it calls save
|
|
|
|
# which makes received_changed? not work anymore
|
|
|
|
oa.attributes = oa_params
|
|
|
|
if oa.units_received_changed?
|
|
|
|
counts[0] += 1
|
|
|
|
if oa.units_received.present?
|
|
|
|
cunits[0] += oa.units_received * oa.article.unit_quantity
|
|
|
|
oacounts = oa.redistribute oa.units_received * oa.price.unit_quantity, rest_to
|
|
|
|
oacounts.each_with_index do |c, i|
|
|
|
|
cunits[i + 1] += c
|
|
|
|
counts[i + 1] += 1 if c > 0
|
2013-12-18 21:06:05 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2023-05-12 13:01:12 +02:00
|
|
|
oa.save!
|
2013-12-18 21:06:05 +01:00
|
|
|
end
|
2014-01-13 11:48:43 +01:00
|
|
|
return nil if counts[0] == 0
|
2021-03-01 15:27:26 +01:00
|
|
|
|
2014-01-13 11:48:43 +01:00
|
|
|
notice = []
|
|
|
|
notice << I18n.t('orders.update_order_amounts.msg1', count: counts[0], units: cunits[0])
|
2023-05-12 13:01:12 +02:00
|
|
|
if params[:rest_to_tolerance]
|
|
|
|
notice << I18n.t('orders.update_order_amounts.msg2', count: counts[1],
|
|
|
|
units: cunits[1])
|
|
|
|
end
|
2014-01-13 11:48:43 +01:00
|
|
|
notice << I18n.t('orders.update_order_amounts.msg3', count: counts[2], units: cunits[2]) if params[:rest_to_stock]
|
2021-03-01 15:27:26 +01:00
|
|
|
if counts[3] > 0 || cunits[3] > 0
|
2023-05-12 13:01:12 +02:00
|
|
|
notice << I18n.t('orders.update_order_amounts.msg4', count: counts[3],
|
|
|
|
units: cunits[3])
|
2014-01-08 13:39:49 +01:00
|
|
|
end
|
2014-01-13 11:48:43 +01:00
|
|
|
notice.join(', ')
|
2013-12-18 21:06:05 +01:00
|
|
|
end
|
|
|
|
|
2014-05-06 11:40:57 +02:00
|
|
|
def remove_empty_article
|
2023-05-12 13:01:12 +02:00
|
|
|
params[:order][:article_ids].compact_blank! if params[:order] && params[:order][:article_ids]
|
2014-05-06 11:40:57 +02:00
|
|
|
end
|
2013-02-08 01:52:20 +01:00
|
|
|
end
|