Esempio n. 1
0
 def post(
     self, request, contact_id, case_id, case_role_id=None, submission_id=None, *args, **kwargs
 ):
     notify_template_key = None
     try:
         contact = Contact.objects.select_related("userprofile", "organisation").get(
             id=contact_id
         )
         case_role = get_role(case_role_id)
         case = Case.objects.get(id=case_id)
         notify_template_key = case.type.meta.get("invite_notify_template_key")
     except Contact.DoesNotExist:
         raise NotFoundApiExceptions("Invalid contact id.")
     except CaseRole.DoesNotExist:
         raise NotFoundApiExceptions("Invalid case role id")
     except Case.DoesNotExist:
         raise InvalidRequestParams("Invalid case id")
     if not contact.organisation and contact.has_user:
         contact.organisation = contact.user.organisation.organisation
     # check if an invite exists already
     created = False
     invitation_kwargs = {}
     if submission_id:
         invitation_kwargs["submission__id"] = submission_id
     organisation_id = request.data.get("organisation_id")
     if organisation_id:
         organisation = Organisation.objects.get(id=organisation_id)
     else:
         organisation = contact.organisation
     try:
         invitation = Invitation.objects.get(
             contact=contact,
             case=case,
             organisation=organisation,
             deleted_at__isnull=True,
             **invitation_kwargs,
         )
     except Invitation.DoesNotExist:
         invitation = Invitation.objects.create(
             created_by=request.user,
             contact=contact,
             case=case,
             case_role=case_role,
             organisation=organisation,
             short_code=crypto.get_random_string(8),
             code=str(uuid.uuid4()),
             email=contact.email,
         )
         created = True
     values = {key: request.data.get(key) for key in request.data.keys()}
     invitation.send(
         sent_by=request.user, context=values, direct=True, template_key=notify_template_key
     )
     return ResponseSuccess(
         {
             "result": invitation.to_dict(),
             "created": created,
         },
         http_status=status.HTTP_201_CREATED,
     )
Esempio n. 2
0
 def post(self, request, case_id, contact_id, organisation_id, *args, **kwargs):
     try:
         contact = Contact.objects.select_related("userprofile", "organisation").get(
             id=contact_id
         )
     except Contact.DoesNotExist:
         raise NotFoundApiExceptions("Contact does not exist or access is denied")
     try:
         organisation = Organisation.objects.get(id=organisation_id)
     except Organisation.DoesNotExist:
         raise NotFoundApiExceptions("Organisation does not exist or access is denied")
     contact.set_primary(case=get_case(case_id), organisation=organisation)
     return ResponseSuccess({"result": contact.to_dict()}, http_status=status.HTTP_201_CREATED)
Esempio n. 3
0
    def get(
        self,
        request,
        case_id=None,
        contact_id=None,
        submission_id=None,
        invitation_id=None,
        organisation_id=None,
        *args,
        **kwargs,
    ):
        if invitation_id:
            invitation = Invitation.objects.get_user_invite(
                invitation_id, requested_by=request.user
            )
            return ResponseSuccess({"result": invitation.to_dict()})

        invitations = Invitation.objects.filter(deleted_at__isnull=True, organisation__isnull=False)
        if contact_id:
            try:
                contact = Contact.objects.select_related("userprofile", "organisation").get(
                    id=contact_id
                )
            except Contact.DoesNotExist:
                raise NotFoundApiExceptions("Invalid contact id.")
            invitations = invitations.filter(contact=contact)
        if case_id:
            try:
                case = Case.objects.get(id=case_id)
            except Case.DoesNotExist:
                raise InvalidRequestParams("Invalid case id")
Esempio n. 4
0
    def get(self, request, organisation_id, *args, **kwargs):
        try:
            organisation = Organisation.objects.get(id=organisation_id)
        except Organisation.DoesNotExist:
            raise NotFoundApiExceptions(
                "Organisation does not exist or access is denied")

        case_id = request.GET.get("case_id")
        if case_id:
            # Get from user-org-case
            user_cases = UserCase.objects.filter(
                organisation_id=organisation_id, case_id=case_id)
            case_contacts = CaseContact.objects.filter(
                organisation_id=organisation_id, case_id=case_id)
            primary_contact_ids = {}
            for cc in case_contacts:
                if cc.primary:
                    primary_contact_ids[str(cc.contact.id)] = True
            results = []
            for user_case in user_cases:
                _dict = user_case.to_dict()
                (_dict.get("user")
                 or {})["contact_id"] = user_case.user.contact.id
                if primary_contact_ids.get(str(user_case.user.contact.id)):
                    _dict["primary"] = True
                results.append(_dict)
            return ResponseSuccess({"results": results})

        return ResponseSuccess(
            {"results": [user.to_user_dict() for user in organisation.users]})
Esempio n. 5
0
 def delete(self, request, invitation_id, *args, **kwargs):
     try:
         invitation = Invitation.objects.get(id=invitation_id)
     except Invitation.DoesNotExist:
         raise NotFoundApiExceptions("Invalid invitation id")
     invitation.delete()
     return ResponseSuccess({"deleted_id": invitation_id})
Esempio n. 6
0
 def post(self,
          request,
          task_id=None,
          case_id=None,
          model_id=None,
          content_type=None,
          *args,
          **kwargs):
     """
     create / update a Task
     """
     task_id = task_id or request.data.get("id")
     case_id = case_id or request.data.get("case_id")
     if task_id:
         try:
             task = Task.objects.get(id=task_id)
         except Task.DoesNotExist:
             raise NotFoundApiExceptions("Invalid task id")
     else:
         # we must be creating a task, so get the key params
         case = get_case(case_id)
         model_id = model_id or request.data.get("model_id")
         content_type = content_type or request.data.get("content_type")
         _content_type = content_type and get_content_type(content_type)
         task = Task(
             case=case,
             created_by=request.user,
             model_id=model_id,
             content_type=_content_type,
             user_context=[request.user],
         )
Esempio n. 7
0
 def delete(self, request, contact_id=None, *args, **kwargs):
     try:
         contact = Contact.objects.select_related("userprofile", "organisation").get(
             id=contact_id
         )
     except Contact.DoesNotExist:
         raise NotFoundApiExceptions("Contact does not exist or access is denied")
     CaseContact.objects.filter(contact=contact).delete()
     contact.delete()
     return ResponseSuccess({"result": {"deleted": True}}, http_status=status.HTTP_200_OK)
Esempio n. 8
0
class OrganisationNonResponsiveToggleAPI(TradeRemediesApiView):
    """
    Toggle the non_responsive flag for this organisation's role in the case.
    """
    def post(self, request, case_id, organisation_id, *args, **kwargs):
        try:
            case = Case.objects.get(id=case_id)
            organisation = Organisation.objects.get(id=organisation_id)
        except Case.DoesNotExist:
            raise NotFoundApiExceptions("Case not found or access denied")
Esempio n. 9
0
 def post(self, request, organisation_id, user_id=None, *args, **kwargs):
     try:
         organisation = Organisation.objects.get(id=organisation_id)
     except Organisation.DoesNotExist:
         raise NotFoundApiExceptions(
             "Organisation does not exist or access is denied")
     if user_id:
         org_user = organisation.users.get(user_id=user_id)
         if org_user and self.toggle_admin:
             org_user.user.toggle_role(SECURITY_GROUP_ORGANISATION_OWNER)
     return ResponseSuccess({"result": org_user.to_user_dict()})
Esempio n. 10
0
    def get(self,
            request,
            task_id=None,
            case_id=None,
            *args,
            **kwargs):  # noqa: C901
        """
        Get one or more tasks based on a set of query parameters and fields.
        """
        query_str = request.GET.get("query")
        query_dict = json.loads(query_str) if query_str else {}
        fields_str = request.GET.get("fields")
        fields = json.loads(fields_str) if fields_str else {}
        if task_id:
            try:
                task = Task.objects.get(id=task_id)
                return ResponseSuccess({"result": task.to_dict()})
            except Task.DoesNotExist:
                raise NotFoundApiExceptions("Task not found id")
        else:
            query = Q(deleted_at__isnull=True)
            orquery = None
            exclude_exp = Q(id__isnull=True)
            for query_item in query_dict:
                field = query_item.get("field")
                field_val = query_item.get("value")

                if field_val:
                    queue = None
                    if field_val == "null":
                        queue = Q(**{field + "__isnull": True})
                    else:
                        queue = Q(**{field: field_val})

                    if query_item.get("combine") == "not":
                        exclude_exp.add(queue, Q.OR)

                    elif query_item.get("combine") == "or":
                        if orquery:
                            orquery.add(queue, Q.OR)
                        else:
                            orquery = queue
                    else:
                        query.add(queue, Q.AND)

            tasks = Task.objects.filter(query).exclude(exclude_exp)
            if orquery:
                tasks = Task.objects.filter(query).exclude(exclude_exp).filter(
                    orquery)
            else:
                tasks = Task.objects.filter(query).exclude(exclude_exp)
        return ResponseSuccess(
            {"results": [_task.to_dict(fields=fields) for _task in tasks]})
Esempio n. 11
0
 def get(self, request, contact_id=None, *args, **kwargs):
     if contact_id:
         try:
             contact = Contact.objects.select_related("userprofile", "organisation").get(
                 id=contact_id
             )
             return ResponseSuccess({"result": contact.to_dict()})
         except Contact.DoesNotExist:
             raise NotFoundApiExceptions("Contact does not exist or access is denied")
     else:
         filter_kwargs = pluck(request.query_params, ["name", "country", "organisation"])
         contacts = Contact.objects.filter(**filter_kwargs)
     return ResponseSuccess({"results": [_contact.to_dict() for _contact in contacts]})
Esempio n. 12
0
    def get(self, request, code, organisation_id, *args, **kwargs):
        try:
            organisation = Organisation.objects.get(id=organisation_id)
            invite = Invitation.objects.get(
                code=code, organisation=organisation, deleted_at__isnull=True
            )
            invited_by = invite.created_by
            invited_by_token = invited_by.auth_token.key
        except (Organisation.DoesNotExist, Invitation.DoesNotExist):
            raise NotFoundApiExceptions("Invite not found")
        response = {"organisation": organisation.to_embedded_dict(), "invite": invite.to_dict()}
        response["invite"]["invited_by"] = invited_by_token

        return ResponseSuccess({"result": response}, http_status=status.HTTP_200_OK)
Esempio n. 13
0
 def post(self,
          request,
          organisation_id=None,
          case_id=None,
          organisation_type=None,
          *args,
          **kwargs):
     result = {}
     case = None
     if case_id:
         try:
             case = Case.objects.get(id=case_id)
         except Case.DoesNotExist:
             raise NotFoundApiExceptions("Case not found or access denied")
Esempio n. 14
0
 def post(self, request, invitation_id, *args, **kwargs):
     try:
         invitation = Invitation.objects.get(
             id=invitation_id,
             deleted_at__isnull=True,
         )
         invitation.accepted_at = timezone.now()
         invitation.user = request.user
         invitation.save()
         return ResponseSuccess(
             {
                 "result": invitation.to_dict(),
             }
         )
     except Invitation.DoesNotExist:
         raise NotFoundApiExceptions("Invitation not found")
Esempio n. 15
0
 def get(self,
         request,
         organisation_id=None,
         case_id=None,
         *args,
         **kwargs):
     is_tra = request.user.is_tra()
     gov_body = request.query_params.get("gov_body",
                                         "false") in TRUTHFUL_INPUT_VALUES
     fields = request.query_params.get("fields")
     case = None
     if case_id:
         try:
             case = Case.objects.get(id=case_id)
         except Case.DoesNotExist:
             raise NotFoundApiExceptions("Case not found or access denied")
Esempio n. 16
0
class InvitationDetailsAPI(TradeRemediesApiView):
    """
    Retrieve the details of an invitation. This call would normally be called
    via the trusted user (healthcheck) and used to display the invitation information
    in the invite welcome screen.

    `GET /api/v1/invitation/{code_id}/{case_id}/`
    Retrieve an invitation
    """

    def get(self, request, code=None, case_id=None, *args, **kwargs):
        try:
            case = Case.objects.get(id=case_id)
            invitation = Invitation.objects.get(code=code, case=case, deleted_at__isnull=True)
            return ResponseSuccess({"result": invitation.to_dict()})
        except Case.DoesNotExist:
            raise NotFoundApiExceptions("Invalid case id")
Esempio n. 17
0
    def get(self, request, document_id, submission_id=None, *args, **kwargs):
        document = Document.objects.get(id=document_id)
        is_tra = request.user.is_tra()

        if (not is_tra and not submission_id
                and not request.user.email == settings.TRUSTED_USER_EMAIL):
            raise InvalidRequestParams("Invalid request params")
        if submission_id:
            submission = Submission.objects.get_submission(id=submission_id)
            doc_submission = SubmissionDocument.objects.get(
                submission=submission, document=document)
            if not is_tra and not doc_submission.downloadable_by(request.user):
                raise NotFoundApiExceptions(
                    "Document not found or access is denied")
            doc_submission.downloads += 1
            doc_submission.save()
        return stream_s3_file_download(document.s3_bucket,
                                       document.s3_key,
                                       filename=document.name)
Esempio n. 18
0
 def post(self, request, case_id, submission_id, contact_id, *args, **kwargs):
     notify_data = request.data.dict()
     case = get_case(case_id)
     submission = Submission.objects.get(id=submission_id, case=case)
     contact = Contact.objects.select_related("userprofile", "organisation").get(id=contact_id)
     try:
         invite = Invitation.objects.get(submission=submission, contact=contact)
     except Invitation.DoesNotExist:
         raise NotFoundApiExceptions("Invite not found")
     send_report = invite.send(
         sent_by=request.user,
         context=notify_data,
         direct=True,
         template_key="NOTIFY_THIRD_PARTY_INVITE",
     )
     invite.email_sent = True
     invite.sent_at = timezone.now()
     invite.approved_by = request.user
     invite.save()
     return ResponseSuccess({"result": invite.to_dict()}, http_status=status.HTTP_201_CREATED)
Esempio n. 19
0
    def get(
        self,
        request,
        note_id=None,
        model_id=None,
        content_type=None,
        case_id=None,
        model_key=None,
        *args,
        **kwargs,
    ):
        if note_id:
            try:
                note = Note.objects.get(id=note_id)
                return ResponseSuccess({"result": note.to_dict()})
            except Note.DoesNotExist:
                raise NotFoundApiExceptions("Invalid note id")
        else:
            notes = Note.objects.filter(deleted_at__isnull=True)
        if case_id:
            notes = notes.filter(case__id=case_id)
        if model_id and content_type:
            _content_type = get_content_type(content_type)
            if model_key:
                notes = notes.filter(model_id=model_id,
                                     content_type=_content_type,
                                     model_key=model_key)
            else:
                notes = notes.filter(model_id=model_id,
                                     content_type=_content_type)

        else:
            raise InvalidRequestParams(
                "A note id, case id or a model identifiers are required")
        notes = notes.order_by("created_at")
        return ResponseSuccess(
            {"results": [_note.to_dict() for _note in notes]})
Esempio n. 20
0
 def post(self, request, code=None, short_code=None, case_id=None, *args, **kwargs):
     if not code and not case_id and short_code:
         invitiation, organisation = Invitation.objects.validate_public_invite(
             short_code, user=request.user
         )
         return ResponseSuccess(
             {"result": {"invitation": invitiation.to_dict(), "deviation": None, "diff": None}}
         )
     else:
         invitation = Invitation.objects.get_invite_by_code(code)
         if invitation:
             invitation.process_invitation(request.user, accept=True)
             deviation, diff = invitation.compare_user_contact()
             return ResponseSuccess(
                 {
                     "result": {
                         "invitation": invitation.to_dict(),
                         "deviation": deviation,
                         "diff": diff,
                     }
                 }
             )
         else:
             raise NotFoundApiExceptions("No invitation found for this user")
Esempio n. 21
0
    def get(self,
            request,
            organisation_id,
            case_id=None,
            *args,
            **kwargs):  # noqa: C901

        contacts = {}
        case = Case.objects.get(id=case_id) if case_id else None

        def add_contact(case_contact, case):
            if get(case_contact, "contact").address != "redacted":
                contact_id = str(get(case_contact, "contact").id)
                if contact_id not in contacts:
                    contact = get(case_contact, "contact")
                    contacts[contact_id] = contact.to_dict(case)
                    contacts[contact_id]["cases"] = {}
                    if get(contacts[contact_id], "user"):
                        try:
                            organisation = contact.user.organisation.organisation
                            contacts[contact_id]["user"]["organisation"] = {
                                "id": organisation.id
                            }
                        except AttributeError:
                            pass
                if case_contact.get("loa"):
                    contacts[contact_id]["loa"] = True
                if case_contact.get("organisation_contact"):
                    contacts[contact_id]["organisation_contact"] = True
                if case_contact.get("case_contact"):
                    contacts[contact_id]["case_contact"] = True
                case = get(case_contact, "case")
                if case:
                    cc = contacts[contact_id]["cases"].get(str(case.id)) or {
                        "name": case.name
                    }
                    cc.update({
                        k: v
                        for k, v in case_contact.items()
                        if v is not None and k in
                        ["primary", "loa", "name", "in_case", "case_contact"]
                    })
                    contacts[contact_id]["cases"][str(case.id)] = cc

        try:
            organisation = Organisation.objects.get(id=organisation_id)
        except Organisation.DoesNotExist:
            raise NotFoundApiExceptions(
                "Organisation does not exist or access is denied")

        users = organisation.users  # get the users from user->org

        # Add contacts that are related via a user-case with this org - representing
        if not request.query_params.get("exclude_indirect"):
            user_cases = UserCase.objects.filter(organisation=organisation, )
            for user_case in user_cases:
                add_contact(
                    {
                        "contact": user_case.user.contact,
                        "case": user_case.case,
                        "primary": False,
                        "in_case": True,
                    },
                    case=case,
                )
            # Add case contacts if we don't have them already
            case_contacts = CaseContact.objects.filter(
                organisation=organisation,
                contact__deleted_at__isnull=True,
            )
            for case_contact in case_contacts:
                add_contact(
                    {
                        "contact": case_contact.contact,
                        "case": case_contact.case,
                        "primary": case_contact.primary,
                        "case_contact": True,
                    },
                    case=case,
                )
        # Add LOA contacts
        for caserole in OrganisationCaseRole.objects.filter(
                organisation=organisation,
                auth_contact__deleted_at__isnull=True):
            if caserole.auth_contact:
                add_contact(
                    {
                        "contact": caserole.auth_contact,
                        "loa": True,
                    },
                    case=case,
                )
        # Add contacts that are attached directly to the organisation
        for org_contact in organisation.contacts:
            add_contact(
                {
                    "contact": org_contact,
                    "organisation_contact": True,
                },
                case=case,
            )

        return ResponseSuccess({"results": contacts.values()})
Esempio n. 22
0
 def get(self, request, invitation_id=None, *args, **kwargs):
     try:
         invitation = Invitation.objects.get(id=invitation_id, user=request.user)
         return ResponseSuccess({"result": invitation.to_dict()})
     except Invitation.DoesNotExist:
         raise NotFoundApiExceptions("Invalid invitation")
Esempio n. 23
0
        content_type=None,
        *args,
        **kwargs,
    ):

        response = None
        if note_id and document_id:
            try:
                note = Note.objects.get(id=note_id, case__id=case_id)
                document = Document.objects.get(id=document_id)
                case = get_case(case_id)
                # Only delete if the doc is not used in any submissions
                if len(document.submissions(case)) == 0:
                    note.documents.remove(document)
                    response = document.delete()
                else:
                    result = {
                        "deleted": False,
                        "result": "Document used in submission"
                    }
            except Note.DoesNotExist:
                raise NotFoundApiExceptions("Invalid note id")
        else:
            raise NotFoundApiExceptions("Invalid note id")

        return ResponseSuccess(
            {"result": {
                "deleted": True,
                "result": response
            }})
Esempio n. 24
0
class NoteAPIView(TradeRemediesApiView):
    """
    Get or create Notes on other models

    ### GET

    `GET /api/v1/notes/case/{CASE_UUID}/` Get all case notes
    `GET /api/v1/notes/case/{CASE_UUID}/on/{CONTENT_TYPE_IDENTIFIER}/{MODEL_ID}/`
    Get all notes for a particular model
    `GET /api/v1/notes/{NOTE_UUID}/` Get a specific note

    ### POST

    `POST /api/v1/notes/case/{CASE_UUID}/on/{CONTENT_TYPE_IDENTIFIER}/{MODEL_ID}/` Create a new note
    `POST /api/v1/notes/{NOTE_UUID}/` Update a specific note
    `GET /api/v1/notes/case/{CASE_UUID}/` Shortcut to create a note directly on a case.
    """
    def get(
        self,
        request,
        note_id=None,
        model_id=None,
        content_type=None,
        case_id=None,
        model_key=None,
        *args,
        **kwargs,
    ):
        if note_id:
            try:
                note = Note.objects.get(id=note_id)
                return ResponseSuccess({"result": note.to_dict()})
            except Note.DoesNotExist:
                raise NotFoundApiExceptions("Invalid note id")
        else:
            notes = Note.objects.filter(deleted_at__isnull=True)
        if case_id:
            notes = notes.filter(case__id=case_id)
        if model_id and content_type:
            _content_type = get_content_type(content_type)
            if model_key:
                notes = notes.filter(model_id=model_id,
                                     content_type=_content_type,
                                     model_key=model_key)
            else:
                notes = notes.filter(model_id=model_id,
                                     content_type=_content_type)

        else:
            raise InvalidRequestParams(
                "A note id, case id or a model identifiers are required")
        notes = notes.order_by("created_at")
        return ResponseSuccess(
            {"results": [_note.to_dict() for _note in notes]})

    def post(  # noqa: C901
        self,
        request,
        case_id=None,
        note_id=None,
        model_id=None,
        document_id=None,
        content_type=None,
        *args,
        **kwargs,
    ):
        """
        create / update the Notes
        :param request:
        :param note_id:
        :param model_id:
        :param args:
        :param kwargs:
        :return:
        """
        case = get_case(case_id)
        _file = request.data.get("document", None)
        _file = json.loads(_file) if isinstance(_file, str) else None
        document = None
        if _file:
            document = Document.objects.create_document(
                file=_file,
                user=request.user,
                case=case,
                confidential=request.data.get("confidentiality") ==
                "confidential",
            )
            document_id = document.id
        if document_id:
            document = Document.objects.get(id=document_id)
            confidentiality = request.data.get("confidentiality")
            if confidentiality in ["confidential", "non-confidential"]:
                document.confidential = confidentiality == "confidential"
                document.save()

        if note_id:
            try:
                note = Note.objects.get(id=note_id, case__id=case_id)
            except Note.DoesNotExist:
                raise NotFoundApiExceptions("Invalid note id")
        else:
            model_id = model_id or request.data.get("model_id")
            content_type = content_type or request.data.get("content_type")
            if not model_id and not content_type:
                model_id = case_id
                _content_type = get_content_type("cases.case")
            else:
                _content_type = get_content_type(content_type)
            note = Note(
                case=case,
                created_by=request.user,
                model_id=model_id,
                content_type=_content_type,
                user_context=[request.user],
            )
        note.load_attributes(request.data, ["note", "model_key"])
        if document:
            note.documents.add(document)
            note.set_user_context([request.user])
            note.generic_audit(
                message=f"Document attached: {document.name}",
                audit_type=AUDIT_TYPE_ATTACH,
                id=str(document.id),
            )
        if note.is_dirty():
            note.save()
        return ResponseSuccess({"result": note.to_dict()},
                               http_status=status.HTTP_201_CREATED)

    def delete(
        self,
        request,
        case_id=None,
        note_id=None,
        model_id=None,
        document_id=None,
        content_type=None,
        *args,
        **kwargs,
    ):

        response = None
        if note_id and document_id:
            try:
                note = Note.objects.get(id=note_id, case__id=case_id)
                document = Document.objects.get(id=document_id)
                case = get_case(case_id)
                # Only delete if the doc is not used in any submissions
                if len(document.submissions(case)) == 0:
                    note.documents.remove(document)
                    response = document.delete()
                else:
                    result = {
                        "deleted": False,
                        "result": "Document used in submission"
                    }
            except Note.DoesNotExist:
                raise NotFoundApiExceptions("Invalid note id")
Esempio n. 25
0
    def post(  # noqa: C901
        self,
        request,
        case_id=None,
        note_id=None,
        model_id=None,
        document_id=None,
        content_type=None,
        *args,
        **kwargs,
    ):
        """
        create / update the Notes
        :param request:
        :param note_id:
        :param model_id:
        :param args:
        :param kwargs:
        :return:
        """
        case = get_case(case_id)
        _file = request.data.get("document", None)
        _file = json.loads(_file) if isinstance(_file, str) else None
        document = None
        if _file:
            document = Document.objects.create_document(
                file=_file,
                user=request.user,
                case=case,
                confidential=request.data.get("confidentiality") ==
                "confidential",
            )
            document_id = document.id
        if document_id:
            document = Document.objects.get(id=document_id)
            confidentiality = request.data.get("confidentiality")
            if confidentiality in ["confidential", "non-confidential"]:
                document.confidential = confidentiality == "confidential"
                document.save()

        if note_id:
            try:
                note = Note.objects.get(id=note_id, case__id=case_id)
            except Note.DoesNotExist:
                raise NotFoundApiExceptions("Invalid note id")
        else:
            model_id = model_id or request.data.get("model_id")
            content_type = content_type or request.data.get("content_type")
            if not model_id and not content_type:
                model_id = case_id
                _content_type = get_content_type("cases.case")
            else:
                _content_type = get_content_type(content_type)
            note = Note(
                case=case,
                created_by=request.user,
                model_id=model_id,
                content_type=_content_type,
                user_context=[request.user],
            )
        note.load_attributes(request.data, ["note", "model_key"])
        if document:
            note.documents.add(document)
            note.set_user_context([request.user])
            note.generic_audit(
                message=f"Document attached: {document.name}",
                audit_type=AUDIT_TYPE_ATTACH,
                id=str(document.id),
            )
        if note.is_dirty():
            note.save()
        return ResponseSuccess({"result": note.to_dict()},
                               http_status=status.HTTP_201_CREATED)
Esempio n. 26
0
    via the trusted user (healthcheck) and used to display the invitation information
    in the invite welcome screen.

    `GET /api/v1/invitation/{code_id}/{case_id}/`
    Retrieve an invitation
    """

    def get(self, request, code=None, case_id=None, *args, **kwargs):
        try:
            case = Case.objects.get(id=case_id)
            invitation = Invitation.objects.get(code=code, case=case, deleted_at__isnull=True)
            return ResponseSuccess({"result": invitation.to_dict()})
        except Case.DoesNotExist:
            raise NotFoundApiExceptions("Invalid case id")
        except Invitation.DoesNotExist:
            raise NotFoundApiExceptions("Invalid invitation details")


class ValidateInvitationAPIView(TradeRemediesApiView):
    """
    Validate an invitation to an Organisation or case
    for a user

    `GET /invitations/{ORGANISATION_ID}/validate/`
    Validate a user (via email and/or user id) is invited to an organisation

    """

    def post(self, request, code=None, short_code=None, case_id=None, *args, **kwargs):
        if not code and not case_id and short_code:
            invitiation, organisation = Invitation.objects.validate_public_invite(
Esempio n. 27
0
    def post(
        self,
        request,
        document_id=None,
        case_id=None,
        organisation_id=None,
        submission_id=None,
        bundle_id=None,
        *args,
        **kwargs,
    ):
        if document_id is None:
            document_id = request.data.get("document_id", None)
        _files = request.FILES.getlist("file", None)
        _issued = request.data.get("issued") or False
        _case_document = request.data.get("case_document")
        _parent_id = request.data.get("parent_id") or False
        _replace_id = request.data.get("replace_id") or False
        _bundle_id = bundle_id or request.data.get("bundle_id")
        _system = request.data.get("system") or bool(_bundle_id)
        _confidential = request.data.get("confidential")
        _submission_document_type = request.data.get(
            "submission_document_type")
        if _submission_document_type:
            submission_document_type = SubmissionDocumentType.objects.get(
                key=_submission_document_type)
        else:
            submission_document_type = SubmissionDocumentType.type_by_user(
                request.user)
        if _confidential is None:
            _confidential = True
        submission_type_id = request.data.get("submission_type_id")
        if (not _case_document and not _bundle_id and not submission_id
                and not submission_type_id and not _system
                and not document_id):
            raise InvalidRequestParams("Submission id or type id are required")
        if not _files and not document_id and not request.data.get(
                "file_name"):
            raise InvalidRequestParams("No file or documents provided")
        case = get_case(case_id)
        submission = None
        if submission_id:
            submission = Submission.objects.get_submission(id=submission_id,
                                                           case=case)
        elif submission_type_id:
            submission_type = SubmissionType.objects.get(id=submission_type_id)
            submission = Submission.objects.create(
                name=submission_type.name,
                case=case,
                organisation=self.organisation,
                type=submission_type,
                status=submission_type.default_status,
                created_by=request.user,
                user_context=[request.user],
            )
        if not _files and request.data.get("file_name"):
            _files = [{
                "name": request.data.get("file_name"),
                "size": request.data.get("file_size"),
                "document_name": request.data.get("document_name"),
            }]
        if _files:
            result = []
            for _file in _files:
                _parent = None
                if _parent_id:
                    try:
                        _parent = Document.objects.get(id=_parent_id)
                    except Document.DoesNotExist:
                        raise NotFoundApiExceptions(
                            "Parent document is not found")
                try:
                    document = Document.objects.create_document(
                        file=_file,
                        user=request.user,
                        confidential=_confidential,
                        system=bool(_system),
                        parent=_parent,
                        document=Document.objects.get(
                            id=document_id) if document_id else None,
                        case=case,
                    )
                except InvalidFile as e:
                    raise InvalidFileUpload(str(e))
                if _replace_id and submission:
                    # We are being asked to replace the given doc in this submission
                    try:
                        # Find the document to replace and get its child
                        _replace_doc = Document.objects.get(id=_replace_id)
                        _child_doc = Document.objects.filter(
                            parent_id=_replace_id).first()
                        replace_submission_document = SubmissionDocument.objects.get(
                            submission=submission, document=_replace_doc)
                        replace_submission_document.set_user_context(
                            request.user)
                        if _child_doc:
                            child_submission_document = SubmissionDocument.objects.get(
                                submission=submission, document=_child_doc)
                            child_submission_document.set_user_context(
                                request.user)
                            # Clone the child doc and add link to parent
                            _child_doc.id = None
                            _child_doc.parent = document
                            _child_doc.save()
                            # Update submission_doc to point to new child doc.
                            child_submission_document.document = _child_doc
                            child_submission_document.save()
                        replace_submission_document.delete()
                    except (Document.DoesNotExist,
                            SubmissionDocument.DoesNotExist) as e:
                        logger.warning(
                            f"Document to replace with id '{_replace_id}' was not found: {e}"
                        )
                if submission:
                    if _submission_document_type:
                        submission_document_type = SubmissionDocumentType.objects.get(
                            key=_submission_document_type)
                    else:
                        submission_document_type = SubmissionDocumentType.type_by_user(
                            request.user)
                    submission_document = submission.add_document(
                        document=document,
                        document_type=submission_document_type,
                        issued=_issued,
                        issued_by=request.user,
                    )
                    result_item = submission_document.to_dict()
                elif _bundle_id:
                    bundle = DocumentBundle.objects.get(id=_bundle_id)
                    bundle.documents.add(document)
                    document.generic_audit(
                        message=f"Attached to bundle {bundle.name}",
                        audit_type=AUDIT_TYPE_ATTACH,
                        id=str(document.id),
                    )
                    result_item = document.to_dict()
                else:
                    result_item = document.to_dict()
                result.append(result_item)
            return ResponseSuccess({"result": result},
                                   http_status=status.HTTP_201_CREATED)
        elif document_id:
            # We just want to attach a document
            document = Document.objects.get(id=document_id)
            if submission_id:
                submission_document = submission.add_document(
                    document=document,
                    document_type=submission_document_type,
                    issued=_issued,
                    issued_by=request.user,
                )
                if not request.user.is_tra():
                    submission.received_at = timezone.now()
                    submission.status = submission.type.received_status
                submission.save()

                return ResponseSuccess(
                    {"result": submission_document.to_dict()},
                    http_status=status.HTTP_201_CREATED)
            document.confidential = _confidential
            document.save()
            return ResponseSuccess(
                {"result": {
                    "document": document.to_dict()
                }})
Esempio n. 28
0
class ContactsAPI(TradeRemediesApiView):
    """
    Return all or one contact records

    `GET /contacts/`
    Return all contact records, allowing for filtering by organisation, name or address
    `GET /contact/{contact_id}/`
    Return a single contact record

    `POST /contact/`
    Create a new contact
    `POST /contact/{contact_id}/`
    Update a contact

    """

    def get(self, request, contact_id=None, *args, **kwargs):
        if contact_id:
            try:
                contact = Contact.objects.select_related("userprofile", "organisation").get(
                    id=contact_id
                )
                return ResponseSuccess({"result": contact.to_dict()})
            except Contact.DoesNotExist:
                raise NotFoundApiExceptions("Contact does not exist or access is denied")
        else:
            filter_kwargs = pluck(request.query_params, ["name", "country", "organisation"])
            contacts = Contact.objects.filter(**filter_kwargs)
        return ResponseSuccess({"results": [_contact.to_dict() for _contact in contacts]})

    def post(  # noqa: C901
        self, request, contact_id=None, organisation_id=None, case_id=None, *args, **kwargs
    ):
        self.required_keys = ["contact_name"]
        if not self.feature_flags("contact_email_read_only"):
            self.required_keys.append("contact_email")
        case_id = case_id or request.data.get("case_id")
        organisation_id = organisation_id or request.data.get("organisation_id")
        missing_required_fields = self.validate_required_fields(request)
        errors = {fld: "Required" for fld in missing_required_fields}
        if not self.feature_flags("contact_email_read_only"):
            if not is_valid_email(request.data.get("contact_email", "")):
                errors["email_not_valid"] = "Invalid email format"
        if errors:
            raise RequestValidationError(detail=errors)
        case = None
        if case_id:
            case = get_case(case_id)
        contact_id = contact_id or request.data.get("contact_id")
        if contact_id:
            try:
                contact = Contact.objects.select_related("userprofile", "organisation").get(
                    id=contact_id
                )
            except Contact.DoesNotExist:
                raise NotFoundApiExceptions("Contact does not exist or access is denied")
            if organisation_id:
                organisation = Organisation.objects.get(id=organisation_id)
                CaseContact.objects.get_or_create(
                    case=case, contact=contact, organisation=organisation, primary=False
                )
        else:
            organisation = None
            if organisation_id:
                organisation = Organisation.objects.get(id=organisation_id)
            contact = Contact(organisation=organisation, created_by=request.user)
        contact.set_case_context(case)
        contact.set_user_context(request.user)
        contact.name = request.data.get("contact_name")
        contact.address = request.data.get("contact_address")
        contact.country = request.data.get("contact_country")
        contact.post_code = request.data.get("contact_post_code")
        if not self.feature_flags("contact_email_read_only"):
            contact.email = request.data.get("contact_email", "").lower()
        contact.phone = request.data.get("contact_phone")
        if case and request.data.get("primary_contact"):
            contact.set_primary(case=case)
Esempio n. 29
0
                "results": [
                    organisation.to_embedded_dict()
                    for organisation in organisations
                ]
            })
        elif organisation_id:
            try:
                organisation = Organisation.objects.get(id=organisation_id)
                org_data = organisation.to_dict(case=case)
                if case_id:
                    case_role = organisation.get_case_role(get_case(case_id))
                    org_data["case_role"] = case_role.to_dict(
                    ) if case_role else None
                return ResponseSuccess({"result": org_data})
            except Organisation.DoesNotExist:
                raise NotFoundApiExceptions(
                    "Organisation does not exist or access is denied")
        elif is_tra:
            organisations = Organisation.objects.filter(
                deleted_at__isnull=True)
            return ResponseSuccess({
                "results":
                [org.to_dict(fields=fields) for org in organisations]
            })

        else:
            organisations = OrganisationUser.objects.filter(user=request.user)
        return ResponseSuccess({
            "results":
            [org_user.organisation.to_dict() for org_user in organisations]
        })