- Versioned product specification table (Unrefined Shea Butter v1.0 seed) with spec-based QC evaluation replacing hard-coded thresholds - Structured QC results with test methods and four-eyes verification (submitter cannot self-approve) - reportlab IXG Quality Summary PDF auto-generated on quality approval, SHA-256 hashed; original independent lab PDF kept authoritative - CertificateOfAnalysis version/status/hash/approval/supersede lifecycle; commercial release publishes to buyers and triggers notification - EUDR evidence workflow: Facility, OriginZone, CollectorGroup, HarvestIntake, IntakeBatchLineage, DueDiligenceCase, EUDREvidence, RiskAssessment, MitigationAction, DueDiligenceStatementReference with rule-based completeness check and risk assessment (no AI legal conclusions) - Ops portal: QC Approvals, CoA Reviews, EUDR Compliance screens - Buyer portal: /portal/compliance page - 22 automated tests covering four-eyes, CAPA, PDF+hash, publish/notify, EUDR blocks and buyer isolation
122 lines
4.3 KiB
Python
122 lines
4.3 KiB
Python
from rest_framework import serializers
|
|
|
|
from .models import (
|
|
ProductSpecification, SpecParameter,
|
|
Facility, OriginZone, CollectorGroup, HarvestIntake, IntakeBatchLineage,
|
|
DueDiligenceCase, EUDREvidence, RiskAssessment, MitigationAction,
|
|
DueDiligenceStatementReference,
|
|
)
|
|
|
|
|
|
class SpecParameterSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = SpecParameter
|
|
fields = "__all__"
|
|
read_only_fields = ["id"]
|
|
|
|
|
|
class ProductSpecificationSerializer(serializers.ModelSerializer):
|
|
parameters = SpecParameterSerializer(many=True, required=False)
|
|
approved_by_name = serializers.CharField(source="approved_by.full_name", read_only=True)
|
|
|
|
class Meta:
|
|
model = ProductSpecification
|
|
fields = "__all__"
|
|
read_only_fields = ["id", "approved_by", "approved_at", "created_at", "updated_at"]
|
|
|
|
|
|
class FacilitySerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Facility
|
|
fields = "__all__"
|
|
read_only_fields = ["id", "created_at"]
|
|
|
|
|
|
class OriginZoneSerializer(serializers.ModelSerializer):
|
|
facility_name = serializers.CharField(source="facility.name", read_only=True)
|
|
verified_by_name = serializers.CharField(source="verified_by.full_name", read_only=True)
|
|
|
|
class Meta:
|
|
model = OriginZone
|
|
fields = "__all__"
|
|
read_only_fields = ["id", "verified_by", "verified_at", "created_at"]
|
|
|
|
|
|
class CollectorGroupSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = CollectorGroup
|
|
fields = "__all__"
|
|
read_only_fields = ["id", "created_at"]
|
|
|
|
|
|
class HarvestIntakeSerializer(serializers.ModelSerializer):
|
|
origin_zone_code = serializers.CharField(source="origin_zone.zone_code", read_only=True)
|
|
collector_group_name = serializers.CharField(source="collector_group.name", read_only=True)
|
|
|
|
class Meta:
|
|
model = HarvestIntake
|
|
fields = "__all__"
|
|
read_only_fields = ["id", "created_at"]
|
|
|
|
|
|
class IntakeBatchLineageSerializer(serializers.ModelSerializer):
|
|
batch_reference = serializers.CharField(source="batch.batch_reference", read_only=True)
|
|
intake_reference = serializers.CharField(source="harvest_intake.intake_reference", read_only=True)
|
|
|
|
class Meta:
|
|
model = IntakeBatchLineage
|
|
fields = "__all__"
|
|
read_only_fields = ["id", "created_at"]
|
|
|
|
|
|
class EUDREvidenceSerializer(serializers.ModelSerializer):
|
|
verified_by_name = serializers.CharField(source="verified_by.full_name", read_only=True)
|
|
|
|
class Meta:
|
|
model = EUDREvidence
|
|
fields = "__all__"
|
|
read_only_fields = ["id", "verified_by", "verified_at", "created_at"]
|
|
|
|
|
|
class RiskAssessmentSerializer(serializers.ModelSerializer):
|
|
assessed_by_name = serializers.CharField(source="assessed_by.full_name", read_only=True)
|
|
|
|
class Meta:
|
|
model = RiskAssessment
|
|
fields = "__all__"
|
|
read_only_fields = ["id", "assessed_at", "assessed_by"]
|
|
|
|
|
|
class MitigationActionSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = MitigationAction
|
|
fields = "__all__"
|
|
read_only_fields = ["id", "created_at"]
|
|
|
|
|
|
class DueDiligenceStatementReferenceSerializer(serializers.ModelSerializer):
|
|
submitted_by_name = serializers.CharField(source="submitted_by.full_name", read_only=True)
|
|
|
|
class Meta:
|
|
model = DueDiligenceStatementReference
|
|
fields = "__all__"
|
|
read_only_fields = ["id", "submitted_by", "created_at"]
|
|
|
|
|
|
class DueDiligenceCaseSerializer(serializers.ModelSerializer):
|
|
batch_reference = serializers.CharField(source="batch.batch_reference", read_only=True)
|
|
approved_by_name = serializers.CharField(source="approved_by.full_name", read_only=True)
|
|
assessed_by_name = serializers.CharField(source="assessed_by.full_name", read_only=True)
|
|
evidence = EUDREvidenceSerializer(many=True, read_only=True)
|
|
risk_assessments = RiskAssessmentSerializer(many=True, read_only=True)
|
|
mitigation_actions = MitigationActionSerializer(many=True, read_only=True)
|
|
statement_references = DueDiligenceStatementReferenceSerializer(many=True, read_only=True)
|
|
|
|
class Meta:
|
|
model = DueDiligenceCase
|
|
fields = "__all__"
|
|
read_only_fields = [
|
|
"id", "status", "risk_level", "completeness_results", "assessed_by",
|
|
"assessed_at", "approved_by", "approved_at", "rejected_reason",
|
|
"created_at", "updated_at",
|
|
]
|