Class: ArticlesController

Inherits:
ApplicationController show all
Defined in:
app/controllers/articles_controller.rb

Instance Method Summary collapse

Methods inherited from ApplicationController

current

Methods included from PathHelper

#finance_group_transactions_path

Instance Method Details

#complete_units_migrationObject



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'app/controllers/articles_controller.rb', line 114

def complete_units_migration
  @invalid_articles = []
  @samples = []

  Article.transaction do
    params[:samples]&.values&.each do |sample|
      next unless sample[:apply_migration] == '1'

      original_unit = nil
      articles = Article.with_latest_versions_and_categories
                        .includes(latest_article_version: [:article_unit_ratios])
                        .find(sample[:article_ids])
      articles.each do |article|
        latest_article_version = article.latest_article_version
        original_unit = latest_article_version.unit
        next if latest_article_version.article_unit_ratios.length > 1 ||
                latest_article_version.billing_unit != latest_article_version.group_order_unit ||
                latest_article_version.price_unit != latest_article_version.group_order_unit

        article_version_params = sample.slice(:supplier_order_unit, :group_order_granularity, :group_order_unit)
        article_version_params[:unit] = nil
        article_version_params[:billing_unit] = article_version_params[:group_order_unit]
        article_version_params[:price_unit] = article_version_params[:group_order_unit]
        article_version_params[:article_unit_ratios_attributes] = {}
        if sample[:first_ratio_unit].present?
          article_version_params[:article_unit_ratios_attributes]['1'] = {
            id: latest_article_version.article_unit_ratios.first&.id,
            sort: 1,
            quantity: sample[:first_ratio_quantity],
            unit: sample[:first_ratio_unit]
          }
        end
        article_version_params[:id] = latest_article_version.id
        @invalid_articles << article unless article.update(latest_article_version_attributes: article_version_params)
      end

      errors = articles.find { |a| !a.errors.nil? }&.errors
      @samples << {
        unit: original_unit,
        conversion_result: sample
                  .except(:article_ids, :first_ratio_quantity, :first_ratio_unit)
                  .merge(
                    first_ratio: {
                      quantity: sample[:first_ratio_quantity],
                      unit: sample[:first_ratio_unit]
                    }
                  ),
        articles: articles,
        errors: errors,
        error: errors.present?
      }
    end
    @supplier.update_attribute(:unit_migration_completed, Time.now)
    raise ActiveRecord::Rollback unless @invalid_articles.empty?
  end

  if @invalid_articles.empty?
    redirect_to supplier_articles_path(@supplier),
                notice: I18n.t('articles.controller.complete_units_migration.notice')
  else
    additional_units = @samples.map do |sample|
      [sample[:conversion_result][:supplier_order_unit], sample[:conversion_result][:group_order_unit],
       sample[:conversion_result][:first_ratio]&.dig(:unit)]
    end.flatten.uniq.compact
    load_article_units(additional_units)

    flash.now.alert = I18n.t('articles.controller.error_invalid')
    render :migrate_units
  end
end

#copyObject



52
53
54
55
56
57
# File 'app/controllers/articles_controller.rb', line 52

def copy
  article = @supplier.articles.find(params[:article_id])
  @article = article.duplicate_including_latest_version_and_ratios
  load_article_units(@article.current_article_units)
  render layout: false
end

#createObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'app/controllers/articles_controller.rb', line 63

def create
  valid = false
  Article.transaction do
    @article = Article.create(supplier_id: @supplier.id)
    @article.attributes = { latest_article_version_attributes: params[:article_version] }
    raise ActiveRecord::Rollback unless @article.valid?

    valid = @article.save
  end

  if valid
    render layout: false
  else
    load_article_categories
    load_article_units(@article.current_article_units)
    render action: 'new', layout: false
  end
end

#destroyObject

Deletes article from database. send error msg, if article is used in a current order



95
96
97
98
99
# File 'app/controllers/articles_controller.rb', line 95

def destroy
  @article = Article.find(params[:id])
  @article.mark_as_deleted unless @order = @article.in_open_order # If article is in an active Order, the Order will be returned
  render layout: false
end

#editObject



59
60
61
# File 'app/controllers/articles_controller.rb', line 59

def edit
  render action: 'new', layout: false
end

#edit_allObject

Renders a form for editing all articles from a supplier



102
103
104
105
106
# File 'app/controllers/articles_controller.rb', line 102

def edit_all
  @articles = @supplier.articles.undeleted

  load_article_units
end

#indexObject



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'app/controllers/articles_controller.rb', line 10

def index
  sort = if params['sort']
           case params['sort']
           when 'name' then 'article_versions.name'
           when 'unit' then 'article_versions.unit'
           when 'article_category' then 'article_categories.name'
           when 'note' then 'article_versions.note'
           when 'availability' then 'article_versions.availability'
           when 'name_reverse' then 'article_versions.name DESC'
           when 'unit_reverse' then 'article_versions.unit DESC'
           when 'article_category_reverse' then 'article_categories.name DESC'
           when 'note_reverse' then 'article_versions.note DESC'
           when 'availability_reverse' then 'article_versions.availability DESC'
           end
         else
           'article_categories.name, article_versions.name'
         end

  @articles = Article.with_latest_versions_and_categories.order(sort).undeleted.where(supplier_id: @supplier,
                                                                                      type: nil)

  if request.format.csv?
    send_data ArticlesCsv.new(@articles, encoding: 'utf-8', foodsoft_url: root_url).to_csv, filename: 'articles.csv', type: 'text/csv'
    return
  end

  @articles = @articles.where('article_versions.name LIKE ?', "%#{params[:query]}%") unless params[:query].nil?

  @articles = @articles.page(params[:page]).per(@per_page)

  respond_to do |format|
    format.html
    format.js { render layout: false }
  end
end

#migrate_unitsObject



110
111
112
# File 'app/controllers/articles_controller.rb', line 110

def migrate_units
  build_article_migration_samples
end

#newObject



46
47
48
49
50
# File 'app/controllers/articles_controller.rb', line 46

def new
  @article = @supplier.articles.build
  @article.latest_article_version = @article.article_versions.build(tax: FoodsoftConfig[:tax_default])
  render layout: false
end

#parse_uploadObject

Update articles from a spreadsheet



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'app/controllers/articles_controller.rb', line 253

def parse_upload
  uploaded_file = params[:articles]['file'] or raise I18n.t('articles.controller.parse_upload.no_file')
  options = { filename: uploaded_file.original_filename, foodsoft_url: root_url }
  options[:delete_unavailable] = (params[:articles]['delete_unavailable'] == '1')
  options[:outlist_absent] = (params[:articles]['outlist_absent'] == '1')
  options[:convert_units] = (params[:articles]['convert_units'] == '1')
  @enable_unit_migration = (params[:articles]['activate_unit_migration'] == '1')
  @updated_article_pairs, @outlisted_articles, @new_articles, import_data = @supplier.sync_from_file(uploaded_file.tempfile,
                                                                                                     options)

  @articles = @updated_article_pairs.pluck(0) + @new_articles
  load_article_units

  if @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty?
    redirect_to supplier_articles_path(@supplier),
                notice: I18n.t('articles.controller.parse_upload.notice', count: import_data.length)
  end
  @ignored_article_count = 0
rescue StandardError => e
  redirect_to upload_supplier_articles_path(@supplier), alert: I18n.t('errors.general_msg', msg: e.message)
end

#prepare_units_migrationObject



108
# File 'app/controllers/articles_controller.rb', line 108

def prepare_units_migration; end

#syncObject

sync all articles with the external database renders a form with articles, which should be updated



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'app/controllers/articles_controller.rb', line 277

def sync
  search_params = {}

  if @supplier.shared_sync_method == 'import'
    order_numbers = Article.with_latest_versions_and_categories.undeleted.where(supplier_id: @supplier, type: nil).where.not(article_versions: { order_number: nil }).map(&:latest_article_version).map(&:order_number)
    redirect_to(supplier_articles_path(@supplier), notice: I18n.t('articles.controller.parse_upload.notice', count: 0)) if order_numbers.empty?
    search_params['order_numbers[]'] = order_numbers
  elsif !FoodsoftConfig[:shared_supplier_article_sync_limit].nil?
    search_params[:page] = 1
    search_params[:per_page] = FoodsoftConfig[:shared_supplier_article_sync_limit]
  end

  @updated_article_pairs, @outlisted_articles, @new_articles, import_data = @supplier.sync_from_remote(search_params: search_params)

  if !search_params[:page].nil? && import_data[:pagination][:total_pages] != 1
    redirect_to supplier_articles_path(@supplier),
                alert: I18n.t('articles.controller.sync.exceeds_shared_supplier_article_sync_limit', sync_method: I18n.t("suppliers.shared_supplier_methods.#{@supplier.shared_sync_method}"), import_sync_method: I18n.t('suppliers.shared_supplier_methods.import'))
  end

  redirect_to(supplier_articles_path(@supplier), notice: I18n.t('articles.controller.parse_upload.notice', count: import_data[:articles].length)) if @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty?
  @ignored_article_count = 0
  load_article_units((@new_articles + @updated_article_pairs.map(&:first)).map(&:current_article_units).flatten.uniq)
rescue StandardError => e
  redirect_to supplier_articles_path(@supplier), alert: I18n.t('errors.general_msg', msg: e.message)
end

#updateObject

Updates one Article and highlights the line if succeded



83
84
85
86
87
88
89
90
91
92
# File 'app/controllers/articles_controller.rb', line 83

def update
  Article.transaction do
    if @article.update(latest_article_version_attributes: params[:article_version])
      render layout: false
    else
      Rails.logger.info @article.errors.to_yaml.to_s
      render action: 'new', layout: false
    end
  end
end

#update_allObject

Updates all article of specific supplier



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'app/controllers/articles_controller.rb', line 186

def update_all
  invalid_articles = false

  Article.transaction do
    if params[:articles].present?
      # Update other article attributes...
      @articles = Article.with_latest_versions_and_categories
                         .includes(latest_article_version: [:article_unit_ratios])
                         .find(params[:articles].keys)
      @articles.each do |article|
        article_version_params = params[:articles][article.id.to_s]
        article_version_params['id'] = article.latest_article_version.id
        unless article.update(latest_article_version_attributes: article_version_params)
          invalid_articles ||= true # Remember that there are validation errors
        end
      end

      @supplier.update_attribute(:unit_migration_completed, Time.now) if params[:complete_migration]

      raise ActiveRecord::Rollback if invalid_articles # Rollback all changes
    end
  end

  if invalid_articles
    # An error has occurred, transaction has been rolled back.
    flash.now.alert = I18n.t('articles.controller.error_invalid')
    render :edit_all
  else
    # Successfully done.
    redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.update_all.notice')
  end
end

#update_selectedObject

makes different actions on selected articles



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'app/controllers/articles_controller.rb', line 220

def update_selected
  raise I18n.t('articles.controller.error_nosel') if params[:selected_articles].nil?

  articles = Article.with_latest_versions_and_categories
                    .includes(latest_article_version: [:article_unit_ratios])
                    .find(params[:selected_articles])
  Article.transaction do
    case params[:selected_action]
    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')
    end
  end
  # action succeded
  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)
end

#update_synchronizedObject

Updates, deletes articles when upload or sync form is submitted



304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'app/controllers/articles_controller.rb', line 304

def update_synchronized
  @enable_unit_migration = (params[:enable_unit_migration] == '1')
  @outlisted_articles = Article.includes(:latest_article_version).where(article_versions: { id: params[:outlisted_articles]&.values || [] })
  @updated_articles = Article.includes(:latest_article_version).where(article_versions: { id: params[:articles]&.values&.map do |v|
                                                                                                v[:id]
                                                                                              end || [] })
  @new_articles = build_articles_from_params_array(params[:new_articles]&.values || [])

  # Prepare updated articles with their parameters
  updated_article_params = []
  @updated_articles.each do |a|
    current_params = params[:articles].values.detect { |p| p[:id] == a.latest_article_version.id.to_s }
    current_params.delete(:id)
    updated_article_params << [a, current_params]
  end

  # Use the SupplierSyncService to persist changes
  service = SupplierSyncService.new(@supplier)
  success = service.persist(@new_articles, @outlisted_articles, updated_article_params, enable_unit_migration: @enable_unit_migration)

  if success
    redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.update_sync.notice')
  else
    load_article_units((@new_articles + @updated_articles).map(&:current_article_units).flatten.uniq)
    @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
  end
end

#uploadObject

lets start with parsing articles from uploaded file, yeah Renders the upload form



250
# File 'app/controllers/articles_controller.rb', line 250

def upload; end