Files
Dena/app/api/v2/management/operations.rb
2026-08-13 19:50:53 +03:30

203 lines
8.4 KiB
Ruby

# encoding: UTF-8
# frozen_string_literal: true
module API
module V2
module Management
class Operations < Grape::API
# POST: api/v2/management/assets
# POST: api/v2/management/expenses
# POST: api/v2/management/revenues
#
# POST: api/v2/management/assets/new
# POST: api/v2/management/expenses/new
# POST: api/v2/management/revenues/new
::Operations::Account::PLATFORM_TYPES.each do |op_type|
op_type_plural = op_type.to_s.pluralize
desc "Returns #{op_type_plural} as paginated collection." do
@settings[:scope] = :read_operations
success API::V2::Management::Entities::Operation
end
params do
optional :currency,
type: String,
values: -> { Currency.codes(bothcase: true) },
desc: 'The currency for operations filtering.'
optional :page,
type: Integer, default: 1,
integer_gt_zero: true,
desc: 'The page number (defaults to 1).'
optional :limit,
type: Integer,
default: 100,
range: 1..1000,
desc: 'The number of objects per page (defaults to 100, maximum is 1000).'
optional :time_from,
type: Integer,
desc: "An integer represents the seconds elapsed since Unix epoch."\
"If set, only operations after the time will be returned."
optional :time_to,
type: Integer,
desc: "An integer represents the seconds elapsed since Unix epoch."\
"If set, only operations before the time will be returned."
optional :reference_type,
type: String,
desc: "The reference type for operations filtering"
end
post op_type_plural do
currency_id = params.fetch(:currency, nil)
"operations/#{op_type}"
.camelize
.constantize
.order(id: :desc)
.tap { |q| q.where!(currency_id: currency_id) if currency_id }
.tap { |q| q.where!(reference_type: params[:reference_type]) if params[:reference_type].present? }
.tap { |q| q.where!('created_at >= ?', Time.at(params[:time_from])) if params[:time_from].present? }
.tap { |q| q.where!('created_at < ?', Time.at(params[:time_to])) if params[:time_to].present? }
.page(params[:page])
.per(params[:limit])
.tap { |q| present q, with: API::V2::Management::Entities::Operation }
status 200
end
desc "Creates new #{op_type} operation." do
@settings[:scope] = :write_operations
success API::V2::Management::Entities::Operation
end
params do
requires :currency,
type: String,
values: -> { ::Currency.codes(bothcase: true) },
desc: 'The currency code.'
requires :code,
type: Integer,
values: -> { ::Operations::Account.where(type: op_type).pluck(:code) },
desc: 'Operation account code'
optional :debit,
type: BigDecimal,
values: ->(v) { v.to_d.positive? },
desc: 'Operation debit amount.'
optional :credit,
type: BigDecimal,
values: ->(v) { v.to_d.positive? },
desc: 'Operation credit amount.'
exactly_one_of :debit, :credit
end
post "/#{op_type_plural}/new" do
attributes = declared(params)
create_operation!(attributes).tap do |op|
present op, with: Entities::Operation
end
status 200
rescue ActiveRecord::RecordInvalid => e
body errors: e.message
status 422
end
end
# POST: api/v2/management/liabilities
#
# POST: api/v2/management/liabilities/new
::Operations::Account::MEMBER_TYPES.each do |op_type|
op_type_plural = op_type.to_s.pluralize
desc "Returns #{op_type_plural} as paginated collection." do
@settings[:scope] = :read_operations
success API::V2::Management::Entities::Operation
end
params do
optional :currency,
type: String,
values: -> { Currency.codes(bothcase: true) },
desc: 'The currency for operations filtering.'
optional :uid,
type: String,
desc: 'The user ID for operations filtering.'
optional :reference_type,
type: String,
desc: "The reference type for operations filtering"
optional :time_from,
type: Integer,
desc: "An integer represents the seconds elapsed since Unix epoch."\
"If set, only operations after the time will be returned."
optional :time_to,
type: Integer,
desc: "An integer represents the seconds elapsed since Unix epoch."\
"If set, only operations before the time will be returned."
optional :page,
type: Integer,
default: 1,
integer_gt_zero: true,
desc: 'The page number (defaults to 1).'
optional :limit,
type: Integer,
default: 100,
range: 1..10000,
desc: 'The number of objects per page (defaults to 100, maximum is 10000).'
end
post op_type_plural do
currency_id = params.fetch(:currency, nil)
member = Member.find_by!(uid: params[:uid]) if params[:uid].present?
"operations/#{op_type}"
.camelize
.constantize
.order(id: :desc)
.tap { |q| q.where!(currency_id: currency_id) if currency_id }
.tap { |q| q.where!(member: member) if member }
.tap { |q| q.where!(reference_type: params[:reference_type]) if params[:reference_type].present? }
.tap { |q| q.where!('created_at >= ?', Time.at(params[:time_from])) if params[:time_from].present? }
.tap { |q| q.where!('created_at < ?', Time.at(params[:time_to])) if params[:time_to].present? }
.tap { |q| present paginate(q), with: API::V2::Management::Entities::Operation }
status 200
end
desc "Creates new #{op_type} operation." do
@settings[:scope] = :write_operations
success API::V2::Management::Entities::Operation
end
params do
requires :currency,
type: String,
values: -> { ::Currency.codes(bothcase: true) },
desc: 'The currency code.'
requires :code,
type: Integer,
values: -> { ::Operations::Account.where(type: op_type).pluck(:code) },
desc: 'Operation account code'
given code: ->(code) { ::Operations::Account.find_by(code: code).try(:scope).try(:member?) } do
requires :uid,
type: String,
desc: 'The user ID for operation owner.'
end
optional :debit,
type: BigDecimal,
values: ->(v) { v.to_d.positive? },
desc: 'Operation debit amount.'
optional :credit,
type: BigDecimal,
values: ->(v) { v.to_d.positive? },
desc: 'Operation credit amount.'
exactly_one_of :debit, :credit
end
post "/#{op_type_plural}/new" do
attributes = declared(params)
create_operation!(attributes).tap do |op|
present op, with: Entities::Operation
end
status 200
rescue ActiveRecord::RecordInvalid => e
body errors: e.message
status 422
end
end
end
end
end
end