"""Contract Lifecycle Schedule marshmallow schema.""" from abacus_common_logic.marshalling.custom_fields import ma from marshmallow import ValidationError, validates_schema from marshmallow.validate import Range from abacus_contract.constants.constants import ( CONTRACT_LIFECYCLE_SCHEDULE_DETAIL_PERIOD_TYPES, CONTRACT_LIFECYCLE_SCHEDULE_RENEWAL_TYPES, ) from abacus_contract.constants.error import ( ERROR_RENEWAL_OFFSET_NOT_REQUIRED, ERROR_RENEWAL_OFFSET_REQUIRED, ERROR_SCHEDULE_END_NOT_REQUIRED, ) from abacus_contract.schemas.contract_lifecycle import ContractLifecyclePostSchema class ContractLifecycleScheduleSchema(ma.Schema): """Schema for contract_lifecycle_schedule details.""" contract_lifecycle_schedule_id = ma.IntegerId(required=True) contract_id = ma.IntegerId(required=True) termination_notice_detail_id = ma.IntegerId() renewal_offset_detail_id = ma.IntegerId() collection_period_detail_id = ma.IntegerId() renewal_type = ma.Enum( options=CONTRACT_LIFECYCLE_SCHEDULE_RENEWAL_TYPES, required=True, data_key='renewal_type', ) schedule_end = ma.FormattedDate(allow_none=True) contract_lifecycle = ma.Nested(ContractLifecyclePostSchema, allow_none=True) class ContractLifecycleSchedulePostSchema(ma.Schema): """Schema for contract_lifecycle_schedule POST request.""" renewal_type = ma.Enum( options=CONTRACT_LIFECYCLE_SCHEDULE_RENEWAL_TYPES, required=True, data_key='renewal_type', ) termination_notice_detail_interval = ma.IntegerId( required=True, validate=[Range(min=1)] ) termination_notice_detail_type = ma.Enum( options=CONTRACT_LIFECYCLE_SCHEDULE_DETAIL_PERIOD_TYPES, required=True, data_key='termination_notice_detail_type', ) renewal_offset_detail_interval = ma.IntegerId( allow_none=True, validate=[Range(min=1)] ) renewal_offset_detail_type = ma.Enum( options=CONTRACT_LIFECYCLE_SCHEDULE_DETAIL_PERIOD_TYPES, data_key='renewal_offset_detail_type', allow_none=True, ) collection_period_detail_interval = ma.IntegerId( allow_none=True, validate=[Range(min=1)] ) collection_period_detail_type = ma.Enum( options=CONTRACT_LIFECYCLE_SCHEDULE_DETAIL_PERIOD_TYPES, data_key='collection_period_detail_type', allow_none=True, ) schedule_end = ma.FormattedDate(allow_none=True) contract_lifecycle = ma.Nested(ContractLifecyclePostSchema, allow_none=True) @validates_schema def validate_schedule_detail_fields(self, data, **kwargs): """Validate schedule detail fields.""" renew_periodically_renewal_type = ( CONTRACT_LIFECYCLE_SCHEDULE_RENEWAL_TYPES.RENEW_PERIODICALLY ) renew_after_certain_date_renewal_type = ( CONTRACT_LIFECYCLE_SCHEDULE_RENEWAL_TYPES.RENEW_AFTER_CERTAIN_DATE ) renewal_type = data.get('renewal_type') schedule_end = data.get('schedule_end') renewal_offset_detail_interval = data.get('renewal_offset_detail_interval') renewal_offset_detail_type = data.get('renewal_offset_detail_type') if renewal_type == renew_periodically_renewal_type: if ( ( renewal_offset_detail_interval is None and renewal_offset_detail_type is None ) or ( renewal_offset_detail_interval is not None and renewal_offset_detail_type is None ) or ( renewal_offset_detail_interval is None and renewal_offset_detail_type is not None ) ): raise ValidationError( ERROR_RENEWAL_OFFSET_REQUIRED.format( renew_periodically_renewal_type ) ) else: if ( renewal_offset_detail_interval is not None or renewal_offset_detail_type is not None ): raise ValidationError( ERROR_RENEWAL_OFFSET_NOT_REQUIRED.format( renew_periodically_renewal_type ) ) # check schedule_end if ( schedule_end is not None and renewal_type != renew_after_certain_date_renewal_type ): raise ValidationError( ERROR_SCHEDULE_END_NOT_REQUIRED.format( renew_after_certain_date_renewal_type ) ) class ContractLifecycleSchedulePutSchema(ContractLifecycleSchedulePostSchema): """Schema for contract_lifecycle_schedule PUT request.""" contract_lifecycle_schedule_id = ma.IntegerId(allow_none=True)