"""Account marshmallow schemas.""" import json from datetime import datetime from typing import TypedDict from abacus_common_logic.marshalling.custom_fields import ma from marshmallow import fields, pre_dump, validate from abacus_account.constants import constants class AccountDetailSchema(ma.Schema): """Account fields.""" account_id = ma.IntegerId(required=True) account_name = ma.NonemptyString(required=True) created_by = ma.NonemptyString(required=False, allow_none=False) sap_created_at = ma.FormattedDateTime() account_payee_id = ma.Pluck( 'AccountPayeeDetailSchema', 'account_payee_id', attribute='account_payee', allow_none=True, ) account_payment_term_id = ma.Pluck( 'AccountPaymentTermDetailSchema', 'account_payment_term_id', attribute='account_payment_term', allow_none=True, ) class AccountPostSchema(AccountDetailSchema): """Account POST body.""" currency_code = ma.NonemptyString(validate=[validate.Length(equal=3)]) country_of_tax_residence = ma.NonemptyString( required=False, allow_none=True, validate=[validate.Length(equal=3)] ) creation_source = ma.NonemptyString(required=False) class AccountPutSchema(ma.Schema): """Account PUT body.""" account_name = ma.NonemptyString() sap_created_at = ma.FormattedDateTime() class ContractsPayableSchema(ma.Schema): """Contract payable balance information.""" def dump(self, data, **kwargs): """Load data from string to json.""" data = json.loads(data) return super().dump(data, **kwargs) contract_id = ma.IntegerId() current_balance = ma.Decimal(as_string=True) currency_code = ma.NonemptyString() class EligibleAccountListSchema(ma.Schema): """Account and payment term info for eligible accounts.""" current_balance = ma.Decimal(as_string=True, allow_none=True, required=False) contracts_payable = fields.Nested(ContractsPayableSchema(many=True), required=False) contracts = fields.List(ma.IntegerId(), required=False) eligibility_status = ma.String(required=False) account_id = ma.IntegerId(required=True) payment_method = ma.String() account_name = ma.NonemptyString(required=True) currency_code = ma.NonemptyString(required=True) payment_entity_id = ma.IntegerId(required=True) payment_minimum = ma.Decimal(as_string=True, allow_none=True) payment_schedule = ma.Enum(options=constants.PAYMENT_SCHEDULE, allow_none=True) country_of_tax_residence = ma.NonemptyString( required=True, validate=[validate.Length(equal=3)] ) payoneer_program_id = ma.NonNegativeInteger() @pre_dump def load_contracts(self, in_data, **kwargs): """Convert contracts to python type.""" try: in_data = {**in_data, 'contracts': json.loads(in_data['contracts'])} except Exception: pass return in_data class SAPFormattedAccountDetailSchema(ma.Schema): """SAP formatted account fields.""" account_name = ma.TruncatedString( required=True, data_key='AcctName', metadata={'truncate': 100} ) account_id = ma.NonemptyString(required=True, data_key='AccountId') Kunnr = ma.IntegerId(default=None) Lifnr = ma.IntegerId(default=None) Zzfield2 = ma.NonemptyString(default=None) Zzfield1 = ma.NonemptyString(default=None) class AccountDetail(TypedDict): """TypedDict that mirrors the serialized output from AccountDetailSchema.""" account_id: int account_name: str created_by: str sap_created_at: datetime | None account_payee_id: int | None account_payment_term_id: int | None