diff --git a/api/cases/apis.py b/api/cases/apis.py index 42003fd..7c4493b 100644 --- a/api/cases/apis.py +++ b/api/cases/apis.py @@ -12,8 +12,10 @@ list_user_cases, ) from api.cases.services import ( + archive_case, create_case, create_case_contact, + finish_case, publish_case, update_case_contact, ) @@ -197,6 +199,20 @@ def get(self, request, case_id): return Response(status=status.HTTP_200_OK) +class CaseFinishApi(APIView): + def get(self, request, case_id): + case = get_case(pk=case_id, fetched_by=request.user) + finish_case(case=case, performed_by=request.user) + return Response(status=status.HTTP_200_OK) + + +class CaseArchiveApi(APIView): + def get(self, request, case_id): + case = get_case(pk=case_id, fetched_by=request.user) + archive_case(case=case, performed_by=request.user) + return Response(status=status.HTTP_200_OK) + + class UserCasesListApi(APIView): class Pagination(LimitOffsetPagination): default_limit = 10 diff --git a/api/cases/models.py b/api/cases/models.py index dda4e8c..cd1a5ca 100644 --- a/api/cases/models.py +++ b/api/cases/models.py @@ -58,11 +58,13 @@ def activate(self): @transition(field=state, source=States.ACTIVE, target=States.FINISHED) def finish(self): self.is_active = False + self.posted_at = None # Switch to ARCHIVED state from any state except ARCHIVED @transition(field=state, source="+", target=States.ARCHIVED) def archive(self): self.is_active = False + self.posted_at = None # If user selected incorrect match or lost again @transition( diff --git a/api/cases/services.py b/api/cases/services.py index 338d527..819a056 100644 --- a/api/cases/services.py +++ b/api/cases/services.py @@ -75,6 +75,7 @@ def update_case(): ... +@transaction.atomic def create_case_details( *, case: Case, @@ -124,6 +125,7 @@ def process_case(case: Case) -> List[Dict[int, int]]: def case_matching_binding(*, case: Case, matches_list: List[Dict[int, int]]) -> None: """ """ if not matches_list: + # TODO refactor notifications create_notification( case=case, action=Notification.Action.PUBLISH, @@ -132,6 +134,16 @@ def case_matching_binding(*, case: Case, matches_list: List[Dict[int, int]]) -> level=Notification.Level.WARNING, sent_to=case.user, ) + msg = Message( + notification=FirebaseNotification( + title="لم نجد حالات مشابه هل تود فى نشر الحاله", + body="لم نعثر على اى حالات مشابهه يمكنك نشر بيانات المفقود فى نطاق اوسع لتزيد احتماليه العثور عليه", + ) + ) + + device = FCMDevice.objects.filter(user=case.user).first() + device.send_message(msg) + return cases_ids = [match["id"] for match in matches_list] @@ -154,6 +166,15 @@ def case_matching_binding(*, case: Case, matches_list: List[Dict[int, int]]) -> level=Notification.Level.SUCCESS, sent_to=match.user, ) + msg = Message( + notification=FirebaseNotification( + title="تم العثور على حالات مشابه", + body="تم الوصول لبعض النتائج قم بتصفحها الان", + ) + ) + + device = FCMDevice.objects.filter(user=match.user).first() + device.send_message(msg) create_notification( case=case, @@ -163,8 +184,18 @@ def case_matching_binding(*, case: Case, matches_list: List[Dict[int, int]]) -> level=Notification.Level.SUCCESS, sent_to=case.user, ) + msg = Message( + notification=FirebaseNotification( + title="تم العثور على حالات مشابه", + body="تم الوصول لبعض النتائج قم بتصفحها الان", + ) + ) + device = FCMDevice.objects.filter(user=case.user).first() + device.send_message(msg) + +@transaction.atomic def activate_case(case: Case): matches = process_case(case) case_matching_binding(case=case, matches_list=matches) @@ -190,6 +221,7 @@ def activate_case(case: Case): device.send_message(msg) +# TODO refactor object permission on view level to some mixin or permission class def publish_case(*, case: Case, performed_by: User): if case.user != performed_by: raise PermissionDenied() @@ -222,6 +254,48 @@ def publish_case(*, case: Case, performed_by: User): device.send_message(msg) +def archive_case(*, case: Case, performed_by: User): + if case.user != performed_by: + raise PermissionDenied() + + if case.state == Case.States.ARCHIVED: + raise ValidationError("Case already archived") + + case.archive() + case.save() + create_notification( + case=case, + action=Notification.Action.PUBLISH, + title="تم ارشفه الحاله بنجاح", + body="تم ارشفه الحاله لن يتمكن اى احد للوصول لها غيرك", + level=Notification.Level.WARNING, + sent_to=case.user, + ) + + +def finish_case(*, case: Case, performed_by: User): + if case.user != performed_by: + raise PermissionDenied() + + if not case.is_active: + raise ValidationError("Cannot finish inactive case") + + if case.state == Case.States.FINISHED: + raise ValidationError("Case already closed") + + case.finish() + case.save() + + create_notification( + case=case, + action=Notification.Action.NONE, + title="تم ارشفه الحاله بنجاح", + body="تم اغلاق الحاله بنجاح نرجو ان يكون ذويك على ما يرام", + level=Notification.Level.SUCCESS, + sent_to=case.user, + ) + + def create_case_contact(*, user: User, case: Case) -> CaseContact: contact = CaseContact(case=case, user=user) contact.full_clean() diff --git a/api/cases/urls.py b/api/cases/urls.py index 3756b74..1dd08d3 100644 --- a/api/cases/urls.py +++ b/api/cases/urls.py @@ -1,8 +1,10 @@ from django.urls import path from .apis import ( + CaseArchiveApi, CaseContactCreateApi, CaseContactUpdateApi, + CaseFinishApi, CaseListApi, CaseMatchListApi, CasePublishApi, @@ -25,4 +27,6 @@ # path("/update/", UpdateCaseApi.as_view(), name="update"), path("/matches/", CaseMatchListApi.as_view(), name="matches"), path("/publish/", CasePublishApi.as_view(), name="publish"), + path("/finish/", CaseFinishApi.as_view(), name="finish"), + path("/archive/", CaseArchiveApi.as_view(), name="archive"), ]