class EcjuQueryExporterRespondSerializer(serializers.ModelSerializer): team = serializers.SerializerMethodField() responded_by_user = PrimaryKeyRelatedSerializerField( queryset=ExporterUser.objects.all(), serializer=ExporterUserViewSerializer) response = serializers.CharField(max_length=2200, allow_blank=False, allow_null=False) documents = serializers.SerializerMethodField() class Meta: model = EcjuQuery fields = ( "id", "question", "response", "case", "responded_by_user", "team", "created_at", "responded_at", "documents", ) def get_team(self, instance): # If the team is not available, use the user's current team. team = instance.team if instance.team else instance.raised_by_user.team return TeamSerializer(team).data def get_documents(self, instance): documents = EcjuQueryDocument.objects.filter(query=instance) return SimpleEcjuQueryDocumentViewSerializer(documents, many=True).data
class RoleSerializer(serializers.ModelSerializer): permissions = PrimaryKeyRelatedField(queryset=Permission.objects.all(), many=True, required=False) organisation = PrimaryKeyRelatedField(queryset=Organisation.objects.all(), required=False, allow_null=True) type = serializers.ChoiceField(choices=UserType.non_system_choices()) name = serializers.CharField( max_length=30, error_messages={"blank": strings.Roles.BLANK_NAME}, ) statuses = PrimaryKeyRelatedSerializerField( queryset=CaseStatus.objects.all(), many=True, required=False, serializer=CaseStatusSerializer) class Meta: model = Role fields = ( "id", "name", "permissions", "type", "organisation", "statuses", )
class FlagReadOnlySerializer(serializers.Serializer): """ More performant read_only flag serializer """ id = serializers.UUIDField(read_only=True) name = serializers.CharField(read_only=True) colour = serializers.CharField(read_only=True) level = serializers.CharField(read_only=True) label = serializers.CharField(read_only=True) status = serializers.CharField(read_only=True) priority = serializers.IntegerField(read_only=True) blocks_approval = serializers.BooleanField(read_only=True) team = PrimaryKeyRelatedSerializerField(queryset=Team.objects.all(), serializer=TeamReadOnlySerializer)
class CaseListSerializer(serializers.Serializer): id = serializers.UUIDField() reference_code = serializers.CharField() case_type = PrimaryKeyRelatedSerializerField( queryset=CaseType.objects.all(), serializer=CaseTypeSerializer) assignments = serializers.SerializerMethodField() status = serializers.SerializerMethodField() submitted_at = serializers.SerializerMethodField() sla_days = serializers.IntegerField() sla_remaining_days = serializers.IntegerField() next_review_date = serializers.DateField() has_open_queries = serializers.BooleanField() def __init__(self, *args, **kwargs): self.team = kwargs.pop("team", None) self.include_hidden = kwargs.pop("include_hidden", None) super().__init__(*args, **kwargs) def get_assignments(self, instance): return_value = {} for assignment in instance.case_assignments.all(): user_id = str(assignment.user.pk) if user_id not in return_value: return_value[user_id] = {} return_value[user_id]["first_name"] = assignment.user.first_name return_value[user_id]["last_name"] = assignment.user.last_name return_value[user_id]["email"] = assignment.user.email if "queues" not in return_value[user_id]: return_value[user_id]["queues"] = [] return_value[user_id]["queues"].append(assignment.queue.name) return return_value def get_submitted_at(self, instance): # Return the DateTime value manually as otherwise # it'll return a string representation which isn't suitable for filtering return instance.submitted_at def get_status(self, instance): return { "key": instance.status.status, "value": CaseStatusEnum.get_text(instance.status.status) }
class AdviceViewSerializer(serializers.Serializer): id = serializers.UUIDField() text = serializers.CharField() note = serializers.CharField() type = KeyValueChoiceField(choices=AdviceType.choices) level = serializers.CharField() proviso = serializers.CharField() denial_reasons = serializers.PrimaryKeyRelatedField( queryset=DenialReason.objects.all(), many=True) footnote = serializers.CharField() user = PrimaryKeyRelatedSerializerField(queryset=GovUser.objects.all(), serializer=GovUserListSerializer) created_at = serializers.DateTimeField() good = serializers.UUIDField(source="good_id") goods_type = serializers.UUIDField(source="goods_type_id") country = serializers.UUIDField(source="country_id") end_user = serializers.UUIDField(source="end_user_id") ultimate_end_user = serializers.UUIDField(source="ultimate_end_user_id") consignee = serializers.UUIDField(source="consignee_id") third_party = serializers.UUIDField(source="third_party_id")
class OrganisationDetailSerializer(serializers.ModelSerializer): primary_site = PrimaryKeyRelatedSerializerField( queryset=Site.objects.all(), serializer=SiteListSerializer) type = KeyValueChoiceField(OrganisationType.choices) flags = serializers.SerializerMethodField() status = KeyValueChoiceField(OrganisationStatus.choices) def get_flags(self, instance): # TODO remove try block when other end points adopt generics try: if hasattr(self.context.get("request").user, "govuser"): return list( instance.flags.values("id", "name", "colour", "label", "priority")) except AttributeError: return list( instance.flags.values("id", "name", "colour", "label", "priority")) class Meta: model = Organisation fields = "__all__"
class CaseNoteSerializer(serializers.ModelSerializer): """ Serializes case notes """ text = serializers.CharField( min_length=2, max_length=2200, error_messages={ "blank": strings.Cases.CaseNotes.BLANK, "min_length": strings.Cases.CaseNotes.MIN_LENGTH, "max_length": strings.Cases.CaseNotes.MAX_LENGTH, }, ) case = serializers.PrimaryKeyRelatedField(queryset=Case.objects.all()) user = PrimaryKeyRelatedSerializerField(queryset=BaseUser.objects.all(), serializer=BaseUserViewSerializer) created_at = serializers.DateTimeField(read_only=True) is_visible_to_exporter = serializers.BooleanField(default=False) class Meta: model = CaseNote fields = "__all__"
class GoodsQuerySerializer(serializers.ModelSerializer): from api.goods.serializers import GoodSerializerInternal organisation = PrimaryKeyRelatedSerializerField( queryset=Organisation.objects.all(), serializer=TinyOrganisationViewSerializer) good = GoodSerializerInternal(read_only=True) submitted_at = serializers.DateTimeField(read_only=True) status = serializers.SerializerMethodField() class Meta: model = GoodsQuery fields = ( "id", "clc_control_list_entry", "clc_raised_reasons", "pv_grading_raised_reasons", "good", "submitted_at", "organisation", "status", "clc_responded", "pv_grading_responded", "created_at", "updated_at", ) def get_status(self, instance): if instance.status: return { "key": instance.status.status, "value": get_status_value_from_case_status_enum(instance.status.status), } return None
class F680ClearanceUpdateSerializer(GenericApplicationUpdateSerializer): name = CharField( max_length=100, required=True, allow_blank=False, allow_null=False, error_messages={ "blank": strings.Applications.Generic.MISSING_REFERENCE_NAME_ERROR }, ) types = PrimaryKeyRelatedSerializerField( queryset=F680ClearanceType.objects.all(), serializer=F680ClearanceTypeSerializer, error_messages={ "required": strings.Applications.F680.NO_CLEARANCE_TYPE }, many=True, ) clearance_level = serializers.ChoiceField(choices=PvGrading.choices, allow_null=True) expedited = serializers.BooleanField(required=False, allow_null=True) expedited_date = serializers.DateField( required=False, error_messages={ "invalid": strings.Applications.F680.AdditionalInformation.Errors. EXPEDITED_DATE_RANGE }, ) foreign_technology = serializers.BooleanField(required=False, allow_null=True) foreign_technology_description = serializers.CharField(max_length=2000, allow_blank=True, required=False) locally_manufactured = serializers.BooleanField(required=False, allow_null=True) locally_manufactured_description = serializers.CharField(max_length=2000, allow_blank=True, required=False) mtcr_type = KeyValueChoiceField(choices=MTCRAnswers.choices, allow_blank=True, required=False) electronic_warfare_requirement = serializers.BooleanField(required=False, allow_null=True) uk_service_equipment = serializers.BooleanField(required=False, allow_null=True) uk_service_equipment_description = serializers.CharField(max_length=2000, allow_blank=True, required=False) uk_service_equipment_type = KeyValueChoiceField( choices=ServiceEquipmentType.choices, allow_blank=True, required=False) prospect_value = serializers.DecimalField( required=False, allow_null=True, max_digits=15, decimal_places=2, error_messages={ "invalid": strings.Applications.F680.AdditionalInformation.Errors. PROSPECT_VALUE }, ) class Meta: model = F680ClearanceApplication fields = (GenericApplicationUpdateSerializer.Meta.fields + constants.F680.ADDITIONAL_INFORMATION_FIELDS + ( "types", "clearance_level", )) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if "types" in self.initial_data: self.initial_data["types"] = [ F680ClearanceTypeEnum.ids.get(clearance_type) for clearance_type in self.initial_data.get("types", []) ] def validate(self, data): error_strings = strings.Applications.F680.AdditionalInformation.Errors error_messages = { "expedited": error_strings.EXPEDITED, "expedited_date": error_strings.EXPEDITED_DATE, "foreign_technology": error_strings.FOREIGN_TECHNOLOGY, "foreign_technology_description": error_strings.FOREIGN_TECHNOLOGY_DESCRIPTION, "locally_manufactured": error_strings.LOCALLY_MANUFACTURED, "locally_manufactured_description": error_strings.LOCALLY_MANUFACTURED_DESCRIPTION, "mtcr_type": error_strings.MTCR_TYPE, "electronic_warfare_requirement": error_strings.ELECTRONIC_WARFARE_REQUIREMENT, "uk_service_equipment": error_strings.UK_SERVICE_EQUIPMENT, "uk_service_equipment_type": error_strings.UK_SERVICE_EQUIPMENT_TYPE, "prospect_value": error_strings.PROSPECT_VALUE, } for field in constants.F680.REQUIRED_FIELDS: if field in self.initial_data: if self.initial_data[field] is None or self.initial_data[ field] == "": raise serializers.ValidationError( {field: [error_messages[field]]}) if self.initial_data[field] is True or self.initial_data[ field] == "True": secondary_field = constants.F680.REQUIRED_SECONDARY_FIELDS.get( field, False) if secondary_field and not self.initial_data.get( secondary_field): raise serializers.ValidationError({ secondary_field: [error_messages[secondary_field]] }) validated_data = super().validate(data) if "types" in self.initial_data and not validated_data.get("types"): raise serializers.ValidationError( {"types": strings.Applications.F680.NO_CLEARANCE_TYPE}) if validated_data.get("expedited"): today = timezone.now().date() limit = (timezone.now() + timedelta(days=30)).date() if today > validated_data["expedited_date"] or validated_data[ "expedited_date"] > limit: raise serializers.ValidationError( {"expedited_date": [error_strings.EXPEDITED_DATE_RANGE]}) validated_data["expedited_date"] = str( validated_data["expedited_date"]) return validated_data def update(self, instance, validated_data): if "types" in validated_data: validated_data["types"] = validated_data.get("types") instance = super().update(instance, validated_data) return instance
class FlagSerializer(serializers.ModelSerializer): name = serializers.CharField( max_length=25, validators=[ UniqueValidator(queryset=Flag.objects.all(), lookup="iexact", message=strings.Flags.NON_UNIQUE) ], error_messages={"blank": strings.Flags.BLANK_NAME}, ) colour = serializers.ChoiceField(choices=FlagColours.choices, default=FlagColours.DEFAULT) level = serializers.ChoiceField( choices=FlagLevels.choices, error_messages={"invalid_choice": "Select a parameter"}, ) label = serializers.CharField( max_length=15, required=False, allow_blank=True, error_messages={ "blank": strings.Flags.ValidationErrors.LABEL_MISSING, }, ) status = serializers.ChoiceField(choices=FlagStatuses.choices, default=FlagStatuses.ACTIVE) priority = serializers.IntegerField( default=0, min_value=0, max_value=100, error_messages={ "invalid": strings.Flags.ValidationErrors.PRIORITY, "max_value": strings.Flags.ValidationErrors.PRIORITY_TOO_LARGE, "min_value": strings.Flags.ValidationErrors.PRIORITY_NEGATIVE, }, ) team = PrimaryKeyRelatedSerializerField(queryset=Team.objects.all(), serializer=TeamSerializer) blocks_approval = serializers.BooleanField( required=True, allow_null=False, error_messages={ "required": strings.Flags.ValidationErrors.BLOCKING_APPROVAL_MISSING, }, ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.context and not self.context.get("request").method == "GET": self.initial_data["team"] = self.context.get( "request").user.govuser.team_id if hasattr(self, "initial_data"): if self.initial_data.get("colour") != FlagColours.DEFAULT: self.fields["label"].required = True self.fields["label"].allow_blank = False class Meta: model = Flag fields = ( "id", "name", "level", "team", "status", "label", "colour", "priority", "blocks_approval", ) def update(self, instance, validated_data): instance.name = validated_data.get("name", instance.name) instance.label = validated_data.get("label", instance.label) instance.colour = validated_data.get("colour", instance.colour) instance.priority = validated_data.get("priority", instance.priority) instance.status = validated_data.get("status", instance.status) instance.blocks_approval = validated_data.get("blocks_approval", instance.blocks_approval) instance.save() return instance
class FlaggingRuleSerializer(serializers.ModelSerializer): team = PrimaryKeyRelatedSerializerField(queryset=Team.objects.all(), serializer=TeamSerializer) level = serializers.ChoiceField( choices=FlagLevels.choices, error_messages={ "required": "Select a parameter", "null": "Select a parameter", }, ) status = serializers.ChoiceField(choices=FlagStatuses.choices, default=FlagStatuses.ACTIVE) flag = PrimaryKeyRelatedField( queryset=Flag.objects.all(), error_messages={"null": strings.FlaggingRules.NO_FLAG}) matching_values = serializers.ListField(child=serializers.CharField(), required=False) matching_groups = serializers.ListField(child=serializers.CharField(), required=False) excluded_values = serializers.ListField(child=serializers.CharField(), required=False) is_for_verified_goods_only = serializers.BooleanField(required=False, allow_null=True) class Meta: model = FlaggingRule fields = ( "id", "team", "level", "flag", "status", "matching_values", "matching_groups", "excluded_values", "is_for_verified_goods_only", ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if hasattr(self, "initial_data"): if "level" not in self.initial_data: self.initial_data[ "level"] = self.instance.level if self.instance else None if "matching_values" not in self.initial_data: self.initial_data["matching_values"] = self.instance.matching_values if self.instance else [] if "matching_groups" not in self.initial_data: self.initial_data["matching_groups"] = self.instance.matching_groups if self.instance else [] if "excluded_values" not in self.initial_data: self.initial_data["excluded_values"] = self.instance.excluded_values if self.instance else [] if "is_for_verified_goods_only" not in self.initial_data: self.initial_data["is_for_verified_goods_only"] = ( self.instance.is_for_verified_goods_only if self.instance else None) def update(self, instance, validated_data): instance.status = validated_data.get("status", instance.status) instance.matching_values = validated_data.get("matching_values", instance.matching_values) instance.matching_groups = validated_data.get("matching_groups", instance.matching_groups) instance.excluded_values = validated_data.get("excluded_values", instance.excluded_values) instance.flag = validated_data.get("flag", instance.flag) instance.is_for_verified_goods_only = validated_data.get( "is_for_verified_goods_only", instance.is_for_verified_goods_only) instance.save() return instance def validate(self, data): errors = {} validated_data = super().validate(data) matching_values = validated_data.get("matching_values") matching_groups = validated_data.get("matching_groups") excluded_values = validated_data.get("excluded_values") if validated_data["level"] == FlagLevels.GOOD: if not matching_values and not matching_groups and not excluded_values: errors["matching_values"] = "Enter a control list entry" errors["matching_groups"] = "Enter a control list entry" errors["excluded_values"] = "Enter a control list entry" elif validated_data["level"] == FlagLevels.DESTINATION: if not matching_values: errors["matching_values"] = "Enter a destination" elif validated_data["level"] == FlagLevels.CASE: if not matching_values: errors["matching_values"] = "Enter an application type" if ("level" in validated_data and validated_data["level"] == FlagLevels.GOOD and validated_data["is_for_verified_goods_only"] is None): errors[ "is_for_verified_goods_only"] = strings.FlaggingRules.NO_ANSWER_VERIFIED_ONLY if errors: raise serializers.ValidationError(errors) return validated_data
class EndUserAdvisoryViewSerializer(serializers.ModelSerializer): organisation = PrimaryKeyRelatedSerializerField( queryset=Organisation.objects.all(), serializer=OrganisationDetailSerializer ) end_user = PartySerializer() reasoning = serializers.CharField(required=False, allow_blank=True, allow_null=True, max_length=2000) note = serializers.CharField(required=False, allow_blank=True, allow_null=True, max_length=2000) contact_email = serializers.EmailField() copy_of = serializers.PrimaryKeyRelatedField(queryset=EndUserAdvisoryQuery.objects.all(), required=False) status = serializers.SerializerMethodField() exporter_user_notification_count = serializers.SerializerMethodField() standard_blank_error_message = "This field may not be blank" class Meta: model = EndUserAdvisoryQuery fields = ( "id", "end_user", "reasoning", "note", "organisation", "copy_of", "nature_of_business", "contact_name", "contact_email", "contact_job_title", "contact_telephone", "status", "exporter_user_notification_count", "reference_code", "case_officer", "created_at", "updated_at", "submitted_by", ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.exporter_user = kwargs.get("context").get("exporter_user") if "context" in kwargs else None self.organisation_id = kwargs.get("context").get("organisation_id") if "context" in kwargs else None if not isinstance(self.exporter_user, ExporterUser): self.fields.pop("exporter_user_notification_count") def get_status(self, instance): if instance.status: return { "key": instance.status.status, "value": get_status_value_from_case_status_enum(instance.status.status), } return None def validate_nature_of_business(self, value): if self.initial_data.get("end_user").get("sub_type") == SubType.COMMERCIAL and not value: raise serializers.ValidationError(self.standard_blank_error_message) return value def validate_contact_name(self, value): if self.initial_data.get("end_user").get("sub_type") != SubType.INDIVIDUAL and not value: raise serializers.ValidationError(self.standard_blank_error_message) return value def validate_contact_job_title(self, value): if self.initial_data.get("end_user").get("sub_type") != SubType.INDIVIDUAL and not value: raise serializers.ValidationError(self.standard_blank_error_message) return value def create(self, validated_data): end_user_data = validated_data.pop("end_user") # We set the country and organisation back to their string IDs, otherwise # the end_user serializer struggles to save them end_user_data["country"] = end_user_data["country"].id end_user_data["organisation"] = end_user_data["organisation"].id end_user_serializer = PartySerializer(data=end_user_data) if end_user_serializer.is_valid(): end_user = end_user_serializer.save() else: raise serializers.ValidationError(end_user_serializer.errors) validated_data["organisation_id"] = end_user_data["organisation"] validated_data["status"] = get_case_status_by_status(CaseStatusEnum.SUBMITTED) validated_data["submitted_at"] = timezone.localtime() validated_data["case_type_id"] = CaseTypeEnum.EUA.id end_user_advisory_query = EndUserAdvisoryQuery.objects.create(**validated_data, end_user=end_user) end_user_advisory_query.save() return end_user_advisory_query def get_exporter_user_notification_count(self, instance): return get_exporter_user_notification_individual_count( exporter_user=self.exporter_user, organisation_id=self.organisation_id, case=instance )
class CaseDetailSerializer(serializers.ModelSerializer): queues = serializers.PrimaryKeyRelatedField(many=True, queryset=Queue.objects.all()) queue_names = serializers.SerializerMethodField() assigned_users = serializers.SerializerMethodField() has_advice = serializers.SerializerMethodField() flags = serializers.SerializerMethodField() all_flags = serializers.SerializerMethodField() case_officer = GovUserSimpleSerializer(read_only=True) copy_of = serializers.SerializerMethodField() audit_notification = serializers.SerializerMethodField() sla_days = serializers.IntegerField() sla_remaining_days = serializers.IntegerField() advice = AdviceViewSerializer(many=True) data = serializers.SerializerMethodField() case_type = PrimaryKeyRelatedSerializerField( queryset=CaseType.objects.all(), serializer=CaseTypeSerializer) next_review_date = serializers.SerializerMethodField() class Meta: model = Case fields = ( "id", "case_type", "flags", "queues", "queue_names", "assigned_users", "has_advice", "advice", "all_flags", "case_officer", "audit_notification", "reference_code", "copy_of", "sla_days", "sla_remaining_days", "data", "next_review_date", ) def __init__(self, *args, **kwargs): self.team = kwargs.pop("team", None) self.user = kwargs.pop("user", None) 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: application = get_application(instance.id) serializer = get_application_view_serializer(application) return serializer(application).data elif instance.case_type.type == CaseTypeTypeEnum.QUERY: return QueryViewSerializer(instance.query, read_only=True).data elif instance.case_type.sub_type == CaseTypeSubTypeEnum.COMP_SITE: compliance = ComplianceSiteCase.objects.get(id=instance.id) return ComplianceSiteViewSerializer(compliance, context={ "team": self.team }).data elif instance.case_type.sub_type == CaseTypeSubTypeEnum.COMP_VISIT: compliance = ComplianceVisitCase.objects.get(id=instance.id) return ComplianceVisitSerializer(compliance).data def get_flags(self, instance): return list(instance.flags.all().values("id", "name", "colour", "label", "priority")) def get_queue_names(self, instance): return list(instance.queues.values_list("name", flat=True)) def get_assigned_users(self, instance): return instance.get_assigned_users() def get_has_advice(self, instance): has_advice = { "user": False, "my_user": False, "team": False, "my_team": False, "final": False } team_advice = Advice.objects.filter(case=instance).values_list( "id", flat=True) if team_advice.exists(): has_advice["team"] = True final_advice = Advice.objects.filter(case=instance).values_list( "id", flat=True) if final_advice.exists(): has_advice["final"] = True if Advice.objects.filter(case=instance).exclude( id__in=team_advice.union(final_advice)).exists(): has_advice["user"] = True my_team_advice = Advice.objects.filter( case=instance, team=self.team).values_list("id", flat=True) if my_team_advice.exists(): has_advice["my_team"] = True if Advice.objects.filter( case=instance, user=self.user).exclude(id__in=my_team_advice).exists(): has_advice["my_user"] = True
class ComplianceVisitSerializer(serializers.ModelSerializer): site_case_reference_code = serializers.CharField( source="site_case.reference_code") site_name = serializers.CharField(source="site_case.site.name") address = AddressSerializer(source="site_case.site.address") status = serializers.SerializerMethodField() organisation = PrimaryKeyRelatedSerializerField( queryset=Organisation.objects.all(), serializer=OrganisationDetailSerializer) overall_risk_value = KeyValueChoiceField( choices=ComplianceRiskValues.choices, allow_blank=True) compliance_risk_value = KeyValueChoiceField( choices=ComplianceRiskValues.choices, error_messages={ "invalid_choice": strings.Compliance.VisitCaseSerializer.RISK_VALUE_INVALID_CHOICE }, ) individuals_risk_value = KeyValueChoiceField( choices=ComplianceRiskValues.choices, error_messages={ "invalid_choice": strings.Compliance.VisitCaseSerializer.RISK_VALUE_INVALID_CHOICE }, ) products_risk_value = KeyValueChoiceField( choices=ComplianceRiskValues.choices, error_messages={ "invalid_choice": strings.Compliance.VisitCaseSerializer.RISK_VALUE_INVALID_CHOICE }, ) visit_type = KeyValueChoiceField(choices=ComplianceVisitTypes.choices, allow_blank=True) licence_risk_value = serializers.IntegerField(min_value=1, max_value=5, allow_null=True) overview = serializers.CharField( max_length=COMPLIANCEVISITCASE_TEXTFIELD_LENGTH) inspection = serializers.CharField( max_length=COMPLIANCEVISITCASE_TEXTFIELD_LENGTH) compliance_overview = serializers.CharField( max_length=COMPLIANCEVISITCASE_TEXTFIELD_LENGTH, error_messages={ "blank": strings.Compliance.VisitCaseSerializer.OVERVIEW_BLANK }, ) individuals_overview = serializers.CharField( max_length=COMPLIANCEVISITCASE_TEXTFIELD_LENGTH, error_messages={ "blank": strings.Compliance.VisitCaseSerializer.OVERVIEW_BLANK }, ) products_overview = serializers.CharField( max_length=COMPLIANCEVISITCASE_TEXTFIELD_LENGTH, error_messages={ "blank": strings.Compliance.VisitCaseSerializer.OVERVIEW_BLANK }, ) people_present = serializers.SerializerMethodField(read_only=True) visit_date = serializers.DateField(allow_null=True) class Meta: model = ComplianceVisitCase fields = ( "id", "site_case_id", "site_case_reference_code", "site_name", "address", "status", "organisation", "site_case", "visit_type", "visit_date", "overall_risk_value", "licence_risk_value", "overview", "inspection", "compliance_overview", "compliance_risk_value", "individuals_overview", "individuals_risk_value", "products_overview", "products_risk_value", "people_present", ) def get_status(self, instance): if instance.status: return { "key": instance.status.status, "value": get_status_value_from_case_status_enum(instance.status.status), } return None def get_people_present(self, instance): people = CompliancePerson.objects.filter(visit_case_id=instance.id) return [{ "id": person.id, "name": person.name, "job_title": person.job_title } for person in people] def __init__(self, instance=None, data=empty, **kwargs): # If an IntegerField receives a blank field, it throws an error. We don't enforce the user to add the # licence_risk_value field till they desire to regardless of form. if data is not empty: if data.get("licence_risk_value") == "": data.pop("licence_risk_value") super(ComplianceVisitSerializer, self).__init__(instance, data, **kwargs)
class RoutingRuleSerializer(serializers.ModelSerializer): team = PrimaryKeyRelatedSerializerField(queryset=Team.objects.all(), serializer=TeamSerializer) queue = PrimaryKeyRelatedSerializerField( queryset=Queue.objects.all(), serializer=TinyQueueSerializer, error_messages={ "required": strings.RoutingRules.Errors.NO_QUEUE, "null": strings.RoutingRules.Errors.NO_QUEUE }, ) status = PrimaryKeyRelatedSerializerField( queryset=CaseStatus.objects.all(), serializer=CaseStatusSerializer, error_messages={ "required": strings.RoutingRules.Errors.NO_CASE_STATUS, "null": strings.RoutingRules.Errors.NO_CASE_STATUS, }, ) tier = serializers.IntegerField( min_value=1, max_value=32000, error_messages={ "required": strings.RoutingRules.Errors.INVALID_TIER, "invalid": strings.RoutingRules.Errors.INVALID_TIER, }, ) additional_rules = serializers.MultipleChoiceField( choices=RoutingRulesAdditionalFields.choices, allow_empty=True, required=False) user = PrimaryKeyRelatedSerializerField( queryset=GovUser.objects.all(), serializer=GovUserViewSerializer, required=False, allow_null=True, error_messages={"required": strings.RoutingRules.Errors.NO_USER}, ) case_types = PrimaryKeyRelatedSerializerField( queryset=CaseType.objects.all(), serializer=CaseTypeSerializer, many=True, required=False, allow_null=True, allow_empty=True, error_messages={"required": strings.RoutingRules.Errors.NO_CASE_TYPE}, ) flags_to_include = PrimaryKeyRelatedSerializerField( queryset=Flag.objects.all(), serializer=FlagSerializer, many=True, required=False, allow_null=True, allow_empty=True, ) flags_to_exclude = PrimaryKeyRelatedSerializerField( queryset=Flag.objects.all(), serializer=FlagSerializer, many=True, required=False, allow_null=True, allow_empty=True, ) country = CountrySerializerField( required=False, allow_null=True, error_messages={"required": strings.RoutingRules.Errors.NO_COUNTRY}, ) class Meta: model = RoutingRule fields = ( "id", "team", "queue", "status", "tier", "user", "case_types", "country", "flags_to_include", "flags_to_exclude", "case_types", "additional_rules", "active", ) def __init__(self, *args, **kwargs): # set fields to required or not depending on additional rules passed forward super().__init__(*args, **kwargs) if kwargs.get("data"): if not kwargs["data"].get("team"): self.initial_data["team"] = kwargs["context"][ "request"].user.govuser.team.id additional_rules = kwargs["data"].get("additional_rules") if not isinstance(additional_rules, list): additional_rules = [additional_rules] if RoutingRulesAdditionalFields.USERS not in additional_rules: self.initial_data["user"] = None if RoutingRulesAdditionalFields.CASE_TYPES not in additional_rules: self.initial_data["case_types"] = [] if RoutingRulesAdditionalFields.COUNTRY not in additional_rules: self.initial_data["country"] = None if RoutingRulesAdditionalFields.FLAGS not in additional_rules: self.initial_data["flags_to_include"] = [] self.initial_data["flags_to_exclude"] = [] def validate(self, data): validated_data = super().validate(data) additional_rules = validated_data.get("additional_rules") if "case_types" in additional_rules and "case_types" not in validated_data: raise serializers.ValidationError( {"case_types[]": "Select a case type"}) if "flags" in additional_rules: if not validated_data.get( "flags_to_include") and not validated_data.get( "flags_to_exclude"): raise serializers.ValidationError({ "routing_rules_flags_condition": "Select a flag and flag condition" }) if "country" in additional_rules: if "country" not in validated_data or validated_data.get( "country") is None: raise serializers.ValidationError( {"country": "Select a country"}) if "users" in additional_rules: if "user" not in validated_data: raise serializers.ValidationError({"user": "******"}) return validated_data
class LetterTemplateSerializer(serializers.ModelSerializer): name = serializers.CharField( max_length=35, validators=[ UniqueValidator( queryset=LetterTemplate.objects.all(), lookup="iexact", message=strings.LetterTemplates.UNIQUE_NAME, ) ], error_messages={"blank": strings.LetterTemplates.NAME_REQUIRED}, ) letter_paragraphs = serializers.PrimaryKeyRelatedField( queryset=PicklistItem.objects.all(), many=True) case_types = PrimaryKeyRelatedSerializerField( queryset=CaseType.objects.all(), serializer=CaseTypeSerializer, error_messages={ "required": strings.LetterTemplates.SELECT_THE_CASE_TYPES }, many=True, ) layout = PrimaryKeyRelatedSerializerField( queryset=LetterLayout.objects.all(), serializer=LetterLayoutSerializer, error_messages={"required": strings.LetterTemplates.SELECT_THE_LAYOUT}, ) decisions = PrimaryKeyRelatedSerializerField( queryset=Decision.objects.all(), serializer=DecisionSerializer, required=False, many=True) visible_to_exporter = serializers.BooleanField( required=True, allow_null=False, error_messages={ "required": strings.LetterTemplates.VISIBLE_TO_EXPORTER }, ) include_digital_signature = serializers.BooleanField( required=True, allow_null=False, error_messages={ "required": strings.LetterTemplates.INCLUDE_DIGITAL_SIGNATURE }, ) class Meta: model = LetterTemplate fields = "__all__" @staticmethod def validate_case_types(attrs): if not attrs: raise serializers.ValidationError( strings.LetterTemplates.NEED_AT_LEAST_ONE_CASE_TYPE) return attrs def validate(self, data): validated_data = super().validate(data) # Prevent decisions from being set on Application case-type templates if validated_data.get("decisions"): case_types = validated_data.get("case_types") errors = [] for case_type in case_types: if case_type.type != CaseTypeTypeEnum.APPLICATION or case_type.sub_type == CaseTypeSubTypeEnum.HMRC: errors.append( CaseTypeReferenceEnum.get_text(case_type.reference)) if errors: raise serializers.ValidationError({ "case_types": strings.LetterTemplates. DECISIONS_NON_APPLICATION_CASE_TYPES_ERROR + ", ".join(sorted(errors)) }) return validated_data
class ComplianceSiteViewSerializer(serializers.ModelSerializer): site_name = serializers.CharField(source="site.name") address = AddressSerializer(source="site.address") status = serializers.SerializerMethodField() organisation = PrimaryKeyRelatedSerializerField( queryset=Organisation.objects.all(), serializer=OrganisationDetailSerializer) open_licence_returns = serializers.SerializerMethodField() visits = serializers.SerializerMethodField() team = None class Meta: model = ComplianceSiteCase fields = ( "address", "site_name", "status", "organisation", "visits", "open_licence_returns", ) def __init__(self, *args, **kwargs): super(ComplianceSiteViewSerializer, self).__init__(*args, **kwargs) self.team = self.context.get("team") def get_status(self, instance): if instance.status: return { "key": instance.status.status, "value": get_status_value_from_case_status_enum(instance.status.status), } return None def get_visits(self, instance): visit_cases = (ComplianceVisitCase.objects.select_related( "case_officer", "case_type").prefetch_related("flags").filter( site_case_id=instance.id)) return [{ "id": case.id, "reference_code": case.reference_code, "visit_date": case.visit_date, "case_officer": f"{case.case_officer.first_name} {case.case_officer.last_name}" if case.case_officer and case.case_officer.first_name else case.case_officer.email if case.case_officer and case.case_officer.email else None, "flags": get_ordered_flags(case=case, team=self.team, limit=3), } 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 RoleListStatusesSerializer(RoleListSerializer): statuses = PrimaryKeyRelatedSerializerField( queryset=CaseStatus.objects.all(), many=True, required=False, serializer=CaseStatusSerializer)
class AdviceCreateSerializer(serializers.ModelSerializer): text = serializers.CharField(required=True, max_length=5000, error_messages={"blank": strings.Advice.TEXT}) note = serializers.CharField(required=False, allow_blank=True, allow_null=True, max_length=200) type = KeyValueChoiceField( choices=AdviceType.choices, required=True, error_messages={"required": strings.Advice.TYPE}) level = serializers.CharField() proviso = serializers.CharField( required=False, allow_blank=True, allow_null=True, max_length=5000, ) denial_reasons = serializers.PrimaryKeyRelatedField( queryset=DenialReason.objects.all(), many=True, required=False) footnote = serializers.CharField( required=False, allow_blank=True, allow_null=True, error_messages={"blank": strings.Advice.FOOTNOTE}) footnote_required = serializers.BooleanField( required=False, allow_null=True, error_messages={"required": strings.Advice.FOOTNOTE_REQUIRED}) user = PrimaryKeyRelatedSerializerField(queryset=GovUser.objects.all(), serializer=GovUserListSerializer) team = PrimaryKeyRelatedSerializerField(queryset=Team.objects.all(), required=False, serializer=TeamReadOnlySerializer) good = serializers.PrimaryKeyRelatedField(queryset=Good.objects.all(), required=False) goods_type = serializers.PrimaryKeyRelatedField( queryset=GoodsType.objects.all(), required=False) country = serializers.PrimaryKeyRelatedField( queryset=Country.objects.all(), required=False) end_user = serializers.PrimaryKeyRelatedField( queryset=Party.objects.filter(type=PartyType.END_USER), required=False) ultimate_end_user = serializers.PrimaryKeyRelatedField( queryset=Party.objects.filter(type=PartyType.ULTIMATE_END_USER), required=False) consignee = serializers.PrimaryKeyRelatedField( queryset=Party.objects.filter(type=PartyType.CONSIGNEE), required=False) third_party = serializers.PrimaryKeyRelatedField( queryset=Party.objects.filter(type=PartyType.THIRD_PARTY), required=False) collated_pv_grading = serializers.CharField(default=None, allow_blank=True, allow_null=True, max_length=120) def to_representation(self, instance): return AdviceViewSerializer(instance).data def validate_denial_reasons(self, value): """ Check that the denial reasons are set if type is REFUSE """ for data in self.initial_data: if data.get( "type") and data["type"] == AdviceType.REFUSE and not data[ "denial_reasons"]: raise serializers.ValidationError( "Select at least one denial reason") return value def validate_proviso(self, value): """ Check that the proviso is set if type is REFUSE """ for data in self.initial_data: if data.get("type") and data[ "type"] == AdviceType.PROVISO and not data["proviso"]: raise ValidationError("Enter a proviso") return value class Meta: model = Advice fields = "__all__" def __init__(self, *args, **kwargs): super(AdviceCreateSerializer, self).__init__(*args, **kwargs) if hasattr(self, "initial_data"): self._footnote_fields_setup() # Only require a reason for the advice decision if it is of type refuse if self.initial_data[0].get("type") != AdviceType.REFUSE: self.fields["text"].required = False self.fields["text"].allow_null = True self.fields["text"].allow_blank = True def _footnote_fields_setup(self): # if the user has permission to maintain footnotes for advice, # they have to explicitly state if a footnote is required. if self.context.get("footnote_permission"): self.fields["footnote_required"].required = True self.fields["footnote_required"].allow_null = False # if a footnote is required, we have to validate each footnote is given if self.initial_data[0].get("footnote_required") == "True": self.fields["footnote"].required = True self.fields["footnote"].allow_null = False self.fields["footnote"].allow_blank = False # if a footnote is not required, we remove any footnotes that may already exist on the objects. if self.initial_data[0].get("footnote_required") == "False": for i in range(0, len(self.initial_data)): self.initial_data[i]["footnote"] = None else: # If the user does not have permission, we do not allow the user to set any footnote details. for i in range(0, len(self.initial_data)): self.initial_data[i]["footnote"] = None self.initial_data[i]["footnote_required"] = None
class OpenGeneralLicenceSerializer(serializers.ModelSerializer): name = serializers.CharField( required=True, allow_blank=False, allow_null=False, max_length=250, error_messages={ "blank": OpenGeneralLicences.serializerErrors.BLANK_NAME }, validators=[ UniqueValidator( queryset=OpenGeneralLicence.objects.all(), message=OpenGeneralLicences.serializerErrors.NON_UNIQUE_NAME) ], ) description = serializers.CharField( required=True, allow_blank=False, allow_null=False, error_messages={ "blank": OpenGeneralLicences.serializerErrors.BLANK_DESCRIPTION }, ) url = serializers.URLField( required=True, allow_blank=False, allow_null=False, error_messages={ "blank": OpenGeneralLicences.serializerErrors.BLANK_URL }, ) case_type = PrimaryKeyRelatedSerializerField( queryset=CaseType.objects.filter( id__in=CaseTypeEnum.OPEN_GENERAL_LICENCE_IDS).all(), required=True, allow_null=False, allow_empty=False, error_messages={ "null": OpenGeneralLicences.serializerErrors.REQUIRED_CASE_TYPE }, serializer=CaseTypeSerializer, ) countries = PrimaryKeyRelatedSerializerField( queryset=Country.objects.all(), many=True, required=True, allow_null=False, allow_empty=False, error_messages={ "required": OpenGeneralLicences.serializerErrors.REQUIRED_COUNTRIES }, serializer=CountrySerializer, ) control_list_entries = ControlListEntryField( many=True, required=True, allow_empty=False, ) registration_required = serializers.BooleanField( required=True, allow_null=False, error_messages={ "invalid": OpenGeneralLicences.serializerErrors.REQUIRED_REGISTRATION_REQUIRED }, ) status = KeyValueChoiceField(choices=OpenGeneralLicenceStatus.choices, required=False) registrations = serializers.SerializerMethodField() def get_registrations(self, instance): if self.context and "cases" in self.context: cases = self.context["cases"] data = [] for case in cases: if case.open_general_licence_id == instance.id: try: licence = Licence.objects.get_active_licence(case) except Licence.DoesNotExist: licence = Licence.objects.order_by( "-created_at").first() data.append({ "reference_code": licence.reference_code, "site": { "id": case.site.id, "name": case.site.name, "address": { "address_line_1": case.site.address.address_line_1, "address_line_2": case.site.address.address_line_2, "city": case.site.address.city, "region": case.site.address.region, "postcode": case.site.address.postcode, "country": { "name": "United Kingdom", }, }, "records_located_at": { "name": case.records_located_at_name }, }, "status": { "key": licence.status, "value": LicenceStatus.to_str(licence.status), }, "submitted_at": case.submitted_at, }) return data