2009-01-06 11:49:19 +01:00
|
|
|
class ArticlesController < ApplicationController
|
2019-10-28 21:11:35 +01:00
|
|
|
before_action :authenticate_article_meta, :find_supplier
|
2009-01-06 11:49:19 +01:00
|
|
|
|
|
|
|
def index
|
2023-05-12 13:01:12 +02:00
|
|
|
sort = if params['sort']
|
|
|
|
case params['sort']
|
|
|
|
when 'name' then 'articles.name'
|
|
|
|
when 'unit' then 'articles.unit'
|
|
|
|
when 'article_category' then 'article_categories.name'
|
|
|
|
when 'note' then 'articles.note'
|
|
|
|
when 'availability' then 'articles.availability'
|
|
|
|
when 'name_reverse' then 'articles.name DESC'
|
|
|
|
when 'unit_reverse' then 'articles.unit DESC'
|
|
|
|
when 'article_category_reverse' then 'article_categories.name DESC'
|
|
|
|
when 'note_reverse' then 'articles.note DESC'
|
|
|
|
when 'availability_reverse' then 'articles.availability DESC'
|
2021-03-01 15:27:26 +01:00
|
|
|
end
|
2023-05-12 13:01:12 +02:00
|
|
|
else
|
|
|
|
'article_categories.name, articles.name'
|
|
|
|
end
|
2009-01-16 16:19:26 +01:00
|
|
|
|
2023-05-12 13:01:12 +02:00
|
|
|
@articles = Article.undeleted.where(supplier_id: @supplier, type: nil).includes(:article_category).order(sort)
|
2020-06-22 16:03:32 +02:00
|
|
|
|
|
|
|
if request.format.csv?
|
|
|
|
send_data ArticlesCsv.new(@articles, encoding: 'utf-8').to_csv, filename: 'articles.csv', type: 'text/csv'
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2012-10-19 01:12:47 +02:00
|
|
|
@articles = @articles.where('articles.name LIKE ?', "%#{params[:query]}%") unless params[:query].nil?
|
2009-01-16 16:19:26 +01:00
|
|
|
|
2012-10-19 01:12:47 +02:00
|
|
|
@articles = @articles.page(params[:page]).per(@per_page)
|
2009-01-16 16:19:26 +01:00
|
|
|
|
|
|
|
respond_to do |format|
|
2011-05-18 17:37:10 +02:00
|
|
|
format.html
|
2023-05-12 13:01:12 +02:00
|
|
|
format.js { render layout: false }
|
2009-01-16 16:19:26 +01:00
|
|
|
end
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
|
2009-01-16 16:19:26 +01:00
|
|
|
def new
|
2023-05-12 13:01:12 +02:00
|
|
|
@article = @supplier.articles.build(tax: FoodsoftConfig[:tax_default])
|
|
|
|
render layout: false
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
2015-01-18 02:04:57 +01:00
|
|
|
|
2019-10-14 09:25:34 +02:00
|
|
|
def copy
|
|
|
|
@article = @supplier.articles.find(params[:article_id]).dup
|
2023-05-12 13:01:12 +02:00
|
|
|
render layout: false
|
|
|
|
end
|
|
|
|
|
|
|
|
def edit
|
|
|
|
@article = Article.find(params[:id])
|
|
|
|
render action: 'new', layout: false
|
2019-10-14 09:25:34 +02:00
|
|
|
end
|
|
|
|
|
2009-01-16 16:19:26 +01:00
|
|
|
def create
|
2009-01-06 11:49:19 +01:00
|
|
|
@article = Article.new(params[:article])
|
2015-01-14 22:56:32 +01:00
|
|
|
if @article.valid? && @article.save
|
2023-05-12 13:01:12 +02:00
|
|
|
render layout: false
|
2009-01-06 11:49:19 +01:00
|
|
|
else
|
2023-05-12 13:01:12 +02:00
|
|
|
render action: 'new', layout: false
|
2011-05-18 17:37:10 +02:00
|
|
|
end
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
2015-01-18 02:04:57 +01:00
|
|
|
|
2009-01-06 11:49:19 +01:00
|
|
|
# Updates one Article and highlights the line if succeded
|
2009-01-16 16:19:26 +01:00
|
|
|
def update
|
|
|
|
@article = Article.find(params[:id])
|
|
|
|
|
2022-10-13 18:25:52 +02:00
|
|
|
if @article.update(params[:article])
|
2023-05-12 13:01:12 +02:00
|
|
|
render layout: false
|
2009-01-06 11:49:19 +01:00
|
|
|
else
|
2023-05-12 13:01:12 +02:00
|
|
|
render action: 'new', layout: false
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Deletes article from database. send error msg, if article is used in a current order
|
2009-01-16 16:19:26 +01:00
|
|
|
def destroy
|
2009-01-06 11:49:19 +01:00
|
|
|
@article = Article.find(params[:id])
|
2013-03-16 17:53:24 +01:00
|
|
|
@article.mark_as_deleted unless @order = @article.in_open_order # If article is in an active Order, the Order will be returned
|
2023-05-12 13:01:12 +02:00
|
|
|
render layout: false
|
2015-01-18 02:04:57 +01:00
|
|
|
end
|
|
|
|
|
2009-01-06 11:49:19 +01:00
|
|
|
# Renders a form for editing all articles from a supplier
|
|
|
|
def edit_all
|
2013-03-16 17:53:24 +01:00
|
|
|
@articles = @supplier.articles.undeleted
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
2009-01-16 16:19:26 +01:00
|
|
|
|
2009-01-06 11:49:19 +01:00
|
|
|
# Updates all article of specific supplier
|
|
|
|
def update_all
|
2013-04-08 01:00:49 +02:00
|
|
|
invalid_articles = false
|
|
|
|
|
2023-05-12 13:01:12 +02:00
|
|
|
Article.transaction do
|
|
|
|
if params[:articles].present?
|
|
|
|
# Update other article attributes...
|
|
|
|
@articles = Article.find(params[:articles].keys)
|
|
|
|
@articles.each do |article|
|
|
|
|
unless article.update(params[:articles][article.id.to_s])
|
|
|
|
invalid_articles ||= true # Remember that there are validation errors
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
end
|
2023-05-12 13:01:12 +02:00
|
|
|
|
|
|
|
raise ActiveRecord::Rollback if invalid_articles # Rollback all changes
|
2009-01-16 16:19:26 +01:00
|
|
|
end
|
2013-04-08 01:00:49 +02:00
|
|
|
end
|
2009-01-16 16:19:26 +01:00
|
|
|
|
2013-04-08 01:00:49 +02:00
|
|
|
if invalid_articles
|
2009-01-06 11:49:19 +01:00
|
|
|
# An error has occurred, transaction has been rolled back.
|
2013-04-12 16:14:54 +02:00
|
|
|
flash.now.alert = I18n.t('articles.controller.error_invalid')
|
2013-04-08 01:00:49 +02:00
|
|
|
render :edit_all
|
|
|
|
else
|
|
|
|
# Successfully done.
|
2013-04-12 16:14:54 +02:00
|
|
|
redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.update_all.notice')
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
end
|
2015-01-18 02:04:57 +01:00
|
|
|
|
2009-01-06 11:49:19 +01:00
|
|
|
# makes different actions on selected articles
|
2009-01-16 16:19:26 +01:00
|
|
|
def update_selected
|
2013-04-12 16:14:54 +02:00
|
|
|
raise I18n.t('articles.controller.error_nosel') if params[:selected_articles].nil?
|
2021-03-01 15:27:26 +01:00
|
|
|
|
2009-01-16 16:19:26 +01:00
|
|
|
articles = Article.find(params[:selected_articles])
|
2013-03-16 17:53:24 +01:00
|
|
|
Article.transaction do
|
|
|
|
case params[:selected_action]
|
2021-03-01 15:27:26 +01:00
|
|
|
when 'destroy'
|
|
|
|
articles.each(&:mark_as_deleted)
|
|
|
|
flash[:notice] = I18n.t('articles.controller.update_sel.notice_destroy')
|
|
|
|
when 'setNotAvailable'
|
|
|
|
articles.each { |a| a.update_attribute(:availability, false) }
|
|
|
|
flash[:notice] = I18n.t('articles.controller.update_sel.notice_unavail')
|
|
|
|
when 'setAvailable'
|
|
|
|
articles.each { |a| a.update_attribute(:availability, true) }
|
|
|
|
flash[:notice] = I18n.t('articles.controller.update_sel.notice_avail')
|
|
|
|
else
|
|
|
|
flash[:alert] = I18n.t('articles.controller.update_sel.notice_noaction')
|
2013-03-16 17:53:24 +01:00
|
|
|
end
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
2009-01-16 16:19:26 +01:00
|
|
|
# action succeded
|
2023-05-12 13:01:12 +02:00
|
|
|
redirect_to supplier_articles_url(@supplier, per_page: params[:per_page])
|
|
|
|
rescue StandardError => e
|
|
|
|
redirect_to supplier_articles_url(@supplier, per_page: params[:per_page]),
|
|
|
|
alert: I18n.t('errors.general_msg', msg: e)
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
2015-01-18 02:04:57 +01:00
|
|
|
|
2009-01-06 11:49:19 +01:00
|
|
|
# lets start with parsing articles from uploaded file, yeah
|
|
|
|
# Renders the upload form
|
2023-05-12 13:01:12 +02:00
|
|
|
def upload; end
|
2012-10-28 18:03:50 +01:00
|
|
|
|
2015-01-18 02:04:57 +01:00
|
|
|
# Update articles from a spreadsheet
|
|
|
|
def parse_upload
|
2015-04-17 18:44:38 +02:00
|
|
|
uploaded_file = params[:articles]['file'] or raise I18n.t('articles.controller.parse_upload.no_file')
|
2021-03-01 15:27:26 +01:00
|
|
|
options = { filename: uploaded_file.original_filename }
|
2015-04-10 20:05:42 +02:00
|
|
|
options[:outlist_absent] = (params[:articles]['outlist_absent'] == '1')
|
|
|
|
options[:convert_units] = (params[:articles]['convert_units'] == '1')
|
2023-05-12 13:01:12 +02:00
|
|
|
@updated_article_pairs, @outlisted_articles, @new_articles = @supplier.sync_from_file uploaded_file.tempfile,
|
|
|
|
options
|
2015-03-27 19:03:21 +01:00
|
|
|
if @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty?
|
2023-05-12 13:01:12 +02:00
|
|
|
redirect_to supplier_articles_path(@supplier),
|
|
|
|
notice: I18n.t('articles.controller.parse_upload.notice')
|
2014-02-24 14:07:03 +01:00
|
|
|
end
|
2015-01-18 02:04:57 +01:00
|
|
|
@ignored_article_count = 0
|
2023-05-12 13:01:12 +02:00
|
|
|
rescue StandardError => e
|
|
|
|
redirect_to upload_supplier_articles_path(@supplier), alert: I18n.t('errors.general_msg', msg: e.message)
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
2015-01-18 02:04:57 +01:00
|
|
|
|
2009-01-06 11:49:19 +01:00
|
|
|
# sync all articles with the external database
|
|
|
|
# renders a form with articles, which should be updated
|
2009-01-16 16:19:26 +01:00
|
|
|
def sync
|
2009-01-06 11:49:19 +01:00
|
|
|
# check if there is an shared_supplier
|
|
|
|
unless @supplier.shared_supplier
|
2023-05-12 13:01:12 +02:00
|
|
|
redirect_to supplier_articles_url(@supplier),
|
|
|
|
alert: I18n.t('articles.controller.sync.shared_alert', supplier: @supplier.name)
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
# sync articles against external database
|
2015-01-18 02:04:57 +01:00
|
|
|
@updated_article_pairs, @outlisted_articles, @new_articles = @supplier.sync_all
|
2023-05-12 13:01:12 +02:00
|
|
|
return unless @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty?
|
|
|
|
|
|
|
|
redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.sync.notice')
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
2013-04-08 01:00:49 +02:00
|
|
|
|
2015-01-18 02:04:57 +01:00
|
|
|
# Updates, deletes articles when upload or sync form is submitted
|
2013-04-08 01:00:49 +02:00
|
|
|
def update_synchronized
|
2021-03-01 15:27:26 +01:00
|
|
|
@outlisted_articles = Article.find(params[:outlisted_articles].try(:keys) || [])
|
|
|
|
@updated_articles = Article.find(params[:articles].try(:keys) || [])
|
|
|
|
@updated_articles.map { |a| a.assign_attributes(params[:articles][a.id.to_s]) }
|
|
|
|
@new_articles = (params[:new_articles] || []).map { |a| @supplier.articles.build(a) }
|
2014-05-21 21:24:03 +02:00
|
|
|
|
2015-04-03 15:53:08 +02:00
|
|
|
has_error = false
|
|
|
|
Article.transaction do
|
|
|
|
# delete articles
|
2015-04-17 18:44:38 +02:00
|
|
|
begin
|
|
|
|
@outlisted_articles.each(&:mark_as_deleted)
|
2023-05-12 13:01:12 +02:00
|
|
|
rescue StandardError
|
2015-04-17 18:44:38 +02:00
|
|
|
# raises an exception when used in current order
|
|
|
|
has_error = true
|
|
|
|
end
|
2015-04-03 15:53:08 +02:00
|
|
|
# Update articles
|
2021-03-01 15:27:26 +01:00
|
|
|
@updated_articles.each { |a| a.save or has_error = true }
|
2015-04-03 15:53:08 +02:00
|
|
|
# Add new articles
|
2021-03-01 15:27:26 +01:00
|
|
|
@new_articles.each { |a| a.save or has_error = true }
|
2013-04-08 01:00:49 +02:00
|
|
|
|
2015-04-03 15:53:08 +02:00
|
|
|
raise ActiveRecord::Rollback if has_error
|
|
|
|
end
|
2013-04-08 01:00:49 +02:00
|
|
|
|
2023-05-12 13:01:12 +02:00
|
|
|
if has_error
|
2015-04-03 15:53:08 +02:00
|
|
|
@updated_article_pairs = @updated_articles.map do |article|
|
|
|
|
orig_article = Article.find(article.id)
|
|
|
|
[article, orig_article.unequal_attributes(article)]
|
|
|
|
end
|
|
|
|
flash.now.alert = I18n.t('articles.controller.error_invalid')
|
|
|
|
render params[:from_action] == 'sync' ? :sync : :parse_upload
|
2023-05-12 13:01:12 +02:00
|
|
|
else
|
|
|
|
redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.update_sync.notice')
|
2013-04-08 01:00:49 +02:00
|
|
|
end
|
|
|
|
end
|
2015-01-18 02:04:57 +01:00
|
|
|
|
|
|
|
# renders a view to import articles in local database
|
|
|
|
#
|
|
|
|
def shared
|
|
|
|
# build array of keywords, required for ransack _all suffix
|
2020-10-10 17:11:35 +02:00
|
|
|
q = params.fetch(:q, {})
|
|
|
|
q[:name_cont_all] = params.fetch(:name_cont_all_joined, '').split(' ')
|
|
|
|
search = @supplier.shared_supplier.shared_articles.ransack(q)
|
|
|
|
@articles = search.result.page(params[:page]).per(10)
|
2023-05-12 13:01:12 +02:00
|
|
|
render layout: false
|
2015-01-18 02:04:57 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
# fills a form whith values of the selected shared_article
|
|
|
|
# when the direct parameter is set and the article is valid, it is imported directly
|
|
|
|
def import
|
|
|
|
@article = SharedArticle.find(params[:shared_article_id]).build_new_article(@supplier)
|
2023-05-12 13:01:12 +02:00
|
|
|
@article.article_category_id = params[:article_category_id] if params[:article_category_id].present?
|
|
|
|
if params[:direct] && params[:article_category_id].present? && @article.valid? && @article.save
|
|
|
|
render action: 'create', layout: false
|
2015-01-18 02:04:57 +01:00
|
|
|
else
|
2023-05-12 13:01:12 +02:00
|
|
|
render action: 'new', layout: false
|
2015-01-18 02:04:57 +01:00
|
|
|
end
|
|
|
|
end
|
2015-04-03 15:53:08 +02:00
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
# @return [Number] Number of articles not taken into account when syncing (having no number)
|
|
|
|
def ignored_article_count
|
|
|
|
if action_name == 'sync' || params[:from_action] == 'sync'
|
2016-04-16 21:15:53 +02:00
|
|
|
@ignored_article_count ||= @supplier.articles.undeleted.where(order_number: [nil, '']).count
|
2015-04-03 15:53:08 +02:00
|
|
|
else
|
|
|
|
0
|
|
|
|
end
|
|
|
|
end
|
2015-06-05 15:34:22 +02:00
|
|
|
helper_method :ignored_article_count
|
2013-01-30 21:21:49 +01:00
|
|
|
end
|