Add inventory item CREATE endpoint [SCI-2687]

This commit is contained in:
Oleksii Kriuchykhin 2018-08-23 14:52:00 +02:00
parent 818129df1b
commit 490376513b
12 changed files with 116 additions and 11 deletions

View file

@ -5,6 +5,7 @@ module Api
class InventoryItemsController < BaseController
before_action :load_team
before_action :load_inventory
before_action :check_manage_permissions, only: %i(create)
def index
items =
@ -12,13 +13,42 @@ module Api
.includes(repository_cells: :repository_column)
.includes(
repository_cells: Extends::REPOSITORY_SEARCH_INCLUDES
).page(params[:page])
.per(params[:page_size])
).page(params.dig(:page, :number))
.per(params.dig(:page, :size))
render json: items,
each_serializer: InventoryItemSerializer,
include: :inventory_cells
end
def create
attributes = inventory_item_params.merge(
created_by: current_user,
last_modified_by: current_user
)
if inventory_cells_params.present?
inventory_cells_params
.each { |p| p.require(:attributes).require(%i(column_id value)) }
item = @inventory.repository_rows.new(attributes)
item.transaction do
item.save!
inventory_cells_params.each do |cell_params|
cell_attributes = cell_params[:attributes]
column =
@inventory.repository_columns.find(cell_attributes[:column_id])
RepositoryCell.create_with_value(
item, column, cell_attributes[:value], current_user
)
end
end
else
item = @inventory.repository_rows.create!(attributes)
end
render json: item,
serializer: InventoryItemSerializer,
include: :inventory_cells,
status: :created
end
private
def load_team
@ -29,6 +59,27 @@ module Api
def load_inventory
@inventory = @team.repositories.find(params.require(:inventory_id))
end
def check_manage_permissions
unless can_manage_repository_rows?(@team)
render body: nil, status: :forbidden
end
end
def inventory_item_params
unless params.require(:data).require(:type) == 'inventory_items'
raise ActionController::BadRequest,
'Wrong object type within parameters'
end
params.require(:data).require(:attributes)
params.permit(data: { attributes: %i(name uid) })[:data]
end
# Partially implement sideposting draft
# https://github.com/json-api/json-api/pull/1197
def inventory_cells_params
params[:included]&.select { |el| el[:type] == 'inventory_cells' }
end
end
end
end

View file

@ -22,4 +22,19 @@ class RepositoryAssetValue < ApplicationRecord
def data
asset.file_file_name
end
def self.new_with_payload(payload, attributes)
value = new(attributes)
team = value.repository_cell.repository_column.repository.team
file = Paperclip.io_adapters.for(payload[:file_data])
file.original_filename = payload[:file_name]
value.asset = Asset.create!(
file: file,
created_by: value.created_by,
last_modified_by: value.created_by,
team: team
)
value.asset.post_process_file(team)
value
end
end

View file

@ -31,12 +31,28 @@ class RepositoryCell < ActiveRecord::Base
end),
optional: true, foreign_key: :value_id
validates_inclusion_of :repository_column,
in: (lambda do |cell|
cell.repository_row.repository.repository_columns
end)
validates :repository_column, presence: true
validate :repository_column_data_type
validates :repository_row,
uniqueness: { scope: :repository_column },
unless: :importing
def self.create_with_value(row, column, data, user)
cell = new(repository_row: row, repository_column: column)
cell.transaction do
value_klass = column.data_type.constantize
value = value_klass.new_with_payload(data, repository_cell: cell,
created_by: user,
last_modified_by: user)
cell.value = value
value.save!
end
end
private
def repository_column_data_type

View file

@ -17,4 +17,10 @@ class RepositoryDateValue < ApplicationRecord
def formatted
data
end
def self.new_with_payload(payload, attributes)
value = new(attributes)
value.data = payload
value
end
end

View file

@ -20,4 +20,13 @@ class RepositoryListValue < ApplicationRecord
return nil unless repository_list_item
repository_list_item.data
end
def self.new_with_payload(payload, attributes)
value = new(attributes)
value.repository_list_item = value.repository_cell
.repository_column
.repository_list_items
.find(payload)
value
end
end

View file

@ -18,4 +18,10 @@ class RepositoryTextValue < ApplicationRecord
def formatted
data
end
def self.new_with_payload(payload, attributes)
value = new(attributes)
value.data = payload
value
end
end

View file

@ -4,16 +4,16 @@ module Api
module V1
class InventoryCellSerializer < ActiveModel::Serializer
type :inventory_cells
attributes :id, :data_type, :data
attributes :id, :value_type, :value
attribute :repository_column_id, key: :column_id
def data_type
def value_type
type_id = RepositoryColumn
.data_types[object.repository_column.data_type]
I18n.t("api.v1.inventory_data_types.t#{type_id}")
end
def data
def value
value =
case object.value_type
when 'RepositoryTextValue'
@ -23,7 +23,7 @@ module Api
when 'RepositoryListValue'
object.repository_list_value
when 'RepositoryAssetValue'
object.repository_list_value
object.repository_asset_value
end
ActiveModelSerializers::SerializableResource.new(
value,

View file

@ -4,7 +4,7 @@ module Api
module V1
class InventoryItemSerializer < ActiveModel::Serializer
type :inventory_items
attributes :id, :name
attributes :name
has_many :repository_cells, key: :inventory_cells,
serializer: InventoryCellSerializer,
class_name: 'RepositoryCell'

View file

@ -3,8 +3,8 @@
module Api
module V1
class RepositoryListValueSerializer < ActiveModel::Serializer
attribute :formatted, key: :value
attribute :repository_list_item_id, key: :inventory_list_item_id
attribute :formatted, key: :inventory_list_item_name
end
end
end

View file

@ -3,7 +3,7 @@
module Api
module V1
class RepositoryTextValueSerializer < ActiveModel::Serializer
attribute :formatted, key: :value
attribute :formatted, key: :text
end
end
end

View file

@ -10,6 +10,7 @@ Api.configure do |config|
end
config.core_api_v1_preview = true if ENV['CORE_API_V1_PREVIEW']
Paperclip::DataUriAdapter.register if ENV['CORE_API_V1_PREVIEW']
vars = ENV.select { |name, _| name =~ /^[[:alnum:]]*_AZURE_AD_APP_ID/ }
vars.each do |name, value|

View file

@ -545,11 +545,12 @@ Rails.application.routes.draw do
resources :teams, only: %i(index show) do
resources :inventories, only: %i(index show) do
get 'columns', to: 'inventory_columns#index'
get 'items', to: 'inventory_items#index'
resources :inventory_items, only: %i(index create), path: 'items'
end
end
resources :users, only: %i(show) do
resources :user_identities, only: %i(index create show update destroy)
resources :user_identities,
only: %i(index create show update destroy)
end
end
end