def delete(self, request, pk, ext_loc_pk):
        application = get_application(pk)
        if not is_case_status_draft(
                application.status.status
        ) and application.status.status in get_case_statuses(read_only=True):
            return JsonResponse(
                data={
                    "error":
                    f"Application status {application.status.status} is read-only."
                },
                status=status.HTTP_400_BAD_REQUEST,
            )

        if (not is_case_status_draft(application.status.status) and
                application.status.status != CaseStatusEnum.APPLICANT_EDITING):
            if ExternalLocationOnApplication.objects.filter(
                    application=application).count() == 1:
                return JsonResponse(
                    data={
                        "errors": {
                            "external_locations": [
                                "Go back and change your answer from ‘Change a site, or delete a good, "
                                "third party or country’ to ’Change something else’."
                            ]
                        }
                    },
                    status=status.HTTP_400_BAD_REQUEST,
                )

        removed_locations = ExternalLocationOnApplication.objects.filter(
            application=application, external_location__pk=ext_loc_pk)

        if removed_locations:
            audit_trail_service.create(
                actor=request.user,
                verb=AuditType.REMOVED_EXTERNAL_LOCATIONS_FROM_APPLICATION,
                target=application.get_case(),
                payload={
                    "locations": [
                        location.external_location.name + " " +
                        location.external_location.country.name
                        if location.external_location.country else
                        location.external_location.name
                        for location in removed_locations
                    ]
                },
            )

        removed_locations.delete()

        return HttpResponse(status=status.HTTP_204_NO_CONTENT)
示例#2
0
    def create(self, *args, **kwargs):
        """
        Create an audit entry for a model
        target: the target object (such as a case)
        actor: the object causing the audit entry (such as a user)
        send_notification: certain scenarios alert internal users, default is True
        ignore_case_status: draft cases become audited, default is False
        """
        # TODO: decouple notifications and audit (signals?)
        from api.cases.models import Case

        target = kwargs.get("target")
        actor = kwargs.get("actor")
        send_notification = kwargs.pop("send_notification", True)
        ignore_case_status = kwargs.pop("ignore_case_status", False)

        if isinstance(target, Case):
            # Only audit cases if their status is not draft
            if not is_case_status_draft(
                    target.status.status) or ignore_case_status:
                audit = super(AuditManager, self).create(*args, **kwargs)

                # Notify gov users when an exporter updates a case
                if isinstance(actor, ExporterUser) and send_notification:
                    for gov_user in GovUser.objects.all():
                        gov_user.send_notification(content_object=audit,
                                                   case=target)

                return audit

            return None

        return super(AuditManager, self).create(*args, **kwargs)
    def _get_new_locations(self, application, user_organisation, location_ids,
                           previous_locations, previous_location_ids):
        new_locations = []

        if (is_case_status_draft(application.status.status) or
                application.status.status == CaseStatusEnum.APPLICANT_EDITING):
            new_locations = [
                get_location(location_id, user_organisation)
                for location_id in location_ids
                if location_id not in previous_location_ids
            ]
        else:
            if has_previous_sites(application):
                return (
                    None,
                    {
                        "external_locations": [
                            "Go back and change your answer from ‘Change a site, or delete a good, third party or "
                            "country’ to ’Change something else’."
                        ]
                    },
                )

            previous_location_countries = list(
                previous_locations.values_list(
                    "external_location__country__id", flat=True))

            for location_id in location_ids:
                new_location = get_location(location_id, user_organisation)

                if (new_location.country and
                    (previous_location_countries and new_location.country.id
                     not in previous_location_countries) or
                    (str(new_location.id) not in previous_location_ids and
                     new_location.location_type == LocationType.SEA_BASED)):
                    return (
                        None,
                        {
                            "external_locations": [
                                "Go back and change your answer from ‘Change a site, or delete a good, "
                                "third party or country’ to ’Change something else’."
                            ]
                        },
                    )
                elif str(new_location.id) not in previous_location_ids:
                    new_locations.append(new_location)

        return new_locations, None
示例#4
0
    def delete(self, request, pk):
        """
        Deleting an application should only be allowed for draft applications
        """
        application = get_application(pk)

        if not is_case_status_draft(application.status.status):
            return JsonResponse(
                data={
                    "errors":
                    strings.Applications.Generic.
                    DELETE_SUBMITTED_APPLICATION_ERROR
                },
                status=status.HTTP_400_BAD_REQUEST,
            )
        application.delete()
        return JsonResponse(data={
            "status":
            strings.Applications.Generic.DELETE_DRAFT_APPLICATION
        },
                            status=status.HTTP_200_OK)
示例#5
0
    def post(self, request, pk):
        """ Add countries to an open licence application. """
        application = get_application(pk)
        if application.goodstype_category in GoodsTypeCategory.IMMUTABLE_DESTINATIONS:
            raise BadRequestError(
                detail=
                "You cannot do this action for this type of open application")
        data = request.data
        country_ids = data.get("countries")

        # Validate that there are countries
        if not country_ids:
            return JsonResponse(
                data={
                    "errors": {
                        "countries": ["You have to pick at least one country"]
                    }
                },
                status=status.HTTP_400_BAD_REQUEST,
            )

        if not is_case_status_draft(
                application.status.status
        ) and application.status.status in get_case_statuses(read_only=True):
            return JsonResponse(
                data={
                    "errors": {
                        "external_locations": [
                            f"Application status {application.status.status} is read-only."
                        ]
                    }
                },
                status=status.HTTP_400_BAD_REQUEST,
            )

        else:
            previous_countries = CountryOnApplication.objects.filter(
                application=application)
            previous_country_ids = [
                str(previous_country_id) for previous_country_id in
                previous_countries.values_list("country__id", flat=True)
            ]
            new_countries = []

            if (is_case_status_draft(application.status.status)
                    or application.status.status
                    == CaseStatusEnum.APPLICANT_EDITING):
                new_countries = [
                    get_country(country_id) for country_id in country_ids
                    if country_id not in previous_country_ids
                ]
            else:
                for country_id in country_ids:
                    if previous_country_ids and country_id not in previous_country_ids:
                        return JsonResponse(
                            data={
                                "errors": {
                                    "countries": [
                                        "Go back and change your answer from ‘Change a site, or delete "
                                        "a good, third party or country’ to ’Change something else’."
                                    ]
                                }
                            },
                            status=status.HTTP_400_BAD_REQUEST,
                        )

            # Get countries to be removed
            removed_country_ids = list(
                set(previous_country_ids) - set(country_ids))
            removed_countries = previous_countries.filter(
                country__id__in=removed_country_ids)

            # Append new Countries to application (only in unsubmitted/applicant editing statuses)
            CountryOnApplication.objects.bulk_create([
                CountryOnApplication(country=country, application=application)
                for country in new_countries
            ])

            countries_data = CountrySerializer(new_countries, many=True).data

            case = Case.objects.get(id=application.id)

            if new_countries:
                audit_trail_service.create(
                    actor=request.user,
                    verb=AuditType.ADD_COUNTRIES_TO_APPLICATION,
                    target=case,
                    payload={
                        "countries":
                        [country.name for country in new_countries]
                    },
                )

            if removed_countries:
                audit_trail_service.create(
                    actor=request.user,
                    verb=AuditType.REMOVED_COUNTRIES_FROM_APPLICATION,
                    target=case,
                    payload={
                        "countries": [
                            country.country.name
                            for country in removed_countries
                        ]
                    },
                )

            removed_countries.delete()
            return JsonResponse(data={"countries": countries_data},
                                status=status.HTTP_201_CREATED)
示例#6
0
 def is_major_editable(self):
     return self.status.status == CaseStatusEnum.APPLICANT_EDITING or is_case_status_draft(
         self.status.status)