from enum import Enum from mongoengine import Document, StringField from apiserver.apierrors import errors from apiserver.database.model.base import DbModelMixin, ABSTRACT_FLAG from apiserver.database.model.company import Company from apiserver.database.model.user import User class AttributedDocument(DbModelMixin, Document): """ Represents objects which are attributed to a company and a user or to "no one". Company must be required since it can be used as unique field. """ meta = ABSTRACT_FLAG company = StringField(required=True, reference_field=Company) user = StringField(reference_field=User) def is_public(self) -> bool: return bool(self.company) class PrivateDocument(AttributedDocument): """ Represents documents which always belong to a single company """ meta = ABSTRACT_FLAG # can not have an empty string as this is the "public" marker company = StringField(required=True, reference_field=Company, min_length=1) user = StringField(reference_field=User, required=True) def is_public(self) -> bool: return False def validate_id(cls, company, **kwargs): """ Validate existence of objects with certain IDs. within company. :param cls: Model class to search in :param company: Company to search in :param kwargs: Mapping of field name to object ID. If any ID does not have a corresponding object, it will be reported along with the name it was assigned to. :return: """ ids = set(kwargs.values()) objs = list(cls.objects(company=company, id__in=ids).only('id')) missing = ids - set(x.id for x in objs) if not missing: return id_to_name = {} for name, obj_id in kwargs.items(): id_to_name.setdefault(obj_id, []).append(name) raise errors.bad_request.ValidationError( 'Invalid {} ids'.format(cls.__name__.lower()), **{name: obj_id for obj_id in missing for name in id_to_name[obj_id]} ) class EntityVisibility(Enum): active = "active" archived = "archived"