Add stock management columns to snapshots [SCI-6448]

This commit is contained in:
Oleksii Kriuchykhin 2022-01-25 17:48:45 +01:00
parent 2c88843924
commit dd5f8c2793
13 changed files with 95 additions and 21 deletions

View file

@ -11,7 +11,7 @@ class RepositoryStockValuesController < ApplicationController
locals: {
repository_row: @repository_row,
repository_stock_column: @repository_column,
units: @repository_column.repository_stock_unit_items,
unit_items: @repository_column.repository_stock_unit_items,
repository_stock_value: RepositoryStockValue.new
}
)
@ -25,7 +25,7 @@ class RepositoryStockValuesController < ApplicationController
locals: {
repository_row: @repository_row,
repository_stock_column: @repository_column,
units: @repository_column.repository_stock_unit_items,
unit_items: @repository_column.repository_stock_unit_items,
repository_stock_value: @repository_stock_value
}
)
@ -40,7 +40,8 @@ class RepositoryStockValuesController < ApplicationController
@repository,
repository_stock_value_params[:comment].presence
)
@repository_stock_value.units = repository_stock_value_params[:units]
@repository_stock_value.repository_stock_unit_item =
@repository_column.repository_stock_unit_items.find(repository_stock_value_params[:unit_item_id])
@repository_stock_value.update_data!(repository_stock_value_params[:amount], current_user)
end
else
@ -51,7 +52,8 @@ class RepositoryStockValuesController < ApplicationController
repository_cell: repository_cell,
created_by: current_user,
last_modified_by: current_user,
units: repository_stock_value_params[:units]
repository_stock_unit_item: @repository_column.repository_stock_unit_items
.find(repository_stock_value_params[:unit_item_id])
)
@repository_stock_value.save!
@repository_stock_value.update_stock_with_ledger!(
@ -77,6 +79,6 @@ class RepositoryStockValuesController < ApplicationController
end
def repository_stock_value_params
params.require(:repository_stock_value).permit(:units, :amount, :comment)
params.require(:repository_stock_value).permit(:unit_item_id, :amount, :comment)
end
end

View file

@ -11,6 +11,7 @@ class MyModuleRepositoryRow < ApplicationRecord
belongs_to :my_module,
touch: true,
inverse_of: :my_module_repository_rows
belongs_to :repository_stock_unit_item, optional: true
validates :repository_row, uniqueness: { scope: :my_module }

View file

@ -19,7 +19,9 @@ class RepositoryCell < ApplicationRecord
repository_date: 'RepositoryDateTimeValueBase',
repository_date_time_range: 'RepositoryDateTimeRangeValueBase',
repository_time_range: 'RepositoryDateTimeRangeValueBase',
repository_date_range: 'RepositoryDateTimeRangeValueBase'
repository_date_range: 'RepositoryDateTimeRangeValueBase',
repository_stock: 'RepositoryStockValue',
repository_stock_consumption_snapshot: 'RepositoryStockConsumptionValue'
}.each do |relation, class_name|
belongs_to "#{relation}_value".to_sym,
(lambda do |repository_cell|
@ -64,6 +66,7 @@ class RepositoryCell < ApplicationRecord
updated_at: updated_at
)
value.snapshot!(cell_snapshot)
cell_snapshot
end
private

View file

@ -1,6 +1,7 @@
# frozen_string_literal: true
class RepositoryColumn < ApplicationRecord
belongs_to :repository, class_name: 'RepositoryBase'
belongs_to :repository_snapshot, foreign_key: :repository_id, optional: true
belongs_to :created_by, foreign_key: :created_by_id, class_name: 'User'
has_many :repository_cells, dependent: :destroy
has_many :repository_rows, through: :repository_cells
@ -24,7 +25,8 @@ class RepositoryColumn < ApplicationRecord
enum data_type: Extends::REPOSITORY_DATA_TYPES
validates :data_type, uniqueness: { if: :RepositoryStockValue?, scope: :repository_id }
validates :data_type, uniqueness: { if: :repository_stock_value?, scope: :repository_id }
validates :data_type, uniqueness: { if: :repository_stock_consumption_value?, scope: :repository_id }
validates :name,
length: { maximum: Constants::NAME_MAX_LENGTH },
@ -41,6 +43,7 @@ class RepositoryColumn < ApplicationRecord
scope :status_type, -> { where(data_type: 'RepositoryStatusValue') }
scope :checkbox_type, -> { where(data_type: 'RepositoryChecklistValue') }
scope :stock_type, -> { where(data_type: 'RepositoryStockValue') }
scope :stock_consumption_type, -> { where(data_type: 'RepositoryStockConsumptionValue') }
def self.name_like(query)
where('repository_columns.name ILIKE ?', "%#{query}%")
@ -101,6 +104,8 @@ class RepositoryColumn < ApplicationRecord
updated_at: updated_at
)
column_snapshot.save!
snapshot_stock_consumption!(repository_snapshot) if repository_stock_value?
column_snapshot
end
def delimiter_char
@ -131,9 +136,20 @@ class RepositoryColumn < ApplicationRecord
end
end
def repository_stock_unit_value_deep_dup(new_column)
def repository_stock_value_deep_dup(new_column)
repository_stock_unit_items.each do |item|
new_column.repository_stock_unit_items << item.deep_dup
end
end
def snapshot_stock_consumption!(repository_snapshot)
column_snapshot = deep_dup
column_snapshot.assign_attributes(
name: I18n.t('repositories.table.row_consumption'),
repository_snapshot: repository_snapshot,
data_type: 'RepositoryStockConsumptionValue',
parent_id: nil
)
column_snapshot.save!
end
end

View file

@ -35,7 +35,8 @@ class RepositoryRow < ApplicationRecord
repository_date_time_range: 'RepositoryDateTimeRangeValue',
repository_time_range: 'RepositoryTimeRangeValue',
repository_date_range: 'RepositoryDateRangeValue',
repository_stock: 'RepositoryStockValue'
repository_stock: 'RepositoryStockValue',
repository_stock_consumption: 'RepositoryStockConsumptionValue'
}.each do |relation, class_name|
has_many "#{relation}_cells".to_sym, -> { where(value_type: class_name) }, class_name: 'RepositoryCell',
inverse_of: :repository_row
@ -119,5 +120,6 @@ class RepositoryRow < ApplicationRecord
row_snapshot.save!
repository_cells.each { |cell| cell.snapshot!(row_snapshot) }
row_snapshot
end
end

View file

@ -10,8 +10,13 @@ class RepositorySnapshot < RepositoryBase
class_name: 'Repository',
inverse_of: :repository_snapshots,
optional: true
belongs_to :my_module, optional: true
has_one :repository_stock_consumption_column,
-> { where(data_type: 'RepositoryStockConsumptionValue') },
class_name: 'RepositoryColumn',
foreign_key: :repository_id,
inverse_of: :repository_snapshot,
dependent: :destroy
validates :name, presence: true, length: { maximum: Constants::NAME_MAX_LENGTH }
validates :status, presence: true

View file

@ -0,0 +1,8 @@
# frozen_string_literal: true
class RepositoryStockConsumptionValue < RepositoryStockValue
def snapshot!
# Snapshots should be done from RepositoryStockValue
railse NotImplementedError
end
end

View file

@ -1,12 +1,14 @@
# frozen_string_literal: true
class RepositoryStockUnitItem < ApplicationRecord
DEFAULT_UNITS = %i(L mL uL g mg ug M mM)
DEFAULT_UNITS = %i(L mL uL g mg ug M mM).freeze
belongs_to :repository_column, inverse_of: :repository_checklist_items
belongs_to :created_by, foreign_key: 'created_by_id', class_name: 'User',
belongs_to :created_by, class_name: 'User',
inverse_of: :created_repository_checklist_types
belongs_to :last_modified_by, foreign_key: 'last_modified_by_id', class_name: 'User',
belongs_to :last_modified_by, class_name: 'User',
inverse_of: :modified_repository_checklist_types
has_many :repository_stock_values, inverse_of: :repository_stock_unit_item, dependent: :nullify
has_many :my_module_repository_rows, inverse_of: :repository_stock_unit_item, dependent: :nullify
validate :validate_per_column_limit
validates :data, presence: true,

View file

@ -1,6 +1,7 @@
# frozen_string_literal: true
class RepositoryStockValue < ApplicationRecord
belongs_to :repository_stock_unit_item, optional: true
belongs_to :created_by, class_name: 'User', optional: true, inverse_of: :created_repository_stock_values
belongs_to :last_modified_by, class_name: 'User', optional: true, inverse_of: :modified_repository_stock_values
has_one :repository_cell, as: :value, dependent: :destroy, inverse_of: :value
@ -12,7 +13,7 @@ class RepositoryStockValue < ApplicationRecord
SORTABLE_COLUMN_NAME = 'repository_stock_values.amount'
def formatted
"#{amount} #{units}"
"#{amount} #{repository_stock_unit_item&.data}"
end
def data_changed?(new_data)
@ -27,8 +28,15 @@ class RepositoryStockValue < ApplicationRecord
def snapshot!(cell_snapshot)
value_snapshot = dup
stock_unit_item =
if repository_stock_unit_item.present?
cell_snapshot.repository_column
.repository_stock_unit_items
.find { |item| item.data == repository_stock_unit_item.data }
end
value_snapshot.assign_attributes(
repository_cell: cell_snapshot,
repository_stock_unit_item: stock_unit_item,
created_at: created_at,
updated_at: updated_at
)

View file

@ -16,6 +16,7 @@ module Repositories
ActiveRecord::Base.transaction(requires_new: true) do
repository = @repository_snapshot.original_repository
has_stock_management = repository.has_stock_management?
repository.repository_columns.each do |column|
column.snapshot!(@repository_snapshot)
@ -26,7 +27,8 @@ module Repositories
.where(my_module_repository_rows: { my_module: @repository_snapshot.my_module })
repository_rows.find_each do |original_row|
original_row.snapshot!(@repository_snapshot)
row_snapshot = original_row.snapshot!(@repository_snapshot)
create_stock_consumption_cell_snapshot!(original_row, row_snapshot) if has_stock_management
end
@repository_snapshot.ready!
@ -62,5 +64,24 @@ module Repositories
end
true
end
def create_stock_consumption_cell_snapshot!(repository_row, row_snapshot)
my_module_repository_row =
repository_row.my_module_repository_rows.find { |mrr| mrr.my_module_id == @repository_snapshot.my_module_id }
return if my_module_repository_row.stock_consumption.blank?
stock_unit_item =
@repository_snapshot.repository_stock_consumption_column
.repository_stock_unit_items
.find { |item| item.data == my_module_repository_row.repository_stock_unit_item&.data }
RepositoryStockConsumptionValue.create!(
repository_cell_attributes: {
repository_column: @repository_snapshot.repository_stock_consumption_column,
repository_row: row_snapshot
},
amount: my_module_repository_row.stock_consumption,
repository_stock_unit_item: stock_unit_item
)
end
end
end

View file

@ -50,10 +50,10 @@
</div>
<div class="col-sm-6">
<label><%= t('repository_stock_values.manage_modal.unit') %></label>
<select class="form-control" name="repository_stock_value[units]" id="repository-stock-value-units" required data-placeholder="<%= t('repository_stock_values.manage_modal.unit_prompt') %>">
<% units.each do |unit| %>
<option value="<%= unit.data %>" <%= 'data-selected=true' if repository_stock_value.units == unit.data %>>
<%= unit.data %>
<select class="form-control" name="repository_stock_value[unit_item_id]" id="repository-stock-value-units" required data-placeholder="<%= t('repository_stock_values.manage_modal.unit_prompt') %>">
<% unit_items.each do |unit_item| %>
<option value="<%= unit_item.id %>" <%= 'data-selected=true' if repository_stock_value.repository_stock_unit_item == unit_item %>>
<%= unit_item.data %>
</option>
<% end %>
</select>

View file

@ -59,7 +59,8 @@ class Extends
RepositoryDateRangeValue: 9,
RepositoryChecklistValue: 10,
RepositoryNumberValue: 11,
RepositoryStockValue: 12 }
RepositoryStockValue: 12,
RepositoryStockConsumptionValue: 13 }
# Data types which can be imported to repository,
# name should match record in REPOSITORY_DATA_TYPES

View file

@ -4,7 +4,8 @@ class AddRepositoryStockManagement < ActiveRecord::Migration[6.1]
def change
create_table :repository_stock_values do |t|
t.decimal :amount, index: true
t.string :units
t.references :repository_stock_unit_item, index: true, foreign_key: true
t.string :type
t.references :last_modified_by, index: true, foreign_key: { to_table: :users }
t.references :created_by, index: true, foreign_key: { to_table: :users }
@ -23,5 +24,9 @@ class AddRepositoryStockManagement < ActiveRecord::Migration[6.1]
end
add_column :my_module_repository_rows, :stock_consumption, :decimal
add_reference :my_module_repository_rows,
:repository_stock_unit_item,
index: { name: 'index_on_repository_stock_unit_item_id' },
foreign_key: true
end
end