"""Abacus statement period handlers.""" from http import HTTPStatus from flask import Response from flask.typing import ResponseReturnValue from flask_pydantic import validate from collaborator.api import app from collaborator.constants import error from collaborator.constants.features import ( ABACUS_COLLABORATORS, ABACUS_COLLABORATORS_PAYONEER_API_INTEGRATION, ) from collaborator.logic import abacus_statement_period from collaborator.logic.dp_payment import get_dp_payments from collaborator.schemas import BaseSchema from collaborator.schemas.abacus_statement_period import ( GetDpPaymentsForAbacusStatementPeriodResponseSchema, PatchDpPaymentsForAbacusStatementPeriodResponseSchema, PatchDpPaymentsForAbacusStatementPeriodSchema, PutDpPaymentsForAbacusStatementPeriodResponseSchema, ) from collaborator.schemas.dp_payment import DpPaymentAction from collaborator.utils import features from collaborator.utils import handlers as handler_utils from collaborator.utils.error import OwsError class AbacusStatementPeriodDataloaderBody(BaseSchema): """Request body model for abacus statement period dataloader.""" abacus_statement_period_ids: list[int] @app.route("/abacus-statement-period/dataloader", methods=["POST"]) @validate() def abacus_statement_period_dataloader( body: AbacusStatementPeriodDataloaderBody, ) -> ResponseReturnValue: """Handle dataloader requests for abacus statement periods.""" periods_by_id = abacus_statement_period.abacus_statement_period_dataloader( body.abacus_statement_period_ids ) return [ {"data": periods_by_id.get(abacus_statement_period_id)} for abacus_statement_period_id in body.abacus_statement_period_ids ] @app.route( "/abacus-statement-period//direct-payment-balances", methods=["GET"], ) def get_direct_payment_balances_for_abacus_statement_period( abacus_statement_period_id: int, ) -> ResponseReturnValue: """Handle direct payment balance requests for abacus statement periods.""" payments = abacus_statement_period.direct_payment_balances( abacus_statement_period_id, ) return payments @app.route( "/abacus-statement-period//dp-payments", methods=["GET"], ) @validate() def get_dp_payments_for_abacus_statement_period( abacus_statement_period_id: int, ) -> ResponseReturnValue | BaseSchema: """Handle GET DP payments for abacus statement period. .. deprecated:: Use ``GET /dp-payments?abacus_statement_period_id=`` instead. This endpoint is kept for backward compatibility and will be removed once all consumers have migrated to the new one. """ if not features.is_feature_enabled(ABACUS_COLLABORATORS): raise OwsError.forbidden( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_FORBIDDEN_USER, ) payments, total_amount = get_dp_payments( abacus_statement_period_id, ) return GetDpPaymentsForAbacusStatementPeriodResponseSchema( currency_agnostic_total_amount=total_amount, total_count=len(payments), payments=payments, ) @app.route( "/abacus-statement-period//dp-payments", methods=["PUT"], ) @validate() @handler_utils.fetch_authorized_resources def put_dp_payments_for_abacus_statement_period( authorized_resources, user, abacus_statement_period_id: int ) -> ResponseReturnValue | BaseSchema: """Handle PUT DP payments for abacus statement period.""" if not features.is_feature_enabled(ABACUS_COLLABORATORS): raise OwsError.forbidden( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_FORBIDDEN_USER, ) payments, total_amount = abacus_statement_period.replace_dp_payments( abacus_statement_period_id, user ) return PutDpPaymentsForAbacusStatementPeriodResponseSchema( currency_agnostic_total_amount=total_amount, total_count=len(payments), payments=payments, ) @app.route( "/abacus-statement-period//dp-payment-transactions", methods=["POST"], ) @handler_utils.fetch_authorized_resources def create_dp_payment_transactions_for_abacus_statement_period( authorized_resources, user, abacus_statement_period_id: int, ) -> ResponseReturnValue: """Handle creating DP payment transactions for an abacus statement period.""" if not features.is_feature_enabled(ABACUS_COLLABORATORS): raise OwsError.forbidden( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_FORBIDDEN_USER, ) abacus_statement_period.create_dp_payment_transactions( abacus_statement_period_id, user, ) return Response(status=HTTPStatus.NO_CONTENT) @app.route( "/abacus-statement-period//dp-payments", methods=["PATCH"], ) @validate() @handler_utils.fetch_authorized_resources def patch_dp_payments_for_abacus_statement_period( authorized_resources, user, abacus_statement_period_id: int, body: PatchDpPaymentsForAbacusStatementPeriodSchema, ) -> ResponseReturnValue | BaseSchema: """Handle PATCH DP payments for abacus statement period.""" if not features.is_feature_enabled(ABACUS_COLLABORATORS): raise OwsError.forbidden( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_FORBIDDEN_USER, ) payments = [] if body.action_name == DpPaymentAction.APPROVE: payments = abacus_statement_period.approve_dp_payments( abacus_statement_period_id, user, ) return PatchDpPaymentsForAbacusStatementPeriodResponseSchema( total_count=len(payments), payments=payments, ) @app.route( "/abacus-statement-period//dp-payments/submit-to-payoneer", methods=["POST"], ) @handler_utils.fetch_authorized_resources def submit_dp_payments_for_abacus_statement_period( authorized_resources, user, abacus_statement_period_id: int, ) -> ResponseReturnValue: """Handle submitting approved DP payments to ows-payee as mass payout batches.""" if not features.is_feature_enabled(ABACUS_COLLABORATORS_PAYONEER_API_INTEGRATION): raise OwsError.forbidden( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_FORBIDDEN_USER, ) result = abacus_statement_period.submit_dp_payments( abacus_statement_period_id, user, ) return result