"""Contract Term marshmallow schemas.""" from abacus_common_logic.marshalling.custom_fields import ma from marshmallow import ValidationError, validates, validates_schema from abacus_contract.constants import constants, error from abacus_contract.schemas.contract_term_condition import ( ContractTermConditionPostSchema, ) class AttachmentsRelationsSchema(ma.Schema): """Schema for contract term's nested attachments_relations.""" contributor_ids = ma.List(ma.String) label_ids = ma.List(ma.String()) upcs = ma.List(ma.String()) class ContractTermSchema(ma.Schema): """Contract term fields.""" contract_term_id = ma.IntegerId(required=True) contract_id = ma.IntegerId(required=True) contract_term_name = ma.String() term_type = ma.Enum(options=constants.CONTRACT_TERM_TYPES, required=True) attachments = ma.List(ma.String(), allow_none=True) attachments_relations = ma.Nested(AttachmentsRelationsSchema, allow_none=True) is_base_term = ma.Boolean() class ContractTermPostSchema(ma.Schema): """Contract term POST fields.""" contract_term_name = ma.String() term_type = ma.Enum(options=constants.CONTRACT_TERM_TYPES, required=True) attachments = ma.List(ma.String(), allow_none=True) attachments_relations = ma.Nested(AttachmentsRelationsSchema, allow_none=True) is_base_term = ma.Boolean() # TODO: After removing attachments and attachments_relations, # update the schedule_ids field to required. schedule_ids = ma.List(ma.String()) @validates_schema def check_attachments_and_schedule_ids(self, data, **kwargs): """Validate attachments and schedule_ids.""" term_type = data.get('term_type') schedule_ids = data.get('schedule_ids') valid_term_types = [ constants.CONTRACT_TERM_TYPES.CONTRIBUTOR_SCHEDULE, constants.CONTRACT_TERM_TYPES.CONTRIBUTION_SCHEDULE, ] if term_type in valid_term_types and ( schedule_ids is None or len(schedule_ids) < 1 ): raise ValidationError(error.ERROR_MISSING_SCHEDULE_IDS) class ContractTermPutSchema(ma.Schema): """Contract term PUT fields.""" contract_term_name = ma.String() term_type = ma.Enum(options=constants.CONTRACT_TERM_TYPES) attachments = ma.List(ma.String(), allow_none=True) attachments_relations = ma.Nested(AttachmentsRelationsSchema, allow_none=True) is_base_term = ma.Boolean() schedule_ids = ma.List(ma.String()) @validates_schema def check_attachments_and_schedule_ids(self, data, **kwargs): """Validate attachments and schedule_ids.""" attachments = data.get('attachments') schedule_ids = data.get('schedule_ids') if schedule_ids is not None and len(schedule_ids) < 1: raise ValidationError(error.ERROR_MISSING_SCHEDULE_IDS) if attachments is not None and len(attachments) < 1: raise ValidationError(error.ERROR_MISSING_ATTACHMENT) class ContractTermVerboseSchema(ContractTermSchema): """Contract Term schema with created and last_modified info.""" created_at = ma.FormattedDateTime() created_by = ma.String() last_modified = ma.FormattedDateTime() last_modified_by = ma.String() class ContractTermBulkPostSchema(ContractTermSchema): """Contract Term schema with nested contract_term_conditions for bulk creation.""" contract_term_conditions = ma.Nested(ContractTermConditionPostSchema, many=True) class ContractTermsByAccountTermTypePostSchema(ma.Schema): """POST schema to get contract terms by attachments and term_type.""" attachments = ma.List(ma.String(), required=True) term_type = ma.Enum(options=constants.CONTRACT_TERM_TYPES, required=True) @validates('attachments') def validate_attachments_length(self, value): """Validate attachments field.""" if len(value) < 1: raise ValidationError(error.ERROR_MISSING_ATTACHMENT)