felicity-lims/felicity/api/gql/client/mutations.py
2023-04-25 16:42:39 +02:00

223 lines
7.6 KiB
Python

import logging
from typing import Dict, Optional
import strawberry # noqa
from api.gql import OperationError, DeletedItem, auth_from_info, verify_user_auth
from api.gql.client.types import ClientContactType, ClientType
from apps.client import models, schemas
from core.uid_gen import FelicityID
from strawberry.types import Info # noqa
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
ClientResponse = strawberry.union(
"ClientResponse", (ClientType, OperationError), description="" # noqa
)
ClientContactResponse = strawberry.union(
"ClientContactResponse", (ClientContactType, OperationError), description="" # noqa
)
DeleteContactResponse = strawberry.union(
"DeleteContactResponse", (DeletedItem, OperationError), description="" # noqa
)
@strawberry.input
class ClientInputType:
name: str
code: str
district_uid: FelicityID | None = None
email: str | None = None
email_cc: str | None = None
consent_email: bool| None = False
phone_mobile: str | None = None
phone_business: str | None = None
consent_sms: bool| None = False
internal_use: bool| None = False
active: bool| None = True
@strawberry.input
class ClientContactInputType:
first_name: str
client_uid: FelicityID
last_name: str | None = None
email: str | None = None
email_cc: str | None = None
mobile_phone: str | None = None
consent_sms: bool| None = False
is_active: bool = True
@strawberry.type
class ClientMutations:
@strawberry.mutation
async def create_client(
self, info: Info, payload: ClientInputType
) -> ClientResponse:
is_authenticated, felicity_user = await auth_from_info(info)
success, auth_err = verify_user_auth(
is_authenticated,
felicity_user,
"Only Authenticated user can create clients",
)
if not success:
return auth_err
if not payload.code or not payload.name:
return OperationError(
error="Please Provide a name and a unique client code"
)
exists = await models.Client.get(code=payload.code)
if exists:
return OperationError(
error=f"Client code {payload.code} already belong to client {exists.name}"
)
incoming: dict = {
"created_by_uid": felicity_user.uid,
"updated_by_uid": felicity_user.uid,
}
for k, v in payload.__dict__.items():
incoming[k] = v
obj_in = schemas.ClientCreate(**incoming)
client: models.Client = await models.Client.create(obj_in)
return ClientType(**client.marshal_simple())
@strawberry.mutation
async def update_client(
self, info, uid: FelicityID, payload: ClientInputType
) -> ClientResponse:
is_authenticated, felicity_user = await auth_from_info(info)
verify_user_auth(
is_authenticated,
felicity_user,
"Only Authenticated user can update clients",
)
if not uid:
return OperationError(error="No uid provided to identify update obj")
client = await models.Client.get(uid=uid)
if not client:
return OperationError(
error=f"Client with uid {uid} not found. Cannot update obj ..."
)
obj_data = client.to_dict()
for field in obj_data:
if field in payload.__dict__:
try:
setattr(client, field, payload.__dict__[field])
except Exception as e:
logger.warning(f"failed to set attribute {field}: {e}")
obj_in = schemas.ClientUpdate(**client.to_dict())
client = await client.update(obj_in)
return ClientType(**client.marshal_simple())
@strawberry.mutation
async def create_client_contact(
self, info, payload: ClientContactInputType
) -> ClientContactResponse:
is_authenticated, felicity_user = await auth_from_info(info)
verify_user_auth(
is_authenticated,
felicity_user,
"Only Authenticated user can create client contacts",
)
if not payload.client_uid or not payload.first_name:
return OperationError(error="Please Provide a first_name and a client uid")
client_exists = await models.Client.get(uid=payload.client_uid)
if not client_exists:
return OperationError(
error=f"Client with uid {payload.client_uid} does not exist"
)
contact_exists = await models.ClientContact.get_all(
client_uid=payload.client_uid, first_name=payload.first_name
) # noqa
logger.warning(contact_exists)
if contact_exists:
return OperationError(
error=f"Client Contact with name {payload.first_name} already exists"
)
incoming: dict = {
"created_by_uid": felicity_user.uid,
"updated_by_uid": felicity_user.uid,
}
for k, v in payload.__dict__.items():
incoming[k] = v
obj_in = schemas.ClientContactCreate(**incoming)
client_contact: models.ClientContact = await models.ClientContact.create(obj_in)
return ClientContactType(**client_contact.marshal_simple(exclude=["is_superuser", "auth_uid"]))
@strawberry.mutation
async def update_client_contact(
self, info, uid: FelicityID, payload: ClientContactInputType
) -> ClientContactResponse:
is_authenticated, felicity_user = await auth_from_info(info)
verify_user_auth(
is_authenticated,
felicity_user,
"Only Authenticated user can update client contacts",
)
if not uid:
return OperationError(error="No uid provided to identify update obj")
client_contact = await models.ClientContact.get(uid=uid)
if not client_contact:
return OperationError(
error=f"Client Contact with uid {uid} not found. Cannot update obj ..."
)
obj_data = client_contact.to_dict()
for field in obj_data:
if field in payload.__dict__:
try:
setattr(client_contact, field, payload.__dict__[field])
except Exception as e:
logger.warning(f"failed to set attribute {field}: {e}")
obj_in = schemas.ClientContactUpdate(**client_contact.to_dict())
client_contact = await client_contact.update(obj_in)
return ClientContactType(**client_contact.marshal_simple(exclude=["is_superuser", "auth_uid"]))
@strawberry.mutation
async def delete_client_contact(self, info, uid: FelicityID) -> DeleteContactResponse:
is_authenticated, felicity_user = await auth_from_info(info)
verify_user_auth(
is_authenticated,
felicity_user,
"Only Authenticated user can delete/deactivate client contacts",
)
if not uid:
return OperationError(error="No uid provided to identify deletion obj")
client_contact = await models.ClientContact.get(uid=uid)
if not client_contact:
return OperationError(
error=f"Client Contact with uid {uid} not found. Cannot delete obj ..."
)
try:
setattr(client_contact, "is_active", False)
except Exception as e:
logger.warning(f"failed to set attribute {field}: {e}")
obj_in = schemas.ClientContactUpdate(**client_contact.to_dict())
client_contact = await client_contact.update(obj_in)
return DeletedItem(uid=client_contact.uid)