|
1 | 1 | import logging |
2 | 2 | from datetime import date, timedelta |
3 | 3 | from typing import Literal |
| 4 | +from itertools import zip_longest |
4 | 5 |
|
5 | 6 | from auth_lib.fastapi import UnionAuth |
6 | 7 | from fastapi import APIRouter, Depends, Query, status |
7 | 8 | from fastapi.responses import FileResponse, JSONResponse |
8 | 9 | from fastapi_sqlalchemy import db |
9 | 10 | from pydantic import TypeAdapter |
10 | 11 |
|
11 | | -from calendar_backend.exceptions import NotEnoughCriteria |
| 12 | +from calendar_backend.exceptions import NotEnoughCriteria, ObjectNotFound |
12 | 13 | from calendar_backend.methods import list_calendar |
13 | | -from calendar_backend.models import Event, Group, Lecturer, Room |
| 14 | +from calendar_backend.models import Event, Group, Lecturer, Room, EventsRooms, EventsGroups, EventsLecturers |
14 | 15 | from calendar_backend.routes.models import EventGet |
15 | 16 | from calendar_backend.routes.models.event import ( |
16 | 17 | EventPatch, |
@@ -199,7 +200,49 @@ async def patch_event_by_name( |
199 | 200 | async def patch_event( |
200 | 201 | id: int, event_inp: EventPatch, _=Depends(UnionAuth(scopes=["timetable.event.update"])) |
201 | 202 | ) -> EventGet: |
202 | | - patched = Event.update(id, session=db.session, **event_inp.model_dump(exclude_unset=True)) |
| 203 | + |
| 204 | + # проверяем, что событие с таким id существует |
| 205 | + Events = db.session.query(Event).filter(Event.id == id).one_or_none() |
| 206 | + if not Events: |
| 207 | + raise ObjectNotFound(type=type(Events), ids=id) |
| 208 | + |
| 209 | + event_upd_data = event_inp.model_dump(exclude_unset=True) |
| 210 | + # получаем списки id всех существующих аудиторий, групп и лекторов |
| 211 | + all_rooms = [room.id for room in db.session.query(Room).all()] |
| 212 | + all_groups = [group.id for group in db.session.query(Group).all()] |
| 213 | + all_lecturers = [lecturer.id for lecturer in db.session.query(Lecturer).all()] |
| 214 | + # проверяем cуществование заданных в body (room_, group_, lecturer_)*id |
| 215 | + for r, g, l in zip_longest(event_upd_data.get("room_id"), event_upd_data.get("group_id"), event_upd_data.get("lecturer_id"), fillvalue=None): |
| 216 | + if r not in all_rooms: |
| 217 | + raise ObjectNotFound(type=type(Room), ids=r) |
| 218 | + if g not in all_groups: |
| 219 | + raise ObjectNotFound(type=type(Group), ids=g) |
| 220 | + if l not in all_lecturers: |
| 221 | + raise ObjectNotFound(type=type(Lecturer), ids=l) |
| 222 | + |
| 223 | + def add_new_remove_old_ids(dbsession, event_id, artefact: str, event_instance, negotiator_instance) -> None: |
| 224 | + """Вспомогательная фукнция описывающая удаление старых и добавление новых (room_, group_, lecturer_)*id - артефактов""" |
| 225 | + # получаем множество артефактов события |
| 226 | + event_artefacts = {room.id for room in getattr(event_instance, f"{artefact}")} |
| 227 | + # получаем множетсво страрых артефактов |
| 228 | + old_artefacts = event_artefacts - set(event_upd_data.get(f"{artefact}_id")) |
| 229 | + # получаем множество новых артефактов |
| 230 | + new_artefacts = set(event_upd_data.get(f"{artefact}_id")) - event_artefacts |
| 231 | + # получаем артефакты к удалению(уникальные старые) |
| 232 | + to_remove = old_artefacts - new_artefacts |
| 233 | + # получаем артефакты к созданию(уникальные новые) |
| 234 | + to_add = new_artefacts - old_artefacts |
| 235 | + |
| 236 | + if to_remove: |
| 237 | + dbsession.query(negotiator_instance).filter(negotiator_instance.event_id==event_id, getattr(negotiator_instance, f"{artefact}_id").in_(to_remove)).delete() |
| 238 | + if to_add: |
| 239 | + dbsession.bulk_insert_mappings(negotiator_instance, [{"event_id" : f"{event_id}", f"{artefact}_id" : id_to_add} for id_to_add in to_add]) |
| 240 | + |
| 241 | + add_new_remove_old_ids(db.session, id, "room", Events, EventsRooms) |
| 242 | + add_new_remove_old_ids(db.session, id, "group", Events, EventsGroups) |
| 243 | + add_new_remove_old_ids(db.session, id, "lecturer", Events, EventsLecturers) |
| 244 | + |
| 245 | + patched = Event.update(id, session=db.session, **event_upd_data) |
203 | 246 | db.session.commit() |
204 | 247 | return EventGet.model_validate(patched) |
205 | 248 |
|
|
0 commit comments