- 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
73 lines
2.4 KiB
Python
73 lines
2.4 KiB
Python
from django.contrib import admin
|
|
|
|
from .models import (
|
|
ProductSpecification, SpecParameter,
|
|
Facility, OriginZone, CollectorGroup, HarvestIntake, IntakeBatchLineage,
|
|
DueDiligenceCase, EUDREvidence, RiskAssessment, MitigationAction,
|
|
DueDiligenceStatementReference,
|
|
)
|
|
|
|
|
|
class SpecParameterInline(admin.TabularInline):
|
|
model = SpecParameter
|
|
extra = 0
|
|
|
|
|
|
@admin.register(ProductSpecification)
|
|
class ProductSpecificationAdmin(admin.ModelAdmin):
|
|
list_display = ["product", "version", "status", "is_current", "effective_from", "effective_to", "approved_at"]
|
|
list_filter = ["status", "is_current", "product"]
|
|
inlines = [SpecParameterInline]
|
|
|
|
|
|
@admin.register(Facility)
|
|
class FacilityAdmin(admin.ModelAdmin):
|
|
list_display = ["name", "country", "region", "facility_type", "is_active"]
|
|
|
|
|
|
@admin.register(OriginZone)
|
|
class OriginZoneAdmin(admin.ModelAdmin):
|
|
list_display = ["zone_code", "facility", "country", "region", "verification_status", "verified_at"]
|
|
list_filter = ["verification_status", "country"]
|
|
|
|
|
|
@admin.register(CollectorGroup)
|
|
class CollectorGroupAdmin(admin.ModelAdmin):
|
|
list_display = ["name", "contact_reference", "origin_zone"]
|
|
|
|
|
|
@admin.register(HarvestIntake)
|
|
class HarvestIntakeAdmin(admin.ModelAdmin):
|
|
list_display = ["intake_reference", "intake_date", "weight_kg", "grade", "origin_zone", "status"]
|
|
list_filter = ["status"]
|
|
|
|
|
|
@admin.register(IntakeBatchLineage)
|
|
class IntakeBatchLineageAdmin(admin.ModelAdmin):
|
|
list_display = ["batch", "harvest_intake", "weight_allocated_kg"]
|
|
|
|
|
|
@admin.register(DueDiligenceCase)
|
|
class DueDiligenceCaseAdmin(admin.ModelAdmin):
|
|
list_display = ["batch", "status", "risk_level", "approved_at", "updated_at"]
|
|
list_filter = ["status", "risk_level"]
|
|
|
|
|
|
@admin.register(EUDREvidence)
|
|
class EUDREvidenceAdmin(admin.ModelAdmin):
|
|
list_display = ["case", "evidence_type", "source", "collected_at", "verified_at"]
|
|
|
|
|
|
@admin.register(RiskAssessment)
|
|
class RiskAssessmentAdmin(admin.ModelAdmin):
|
|
list_display = ["case", "risk_level", "assessed_by", "assessed_at"]
|
|
|
|
|
|
@admin.register(MitigationAction)
|
|
class MitigationActionAdmin(admin.ModelAdmin):
|
|
list_display = ["case", "action", "status", "owner", "due_date"]
|
|
|
|
|
|
@admin.register(DueDiligenceStatementReference)
|
|
class DueDiligenceStatementReferenceAdmin(admin.ModelAdmin):
|
|
list_display = ["case", "dds_reference", "submission_date", "submitted_by", "reconciliation_status"]
|