"""ScheduleAttachment logic.""" from typing import Type from abacus_common_logic.connectors.database import db from owsresponse import response from abacus_schedule import models from abacus_schedule.schemas.schedule_attachment import ScheduleAttachmentDetailSchema from abacus_schedule.utils.format_error import validation_error def get_schedule_attachments_by_schedule_id( schedule_id: int, limit: int, offset: int ) -> Type[response.Response]: """Get a list of schedule_attachment by schedule id. Args: schedule_id(int): Id of schedule. limit (int): The number of items to return; the size of the page. offset (int): The number of items to skip before returning results; the page num. Returns: A list of schedule attachments. """ models.Schedule.get_by_id_or_error(schedule_id) items, total_count = ( models.ScheduleAttachment.get_schedule_attachments_by_schedule_id( schedule_id, limit, offset ) ) message = dict( items=ScheduleAttachmentDetailSchema(many=True).dump(items), total_count=total_count, ) return response.Response(message=message, status=200) def soft_delete_schedule_attachment( schedule_attachment: models.ScheduleAttachment, ) -> Type[response.Response]: """Soft delete schedule_attchment. Args: schedule_attachment (models.ScheduleAttachment): ScheduleAttachment model object """ models.ScheduleAttachment.delete_by_id_or_error( schedule_attachment.schedule_attachment_id, soft_delete=True ) return response.Response(status=204) def _bulk_create_schedule_attachments( schedule_id: int, target_ids: list, target_type: str ) -> list: """Create schedule attachments. If schedule_attachment already exists for specified target_id, target_type, and schedule_id and has been deleted, then this method updates the "deleted_at" and "deleted_by" columns of schedule_attachment to NULL, otherwise it creates a new schedule_attachment. Args: schedule_id (int): id of the schedule target_ids (list): a list of target ids target_type (str): target type of schedule_attachment Returns: A list of newly created schedule_attachment records. """ existing_schedule_attachments = models.ScheduleAttachment.get_schedule_attachments( schedule_id, target_ids, target_type ) existing_target_ids = [ schedule_attachment.target_id for schedule_attachment in existing_schedule_attachments ] non_existing_target_ids = list(set(target_ids) - set(existing_target_ids)) schedule_attachments = list() try: if non_existing_target_ids: for target_id in non_existing_target_ids: schedule_attachment = dict( schedule_id=schedule_id, target_type=target_type, target_id=target_id, ) new_record = models.ScheduleAttachment.build(**schedule_attachment) schedule_attachments.append(new_record) db.session.commit() if existing_schedule_attachments: for schedule_attachment in existing_schedule_attachments: updated_schedule_attachment = dict( schedule_attachment_id=schedule_attachment.schedule_attachment_id, deleted_by=None, deleted_at=None, ) schedule_attachment.update_attributes(**updated_schedule_attachment) schedule_attachments.append(schedule_attachment) db.session.commit() except Exception as e: raise e return schedule_attachments def _bulk_soft_delete_schedule_attachments( schedule_id: int, target_ids: list, target_type: str ) -> bool: """Delete schedule attachments. Args: schedule_id (int): id of the schedule target_ids (list): a list of target ids target_type (str): target type of schedule_attachment """ schedule_attachments = models.ScheduleAttachment.get_schedule_attachments( schedule_id, target_ids, target_type ) for schedule_attachment in schedule_attachments: if ( schedule_attachment.deleted_by is None and schedule_attachment.deleted_at is None ): models.ScheduleAttachment.delete_by_id_or_error( schedule_attachment.schedule_attachment_id, soft_delete=True ) return True def bulk_update_schedule_attachments( schedule_id: int, target_type: str, params: dict ) -> Type[response.Response]: """ADD/DELETE schedule attachments for a specified schedule_id. Args: schedule_id (int): id of the schedule target_type (str): target type of schedule_attachment params (dict): a dict of list of target ids that need to be created or deleted - unassigned_target_ids (list): a list of target ids to be deleted - assigned_target_ids (list): a list of target ids to be created """ unassigned_target_ids = params.get('unassigned_target_ids', None) assigned_target_ids = params.get('assigned_target_ids', None) models.Schedule.get_by_id_or_error(schedule_id) try: ScheduleAttachmentDetailSchema(only=('target_type',)).load( {'target_type': target_type} ) if unassigned_target_ids: _bulk_soft_delete_schedule_attachments( schedule_id, unassigned_target_ids, target_type ) if assigned_target_ids: _bulk_create_schedule_attachments( schedule_id, assigned_target_ids, target_type ) except Exception as e: return validation_error(str(e)) return response.Response( message='Schedule Attachments created/deleted successfully.', status=200 )