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

111 lines
5.0 KiB
Ruby

# encoding: UTF-8
# frozen_string_literal: true
module API
module V2
module Management
class Beneficiaries < Grape::API
namespace :beneficiaries do
desc 'Get list of user beneficiaries' do
@settings[:scope] = :read_beneficiaries
success API::V2::Management::Entities::Beneficiary
end
params do
requires :uid,
type: String,
desc: 'The shared user ID.'
optional :currency,
type: String,
values: { value: -> { Currency.visible.codes(bothcase: true) }, message: 'management.currency.doesnt_exist' },
as: :currency_id,
desc: 'Beneficiary currency code.'
optional :state,
type: String,
values: { value: -> { ::Beneficiary::STATES_AVAILABLE_FOR_MEMBER.map(&:to_s) }, message: 'management.beneficiary.invalid_state'},
desc: 'Defines either beneficiary active - user can use it to withdraw money'\
'or pending - requires beneficiary activation with pin.'
end
post '/list' do
member = Member.find_by!(uid: params[:uid])
member
.beneficiaries
.available_to_member
.tap { |q| q.where!(currency_id: params[:currency_id]) if params[:currency_id].present? }
.tap {|q| q.where!(state: params[:state]) if params[:state].present? }
.yield_self { |b| present paginate(b), with: API::V2::Management::Entities::Beneficiary }
status 200
end
desc 'Create new beneficiary' do
@settings[:scope] = :write_beneficiaries
success API::V2::Management::Entities::Beneficiary
end
params do
requires :currency,
type: String,
values: { value: -> { Currency.visible.codes(bothcase: true) }, message: 'management.currency.doesnt_exist' },
as: :currency_id,
desc: 'Beneficiary currency code.'
requires :name,
type: String,
allow_blank: false,
values: { value: ->(v) { v.present? && v.size <= 64 }, message: 'management.beneficiary.too_long_name' },
desc: 'Human rememberable name which refer beneficiary.'
optional :description,
type: String,
values: { value: ->(v) { v.size <= 255 }, message: 'management.beneficiary.too_long_description' },
desc: 'Human rememberable description which refer beneficiary.'
requires :data,
type: { value: JSON, message: 'management.beneficiary.non_json_data' },
allow_blank: false,
desc: 'Beneficiary data in JSON format'
requires :uid,
type: String,
desc: 'The shared user ID.'
optional :state,
type: String,
values: { value: -> { ::Beneficiary::STATES_AVAILABLE_FOR_MEMBER.map(&:to_s) }, message: 'management.beneficiary.invalid_state'},
desc: 'Defines either beneficiary active - user can use it to withdraw money'\
'or pending - requires beneficiary activation with pin.'
end
post do
declared_params = declared(params)
member = Member.find_by!(uid: params[:uid])
currency = Currency.find_by!(id: params[:currency_id])
if !currency.withdrawal_enabled?
error!({ errors: ['management.currency.withdrawal_disabled'] }, 422)
elsif currency.coin? && declared_params.dig(:data, :address).blank?
error!({ errors: ['management.beneficiary.missing_address_in_data'] }, 422)
elsif currency.fiat? && declared_params.dig(:data, :full_name).blank?
error!({ errors: ['management.beneficiary.missing_full_name_in_data'] }, 422)
end
# Since data is stored in MySQL JSON format we iterate through all
# beneficiaries one by one to detect duplicated address.
if currency.coin? &&
member
.beneficiaries
.available_to_member
.where(currency: currency)
.any? { |b| b.data['address'] == declared_params.dig(:data, :address) }
error!({ errors: ['management.beneficiary.duplicate_address'] }, 422)
end
present member
.beneficiaries
.create!(declared_params.except(:uid)),
with: API::V2::Management::Entities::Beneficiary
rescue ActiveRecord::RecordInvalid => e
report_exception(e)
error!({ errors: ['management.beneficiary.failed_to_create'] }, 422)
end
end
end
end
end
end