"""Requests to ows-payee.""" from datetime import date from http import HTTPStatus from typing import Any from httpx import HTTPStatusError from src.connectors.exceptions import OwsPayeeException from src.constants import DEFAULT_BATCH_SIZE, PAYONEER_DEFAULT_TIMEOUT from src.error_handlers.tax_details import handle_save_error from src.models import ( BaseUSTaxForm, NewTaxDetails, Payee, PayeeDetails, TaxDetails, TaxDetailsDataloaderItem, TaxFormInfoBulk, TaxFormInfoDetailsBulk, ) from src.requests import delete, get, post SERVICE = 'ows-payee' def save_bank_details(payee: PayeeDetails) -> None: """Save bank details info.""" path = f'/account-payee/{payee.account_payee_id}/bank-details' body = payee.model_dump(mode='json', exclude={'account_payee_id'}) try: response = post(SERVICE, path, body) response.raise_for_status() except Exception as e: raise OwsPayeeException( f'Failed to save bank details for payee {payee.account_payee_id}: {e}' ) def delete_banking_details(account_payee_id: int) -> None: """Delete banking details by account_payee_id.""" path = f'/account-payee/{account_payee_id}/bank-details' try: response = delete(SERVICE, path) response.raise_for_status() except Exception as e: raise OwsPayeeException( f'Failed to delete bank details for payee {account_payee_id}: {e}' ) def get_tax_form_info_details_bulk( account_payee_ids: list[int], expiration_date_start: date | None = None, expiration_date_end: date | None = None, is_active: bool | None = None, offset: int = 0, limit: int = DEFAULT_BATCH_SIZE, ) -> TaxFormInfoDetailsBulk: """Get tax form details info bulk.""" path = f'/account-payee/tax-form-info/details/bulk?offset={offset}&limit={limit}' body: dict[str, Any] = {'account_payee_ids': account_payee_ids} if expiration_date_start: body['expiration_date_start'] = expiration_date_start.isoformat() if expiration_date_end: body['expiration_date_end'] = expiration_date_end.isoformat() if is_active is not None: body['is_active'] = is_active try: response = post(SERVICE, path, body) response.raise_for_status() except Exception as e: raise OwsPayeeException( f'Failed to get tax form details for {account_payee_ids}: {e}' ) return TaxFormInfoDetailsBulk.model_validate(response.json()) def get_bank_details_by_account_payee(account_payee_id: int) -> PayeeDetails: """Get bank details info.""" path = f'/account-payee/{account_payee_id}/bank-details' try: response = get(SERVICE, path) response.raise_for_status() except Exception as e: raise OwsPayeeException( f'Failed to get bank details for account payee {account_payee_id}: {e}' ) return PayeeDetails.model_validate(response.json()) def get_bank_details_by_payee(payee_id: int) -> PayeeDetails: """Get bank details info.""" path = f'/payee/{payee_id}/bank-details' try: response = get(SERVICE, path) response.raise_for_status() except Exception as e: raise OwsPayeeException(f'Failed to get bank details for payee {payee_id}: {e}') return PayeeDetails.model_validate(response.json()) def get_tax_form_info_bulk( account_payee_ids: list[int], expiration_date_start: date | None = None, expiration_date_end: date | None = None, is_active: bool | None = None, offset: int = 0, limit: int = DEFAULT_BATCH_SIZE, ) -> TaxFormInfoBulk: """Get tax form info bulk.""" path = f'/account-payee/tax-form-info/bulk?offset={offset}&limit={limit}' body: dict[str, Any] = {'account_payee_ids': account_payee_ids} if expiration_date_start: body['expiration_date_start'] = expiration_date_start.isoformat() if expiration_date_end: body['expiration_date_end'] = expiration_date_end.isoformat() if is_active is not None: body['is_active'] = is_active try: response = post(SERVICE, path, body, raise_for_status=True) except Exception as e: raise OwsPayeeException( f'Failed to get tax form info for {account_payee_ids}: {e}' ) return TaxFormInfoBulk.model_validate(response.json()) def save_tax_form_info(account_payee_id: int, tax_form_info: BaseUSTaxForm) -> None: """Save tax form info.""" path = f'/account-payee/{account_payee_id}/tax-form-info' body = tax_form_info.model_dump(mode='json') try: post(SERVICE, path, body, raise_for_status=True) except Exception as e: raise OwsPayeeException( f'Failed to save tax form info for payee {account_payee_id}: {e}' ) def delete_tax_form_info(tax_form_info_id: int) -> None: """Delete tax form info.""" path = f'/account-payee/tax-form-info/{tax_form_info_id}' try: delete(SERVICE, path, raise_for_status=True) except Exception as e: raise OwsPayeeException( f'Failed to delete tax form info {tax_form_info_id}: {e}' ) def get_tax_details(account_payee_id: int) -> TaxDetails | None: """Get tax details.""" path = f'/account-payee/{account_payee_id}/tax-details' try: response = get(SERVICE, path, raise_for_status=True) except Exception as e: if ( isinstance(e, HTTPStatusError) and e.response.status_code == HTTPStatus.NOT_FOUND ): return None raise OwsPayeeException( f'Failed to get tax details for payee {account_payee_id}: {e}' ) return TaxDetails.model_validate(response.json()) def save_tax_details(account_payee_id: int, payload: NewTaxDetails) -> None: """Save tax details.""" path = f'/account-payee/{account_payee_id}/tax-details' try: post( SERVICE, path, payload.model_dump(mode='json', exclude_none=True), raise_for_status=True, ) except Exception as e: handle_save_error(account_payee_id, payload, e) def register_banking_details(account_payee_id: int) -> None: """Register in payoneer banking details that are stored in DB.""" try: post( SERVICE, f'/account-payee/{account_payee_id}/register-whitelabel-profile', raise_for_status=True, timeout=PAYONEER_DEFAULT_TIMEOUT, ) except Exception as e: raise OwsPayeeException( f'Failed to register banking details for payee {account_payee_id}: {e}' ) def get_tax_details_bulk( account_payee_ids: list[int], ) -> list[TaxDetailsDataloaderItem]: """Get tax details bulk.""" body = [{'accountPayeeId': item, 'revision': None} for item in account_payee_ids] try: response = post( SERVICE, '/account-payee/tax-details-dataloader', body, raise_for_status=True, ) except Exception as e: raise OwsPayeeException( f'Failed to get tax details for {account_payee_ids}: {e}' ) return TaxDetailsDataloaderItem.list_validate( [item['data'] for item in response.json() if item.get('data')] ) def get_payees_by_client_refs( payoneer_client_reference_ids: list[str], ) -> dict[str, int]: """Get payee dataloader.""" body = {'payoneer_client_reference_ids': payoneer_client_reference_ids} try: response = post( SERVICE, '/payee/dataloader', body, raise_for_status=True, ) except Exception as e: raise OwsPayeeException( f'Failed to get payee dataloader for {payoneer_client_reference_ids}: {e}' ) data = Payee.list_validate( [item['data'] for item in response.json().get('payees', []) if item.get('data')] ) return { item.payoneer_client_reference_id: item.payee_id for item in data if item.payoneer_client_reference_id and item.payee_id }