mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-28 19:24:10 +08:00
Merge pull request #1280 from okriuchykhin/ok_SCI_2688
Add SHOW, UPDATE and DELETE inventory item endpoints [SCI-2688][SCI-2689]
This commit is contained in:
commit
a825f1c2ec
12 changed files with 142 additions and 76 deletions
|
@ -7,8 +7,9 @@ module Api
|
|||
before_action :load_inventory, only: %i(show)
|
||||
|
||||
def index
|
||||
inventories =
|
||||
@team.repositories.page(params[:page]).per(params[:page_size])
|
||||
inventories = @team.repositories
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
render jsonapi: inventories, each_serializer: InventorySerializer
|
||||
end
|
||||
|
||||
|
@ -20,7 +21,7 @@ module Api
|
|||
|
||||
def load_team
|
||||
@team = Team.find(params.require(:team_id))
|
||||
return render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
end
|
||||
|
||||
def load_inventory
|
||||
|
|
|
@ -5,7 +5,8 @@ module Api
|
|||
class InventoryItemsController < BaseController
|
||||
before_action :load_team
|
||||
before_action :load_inventory
|
||||
before_action :check_manage_permissions, only: %i(create)
|
||||
before_action :load_inventory_item, only: %i(show update destroy)
|
||||
before_action :check_manage_permissions, only: %i(create update destroy)
|
||||
|
||||
def index
|
||||
items =
|
||||
|
@ -35,7 +36,7 @@ module Api
|
|||
cell_attributes = cell_params[:attributes]
|
||||
column =
|
||||
@inventory.repository_columns.find(cell_attributes[:column_id])
|
||||
RepositoryCell.create_with_value(
|
||||
RepositoryCell.create_with_value!(
|
||||
item, column, cell_attributes[:value], current_user
|
||||
)
|
||||
end
|
||||
|
@ -49,17 +50,62 @@ module Api
|
|||
status: :created
|
||||
end
|
||||
|
||||
def show
|
||||
render jsonapi: @inventory_item,
|
||||
serializer: InventoryItemSerializer,
|
||||
include: :inventory_cells
|
||||
end
|
||||
|
||||
def update
|
||||
item_changed = false
|
||||
if inventory_cells_params.present?
|
||||
inventory_cells_params.each do |p|
|
||||
p.require(%i(id attributes))
|
||||
p.require(:attributes).require(:value)
|
||||
end
|
||||
@inventory_item.transaction do
|
||||
inventory_cells_params.each do |cell_params|
|
||||
cell = @inventory_item.repository_cells.find(cell_params[:id])
|
||||
cell_value = cell_params.dig(:attributes, :value)
|
||||
next unless cell.value.data_changed?(cell_value)
|
||||
cell.value.update_data!(cell_value, current_user)
|
||||
item_changed = true
|
||||
end
|
||||
end
|
||||
end
|
||||
@inventory_item.attributes = update_inventory_item_params
|
||||
item_changed = true if @inventory_item.changed?
|
||||
if item_changed
|
||||
@inventory_item.last_modified_by = current_user
|
||||
@inventory_item.save!
|
||||
render json: @inventory_item,
|
||||
serializer: InventoryItemSerializer,
|
||||
include: :inventory_cells
|
||||
else
|
||||
render body: nil
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@inventory_item.destroy!
|
||||
render body: nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_team
|
||||
@team = Team.find(params.require(:team_id))
|
||||
return render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
end
|
||||
|
||||
def load_inventory
|
||||
@inventory = @team.repositories.find(params.require(:inventory_id))
|
||||
end
|
||||
|
||||
def load_inventory_item
|
||||
@inventory_item = @inventory.repository_rows.find(params[:id].to_i)
|
||||
end
|
||||
|
||||
def check_manage_permissions
|
||||
unless can_manage_repository_rows?(@team)
|
||||
render body: nil, status: :forbidden
|
||||
|
@ -75,6 +121,14 @@ module Api
|
|||
params.permit(data: { attributes: %i(name uid) })[:data]
|
||||
end
|
||||
|
||||
def update_inventory_item_params
|
||||
unless params.require(:data).require(:id).to_i == params[:id].to_i
|
||||
raise ActionController::BadRequest,
|
||||
'Object ID mismatch in URL and request body'
|
||||
end
|
||||
inventory_item_params[:attributes]
|
||||
end
|
||||
|
||||
# Partially implement sideposting draft
|
||||
# https://github.com/json-api/json-api/pull/1197
|
||||
def inventory_cells_params
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class TeamsController < BaseController
|
||||
before_action :load_team, only: :show
|
||||
|
||||
def index
|
||||
teams = current_user.teams.page(params[:page]).per(params[:page_size])
|
||||
teams = current_user.teams
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
render jsonapi: teams, each_serializer: TeamSerializer
|
||||
end
|
||||
|
||||
|
@ -16,7 +20,7 @@ module Api
|
|||
|
||||
def load_team
|
||||
@team = Team.find(params.require(:id))
|
||||
return render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,6 +23,19 @@ class RepositoryAssetValue < ApplicationRecord
|
|||
asset.file_file_name
|
||||
end
|
||||
|
||||
def data_changed?(_new_data)
|
||||
true
|
||||
end
|
||||
|
||||
def update_data!(new_data, user)
|
||||
file = Paperclip.io_adapters.for(new_data[:file_data])
|
||||
file.original_filename = new_data[:file_name]
|
||||
asset.file = file
|
||||
asset.last_modified_by = user
|
||||
self.last_modified_by = user
|
||||
asset.save! && save!
|
||||
end
|
||||
|
||||
def self.new_with_payload(payload, attributes)
|
||||
value = new(attributes)
|
||||
team = value.repository_cell.repository_column.repository.team
|
||||
|
|
|
@ -41,7 +41,7 @@ class RepositoryCell < ActiveRecord::Base
|
|||
uniqueness: { scope: :repository_column },
|
||||
unless: :importing
|
||||
|
||||
def self.create_with_value(row, column, data, user)
|
||||
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
|
||||
|
|
|
@ -18,6 +18,16 @@ class RepositoryDateValue < ApplicationRecord
|
|||
data
|
||||
end
|
||||
|
||||
def data_changed?(new_data)
|
||||
new_data != data
|
||||
end
|
||||
|
||||
def update_data!(new_data, user)
|
||||
self.data = new_data
|
||||
self.last_modified_by = user
|
||||
save!
|
||||
end
|
||||
|
||||
def self.new_with_payload(payload, attributes)
|
||||
value = new(attributes)
|
||||
value.data = payload
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
class RepositoryListValue < ApplicationRecord
|
||||
belongs_to :repository_list_item,
|
||||
optional: true
|
||||
belongs_to :repository_list_item
|
||||
belongs_to :created_by,
|
||||
foreign_key: :created_by_id,
|
||||
class_name: 'User'
|
||||
|
@ -11,6 +10,12 @@ class RepositoryListValue < ApplicationRecord
|
|||
accepts_nested_attributes_for :repository_cell
|
||||
|
||||
validates :repository_cell, presence: true
|
||||
validates_inclusion_of :repository_list_item,
|
||||
in: (lambda do |list_value|
|
||||
list_value.repository_cell
|
||||
.repository_column
|
||||
.repository_list_items
|
||||
end)
|
||||
|
||||
def formatted
|
||||
data.to_s
|
||||
|
@ -21,6 +26,16 @@ class RepositoryListValue < ApplicationRecord
|
|||
repository_list_item.data
|
||||
end
|
||||
|
||||
def data_changed?(new_data)
|
||||
new_data.to_i != repository_list_item_id
|
||||
end
|
||||
|
||||
def update_data!(new_data, user)
|
||||
self.repository_list_item_id = new_data.to_i
|
||||
self.last_modified_by = user
|
||||
save!
|
||||
end
|
||||
|
||||
def self.new_with_payload(payload, attributes)
|
||||
value = new(attributes)
|
||||
value.repository_list_item = value.repository_cell
|
||||
|
|
|
@ -19,6 +19,16 @@ class RepositoryTextValue < ApplicationRecord
|
|||
data
|
||||
end
|
||||
|
||||
def data_changed?(new_data)
|
||||
new_data != data
|
||||
end
|
||||
|
||||
def update_data!(new_data, user)
|
||||
self.data = new_data
|
||||
self.last_modified_by = user
|
||||
save!
|
||||
end
|
||||
|
||||
def self.new_with_payload(payload, attributes)
|
||||
value = new(attributes)
|
||||
value.data = payload
|
||||
|
|
|
@ -48,11 +48,10 @@ module RepositoryImportParser
|
|||
if @column_list_items_size >= Constants::REPOSITORY_LIST_ITEMS_PER_COLUMN
|
||||
return
|
||||
end
|
||||
item = RepositoryListItem.new(data: value,
|
||||
created_by: @user,
|
||||
last_modified_by: @user,
|
||||
repository_column: @column,
|
||||
repository: @repository)
|
||||
item = @column.repository_list_items.new(data: value,
|
||||
created_by: @user,
|
||||
last_modified_by: @user,
|
||||
repository: @repository)
|
||||
if item.save
|
||||
@column_list_items_size += 1
|
||||
return item
|
||||
|
|
|
@ -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/ }
|
||||
|
|
|
@ -546,7 +546,7 @@ Rails.application.routes.draw do
|
|||
resources :inventories, only: %i(index show) do
|
||||
get 'columns', to: 'inventory_columns#index'
|
||||
resources :inventory_items,
|
||||
only: %i(index create),
|
||||
only: %i(index create show update destroy),
|
||||
path: 'items',
|
||||
as: :items
|
||||
end
|
||||
|
|
|
@ -20,13 +20,13 @@ RSpec.describe RepositoryListValue, type: :model do
|
|||
|
||||
describe '#formatted' do
|
||||
let!(:repository) { create :repository }
|
||||
let!(:repository_column) { create :repository_column, name: 'My column' }
|
||||
let!(:repository_column) do
|
||||
create :repository_column, data_type: :RepositoryListValue
|
||||
create :repository_column, name: 'My column',
|
||||
data_type: :RepositoryListValue
|
||||
end
|
||||
let!(:repository_row) { create :repository_row, name: 'My row' }
|
||||
let!(:repository_list_value) do
|
||||
create :repository_list_value, repository_cell_attributes: {
|
||||
build :repository_list_value, repository_cell_attributes: {
|
||||
repository_column: repository_column,
|
||||
repository_row: repository_row
|
||||
}
|
||||
|
@ -38,49 +38,20 @@ RSpec.describe RepositoryListValue, type: :model do
|
|||
repository: repository,
|
||||
repository_column: repository_column
|
||||
repository_list_value.repository_list_item = list_item
|
||||
repository_list_value.save
|
||||
repository_list_value.save!
|
||||
expect(repository_list_value.reload.formatted).to eq 'my item'
|
||||
end
|
||||
|
||||
it 'retuns only the the item related to the list' do
|
||||
repository_row_two = create :repository_row, name: 'New row'
|
||||
repository_list_value_two =
|
||||
create :repository_list_value, repository_cell_attributes: {
|
||||
repository_column: repository_column,
|
||||
repository_row: repository_row_two
|
||||
}
|
||||
list_item = create :repository_list_item,
|
||||
data: 'new item',
|
||||
repository: repository,
|
||||
repository_column: repository_column
|
||||
repository_list_value.repository_list_item = list_item
|
||||
expect(repository_list_value.reload.formatted).to_not eq 'my item'
|
||||
expect(repository_list_value.formatted).to eq ''
|
||||
end
|
||||
|
||||
it 'returns an empty string if no item selected' do
|
||||
list_item = create :repository_list_item,
|
||||
data: 'my item',
|
||||
repository: repository,
|
||||
repository_column: repository_column
|
||||
expect(repository_list_value.reload.formatted).to eq ''
|
||||
end
|
||||
|
||||
it 'returns an empty string if item does not exists' do
|
||||
repository_list_value.repository_list_item = nil
|
||||
expect(repository_list_value.reload.formatted).to eq ''
|
||||
end
|
||||
end
|
||||
|
||||
describe '#data' do
|
||||
let!(:repository) { create :repository }
|
||||
let!(:repository_column) { create :repository_column, name: 'My column' }
|
||||
let!(:repository_column) do
|
||||
create :repository_column, data_type: :RepositoryListValue
|
||||
create :repository_column, name: 'My column',
|
||||
data_type: :RepositoryListValue
|
||||
end
|
||||
let!(:repository_row) { create :repository_row, name: 'My row' }
|
||||
let!(:repository_list_value) do
|
||||
create :repository_list_value, repository_cell_attributes: {
|
||||
build :repository_list_value, repository_cell_attributes: {
|
||||
repository_column: repository_column,
|
||||
repository_row: repository_row
|
||||
}
|
||||
|
@ -92,36 +63,24 @@ RSpec.describe RepositoryListValue, type: :model do
|
|||
repository: repository,
|
||||
repository_column: repository_column
|
||||
repository_list_value.repository_list_item = list_item
|
||||
repository_list_value.save
|
||||
repository_list_value.save!
|
||||
expect(repository_list_value.reload.data).to eq 'my item'
|
||||
end
|
||||
|
||||
it 'retuns only the the item related to the list' do
|
||||
repository_row_two = create :repository_row, name: 'New row'
|
||||
create :repository_list_value,
|
||||
repository_cell_attributes: {
|
||||
repository_column: repository_column,
|
||||
repository_row: repository_row_two
|
||||
}
|
||||
repository_column_two = create :repository_column, name: 'New column'
|
||||
list_item = create :repository_list_item,
|
||||
data: 'new item',
|
||||
repository: repository,
|
||||
repository_column: repository_column
|
||||
repository_list_value.repository_list_item = list_item
|
||||
expect(repository_list_value.reload.data).to_not eq 'my item'
|
||||
expect(repository_list_value.data).to be_nil
|
||||
end
|
||||
|
||||
it 'returns an empty string if no item selected' do
|
||||
create :repository_list_item, data: 'my item',
|
||||
repository: repository,
|
||||
repository_column: repository_column
|
||||
expect(repository_list_value.reload.data).to be_nil
|
||||
end
|
||||
|
||||
it 'returns an empty string if item does not exists' do
|
||||
repository_list_value.repository_list_item = nil
|
||||
expect(repository_list_value.reload.data).to be_nil
|
||||
repository_column: repository_column_two
|
||||
repository_list_value_two = build :repository_list_value,
|
||||
repository_cell_attributes: {
|
||||
repository_column: repository_column,
|
||||
repository_row: repository_row
|
||||
}
|
||||
repository_list_value_two.repository_list_item = list_item
|
||||
saved = repository_list_value_two.save
|
||||
expect(saved).to eq false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue