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

<https://ref.openepcis.io/extensions/eu/ppwr/shapes/>
    a sh:ShapesGraph ;
    dcterms:title "OpenEPCIS PPWR SHACL Shapes"@en ;
    dcterms:description "SHACL validation shapes for the PPWR vocabulary (EU Regulation 2025/40)."@en ;
    dcterms:created "2026-05-01"^^xsd:date ;
    dcterms:modified "2026-06-18"^^xsd:date .

ppwr-sh:PackagingShape
    a sh:NodeShape ;
    sh:targetClass euppwr:Packaging ;
    rdfs:label "PPWR Packaging Shape"@en ;
    sh:property [
        sh:path euppwr:packagingTier ;
        sh:nodeKind sh:IRI ;
        sh:in ( euppwr:Sales euppwr:Grouped euppwr:Transport ) ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:message "euppwr:Packaging must declare exactly one packagingTier (Sales / Grouped / Transport; Article 3)"@en
    ] ;
    sh:property [
        sh:path euppwr:recyclabilityGrade ;
        sh:nodeKind sh:IRI ;
        sh:in ( euppwr:GradeA euppwr:GradeB euppwr:GradeC ) ;
        sh:maxCount 1 ;
        sh:message "euppwr:recyclabilityGrade must be A, B, or C (PPWR Article 4)"@en
    ] ;
    sh:property [
        sh:path euppwr:harmonisedSymbol ;
        sh:datatype xsd:anyURI ;
        sh:message "euppwr:harmonisedSymbol must be a URI referencing the harmonised label per PPWR Article 12 / Annex IX"@en
    ] .

# Event-bound observations introduced with the lifecycle event templates
# (deposit-return, recovery, observation-recyclability). Validate the
# narrow shape of each sensor-report payload so the captures are
# well-formed before the DLR / EPCIS REST ingests them.

ppwr-sh:DepositRefundIssuedShape
    a sh:NodeShape ;
    rdfs:label "Deposit-return refund issued sensor report"@en ;
    sh:targetSubjectsOf euppwr:depositRefundIssued ;
    sh:property [
        sh:path euppwr:depositRefundIssued ;
        sh:datatype xsd:decimal ;
        sh:minInclusive 0.00 ;
        sh:message "euppwr:depositRefundIssued must be a non-negative decimal monetary amount (PPWR Art. 50)"@en
    ] .

ppwr-sh:RecyclabilityGradeObservationShape
    a sh:NodeShape ;
    rdfs:label "Recyclability-grade declaration shape"@en ;
    sh:targetSubjectsOf euppwr:recyclabilityGrade ;
    sh:property [
        sh:path euppwr:recyclabilityScore ;
        sh:datatype xsd:decimal ;
        sh:minInclusive 0 ;
        sh:maxInclusive 100 ;
        sh:message "euppwr:recyclabilityScore is a percentage in [0, 100] aligned with the grade boundaries in Annex II"@en
    ] ;
    sh:property [
        sh:path euppwr:designForRecyclingMethodology ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:message "Cite exactly one D4R methodology (RecyClass, CEFLEX, APR, …)"@en
    ] .
