felicity-lims/felicity/api/gql/noticeboard/mutations.py
2024-07-26 23:29:01 +02:00

150 lines
5.2 KiB
Python

import logging
from typing import List, Optional
import strawberry # noqa
from felicity.api.gql.auth import auth_from_info
from felicity.api.gql.noticeboard.types import NoticeType
from felicity.api.gql.permissions import IsAuthenticated
from felicity.api.gql.types import DeletedItem, DeleteResponse, OperationError
from felicity.apps.noticeboard import schemas
from felicity.apps.noticeboard.services import NoticeService
from felicity.apps.user.services import GroupService, UserService
from felicity.apps.setup.services import DepartmentService
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
NoticeResponse = strawberry.union(
"NoticeResponse",
(NoticeType, OperationError), # noqa
description="Union of possible outcomes when adding a new notice",
)
@strawberry.input
class NoticeInputType:
title: str
body: str
expiry: str
groups: Optional[List[str]]
departments: Optional[List[str]]
@strawberry.type
class NoticeMutations:
@strawberry.mutation(permission_classes=[IsAuthenticated])
async def create_notice(self, info, payload: NoticeInputType) -> NoticeResponse:
felicity_user = await auth_from_info(info)
if not payload.title or not payload.body or not payload.expiry:
return OperationError(
error="Some fields have missing required data",
suggestion="Make sure that the fields: [title, body, expiry] all have values",
)
exists = await NoticeService().get(title=payload.title)
if exists:
return OperationError(
error="Notice title Duplication not Allowed",
suggestion=f"Change the notice title",
)
incoming = {
"created_by_uid": felicity_user.uid,
"updated_by_uid": felicity_user.uid,
}
for k, v in payload.__dict__.items():
incoming[k] = v
if payload.groups:
incoming["groups"] = []
for g_uid in payload.groups:
_gr = GroupService().get(uid=g_uid)
if _gr:
incoming["groups"].append(_gr)
if payload.departments:
incoming["departments"] = []
for dept_uid in payload.departments:
_gr = DepartmentService().get(uid=dept_uid)
if _gr:
incoming["departments"].append(_gr)
obj_in = schemas.NoticeCreate(**incoming)
notice = await NoticeService().create(obj_in)
return NoticeType(**notice.marshal_simple())
@strawberry.mutation(permission_classes=[IsAuthenticated])
async def update_notice(
self, info, uid: str, payload: NoticeInputType
) -> NoticeResponse:
felicity_user = await auth_from_info(info)
notice = await NoticeService().get(uid=uid)
if not notice:
raise OperationError(
error=f"notice with uid {uid} does not exist",
suggestion=f"Refresh page",
)
notice_data = notice.to_dict()
for field in notice_data:
if field in payload.__dict__:
try:
setattr(notice, field, payload.__dict__[field])
except Exception as e:
logger.warning(e)
if payload.groups:
_groups = []
for g_uid in payload.groups:
_gr = GroupService().get(uid=g_uid)
if _gr:
_groups.append(_gr)
setattr(notice, "groups", _groups)
if payload.departments:
_departments = []
for dept_uid in payload.departments:
_gr = DepartmentService().get(uid=dept_uid)
if _gr:
_departments.append(_gr)
setattr(notice, "departments", _departments)
setattr(notice, "update_by_uid", felicity_user.uid)
notice_in = schemas.NoticeUpdate(**notice.to_dict())
notice = await NoticeService().update(notice.uid, notice_in)
return NoticeType(**notice.marshal_simple())
@strawberry.mutation(permission_classes=[IsAuthenticated])
async def view_notice(self, info, uid: str, viewer: str) -> NoticeType:
felicity_user = await auth_from_info(info)
notice = await NoticeService().get(uid=uid)
if not notice:
raise Exception(f"Notice with uid {uid} does not exist")
_viewer = await UserService().get(uid=viewer)
if not _viewer:
raise Exception(f"User with uid {viewer} does not exist")
notice = await NoticeService().add_viewer(notice.uid, _viewer)
return NoticeType(**notice.marshal_simple())
@strawberry.mutation(permission_classes=[IsAuthenticated])
async def delete_notice(self, info, uid: str) -> DeleteResponse:
felicity_user = await auth_from_info(info)
notice = await NoticeService().get(uid=uid)
if not notice:
raise Exception(f"Notice with uid {uid} does not exist")
await notice.delete()
return DeletedItem(uid=uid)