# frozen_string_literal: true module API::V2 module Resource # CR functionality over profiles table class Profiles < Grape::API helpers do def profile_param_keys %w[first_name last_name dob address postcode city country metadata national_code].freeze end def treasury_param_keys %w[title data kind].freeze end end desc 'Profile related routes' resource :profiles do desc 'Return profiles of current resource owner', failure: [ { code: 401, message: 'Invalid bearer token' }, { code: 404, message: 'User has no profile' } ], success: API::V2::Entities::Profile get '/me' do present current_user.profiles, with: API::V2::Entities::Profile end # personal info - kyc level one step one desc 'Create Level one - step one - personal info in profiles', failure: [ { code: 400, message: 'Required params are empty' }, { code: 401, message: 'Invalid bearer token' }, { code: 409, message: 'Profile already exists' }, { code: 422, message: 'Validation errors' } ], success: API::V2::Entities::Profile params do requires :first_name, type: String, desc: 'First Name' requires :last_name, type: String, desc: 'Last Name' requires :dob, type: Date, desc: 'Date of Birth' requires :national_code, type: String, desc: 'national code' requires :upload, desc: 'Array of Rack::Multipart::UploadedFile' optional :confirm, type: Boolean, default: true, desc: 'Profile confirmation' end post do error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 1 declared_params = declared(params.slice(*profile_param_keys), include_missing: false) declared_params.merge!(state: 'submitted') # declared_params.merge!(state: 'submitted') if params['confirm'] ActiveRecord::Base.transaction do profile = current_user.profiles.create(declared_params) code_error!(profile.errors.details, 422) if profile.errors.any? doc = current_user.documents.new(upload: params[:upload], identificator: SecureRandom.hex(16), doc_type: 'Identity card', doc_category: 'front_side') code_error!(doc.errors.details, 422) unless doc.save present profile, with: API::V2::Entities::Profile end end desc 'Update a profile for current_user', failure: [ { code: 401, message: 'Invalid bearer token' }, { code: 401, message: 'Invalid bearer token' }, { code: 422, message: 'Validation errors' } ], success: API::V2::Entities::Profile params do requires :first_name, type: String, desc: 'First Name' requires :last_name, type: String, desc: 'Last Name' requires :dob, type: Date, desc: 'Date of Birth' requires :national_code, type: String, desc: 'national code' requires :upload, desc: 'Array of Rack::Multipart::UploadedFile' optional :confirm, type: Boolean, default: true, desc: 'Profile confirmation' end put do target_profile = current_user.submitted_profile error!({ errors: ['resource.profile.doesnt_exist_or_not_editable'] }, 404) if target_profile.nil? declared_params = declared(params.slice(*profile_param_keys), include_missing: false) # declared_params.merge!(state: 'submitted') if params['confirm'] declared_params.merge!(state: 'submitted') ActiveRecord::Base.transaction do code_error!(target_profile.errors.details, 422) unless target_profile.update(declared_params) document = current_user.front_icard document.update!(upload: params[:upload]) if document.present? end present target_profile, with: API::V2::Entities::Profile end # card bank info - kyc level one step three resource :treasury do # one request add iban just desc 'Create Level one - step three - info bank ', failure: [ { code: 400, message: 'Required params are empty' }, { code: 401, message: 'Invalid bearer token' }, { code: 409, message: 'Bank info already exists' }, { code: 422, message: 'Validation errors' } ], success: API::V2::Entities::Profile params do requires :data, type: String, desc: 'treasury number' requires :kind, type: String, desc: 'iban or card' optional :title, type: String, desc: 'treasury name' optional :confirm, type: Boolean, default: true, desc: 'Treasury confirmation' end post do error!({ errors: ['resource.verified.profile.doesnt_exist'] }, 404) unless current_user.verified_profile.present? declared_params = declared(params.slice(*treasury_param_keys), include_missing: false) # declared_params.merge!(state: 'submitted') if params['confirm'].present? declared_params.merge!(state: 'submitted') error!({ errors: ['treasury.kind.not_exist'] }, 404) if Treasury.kinds.keys.exclude?(declared_params['kind']) error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 3 && declared_params['kind'].to_s == 'card' error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 4 && declared_params['kind'].to_s == 'iban' treasury = current_user.treasuries.create(declared_params) code_error!(treasury.errors.details, 422) if treasury.errors.any? KYC.const_get(Barong::App.config.kyc_provider.capitalize, false)::TreasuryWorker.perform_async(current_user.verified_profile.id) present treasury, with: API::V2::Entities::Treasury end desc 'Delete a treasury', success: { code: 204, message: 'Successfully deleted' }, failure: [ { code: 400, message: 'Required params are empty' }, { code: 401, message: 'Invalid bearer token' }, { code: 404, message: 'Record is not found' } ] delete ':id' do treasury = Treasury.find_by!(id: params[:id], user_id: current_user.id) treasury.destroy code_error!(treasury.errors.details, 422) if treasury.errors.any? status 204 end desc 'Return list of treasuries', failure: [ { code: 401, message: 'Invalid bearer token' }, { code: 404, message: 'User has no treasuries' } ], success: API::V2::Entities::Treasury get '/list' do present current_user.treasuries, with: API::V2::Entities::Treasury end end resource :selfie do # submit selfie - kyc level two step three desc 'Create Level two - step three - selfie', failure: [ { code: 400, message: 'Required params are empty' }, { code: 401, message: 'Invalid bearer token' }, { code: 409, message: 'Selfie already exists' }, { code: 422, message: 'Validation errors' } ], success: API::V2::Entities::Profile params do requires :upload, desc: 'Array of Rack::Multipart::UploadedFile' optional :confirm, type: Boolean, default: true, desc: 'Profile confirmation' end post do error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 7 target_profile = current_user.verified_profile error!({ errors: ['resource.verified.profile.doesnt_exist'] }, 404) if target_profile.nil? label = current_user.labels.find_by(key: 'selfie', value: 'verified') error!({ errors: ['resource.verified.selfie.already_exist'] }, 404) if label.present? doc = current_user.documents.find_by(doc_type: 'Selfie', state: 'pending') if doc.present? doc.update(upload: params[:upload]) else doc = current_user.documents.new(upload: params[:upload], identificator: SecureRandom.hex(16), doc_type: 'Selfie', doc_category: 'front_side') code_error!(doc.errors.details, 422) unless doc.save end status 201 end end resource :address do desc 'Adding Address', failure: [ { code: 400, message: 'Required params are empty' }, { code: 401, message: 'Invalid bearer token' }, { code: 404, message: 'needed data doesnt exist' }, { code: 422, message: 'Validation errors' } ], success: API::V2::Entities::Profile params do requires :city, type: String, desc: 'city name' requires :province, type: String, desc: 'province name' requires :address, type: String, desc: 'address' requires :postcode, type: String, desc: 'post code' requires :upload, desc: 'Array of Rack::Multipart::UploadedFile' end post do error!({ errors: ['resource.address.already_exist'] }, 422) if current_user.documents.find_by(doc_type: 'Poa', state: 'verified').present? error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 5 declared_params = declared(params) profile = current_user.verified_profile # TODO change city and province to id instead of string province = Province.find_by(name: declared_params['province']) error!({ errors: ['resource.profile.province_doesnt_exist'] }, 404) if province.nil? city = province.cities.find_by(name: declared_params['city']) error!({ errors: ['resource.profile.province_doesnt_exist'] }, 404) if city.nil? doc = current_user.documents.find_by(doc_type: 'Poa', state: 'pending') # declared_params.merge!(state: 'submitted') if params['confirm'] ActiveRecord::Base.transaction do profile.update(city: city, address: declared_params['address'], postcode: declared_params['postcode']) code_error!(profile.errors.details, 422) if profile.errors.any? if doc.present? doc.update(upload: params[:upload]) else doc = current_user.documents.new(upload: params[:upload], identificator: SecureRandom.hex(16), doc_type: 'Poa', doc_category: 'front_side') end code_error!(doc.errors.details, 422) unless doc.save present profile, with: API::V2::Entities::Profile end end end end end end end