@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix eudet: <https://ref.openepcis.io/extensions/eu/detergent/> .
@prefix gs1: <https://ref.gs1.org/voc/> .
@prefix schema: <https://schema.org/> .
@prefix oec: <https://ref.openepcis.io/extensions/common/core/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .

<https://ref.openepcis.io/extensions/eu/detergent/shapes/>
    a sh:ShapesGraph ;
    dcterms:title "OpenEPCIS Detergent SHACL Shapes"@en ;
    dcterms:description "SHACL validation shapes for Detergent vocabulary."@en ;
    dcterms:created "2026-03-12"^^xsd:date ;
    dcterms:modified "2026-06-07"^^xsd:date .

# =============================================================================
# OpenEPCIS Detergent Vocabulary SHACL Shapes v0.9.6
# Validation shapes for Detergent Digital Product Passport data
# Aligned with EU Regulation 2026/405 on Detergents and Surfactants
# =============================================================================

# -----------------------------------------------------------------------------
# Detergent Product Shape
# -----------------------------------------------------------------------------
eudet:DetergentProductShape a sh:NodeShape ;
    sh:targetClass eudet:DetergentProduct ;
    rdfs:label "Detergent Product Shape" ;
    rdfs:comment "Validation shape for DetergentProduct instances per EU 2026/405." ;
    sh:property [
        sh:path schema:category ;
        sh:name "Detergent Category" ;
        sh:description "Product category (laundry, dishwasher, etc.)." ;
        sh:maxCount 1 ;
        sh:class eudet:DetergentCategory
    ] ;
    sh:property [
        sh:path eudet:productForm ;
        sh:name "Product Form" ;
        sh:description "Physical form (liquid, powder, capsule, etc.)." ;
        sh:maxCount 1 ;
        sh:class eudet:ProductForm
    ] ;
    sh:property [
        sh:path eudet:intendedUse ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:cnCode ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:ingredientList ;
        sh:name "Ingredient List" ;
        sh:class eudet:Ingredient
    ] ;
    sh:property [
        sh:path eudet:surfactantBiodegradability ;
        sh:name "Surfactant Biodegradability" ;
        sh:class eudet:SurfactantBiodegradability
    ] ;
    sh:property [
        sh:path eudet:fragranceAllergens ;
        sh:name "Fragrance Allergens" ;
        sh:class eudet:FragranceAllergen
    ] ;
    sh:property [
        sh:path eudet:microorganisms ;
        sh:name "Microorganisms" ;
        sh:class eudet:MicroorganismInfo
    ] ;
    sh:property [
        sh:path eudet:hazardousSubstances ;
        sh:name "Hazardous Substances" ;
        sh:class oec:HazardousSubstance
    ] ;
    sh:property [
        sh:path eudet:hazardPictograms ;
        sh:name "Hazard Pictograms" ;
        sh:datatype xsd:string
    ] ;
    sh:property [
        sh:path eudet:hStatements ;
        sh:name "H Statements" ;
        sh:datatype xsd:string
    ] ;
    sh:property [
        sh:path eudet:pStatements ;
        sh:name "P Statements" ;
        sh:datatype xsd:string
    ] ;
    sh:property [
        sh:path eudet:signalWord ;
        sh:name "Signal Word" ;
        sh:maxCount 1 ;
        sh:class eudet:SignalWord
    ] ;
    sh:property [
        sh:path eudet:phosphorusContentPercent ;
        sh:datatype xsd:decimal ;
        sh:maxCount 1 ;
        sh:minInclusive 0
    ] ;
    sh:property [
        sh:path eudet:phosphateCompliant ;
        sh:datatype xsd:boolean ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:filmBiodegradable ;
        sh:datatype xsd:boolean ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:filmBiodegradabilityPercentage ;
        sh:datatype xsd:decimal ;
        sh:maxCount 1 ;
        sh:minInclusive 0 ;
        sh:maxInclusive 100
    ] ;
    sh:property [
        sh:path eudet:recommendedDosage ;
        sh:class gs1:QuantitativeValue ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:dosageInstructions ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:safetyDataSheet ;
        sh:class oec:DocumentReference ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:biodegradabilityTestReport ;
        sh:class oec:DocumentReference ;
        sh:maxCount 1
    ] .

# -----------------------------------------------------------------------------
# Ingredient Shape
# -----------------------------------------------------------------------------
eudet:IngredientShape a sh:NodeShape ;
    sh:targetClass eudet:Ingredient ;
    rdfs:label "Ingredient Shape" ;
    sh:property [
        sh:path schema:name ;
        sh:name "INCI Name" ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:ingredientFunction ;
        sh:name "Ingredient Function" ;
        sh:class eudet:IngredientFunction ;
        sh:minCount 1 ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:weightPercentRange ;
        sh:name "Weight Percent Range" ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:casNumber ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:isSurfactant ;
        sh:datatype xsd:boolean ;
        sh:maxCount 1
    ] .

# -----------------------------------------------------------------------------
# Surfactant Biodegradability Shape
# -----------------------------------------------------------------------------
eudet:SurfactantBiodegradabilityShape a sh:NodeShape ;
    sh:targetClass eudet:SurfactantBiodegradability ;
    rdfs:label "Surfactant Biodegradability Shape" ;
    sh:property [
        sh:path eudet:surfactantType ;
        sh:name "Surfactant Type" ;
        sh:class eudet:SurfactantType ;
        sh:minCount 1 ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:biodegradationPercentage ;
        sh:name "Biodegradation Percentage" ;
        sh:datatype xsd:decimal ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:minInclusive 0 ;
        sh:maxInclusive 100
    ] ;
    sh:property [
        sh:path eudet:testMethod ;
        sh:name "Test Method" ;
        sh:class eudet:BiodegradabilityTestMethod ;
        sh:minCount 1 ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:testDurationDays ;
        sh:datatype xsd:integer ;
        sh:maxCount 1 ;
        sh:minInclusive 1
    ] ;
    sh:property [
        sh:path eudet:passesUltimateBiodegradability ;
        sh:datatype xsd:boolean ;
        sh:maxCount 1
    ] .

# -----------------------------------------------------------------------------
# Fragrance Allergen Shape
# -----------------------------------------------------------------------------
eudet:FragranceAllergenShape a sh:NodeShape ;
    sh:targetClass eudet:FragranceAllergen ;
    rdfs:label "Fragrance Allergen Shape" ;
    sh:property [
        sh:path gs1:allergenSpecificationName ;
        sh:name "Allergen Name" ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:allergenCasNumber ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:allergenConcentration ;
        sh:datatype xsd:decimal ;
        sh:maxCount 1 ;
        sh:minInclusive 0
    ] .

# -----------------------------------------------------------------------------
# Microorganism Info Shape
# -----------------------------------------------------------------------------
eudet:MicroorganismInfoShape a sh:NodeShape ;
    sh:targetClass eudet:MicroorganismInfo ;
    rdfs:label "Microorganism Info Shape" ;
    sh:property [
        sh:path schema:name ;
        sh:name "Species Name" ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:strainDesignation ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path eudet:endProductCharacteristics ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] .
