"""Blueprint for EarningTransfer API.""" from http import HTTPStatus from abacus_common_logic.views.validations import validated_request_body from common_apispec import doc, marshal_with, use_kwargs from flask import Blueprint, request from owsrequest import flask_request from owsresponse import response from owsresponse.adaptors.flask import flaskify from royalties.constants.error import ERROR_CODE_AUTHORIZATION from royalties.logic import earnings_transfer as logic from royalties.schemas import ( EarningsTransferDetailSchema, EarningsTransferPostSchema, EarningsTransferPutSchema, ) earnings_transfer_api = Blueprint('earnings_transfer_api', __name__) @earnings_transfer_api.route('/earnings-transfers', methods=['GET']) @doc( summary='Get the list of earnings transfers.', description='Retrieves a paginated list of earnings transfers.', params={ 'reference_payment_entities': { 'description': 'Comma separated list of payment entities', 'type': 'string', }, 'payment_schedules': { 'description': 'Comma separated list of payment schedules', 'type': 'string', }, 'limit': {'description': 'The size of page', 'type': 'integer', 'default': 100}, 'offset': { 'description': 'The number of items to skip', 'type': 'integer', 'default': 0, }, 'sort_by': {'description': 'Column name to sort by', 'type': 'string'}, 'sort_order': {'description': 'asc or desc', 'type': 'string'}, }, ) @marshal_with( EarningsTransferDetailSchema(many=True), code=HTTPStatus.OK, description='the list of earnings transfers', ) @marshal_with( None, code=HTTPStatus.BAD_REQUEST, description='Invalid query parameter syntax or validation error', ) @marshal_with( None, code=HTTPStatus.UNAUTHORIZED, description=HTTPStatus.UNAUTHORIZED.phrase, ) @marshal_with( None, code=HTTPStatus.INTERNAL_SERVER_ERROR, description='Internal server error', ) def get_earnings_transfers(): """Get a list of earnings transfer.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) return flaskify(logic.get_earnings_transfers(request.args)) @earnings_transfer_api.route( '/contract//earnings-transfers/', methods=['GET'], ) @earnings_transfer_api.route( '/contract//earnings-transfers', methods=['GET'] ) @doc( summary='Get the list of earnings transfers.', description='Retrieves a paginated list of earnings transfers.', params={ # Path Parameters 'contract_id': { 'description': 'The unique ID of the contract', 'type': 'integer', 'required': True, 'in': 'path', }, 'transfer_type': { 'description': 'Filter by transfer type - reclass, override, or transfer', 'type': 'string', 'required': False, 'in': 'path', }, # Query Parameters (Pagination/Sorting) 'limit': {'description': 'The size of page', 'type': 'integer', 'default': 100}, 'offset': { 'description': 'The number of items to skip', 'type': 'integer', 'default': 0, }, 'sort_by': {'description': 'Column name to sort by', 'type': 'string'}, 'sort_order': {'description': 'asc or desc', 'type': 'string'}, }, ) @marshal_with( EarningsTransferDetailSchema(many=True), code=HTTPStatus.OK, description='the list of earnings transfers', ) @marshal_with( None, code=HTTPStatus.BAD_REQUEST, description='Invalid query parameter syntax or validation error', ) @marshal_with( None, code=HTTPStatus.UNAUTHORIZED, description=HTTPStatus.UNAUTHORIZED.phrase, ) @marshal_with( None, code=HTTPStatus.INTERNAL_SERVER_ERROR, description='Internal server error', ) def get_earnings_transfers_by_contract_id(contract_id: int, transfer_type: str = None): """GET endpoint for earning transfers by ContractID, with an optional path-based filter for Transfer Type..""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) return flaskify( logic.get_earnings_transfers_by_contract_id( contract_id, transfer_type, request.args ) ) @earnings_transfer_api.route( '/earnings-transfer/', methods=['GET'], ) @doc( summary='Get an earnings transfer.', description='Retrieve a specific earnings transfer by ID.', params={ 'earnings_transfer_id': { 'description': 'The unique ID of the earnings transfer', 'type': 'integer', 'required': True, 'in': 'path', }, }, ) @marshal_with( EarningsTransferDetailSchema(), code=HTTPStatus.OK, description='The earnings transfer', ) @marshal_with( None, code=HTTPStatus.NOT_FOUND, description=HTTPStatus.NOT_FOUND.phrase, ) @marshal_with( None, code=HTTPStatus.UNAUTHORIZED, description=HTTPStatus.UNAUTHORIZED.phrase, ) @marshal_with( None, code=HTTPStatus.INTERNAL_SERVER_ERROR, description='Internal server error', ) def get_earnings_transfer_by_id(earnings_transfer_id: int): """Get an earnings transfer by ID.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) return flaskify(logic.get_earnings_transfer_by_id(earnings_transfer_id)) @earnings_transfer_api.route('/earnings-transfer/bulk', methods=['POST']) @doc( summary='Create one or more EarningsTransfer', description='Create one or more earnings transfer records in bulk. ' 'Each record specifies a source and destination contract, ' 'transfer type, amount, and other configuration.', ) @use_kwargs( EarningsTransferPostSchema(many=True), location='json', required=True, apply=False, ) @marshal_with( EarningsTransferDetailSchema(many=True), code=HTTPStatus.CREATED, description='The list of created earnings transfers', ) @marshal_with( None, code=HTTPStatus.BAD_REQUEST, description='Invalid request body or contract validation error', ) @marshal_with( None, code=HTTPStatus.UNAUTHORIZED, description='Missing or invalid authentication credentials', ) @marshal_with( None, code=HTTPStatus.INTERNAL_SERVER_ERROR, description='Unexpected server error', ) def bulk_create_earnings_transfers(): """POST one or more earnings_transfer records.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) processed_body = validated_request_body(EarningsTransferPostSchema(many=True)) return flaskify(logic.bulk_create_earnings_transfers(processed_body)) @earnings_transfer_api.route('/earnings-transfer/bulk', methods=['PUT']) @doc( summary='Update one or more EarningsTransfer', description='Update one or more existing earnings transfer records in bulk. ' 'Each record must specify its unique ID.', ) @use_kwargs( EarningsTransferPutSchema(many=True), location='json', required=True, apply=False, ) @marshal_with( EarningsTransferDetailSchema(many=True), code=HTTPStatus.OK, description='The list of updated earnings transfers', ) @marshal_with( None, code=HTTPStatus.BAD_REQUEST, description='Invalid request body, ID not found, or validation error', ) @marshal_with( None, code=HTTPStatus.UNAUTHORIZED, description='Missing or invalid authentication credentials', ) @marshal_with( None, code=HTTPStatus.INTERNAL_SERVER_ERROR, description='Unexpected server error', ) def bulk_update_earnings_transfers(): """PUT one or more earnings_transfer records.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) processed_body = validated_request_body(EarningsTransferPutSchema(many=True)) return flaskify(logic.bulk_update_earnings_transfers(processed_body))