"""Blueprint for payee API.""" from http import HTTPStatus from abacus_common_logic.views.validations import validated_request_body import analytics from common_apispec import doc, marshal_with, use_kwargs from flask import Blueprint, g, request from owsrequest.flask_request import flaskify from owsresponse import response from payee.config import Config from payee.constants import error from payee.constants.constants import ( PAYONEER_ACCOUNT_STATUS_CODES_NAMES, PAYONEER_STATUS_DESC, PERMISSIONS_RESOURCE_TYPES, PROFILES, ) from payee.logic import payoneer as logic from payee.logic.exceptions import LogicError from payee.logic.payee import map_payee_id from payee.models.account_payee import AccountPayee from payee.models.payee import Payee from payee.schemas.payoneer import ( CreateMassPayoutsSchema, CreatePayoneerRegistrationLinkResponseSchema, CreatePayoneerRegistrationLinkSchema, MovePayoneerProgramSchema, PayeeRegistrationFormatGetSchema, PayeeRegistrationFormatSchema, PayoneerStatusResponseSchema, ReleasePayoneerProgramResponseSchema, ReleasePayoneerProgramSchema, ) from payee.utils.permissions import ( check_access, check_jwt_identity, check_record_owner, or_, ) from payee.utils.validations import validate_multiple_record_owner payoneer_api = Blueprint('payoneer_api', __name__) @payoneer_api.route('/payoneer/registration-link', methods=['POST']) @doc( tags=['payee registration'], description='Create registration link', ) @check_access( resource_type=PERMISSIONS_RESOURCE_TYPES.BANK_INFO, allowed_profiles=[PROFILES.DOCUMENTS], ) @use_kwargs(CreatePayoneerRegistrationLinkSchema, location='json') @marshal_with( CreatePayoneerRegistrationLinkResponseSchema, code=HTTPStatus.CREATED, description=HTTPStatus.OK.phrase, ) def create_registration_link(**create_params): """Create a Payoneer registration link.""" account_payee_id = create_params['account_payee_id'] try: analytics.identify(account_payee_id) analytics.track( account_payee_id, 'Payoneer onboarding', { 'account_payee_id': account_payee_id, }, ) g.log.info( f'Message with topic `Payoneer onboarding` ' f'for account_payee_id:{account_payee_id} was sent.' ) except Exception as e: g.log.error(f'Error when sending message to segment:`{str(e)}`') return logic.create_registration_link(create_params), 201 @payoneer_api.route( '/payoneer/programs//mass-payouts', methods=['POST'] ) def create_mass_payouts(program_id): """Handle mass payouts creation.""" post_schema = CreateMassPayoutsSchema(many=True) payments = validated_request_body(post_schema) return flaskify(logic.create_mass_payouts(program_id, payments)) @payoneer_api.route( '/account-payee//payoneer-status', methods=['GET'] ) def get_payoneer_account_status(account_payee_id): """Get payoneer account status.""" result = validate_multiple_record_owner([account_payee_id])[account_payee_id] if not result: return flaskify( response.Response( message={'error': error.ERROR_DONT_HAVE_PERMISSIONS}, status=401 ) ) payoneer_response = logic.get_payoneer_account(account_payee_id) if payoneer_response.status != 200: return flaskify(payoneer_response) payoneer_account = payoneer_response.message.get('result', {}) payoneer_status = payoneer_account.get('status', {}).get('type') g.log.info( f'Payoneer account status for payee:{account_payee_id}.' f'Payoneer status:{payoneer_status}' ) result = { 'payoneer_account_id': payoneer_account.get('account_id'), 'status': PAYONEER_ACCOUNT_STATUS_CODES_NAMES[payoneer_status] if payoneer_status in PAYONEER_ACCOUNT_STATUS_CODES_NAMES else payoneer_status, } return result @payoneer_api.route( '/account-payee//payee-payoneer-details', methods=['GET'] ) def get_payee_payoneer_details(account_payee_id): """Get payee payoneer details.""" result = validate_multiple_record_owner([account_payee_id])[account_payee_id] if not result: return flaskify( response.Response( message={'error': error.ERROR_DONT_HAVE_PERMISSIONS}, status=401 ) ) payoneer_payee_details_response = logic.get_payoneer_payee_details(account_payee_id) if payoneer_payee_details_response.status != 200: return flaskify(payoneer_payee_details_response) payoneer_payee_details = payoneer_payee_details_response.message payoneer_payee_name = logic.get_payoneer_payee_name(payoneer_payee_details) return flaskify(response.Response(message={'payee_name': payoneer_payee_name})) @payoneer_api.route( '/account-payee//payoneer-account', methods=['DELETE'] ) @payoneer_api.route('/payee//payoneer-account', methods=['DELETE']) @map_payee_id @or_( check_jwt_identity(Config.PAYONEER_SERVICE_IDENTITIES), check_record_owner(field_name='payee'), ) @doc( tags=['payee releasing'], description='Release payee from payoneer program', ) @use_kwargs(ReleasePayoneerProgramSchema, location='json') @marshal_with( ReleasePayoneerProgramResponseSchema, code=HTTPStatus.OK, description=HTTPStatus.OK.phrase, ) @marshal_with( None, code=HTTPStatus.BAD_REQUEST, description=HTTPStatus.BAD_REQUEST.phrase, ) @marshal_with( None, code=HTTPStatus.NOT_FOUND, description=HTTPStatus.NOT_FOUND.phrase, ) def release_payee_from_payoneer( payee: Payee | AccountPayee, payoneer_program_id: int | None = None ): """Release payee from payoneer.""" payoneer_response = logic.get_payoneer_account( payee.payoneer_client_reference_id, payoneer_program_id or payee.payoneer_program_id, ) if payoneer_response.status != 200: return flaskify(payoneer_response) result = logic.payoneer_release_payee( payee.payoneer_client_reference_id, payoneer_program_id or payee.payoneer_program_id, ) return flaskify(result) @payoneer_api.route( '/account-payee//move-payoneer-program', methods=['POST'] ) def move_payoneer_program(account_payee_id): """Move Payoneer program.""" post_schema = MovePayoneerProgramSchema() validated_payload = validated_request_body(post_schema) result = logic.move_payoneer_program(account_payee_id, **validated_payload) return flaskify(result) @payoneer_api.route( '/account-payee//program//payoneer-status', methods=['GET'], ) def get_payee_status(account_payee_id, program_id): """Get Payoneer payee status.""" result = logic.get_payee_status(account_payee_id, program_id) return flaskify(result) @payoneer_api.route( '/account-payee//whitelabel/payee-registration/format', methods=['GET'], ) @payoneer_api.route( '/payee//whitelabel/payee-registration/format', methods=['GET'], ) @map_payee_id @check_access( resource_type=PERMISSIONS_RESOURCE_TYPES.BANK_INFO, ) @doc( tags=['payee registration'], description='Get account payee bank details format', ) @use_kwargs(PayeeRegistrationFormatGetSchema, location='query') @marshal_with( PayeeRegistrationFormatSchema, code=HTTPStatus.OK, description=HTTPStatus.OK.phrase, ) @marshal_with( None, code=HTTPStatus.BAD_REQUEST, description=HTTPStatus.BAD_REQUEST.phrase, ) def get_payee_whitelabel_registration_format(payee: Payee | AccountPayee, **payload): """Get payee whitelabel registration format.""" try: message = logic.get_payee_register_format(payee, **payload) except LogicError as e: return str(e), HTTPStatus.INTERNAL_SERVER_ERROR return message, HTTPStatus.OK @payoneer_api.route('/payoneer_status', methods=['GET']) @doc( tags=['payoneer service status'], description='Get payoneer service status', ) @marshal_with( PayoneerStatusResponseSchema, code=HTTPStatus.OK, description=HTTPStatus.OK.phrase, ) def get_payoneer_status(): """Get Payoneer status.""" payoneer_status_code = logic.get_payoneer_service_status() return flaskify( response.Response( message={ 'status_code': payoneer_status_code, 'status_desc': PAYONEER_STATUS_DESC.get(payoneer_status_code), }, status=200, ) )