Skip to content

Commit

Permalink
Remove open licence references
Browse files Browse the repository at this point in the history
  • Loading branch information
hnryjmes committed Dec 13, 2024
1 parent 41debc1 commit ef3667f
Show file tree
Hide file tree
Showing 25 changed files with 26 additions and 308 deletions.
5 changes: 1 addition & 4 deletions api/cases/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,19 +546,16 @@ def filter_for_cases_related_to_compliance_case(self, compliance_case_id):
],
baseapplication__application_sites__site__site_records_located_at__compliance__id=compliance_case_id,
)
| Q(opengenerallicencecase__site__site_records_located_at__compliance__id=compliance_case_id)
)

# We filter for OIEL, OICL, OGLs, and specific SIELs (dependant on CLC codes present) as these are the only case
# We filter for specific SIELs (dependant on CLC codes present) as these are the only case
# types relevant for compliance cases
GoodOnLicence = apps.get_model("licences", "GoodOnLicence")
approved_goods_on_licence = GoodOnLicence.objects.filter(
good__good__control_list_entries__rating__regex=COMPLIANCE_CASE_ACCEPTABLE_GOOD_CONTROL_CODES
).values_list("good", flat=True)

queryset = queryset.filter(
case_type__id__in=[CaseTypeEnum.OICL.id, CaseTypeEnum.OIEL.id, *CaseTypeEnum.OPEN_GENERAL_LICENCE_IDS]
) | queryset.filter(
baseapplication__goods__id__in=approved_goods_on_licence,
)

Expand Down
6 changes: 1 addition & 5 deletions api/cases/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
from api.documents.libraries.process_document import process_document
from api.goodstype.models import GoodsType
from api.gov_users.serializers import GovUserSimpleSerializer
from api.licences.helpers import get_open_general_export_licence_case
from api.organisations.models import Organisation
from api.organisations.serializers import TinyOrganisationViewSerializer
from api.queries.serializers import QueryViewSerializer
Expand Down Expand Up @@ -308,12 +307,9 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def get_data(self, instance):
from api.licences.serializers.open_general_licences import OpenGeneralLicenceCaseSerializer
from api.applications.helpers import get_application_view_serializer

if instance.case_type.type == CaseTypeTypeEnum.REGISTRATION:
return OpenGeneralLicenceCaseSerializer(get_open_general_export_licence_case(instance.id)).data
elif instance.case_type.type == CaseTypeTypeEnum.APPLICATION:
if instance.case_type.type == CaseTypeTypeEnum.APPLICATION:
application = get_application(instance.id)
serializer = get_application_view_serializer(application)
return serializer(application).data
Expand Down
1 change: 0 additions & 1 deletion api/cases/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@
path("<uuid:pk>/finalise/", views.FinaliseView.as_view(), name="finalise"),
path("<uuid:pk>/licences/", licences.LicencesView.as_view(), name="licences"),
path("<uuid:pk>/assigned-queues/", case_actions.AssignedQueues.as_view(), name="assigned_queues"),
path("<uuid:pk>/reissue-ogl/", case_actions.OpenGeneralLicenceReissue.as_view(), name="reissue_ogl"),
path("<uuid:pk>/rerun-routing-rules/", case_actions.RerunRoutingRules.as_view(), name="rerun_routing_rules"),
# Advice2.0
path("<uuid:pk>/countersign-advice/", views.CountersignAdviceView.as_view(), name="countersign_advice"),
Expand Down
63 changes: 4 additions & 59 deletions api/compliance/helpers.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import csv
import re
from typing import Optional

from django.utils import timezone
from django.conf import settings

from rest_framework.exceptions import ValidationError

from api.audit_trail.enums import AuditType
from api.audit_trail.models import Audit
Expand All @@ -17,9 +14,7 @@
from api.core.exceptions import NotFoundError
from api.core.permissions import check_user_has_permission
from api.goods.models import Good
from api.licences.models import Licence
from lite_content.lite_api import strings
from lite_content.lite_api.strings import Compliance
from api.organisations.libraries.get_organisation import get_request_user_organisation
from api.organisations.models import Site, Organisation
from api.staticdata.statuses.enums import CaseStatusEnum
Expand Down Expand Up @@ -48,21 +43,16 @@ def case_meets_conditions_for_compliance(case: Case):
).exists():
return True
return False
elif case.case_type.id in [CaseTypeEnum.OIEL.id, CaseTypeEnum.OICL.id, *CaseTypeEnum.OPEN_GENERAL_LICENCE_IDS]:
return True
else:
return False


def get_record_holding_sites_for_case(case):
if case.case_type.id in CaseTypeEnum.OPEN_GENERAL_LICENCE_IDS:
return {case.site.site_records_located_at_id}
else:
return set(
Site.objects.filter(sites_on_application__application_id=case.id).values_list(
"site_records_located_at_id", flat=True
)
return set(
Site.objects.filter(sites_on_application__application_id=case.id).values_list(
"site_records_located_at_id", flat=True
)
)


def generate_compliance_site_case(case: Case):
Expand Down Expand Up @@ -118,51 +108,6 @@ def generate_compliance_site_case(case: Case):
TOTAL_COLUMNS = 5


def read_and_validate_csv(text):
"""
Used for parsing Open Licence returns CSV files which are uploaded by the exporter for certain case types
and contain the Licence reference as well as other properties for compliance.
Takes CSV formatted text and returns the licence references & cleaned format of the CSV.
Requires the first column to be the licence reference.
Requires 5 items per row or throws a ValidationError.
Requires the first line to be blank/headers or data will be lost.
"""
references = set()
cleaned_text = ""

try:
csv_reader = csv.reader(text.split("\n"), delimiter=",")
# skip headers
next(csv_reader, None)
for row in csv_reader:
if row:
if len(row) != TOTAL_COLUMNS:
raise ValidationError({"file": [Compliance.OpenLicenceReturns.INVALID_FILE_FORMAT]})
references.add(row[0])
# https://owasp.org/www-community/attacks/CSV_Injection
cleaned_text += ",".join([re.sub("[^A-Za-z0-9/,.-]+", "", item.strip()) for item in row]) + "\n"
except csv.Error:
raise ValidationError({"file": [Compliance.OpenLicenceReturns.INVALID_FILE_FORMAT]})

return references, cleaned_text


def fetch_and_validate_licences(references, organisation_id):
if len(references) == 0:
raise ValidationError({"file": [Compliance.OpenLicenceReturns.INVALID_LICENCES]})

licence_ids = list(
Licence.objects.filter(reference_code__in=references, case__organisation_id=organisation_id).values_list(
"id", flat=True
)
)
if len(licence_ids) != len(references):
raise ValidationError({"file": [Compliance.OpenLicenceReturns.INVALID_LICENCES]})

return licence_ids


def compliance_visit_case_complete(case: ComplianceVisitCase) -> bool:
"""
Function to ensure that all the details of a ComplianceVisitCase is filled in, allowing for the status to be changed
Expand Down
20 changes: 1 addition & 19 deletions api/compliance/serializers/ComplianceSiteCaseSerializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
from rest_framework import serializers

from api.addresses.serializers import AddressSerializer
from api.cases.enums import CaseTypeEnum
from api.cases.models import Case
from api.compliance.models import ComplianceSiteCase, ComplianceVisitCase, OpenLicenceReturns
from api.compliance.serializers.OpenLicenceReturns import OpenLicenceReturnsListSerializer
from api.compliance.models import ComplianceSiteCase, ComplianceVisitCase
from api.core.serializers import PrimaryKeyRelatedSerializerField
from api.licences.enums import LicenceStatus
from api.licences.models import Licence
Expand All @@ -28,7 +26,6 @@ class ComplianceSiteViewSerializer(serializers.ModelSerializer):
organisation = PrimaryKeyRelatedSerializerField(
queryset=Organisation.objects.all(), serializer=OrganisationDetailSerializer
)
open_licence_returns = serializers.SerializerMethodField()
visits = serializers.SerializerMethodField()
team = None

Expand All @@ -40,7 +37,6 @@ class Meta:
"status",
"organisation",
"visits",
"open_licence_returns",
)

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -77,13 +73,6 @@ def get_visits(self, instance):
for case in visit_cases
]

def get_open_licence_returns(self, instance):
queryset = OpenLicenceReturns.objects.filter(organisation_id=instance.organisation_id).order_by(
"-year", "-created_at"
)

return OpenLicenceReturnsListSerializer(queryset, many=True).data


class ComplianceLicenceListSerializer(serializers.ModelSerializer):
flags = serializers.SerializerMethodField()
Expand All @@ -110,13 +99,6 @@ def get_flags(self, instance):
return get_ordered_flags(case=instance, team=self.team, limit=3)

def get_status(self, instance):
# Not all case types contain a licence, for example OGLs do not. As a result we display the case status
if instance.case_type.id in CaseTypeEnum.OPEN_GENERAL_LICENCE_IDS:
return {
"key": instance.status.status,
"value": get_status_value_from_case_status_enum(instance.status.status),
}

# The latest non draft licence should be the only non-draft licence on a case or the licence that was active
last_licence = (
Licence.objects.filter(case_id=instance.id)
Expand Down
6 changes: 0 additions & 6 deletions api/compliance/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,4 @@
views.ComplianceVisitPersonPresentView.as_view(),
name="person_present",
),
path("open-licence-returns/", views.OpenLicenceReturnsView.as_view(), name="open_licence_returns"),
path(
"open-licence-returns/<uuid:pk>/",
views.OpenLicenceReturnDownloadView.as_view(),
name="open_licence_return_download",
),
]
24 changes: 1 addition & 23 deletions api/compliance/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
from uuid import UUID

from django.db import transaction
from django.http import JsonResponse
from django.utils import timezone
from rest_framework import status
from rest_framework.generics import (
ListAPIView,
Expand All @@ -23,7 +20,7 @@
get_compliance_site_case,
get_exporter_visible_compliance_site_cases,
)
from api.compliance.models import OpenLicenceReturns, ComplianceVisitCase, CompliancePerson
from api.compliance.models import ComplianceVisitCase, CompliancePerson
from api.compliance.serializers.ComplianceSiteCaseSerializers import (
ComplianceLicenceListSerializer,
ExporterComplianceVisitListSerializer,
Expand Down Expand Up @@ -115,25 +112,6 @@ def get_queryset(self):

return cases

def get_paginated_response(self, data):
current_date = timezone.now().date()

# We take an OLR as outstanding if it hasn't been added by the end of January, meaning if the
# month is currently January we only go back 1 year
olr_year = current_date.year - 2 if current_date.month == 1 else current_date.year - 1

org_id = get_case(self.kwargs["pk"]).organisation_id
licences_with_olr = set(
OpenLicenceReturns.objects.filter(year=olr_year, organisation_id=org_id).values_list(
"licences__case", flat=True
)
)

for licence in data:
licence["has_open_licence_returns"] = UUID(licence["id"]) in licences_with_olr

return super().get_paginated_response(data)


class ComplianceSiteVisits(ListCreateAPIView):
authentication_classes = (GovAuthentication,)
Expand Down
1 change: 0 additions & 1 deletion api/conf/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@
"api.queries.goods_query",
"api.queries.end_user_advisories",
"api.queues",
"api.open_general_licences",
"rest_framework",
"api.staticdata",
"api.staticdata.case_types",
Expand Down
1 change: 0 additions & 1 deletion api/conf/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
path("queries/", include("api.queries.urls")),
path("routing-rules/", include("api.workflow.routing_rules.urls")),
path("licences/", include("api.licences.urls")),
path("open-general-licences/", include("api.open_general_licences.urls")),
path(
"data-workspace/", include("api.data_workspace.urls")
), # when changing this value please update schema_generator_urls.py
Expand Down
1 change: 0 additions & 1 deletion api/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class GovPermissions(Enum):
MANAGE_PICKLISTS = "Manage picklists"
ENFORCEMENT_CHECK = "Enforcement check permission"
MAINTAIN_FOOTNOTES = "Create footnotes"
MAINTAIN_OGL = "Maintain open general licences"
REMOVE_AUTHORISED_COUNTERSIGNER_FLAGS = "Can remove authorised countersigner flags"
REMOVE_HEAD_OF_LICENSING_UNIT_FLAGS = "Can remove Head of Licensing Unit flags"

Expand Down
1 change: 0 additions & 1 deletion api/core/management/commands/create_er_diagrams.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"goodstype",
"letter_templates",
"licences",
"open_general_licences",
"organisations",
"parties",
"picklists",
Expand Down
9 changes: 1 addition & 8 deletions api/data_workspace/v0/licence_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from rest_framework import viewsets
from rest_framework.pagination import LimitOffsetPagination

from api.cases.enums import CaseTypeEnum
from api.core.authentication import DataWorkspaceOnlyAuthentication
from api.licences import models, enums
from api.licences.serializers import view_licence as serializers
Expand All @@ -17,13 +16,7 @@ class LicencesListDW(viewsets.ReadOnlyModelViewSet):
non_active_states = CaseStatus.objects.filter(status=CaseStatusEnum.SURRENDERED)

queryset = (
# OGL's are always hidden as we don't treat them as a licence
# and they shouldn't be viewed from this endpoint
models.Licence.objects.exclude(
Q(case__status__in=non_active_states)
| Q(case__case_type__id__in=CaseTypeEnum.OPEN_GENERAL_LICENCE_IDS)
| Q(status=enums.LicenceStatus.DRAFT)
)
models.Licence.objects.exclude(Q(case__status__in=non_active_states) | Q(status=enums.LicenceStatus.DRAFT))
.order_by("created_at")
.reverse()
)
5 changes: 0 additions & 5 deletions api/data_workspace/v0/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,3 @@
licence_views.LicencesListDW,
basename="dw-licences-only",
)
router_v0.register(
"ogl",
licence_views.OpenGeneralLicenceListDW,
basename="dw-ogl-only",
)
8 changes: 1 addition & 7 deletions api/letter_templates/context_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from api.organisations.models import Organisation
from api.addresses.models import Address
from api.parties.models import Party
from api.compliance.models import ComplianceVisitCase, CompliancePerson, OpenLicenceReturns
from api.compliance.models import ComplianceVisitCase, CompliancePerson
from api.licences.models import Licence
from api.organisations.models import Site, ExternalLocation
from api.queries.end_user_advisories.models import EndUserAdvisoryQuery
Expand Down Expand Up @@ -592,7 +592,6 @@ class Meta:

site_name = serializers.SerializerMethodField()
address = AddressSerializer()
open_licence_returns = serializers.SerializerMethodField()
licences = serializers.SerializerMethodField()

def get_site_name(self, obj):
Expand Down Expand Up @@ -633,7 +632,6 @@ class ComplianceSiteSerializer(serializers.Serializer):
reference_code = serializers.CharField()
site_name = serializers.SerializerMethodField()
address = serializers.SerializerMethodField()
open_licence_returns = serializers.SerializerMethodField()
licences = serializers.SerializerMethodField()

def get_site_name(self, obj):
Expand All @@ -642,10 +640,6 @@ def get_site_name(self, obj):
def get_address(self, obj):
return AddressSerializer(obj.compliancesitecase.site.address).data

def get_open_licence_returns(self, obj):
olrs = OpenLicenceReturns.objects.filter(organisation_id=obj.organisation.id).order_by("-year", "-created_at")
return OpenLicenceReturnsSerializer(olrs, many=True).data

def get_licences(self, obj):
cases = Case.objects.filter_for_cases_related_to_compliance_case(obj.id)
return ComplianceSiteLicenceSerializer(cases, many=True).data
Expand Down
2 changes: 1 addition & 1 deletion api/letter_templates/tests/test_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def test_create_letter_templates_order_is_saved(self):
self.assertEqual(letter_paragraphs[1].id, picklist_items[1].id)

def test_create_letter_template_with_decisions_success(self):
case_type_references = [CaseTypeEnum.SIEL.reference, CaseTypeEnum.OIEL.reference]
case_type_references = [CaseTypeEnum.SIEL.reference]
data = {
"name": "Letter Template",
"case_types": case_type_references,
Expand Down
2 changes: 1 addition & 1 deletion api/letter_templates/tests/test_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def setUp(self):
self.gov_user.role.permissions.set([constants.GovPermissions.CONFIGURE_TEMPLATES.name])
self.letter_template = self.create_letter_template(
name="SIEL",
case_types=[CaseTypeEnum.SIEL.id, CaseTypeEnum.OIEL.id],
case_types=[CaseTypeEnum.SIEL.id],
decisions=[Decision.objects.get(name="refuse"), Decision.objects.get(name="no_licence_required")],
)
self.url = reverse("letter_templates:letter_template", kwargs={"pk": self.letter_template.id})
Expand Down
Loading

0 comments on commit ef3667f

Please sign in to comment.