"""Schema for WorksheetPaymentCustom serialization.""" from decimal import Decimal from abacus_common_logic.marshalling.custom_fields import ma from marshmallow import validate, validates_schema, ValidationError class WorksheetPaymentCustomPostSchema(ma.Schema): """Post WorksheetPaymentCustom schema.""" account_id = ma.NonNegativeInteger(required=True) contract_id = ma.NonNegativeInteger(required=True) currency_code = ma.NonemptyString(required=True) amount = ma.Decimal( as_string=True, required=True, validate=validate.Range(min=0, min_inclusive=True), ) withholding_tax_amount = ma.Decimal( as_string=True, required=False, allow_none=False, load_default=Decimal('0'), ) withholding_tax_rate = ma.Decimal( as_string=True, required=False, allow_none=False, validate=validate.Range(min=0, min_inclusive=True), load_default=Decimal('0'), ) vat_amount = ma.Decimal( as_string=True, required=False, allow_none=False, load_default=Decimal('0'), ) vat_rate = ma.Decimal( as_string=True, required=False, allow_none=False, validate=validate.Range(min=0, min_inclusive=True), load_default=Decimal('0'), ) amount_after_withholding_and_vat = ma.Decimal( as_string=True, required=True, validate=validate.Range(min=0, min_inclusive=False), ) activity_statement_period_id = ma.NonNegativeInteger(required=True) statement_period_id = ma.NonNegativeInteger(required=True) payment_name = ma.NonemptyString(required=True) @validates_schema def validate_amount_calculation(self, data, **kwargs): """Validate that amount_after_withholding_and_vat = amount + wht + vat.""" amount = data.get('amount') wht = data.get('withholding_tax_amount') or Decimal('0') vat = data.get('vat_amount') or Decimal('0') amount_after = data.get('amount_after_withholding_and_vat') if amount is not None and amount_after is not None: expected = amount + wht + vat if amount_after != expected: raise ValidationError( f'amount_after_withholding_and_vat must equal amount + withholding_tax_amount + vat_amount. ' f'Expected {expected}, got {amount_after}', field_name='amount_after_withholding_and_vat', ) @validates_schema def validate_withholding_tax_rate(self, data, **kwargs): """Validate withholding_tax_rate.""" if data.get('withholding_tax_amount') and not data.get('withholding_tax_rate'): raise ValidationError( ma.Field.default_error_messages['required'], field_name='withholding_tax_rate', ) @validates_schema def validate_vat_rate(self, data, **kwargs): """Validate vat_rate.""" if data.get('vat_amount') and not data.get('vat_rate'): raise ValidationError( ma.Field.default_error_messages['required'], field_name='vat_rate' ) @validates_schema def validate_withholding_tax_amount(self, data, **kwargs): """Validate withholding_tax_amount.""" if data.get('withholding_tax_rate') and not data.get('withholding_tax_amount'): raise ValidationError( ma.Field.default_error_messages['required'], field_name='withholding_tax_amount', ) @validates_schema def validate_vat_amount(self, data, **kwargs): """Validate vat_amount.""" if data.get('vat_rate') and not data.get('vat_amount'): raise ValidationError( ma.Field.default_error_messages['required'], field_name='vat_amount' ) class WorksheetPaymentCustomDetailSchema(ma.Schema): """WorksheetPaymentCustom detail schema.""" worksheet_payment_custom_id = ma.NonNegativeInteger(required=True) account_id = ma.NonNegativeInteger(required=True) contract_id = ma.NonNegativeInteger(required=True) currency_code = ma.NonemptyString(required=True) amount = ma.Decimal(as_string=True, required=True) withholding_tax_amount = ma.Decimal(as_string=True, required=False, allow_none=True) withholding_tax_rate = ma.Decimal( as_string=True, required=False, allow_none=True, validate=validate.Range(min=0, min_inclusive=True), ) vat_amount = ma.Decimal(as_string=True, required=False, allow_none=True) vat_rate = ma.Decimal( as_string=True, required=False, allow_none=True, validate=validate.Range(min=0, min_inclusive=True), ) amount_after_withholding_and_vat = ma.Decimal(as_string=True, required=True) activity_statement_period_id = ma.NonNegativeInteger(required=True) statement_period_id = ma.NonNegativeInteger(required=True) payment_name = ma.NonemptyString(required=True) created_at = ma.FormattedDateTime(required=True) created_by = ma.String(required=True) last_modified = ma.FormattedDateTime(required=True) last_modified_by = ma.String(required=True) class WorksheetPaymentCustomFilterKeySchema(ma.Schema): """Filter key for filtering.""" worksheet_payment_custom_ids = ma.List(ma.NonNegativeInteger(), required=False) class WorksheetPaymentCustomFilterParamsPostSchema(ma.Schema): """Post request params for entries filtering.""" filters = ma.Nested( WorksheetPaymentCustomFilterKeySchema, required=False, load_default={}, ) class WorksheetPaymentCustomListSchema(ma.Schema): items = ma.Nested(WorksheetPaymentCustomDetailSchema, many=True) total_count = ma.NonNegativeInteger(required=True)