@prefix country: <https://data.csoares.me/country/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix onto: <https://data.csoares.me/onto#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix schema: <https://schema.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<https://data.csoares.me/onto> a owl:Ontology ;
    rdfs:label "Ontology of the catalogue and the orders"@en ;
    dcterms:creator "WSW3" ;
    rdfs:comment "The unit's own demonstration vocabulary: products, manufacturers, customers, orders and supplies. It reuses schema.org, SKOS and Dublin Core."@en ;
    owl:imports <http://www.w3.org/2004/02/skos/core> ;
    owl:versionInfo "2026-27, class 08" .

onto:Batch a owl:Class ;
    rdfs:label "Batch"@en ;
    rdfs:comment "A set of products handled as a single unit."@en ;
    rdfs:subClassOf onto:Grouping .

onto:Component a owl:Class ;
    rdfs:label "Component"@en ;
    rdfs:comment "A piece that is part of a product or of another component."@en .

onto:Container a owl:Class ;
    rdfs:label "Container"@en ;
    rdfs:comment "A shipping unit that contains batches."@en ;
    rdfs:subClassOf onto:Grouping .

onto:DigitalProduct a owl:Class ;
    rdfs:label "Digital product"@en ;
    rdfs:comment "A product delivered by transfer, with no physical existence."@en ;
    rdfs:subClassOf onto:Product ;
    owl:disjointWith onto:PhysicalProduct .

onto:DiscontinuedProduct a owl:Class ;
    rdfs:label "Discontinued product"@en ;
    rdfs:comment "A product that is no longer sold and that may have a replacement."@en ;
    rdfs:subClassOf onto:Product .

onto:LargeOrder a owl:Class ;
    rdfs:label "Large order"@en ;
    rdfs:comment "An order whose total value is 500 euros or more (50000 cents). A class defined by a restriction on a datatype."@en ;
    owl:equivalentClass [ a owl:Restriction ;
            owl:onProperty onto:totalCents ;
            owl:someValuesFrom [ a rdfs:Datatype ;
                    owl:onDatatype xsd:integer ;
                    owl:withRestrictions ( [ xsd:minInclusive 50000 ] ) ] ] .

onto:PortugueseProduct a owl:Class ;
    rdfs:label "Portuguese product"@en ;
    rdfs:comment "A product made by a Portuguese manufacturer. It answers competency question Q1."@en ;
    owl:equivalentClass [ a owl:Restriction ;
            owl:onProperty onto:manufacturedBy ;
            owl:someValuesFrom onto:PortugueseManufacturer ] .

onto:Service a owl:Class ;
    rdfs:label "Service"@en ;
    rdfs:comment "A contracted service; it is neither manufactured nor stored."@en ;
    owl:disjointWith onto:Product .

onto:block a owl:DatatypeProperty ;
    rdfs:label "block"@en ;
    rdfs:comment "The number of the block the event was included in."@en ;
    rdfs:domain onto:OnChainRecord ;
    rdfs:range xsd:integer .

onto:confidence a owl:DatatypeProperty ;
    rdfs:label "confidence"@en ;
    rdfs:comment "How sure the identity decision is, from 0 to 1."@en ;
    rdfs:range xsd:decimal .

onto:containsProduct a owl:ObjectProperty ;
    rdfs:label "contains product"@en ;
    rdfs:comment "The product ordered."@en ;
    rdfs:domain onto:Order ;
    rdfs:range onto:Product .

onto:date a owl:DatatypeProperty ;
    rdfs:label "date"@en ;
    rdfs:comment "The date of the fact: of the order or of the supply."@en ;
    rdfs:range xsd:date .

onto:district a owl:DatatypeProperty ;
    rdfs:label "district"@en ;
    rdfs:comment "The district where a manufacturer is based, as the suppliers' CSV gives it."@en ;
    rdfs:domain onto:Manufacturer ;
    rdfs:range xsd:string .

onto:document a owl:ObjectProperty ;
    rdfs:label "document"@en ;
    rdfs:comment "The certificate an on-chain record is about."@en ;
    rdfs:domain onto:OnChainRecord ;
    rdfs:range onto:Certificate .

onto:documentDigest a owl:DatatypeProperty ;
    rdfs:label "document digest"@en ;
    rdfs:comment "The digest of the document that was anchored on the chain."@en ;
    rdfs:domain onto:OnChainRecord ;
    rdfs:range xsd:string .

onto:hasCertificate a owl:ObjectProperty ;
    rdfs:label "has certificate"@en ;
    rdfs:comment "A certificate the manufacturer holds."@en ;
    rdfs:domain onto:Manufacturer ;
    rdfs:range onto:Certificate .

onto:manufactures a owl:ObjectProperty ;
    rdfs:label "manufactures"@en ;
    rdfs:comment "The same relation seen from the manufacturer's side. It is never asserted in the data: it is inferred."@en ;
    rdfs:domain onto:Manufacturer ;
    rdfs:range onto:Product ;
    owl:inverseOf onto:manufacturedBy .

onto:method a owl:DatatypeProperty ;
    rdfs:label "method"@en ;
    rdfs:comment "How the identity decision was reached, for example comparison of the tax number."@en ;
    rdfs:range xsd:string .

onto:object a owl:ObjectProperty ;
    rdfs:label "object of the decision"@en ;
    rdfs:comment "The second of the two resources an identity decision is about."@en .

onto:partOf a owl:ObjectProperty,
        owl:TransitiveProperty ;
    rdfs:label "part of"@en ;
    rdfs:comment "The inverse of has part. Transitive: what is in a batch that is in a container is in the container."@en ;
    owl:inverseOf onto:hasPart .

onto:predicate a owl:ObjectProperty ;
    rdfs:label "predicate of the decision"@en ;
    rdfs:comment "The link asserted between the two resources: owl:sameAs or skos:closeMatch."@en .

onto:price a owl:DatatypeProperty ;
    rdfs:label "list price"@en ;
    rdfs:comment "The list price in the relational catalogue, one per product. Not to be confused with schema:price, which lives in an offer (schema:offers): a product can have several offers, but has one list price."@en ;
    rdfs:domain onto:Product ;
    rdfs:range xsd:decimal .

onto:product a owl:ObjectProperty ;
    rdfs:label "product"@en ;
    rdfs:comment "What was supplied, in the supply fact."@en ;
    rdfs:domain onto:Supply ;
    rdfs:range onto:Product .

onto:quantity a owl:DatatypeProperty ;
    rdfs:label "quantity"@en ;
    rdfs:comment "The number of units supplied."@en ;
    rdfs:domain onto:Supply ;
    rdfs:range xsd:integer .

onto:replaces a owl:ObjectProperty ;
    rdfs:label "replaces"@en ;
    rdfs:comment "The subject is the product sold in place of the object. It is deliberately not transitive: three generations of replacement do not make the first model a replacement for the last."@en ;
    rdfs:domain onto:Product ;
    rdfs:range onto:Product .

onto:revocationReason a owl:DatatypeProperty ;
    rdfs:label "revocation reason"@en ;
    rdfs:comment "Why the document was revoked, as the contract event states it."@en ;
    rdfs:domain onto:OnChainRecord ;
    rdfs:range xsd:string .

onto:revoked a owl:DatatypeProperty ;
    rdfs:label "revoked"@en ;
    rdfs:comment "Whether the anchored document was revoked on the chain."@en ;
    rdfs:domain onto:OnChainRecord ;
    rdfs:range xsd:boolean .

onto:subject a owl:ObjectProperty ;
    rdfs:label "subject of the decision"@en ;
    rdfs:comment "The first of the two resources an identity decision is about."@en .

onto:taxId a owl:DatatypeProperty ;
    rdfs:label "tax identification number"@en ;
    rdfs:comment "The manufacturer's tax number. It is the stable key the suppliers' CSV builds the manufacturer URI from."@en ;
    rdfs:domain onto:Manufacturer ;
    rdfs:range xsd:string .

onto:transaction a owl:DatatypeProperty ;
    rdfs:label "transaction"@en ;
    rdfs:comment "The hash of the transaction that emitted the event."@en ;
    rdfs:domain onto:OnChainRecord ;
    rdfs:range xsd:string .

onto:unitPriceCents a owl:DatatypeProperty ;
    rdfs:label "unit price in cents"@en ;
    rdfs:comment "The price per unit in the supply, in cents."@en ;
    rdfs:domain onto:Supply ;
    rdfs:range xsd:integer .

onto:validUntil a owl:DatatypeProperty ;
    rdfs:label "valid until"@en ;
    rdfs:comment "The last day the certificate is valid."@en ;
    rdfs:domain onto:Certificate ;
    rdfs:range xsd:date .

onto:version a owl:DatatypeProperty ;
    rdfs:label "version"@en ;
    rdfs:comment "The version of the source record an ingestion run applied (example 09): an older event never overwrites a newer one."@en ;
    rdfs:range xsd:integer .

onto:Country a owl:Class ;
    rdfs:label "Country"@en ;
    rdfs:comment "A country, identified by its own URI so that it can be linked to outside sources."@en .

onto:Customer a owl:Class ;
    rdfs:label "Customer"@en ;
    rdfs:comment "An organisation that places orders."@en ;
    rdfs:subClassOf schema:Organization .

onto:PhysicalProduct a owl:Class ;
    rdfs:label "Physical product"@en ;
    rdfs:comment "A product with a physical existence, which is shipped and stored."@en ;
    rdfs:subClassOf onto:Product .

onto:PortugueseManufacturer a owl:Class ;
    rdfs:label "Portuguese manufacturer"@en ;
    rdfs:comment "A manufacturer whose country is Portugal. A defined class: membership is inferred, never asserted."@en ;
    owl:equivalentClass [ a owl:Restriction ;
            owl:hasValue country:PT ;
            owl:onProperty onto:country ] .

onto:country a owl:ObjectProperty ;
    rdfs:label "country"@en ;
    rdfs:comment "The country of an organisation. The value is an entity, not text."@en ;
    rdfs:range onto:Country .

onto:hasPart a owl:ObjectProperty,
        owl:TransitiveProperty ;
    rdfs:label "has part"@en ;
    rdfs:comment "Composition: the object is part of the subject. Transitive."@en .

onto:totalCents a owl:DatatypeProperty ;
    rdfs:label "total in cents"@en ;
    rdfs:comment "The total value of the order, in cents, to avoid floating point."@en ;
    rdfs:domain onto:Order ;
    rdfs:range xsd:integer .

onto:Grouping a owl:Class ;
    rdfs:label "Grouping"@en ;
    rdfs:comment "A unit of physical aggregation: batch, pallet, container."@en .

onto:hasCustomer a owl:ObjectProperty ;
    rdfs:label "has customer"@en ;
    rdfs:comment "The customer who placed the order. Exactly one per order."@en ;
    rdfs:domain onto:Order ;
    rdfs:range onto:Customer .

onto:supplier a owl:ObjectProperty ;
    rdfs:label "supplier"@en ;
    rdfs:comment "Who supplied it, in the supply fact."@en ;
    rdfs:domain onto:Supply ;
    rdfs:range onto:Manufacturer .

onto:Certificate a owl:Class ;
    rdfs:label "Certificate"@en ;
    rdfs:comment "A certificate a manufacturer holds, whose digest is anchored on the chain."@en .

onto:Order a owl:Class ;
    rdfs:label "Order"@en ;
    rdfs:comment "A request from a customer, with a date and one or more products."@en ;
    rdfs:subClassOf [ a owl:Restriction ;
            owl:minCardinality "1"^^xsd:nonNegativeInteger ;
            owl:onProperty onto:hasCustomer ],
        [ a owl:Restriction ;
            owl:maxCardinality "1"^^xsd:nonNegativeInteger ;
            owl:onProperty onto:hasCustomer ] .

onto:manufacturedBy a owl:ObjectProperty ;
    rdfs:label "manufactured by"@en ;
    rdfs:comment "Links a product to the manufacturer that makes it."@en ;
    rdfs:domain onto:Product ;
    rdfs:range onto:Manufacturer ;
    rdfs:subPropertyOf schema:manufacturer .

onto:Supply a owl:Class ;
    rdfs:label "Supply"@en ;
    rdfs:comment "A fact with qualifiers: a supplier delivered a quantity of a product, at a price, on a date. It is the n-ary relation pattern."@en ;
    rdfs:subClassOf [ a owl:Restriction ;
            owl:maxCardinality "1"^^xsd:nonNegativeInteger ;
            owl:onProperty onto:supplier ],
        [ a owl:Restriction ;
            owl:minCardinality "1"^^xsd:nonNegativeInteger ;
            owl:onProperty onto:supplier ] .

onto:OnChainRecord a owl:Class ;
    rdfs:label "On-chain record"@en ;
    rdfs:comment "One event of the contract, as the indexer writes it into the graph."@en .

onto:Manufacturer a owl:Class ;
    rdfs:label "Manufacturer"@en ;
    rdfs:comment "An organisation that manufactures products in the catalogue."@en ;
    rdfs:subClassOf schema:Organization .

onto:Product a owl:Class ;
    rdfs:label "Product"@en ;
    rdfs:comment "A good put up for sale in the catalogue."@en ;
    rdfs:subClassOf [ a owl:Restriction ;
            owl:onProperty onto:manufacturedBy ;
            owl:someValuesFrom onto:Manufacturer ],
        schema:Product .

