From 3fc6f20bd42ae5c00d2a0752a33a2c0e516012a4 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 20 Sep 2024 15:16:16 +0200 Subject: [PATCH] Fix import and validation for containers without box [SCI-11065] --- ...age_location_repository_rows_controller.rb | 4 +-- .../vue/storage_locations/modals/assign.vue | 2 ++ app/models/storage_location_repository_row.rb | 12 +++++++++ .../storage_locations/import_service.rb | 25 +++++++++++++------ config/locales/en.yml | 2 ++ 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/app/controllers/storage_location_repository_rows_controller.rb b/app/controllers/storage_location_repository_rows_controller.rb index c9ee5647b..a1d3fc196 100644 --- a/app/controllers/storage_location_repository_rows_controller.rb +++ b/app/controllers/storage_location_repository_rows_controller.rb @@ -31,7 +31,7 @@ class StorageLocationRepositoryRowsController < ApplicationController render json: @storage_location_repository_row, serializer: Lists::StorageLocationRepositoryRowSerializer else - render json: @storage_location_repository_row.errors, status: :unprocessable_entity + render json: { errors: @storage_location_repository_row.errors.full_messages }, status: :unprocessable_entity end end end @@ -45,7 +45,7 @@ class StorageLocationRepositoryRowsController < ApplicationController render json: @storage_location_repository_row, serializer: Lists::StorageLocationRepositoryRowSerializer else - render json: @storage_location_repository_row.errors, status: :unprocessable_entity + render json: { errors: @storage_location_repository_row.errors.full_messages }, status: :unprocessable_entity end end end diff --git a/app/javascript/vue/storage_locations/modals/assign.vue b/app/javascript/vue/storage_locations/modals/assign.vue index 499c7f1d9..b3bfa0a6d 100644 --- a/app/javascript/vue/storage_locations/modals/assign.vue +++ b/app/javascript/vue/storage_locations/modals/assign.vue @@ -91,6 +91,8 @@ export default { metadata: { position: this.position?.map((pos) => parseInt(pos, 10)) } }).then(() => { this.$emit('close'); + }).catch((error) => { + HelperModule.flashAlertMsg(error.response.data.errors.join(', '), 'danger'); }); } } diff --git a/app/models/storage_location_repository_row.rb b/app/models/storage_location_repository_row.rb index 608b7d0e9..73e57a85b 100644 --- a/app/models/storage_location_repository_row.rb +++ b/app/models/storage_location_repository_row.rb @@ -14,6 +14,10 @@ class StorageLocationRepositoryRow < ApplicationRecord validate :ensure_uniq_position end + with_options if: -> { storage_location.container && storage_location.metadata['display_type'] != 'grid' } do + validate :unique_repository_row + end + def human_readable_position return unless metadata['position'] @@ -34,4 +38,12 @@ class StorageLocationRepositoryRow < ApplicationRecord errors.add(:base, I18n.t('activerecord.errors.models.storage_location.not_uniq_position')) end end + + def unique_repository_row + if storage_location.storage_location_repository_rows + .where(repository_row_id: repository_row_id) + .where.not(id: id).exists? + errors.add(:base, I18n.t('activerecord.errors.models.storage_location.not_uniq_repository_row')) + end + end end diff --git a/app/services/storage_locations/import_service.rb b/app/services/storage_locations/import_service.rb index 01a6a29fe..02dd28201 100644 --- a/app/services/storage_locations/import_service.rb +++ b/app/services/storage_locations/import_service.rb @@ -26,8 +26,13 @@ module StorageLocations return { status: :error, message: I18n.t('storage_locations.show.import_modal.errors.invalid_position') } end + # Check if duplicate repository rows are present in the file + if !@storage_location.with_grid? && @rows.pluck(:repository_row_id).uniq.length != @rows.length + return { status: :error, message: I18n.t('storage_locations.show.import_modal.errors.duplicate_items') } + end + ActiveRecord::Base.transaction do - unassign_repository_rows! + unassign_repository_rows! if @storage_location.with_grid? @rows.each do |row| if @storage_location.with_grid? && !position_valid?(row[:position]) @@ -59,18 +64,22 @@ module StorageLocations row = SpreadsheetParser.parse_row(r, @sheet) { position: convert_position_letter_to_number(row[0]), - repository_row_id: row[1].gsub('IT', '').to_i + repository_row_id: row[1].to_s.gsub('IT', '').to_i } end end def import_row!(row) - storage_location_repository_row = - @storage_location.storage_location_repository_rows - .find_or_initialize_by( - repository_row_id: row[:repository_row_id], - metadata: { position: row[:position] } - ) + storage_location_repository_row = if @storage_location.with_grid? + @storage_location.storage_location_repository_rows + .find_or_initialize_by( + repository_row_id: row[:repository_row_id], + metadata: { position: row[:position] } + ) + else + @storage_location.storage_location_repository_rows + .find_or_initialize_by(repository_row_id: row[:repository_row_id]) + end if storage_location_repository_row.new_record? @assigned_count += 1 diff --git a/config/locales/en.yml b/config/locales/en.yml index 4b046bb51..cc93a7783 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -264,6 +264,7 @@ en: storage_location: missing_position: 'Missing position metadata' not_uniq_position: 'Position already taken' + not_uniq_repository_row: 'Inventory item already exists' attributes: parent_storage_location: "Storage location cannot be parent to itself" parent_storage_location_child: "Storage location cannot be moved to it's child" @@ -2709,6 +2710,7 @@ en: errors: invalid_structure: "The imported file content doesn't meet criteria." invalid_position: "Positions in the file must match with the box." + duplicate_items: "Item ID has duplicates in the imported file" invalid_item: "Item ID %{row_id} doesn't exist." index: head_title: "Locations"