@prefix : <https://ontology.inferal.com/modules/commerce-transaction/> .
@prefix adm: <https://ontology.inferal.com/modules/advertising-measurement/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix mod: <https://w3id.org/mod#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix pubacc: <https://ontology.inferal.com/modules/publication-access/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix vann: <http://purl.org/vocab/vann/> .

<https://ontology.inferal.com/modules/commerce-transaction/owl>
    a owl:Ontology, pubacc:PublicationManagedOntology ;
    dcterms:accessRights pubacc:PublicAccess ;
    owl:imports : , adm:owl ;
    dcterms:title "Commerce Transaction Ontology - OWL Addendum" ;
    dcterms:description "OWL class, property, key, and disjointness axioms layered on the RDFS Commerce Transaction Ontology." ;
    dcterms:license <https://creativecommons.org/licenses/by/4.0/> ;
    dcterms:source : ;
    vann:preferredNamespacePrefix "ctx" ;
    vann:preferredNamespaceUri "https://ontology.inferal.com/modules/commerce-transaction/" ;
    mod:status "draft" ;
    rdfs:comment "States what makes two records the same transaction, and keeps the three state axes apart from one another so a reasoner cannot treat a payment outcome as a delivery outcome." ;
    owl:versionInfo "0.1.0" .


# --- Classes -----------------------------------------------------------------

:Order a owl:Class .
:LineItem a owl:Class .
:Buyer a owl:Class .
:Refund a owl:Class .
:PaymentState a owl:Class .
:FulfillmentState a owl:Class .
:OrderLifecycleState a owl:Class .
:BuyerStatus a owl:Class .


# --- Object properties -------------------------------------------------------

:orderTotal a owl:ObjectProperty , owl:FunctionalProperty .
:placedBy a owl:ObjectProperty , owl:FunctionalProperty .
:paymentState a owl:ObjectProperty , owl:FunctionalProperty .
:fulfillmentState a owl:ObjectProperty , owl:FunctionalProperty .
:orderLifecycle a owl:ObjectProperty , owl:FunctionalProperty .
:placedAt a owl:ObjectProperty , owl:FunctionalProperty .
:lineItemProduct a owl:ObjectProperty , owl:FunctionalProperty .
:lineItemRevenue a owl:ObjectProperty , owl:FunctionalProperty .
:costOfGoods a owl:ObjectProperty , owl:FunctionalProperty .
:refundedAmount a owl:ObjectProperty , owl:FunctionalProperty .
:refundOf a owl:ObjectProperty , owl:FunctionalProperty .
:refundedAt a owl:ObjectProperty , owl:FunctionalProperty .
:buyerStatus a owl:ObjectProperty , owl:FunctionalProperty .

# Deliberately not functional: an order of several products is several lines.
:orderContains a owl:ObjectProperty .


# --- Datatype properties -----------------------------------------------------

:lineItemQuantity a owl:DatatypeProperty , owl:FunctionalProperty .
:orderIdentifier a owl:DatatypeProperty , owl:FunctionalProperty .


# --- Identity ----------------------------------------------------------------

# An order is identified by the merchant's own number for it and the instant it
# was placed. Both are required by the shapes, which is what makes the key safe:
# a key naming a property an individual may lack stops applying exactly where
# two individuals are least distinguishable.
#
# Buyer and instant were tried first and are not identity: one person can place
# two orders in the same second from two tabs, and those are two orders.
#
# The total is excluded deliberately. Two records of one order number at one
# instant differing in total are a restatement conflict to surface, not two
# orders.
:Order
    owl:hasKey ( :orderIdentifier :placedAt ) .

# A refund is identified by what it reverses and when. Two partial refunds
# against one order at different instants are different refunds; two records of
# the same reversal at the same instant are one.
:Refund
    owl:hasKey ( :refundOf :refundedAt ) .


# --- Incompatibility ---------------------------------------------------------

# The three axes a single order status merges. Declaring them disjoint is what
# stops a reasoner treating a payment outcome as a delivery outcome, which is
# the confusion that lets a query for undelivered orders return unpaid ones.
:PaymentState owl:disjointWith :FulfillmentState , :OrderLifecycleState , :BuyerStatus .
:FulfillmentState owl:disjointWith :OrderLifecycleState , :BuyerStatus .
:OrderLifecycleState owl:disjointWith :BuyerStatus .

# A transaction is not one of its parts, and a reversal is not the thing it
# reverses.
:Order owl:disjointWith :LineItem , :Refund , :Buyer .
:LineItem owl:disjointWith :Refund , :Buyer .
:Refund owl:disjointWith :Buyer .
