"""Requests to ows-payment.""" from typing import List, Optional import simplejson as json from src.connectors.requests import delete, get, post, put from src.exceptions import OwsPaymentException from src.models import ( Account, AccountPaymentDetails, AccountPaymentDetailsResponse, ContractCloseBalance, GetPayableBalanceAfterTaxResponse, PaginatedContractCloseBalances, PayableBalanceAfterTax, PayableDetailsResponse, PaymentAccount, PaymentAccountInstance, PaymentAllocationFlowthroughResponse, PaymentAllocationFlowthroughUpdate, PaymentGroup, PaymentGroupPayment, PaymentMethodMinimum, ) SERVICE = 'ows-payment' def delete_balance_entries_after_tax(event_id: int) -> None: """Delete worksheet account contract payable balance after tax.""" path = f'/worksheet-payable-balance-after-tax/event/{event_id}/bulk' response = delete(SERVICE, path) if response.status_code != 204: raise OwsPaymentException( f'ERROR from DELETE {path}', status_code=response.status_code ) def bulk_create_worksheet_contract_balance_after_tax( event_id: int, statement_period_id: int, body_entries: List[PayableBalanceAfterTax] ) -> None: """Bulk create worksheet account contract payable balance after tax.""" path = f'/worksheet-payable-balance-after-tax/event/{event_id}/statement-period/{statement_period_id}/bulk' # noqa: E501 response = post( SERVICE, path, json.loads( json.dumps( [PayableBalanceAfterTax.model_dump(entry) for entry in body_entries], allow_nan=False, ) ), ) if response.status_code != 201: raise OwsPaymentException( f'ERROR from POST {path}', status_code=response.status_code, text=response.text, ) def get_payment_group_payment( payment_group_payment_id: int, ) -> Optional[PaymentGroupPayment]: """Get the payment_group_payment details.""" path = f'/payment-group-payment/{payment_group_payment_id}/' response = get(SERVICE, path) if response.status_code != 200: raise OwsPaymentException(f'ERROR in GET {path}') return PaymentGroupPayment.model_validate(response.json()) def get_contract_closing_balance_entries( statement_period_id: int, accounts: List[Account], limit: int = 300, offset: int = 0 ) -> PaginatedContractCloseBalances: """Get worksheet account contract closing balance for specific statement period and with provided accounts.""" # noqa: E501 account_ids = ','.join([str(account.account_id) for account in accounts]) path = ( f'/worksheet-account-contract-closing-balance/statement-period/{statement_period_id}/' # noqa: E501 f'?account_ids={account_ids}&limit={limit}&offset={offset}' ) response = get(SERVICE, path) if response.status_code != 200: raise OwsPaymentException(f'ERROR in GET {path}') contract_close_balances = PaginatedContractCloseBalances( items=[ ContractCloseBalance.model_validate(elem) for elem in response.json()['items'] ], total_count=response.json()['total_count'], ) return contract_close_balances def get_payment_minimums() -> List[PaymentMethodMinimum]: """Get the get_payment_minimums details.""" path = '/payment-minimums/' response = get(SERVICE, path) if response.status_code != 200: raise OwsPaymentException(f'ERROR in GET {path}') return [ PaymentMethodMinimum.model_validate(elem) for elem in response.json()['items'] ] def get_last_payment(account_id: int) -> Optional[AccountPaymentDetails]: """GET /payment-group-payment-account/last-payment/. The balance_after_tax of the last posted payment_group_payment_account is the amount most recently posted to the account. """ path = f'/payment-group-payment-account/last-payment/{account_id}/' response = get(SERVICE, path) if response.status_code != 200: raise OwsPaymentException(f'ERROR in GET {path}') return AccountPaymentDetails.model_validate(response.json()) def get_bulk_last_payments( account_ids: List[int], limit: int = 300, offset: int = 0 ) -> List[AccountPaymentDetails]: """POST /payment-group-payment-account/last-payment/bulk. Bulk endpoint to get the last posted payment for multiple accounts. The balance_after_tax of the last posted payment_group_payment_account is the amount most recently posted to the account. """ path = f'/payment-group-payment-account/last-payment/bulk?limit={limit}&offset={offset}' body = {'filters': {'account_ids': account_ids}} response = post(SERVICE, path, body) if response.status_code != 200: raise OwsPaymentException(f'ERROR in POST {path}') items = response.json().get('items', []) return [AccountPaymentDetails.model_validate(item) for item in items] def get_bulk_last_payments_v2( account_ids: List[int], limit: int = 300, offset: int = 0 ) -> AccountPaymentDetailsResponse: """POST /payment-group-payment-account/last-payment/bulk. Bulk endpoint to get the last posted payment for multiple accounts. The balance_after_tax of the last posted payment_group_payment_account is the amount most recently posted to the account. """ path = f'/payment-group-payment-account/last-payment/bulk?limit={limit}&offset={offset}' body = {'filters': {'account_ids': account_ids}} response = post(SERVICE, path, body) if response.status_code != 200: raise OwsPaymentException(f'ERROR in POST {path}') return AccountPaymentDetailsResponse.model_validate(response.json()) def bulk_create_payment_accounts( payment_group_payment_id: int, payment_accounts: List[PaymentAccount] ) -> List[PaymentAccountInstance]: """Bulk create payment-group-payment-accounts.""" path = f'/payment-group-payment/{payment_group_payment_id}/accounts/' response = post( SERVICE, path, [entry.model_dump(mode='json') for entry in payment_accounts] ) if response.status_code != 201: raise OwsPaymentException( f'ERROR from POST {path}', payment_accounts=payment_accounts, status_code=response.status_code, text=response.text, ) return [PaymentAccountInstance.model_validate(item) for item in response.json()] def get_payable_balance_after_tax_entries( event_id: int, limit: int = 300, offset: int = 0 ) -> GetPayableBalanceAfterTaxResponse: """Get payable balance after tax for specific statement period.""" path = f'/worksheet-payable-balance-after-tax/event/{event_id}/?limit={limit}&offset={offset}' # noqa: E501 response = get(SERVICE, path) if response.status_code != 200: raise OwsPaymentException(f'ERROR in GET {path}') return GetPayableBalanceAfterTaxResponse.model_validate(response.json()) def get_payment_group(payment_group_id: int) -> PaymentGroup: """Get the payment_group details.""" path = f'/payment-group/{payment_group_id}/' response = get(SERVICE, path) if response.status_code != 200: raise OwsPaymentException(f'ERROR in GET {path}') return PaymentGroup.model_validate(response.json()) def get_bulk_payable_details( payment_group_payment_account_ids: List[int] | None = None, payable_detail_type_ids: List[int] | None = None, limit: int = 300, offset: int = 0, ) -> PayableDetailsResponse: """POST bulk payable details for payment-group-payment-accounts.""" path = f'/payment-group-payment-account/payable-details/bulk?limit={limit}&offset={offset}' # noqa: E501 body = { 'filters': { 'payment_group_payment_account_ids': payment_group_payment_account_ids, 'payable_detail_type_ids': payable_detail_type_ids, } } response = post(SERVICE, path, body) if response.status_code != 200: raise OwsPaymentException( f'ERROR in POST {path}', status_code=response.status_code, text=response.text, ) return PayableDetailsResponse.model_validate(response.json()) def get_bulk_payment_allocations_flowthrough( payment_allocation_ids: List[int] | None = None, contract_ids: List[int] | None = None, payment_statuses: List[str] | None = None, ledger_statuses: List[str] | None = None, limit: int = 300, offset: int = 0, ) -> PaymentAllocationFlowthroughResponse: """POST bulk payment allocations flowthrough.""" path = f'/payment-allocations/flowthrough/bulk?limit={limit}&offset={offset}' body = { 'payment_allocation_ids': payment_allocation_ids, 'contract_ids': contract_ids, 'payment_statuses': payment_statuses, 'ledger_statuses': ledger_statuses, } response = post(SERVICE, path, body) if response.status_code != 200: raise OwsPaymentException( f'ERROR in POST {path}', status_code=response.status_code, text=response.text, ) return PaymentAllocationFlowthroughResponse.model_validate(response.json()) def bulk_update_payment_allocations_flowthrough( update_body: List[PaymentAllocationFlowthroughUpdate], ) -> None: """POST bulk payment allocations flowthrough update.""" path = f'/payment-allocations/flowthrough' response = put( SERVICE, path, [item.model_dump(mode='json', exclude_none=True) for item in update_body], ) if response.status_code != 200: raise OwsPaymentException( f'ERROR in POST {path}', status_code=response.status_code, text=response.text, )