"""Logic for ContractTermSchedule.""" from typing import Type from owsresponse import response from abacus_contract import models from abacus_contract.schemas.contract_term_schedule import ( ContractTermScheduleDetailSchema, ) def get_contract_term_schedules_by_term_id( contract_term_id: int, ) -> Type[response.Response]: """GET a list of contract_term_schedule's by contract_term_id. Arg: contract_term_id(int): id of the related contract_term Returns: A list of contract term schedules """ models.ContractTerm.get_by_id_or_error(contract_term_id) items = models.ContractTermSchedule.get_by_term_id(contract_term_id) return response.Response( message=ContractTermScheduleDetailSchema().dump(items, many=True), status=200 ) def get_contract_term_schedule_records_by_term_ids(authorized_term_ids: list) -> list: """Flat ContractTermScheduleDetailSchema records for the authorized term ids (each carries contract_term_id).""" if not authorized_term_ids: return [] schedules = models.ContractTermSchedule.get_by_term_ids(authorized_term_ids) return ContractTermScheduleDetailSchema(many=True).dump(schedules) def create_or_update_contract_term_schedules( schedule_ids: list, contract_term_id: int ) -> Type[response.Response]: """Create schedule contract_term_schedules. Args: schedule_ids (list): a list of ids of the schedule contract_term_id (list): id of the related contract_term Returns: A list of created/updated contract_term_schedule records. """ contract_term_schedules = list() contract_term = models.ContractTerm.get_by_id(contract_term_id) items = contract_term.contract_term_schedule existing_schedules = dict([(str(item.schedule_id), item) for item in items]) if existing_schedules: existing_term_schedule_ids = list(existing_schedules.keys()) new_schedule_ids = list(set(schedule_ids) - set(existing_term_schedule_ids)) if new_schedule_ids: contract_term_schedules = create_contract_term_schedules( new_schedule_ids, contract_term_id ) contract_term_schedules = delete_or_restore_contract_term_schedules( existing_schedules, existing_term_schedule_ids, schedule_ids ) else: contract_term_schedules = create_contract_term_schedules( schedule_ids, contract_term_id ) return response.Response( message=ContractTermScheduleDetailSchema().dump( contract_term_schedules, many=True ), status=200, ) def create_contract_term_schedules( schedule_ids: list, contract_term_id: int ) -> Type[response.Response]: """Create one or more contract_term_schedules. Args: schedule_ids (list): a list of the related schedule ids contract_term_id (list): id of the related contract_term Returns: A list of new contract_term_schedule records. """ try: contract_term_schedules = list() for schedule_id in schedule_ids: contract_term_schedule = models.ContractTermSchedule.build( contract_term_id=contract_term_id, schedule_id=schedule_id ) contract_term_schedules.append(contract_term_schedule) models.ContractTermSchedule.commit_changes() except Exception as e: raise e return contract_term_schedules def delete_or_restore_contract_term_schedules( existing_schedules: list, existing_term_schedule_ids: list, new_schedule_ids: list ): """Delete/Restore the contact_term_schedules. If a contract_term_schedule already exists for the specified contract_term_id, schedule_id and If a record has been deleted, then this method will update the "deleted_at" and "deleted_by" columns to NULL. If a contract_term_schedule already exists for specified contract_term_id, schedule_id but schedule_id is not included in the PUT request, then contract_term_schedule gets soft deleted. Args: existing_schedules (list): a list of existing contract term schedules existing_term_schedule_ids (list): a list of existing term schedule ids new_schedule_ids (list): a list of new schedules ids Returns: """ # if existing non-deleted contract-term-schedules are not available # in the PUT request then soft delete those records from the table. try: contract_term_schedules = list() deleted_schedule_ids = list( set(existing_term_schedule_ids) - set(new_schedule_ids) ) if deleted_schedule_ids: for schedule_id in deleted_schedule_ids: contract_term_schedule = existing_schedules[schedule_id] if ( contract_term_schedule.deleted_by is None or contract_term_schedule.deleted_by is None ): contract_term_schedule.delete_by_id_or_error( contract_term_schedule.contract_term_schedule_id, soft_delete=True, ) # if previously deleted contract_term_schedules are added back, # then the deleted_by and deleted_at column should be updated to NULL. common_schedule_ids = list( set(new_schedule_ids) & set(existing_term_schedule_ids) ) if common_schedule_ids: for schedule_id in common_schedule_ids: contract_term_schedule = existing_schedules[schedule_id] if schedule_id in existing_schedules and ( contract_term_schedule.deleted_by is not None or contract_term_schedule.deleted_at is not None ): updated_contract_term_schedules = dict( contract_term_schedule_id=contract_term_schedule.contract_term_schedule_id, deleted_by=None, deleted_at=None, ) contract_term_schedule.update_attributes( **updated_contract_term_schedules ) contract_term_schedules.append(contract_term_schedule) models.ContractTermSchedule.commit_changes() except Exception as e: raise e return contract_term_schedules