@prefix : <https://ontology.inferal.com/modules/commerce-transaction/> .
@prefix adm: <https://ontology.inferal.com/modules/advertising-measurement/> .
@prefix cmi: <https://ontology.inferal.com/modules/commercial-intelligence/> .
@prefix ex: <https://example.com/commerce-transaction/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix time: <http://www.w3.org/2006/time#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

# Worked instances for the Commerce Transaction module.
#
# Four scenarios:
#   A. An order paid, delivered, and then partly refunded. A single merged
#      status cannot say all three, which is why the axes are separate.
#   B. Two orders agreeing on payment and differing on fulfilment, which is the
#      pairing that shows the axes are genuinely independent rather than two
#      names for one progression.
#   C. Line items carrying what they sold for and what they cost, so margin is
#      computable rather than merely mentioned.
#   D. A first-time buyer beside a returning one.


# --- Instants ----------------------------------------------------------------

ex:t-ordered a time:Instant ;
    time:inXSDDateTimeStamp "2026-06-04T09:12:00Z"^^xsd:dateTimeStamp .
ex:t-ordered-later a time:Instant ;
    time:inXSDDateTimeStamp "2026-06-11T14:03:00Z"^^xsd:dateTimeStamp .
ex:t-abandoned a time:Instant ;
    time:inXSDDateTimeStamp "2026-06-13T21:57:00Z"^^xsd:dateTimeStamp .
ex:t-ordered-latest a time:Instant ;
    time:inXSDDateTimeStamp "2026-06-19T18:44:00Z"^^xsd:dateTimeStamp .
ex:t-refunded a time:Instant ;
    rdfs:comment "Later than the order it reverses, and in this case in a different reporting week, which is why a refund carries its own instant." ;
    time:inXSDDateTimeStamp "2026-06-24T11:20:00Z"^^xsd:dateTimeStamp .


# --- Products ----------------------------------------------------------------

ex:trail-jacket a cmi:Product ;
    rdfs:label "Trail jacket" .

ex:wool-socks a cmi:Product ;
    rdfs:label "Merino socks, three pack" .


# --- Buyers ------------------------------------------------------------------

ex:first-time-buyer a :Buyer ;
    rdfs:label "someone buying for the first time" ;
    :buyerStatus :firstTimeBuyer .

ex:returning-buyer a :Buyer ;
    rdfs:label "someone who has bought before" ;
    :buyerStatus :returningBuyer .


# --- Scenario A: paid, delivered, then partly refunded -----------------------
#
# The order was paid in full, everything reached the buyer, and one of the two
# lines came back a fortnight later. Under one merged status this order is
# refunded or delivered and never both, and the amount that came back cannot be
# stated at all.

ex:order-1 a :Order ;
    :orderIdentifier "NW-10241" ;
    rdfs:label "delivered, then partly refunded" ;
    :placedBy ex:first-time-buyer ;
    :placedAt ex:t-ordered ;
    :orderTotal ex:order-1-total ;
    :paymentState :partlyRefunded ;
    :fulfillmentState :delivered ;
    :orderLifecycle :placedOrder ;
    :orderContains ex:order-1-jacket , ex:order-1-socks .

ex:order-1-total a adm:MonetaryAmount ;
    adm:amountValue "154.00"^^xsd:decimal ; adm:currencyCode "GBP" .

ex:order-1-jacket a :LineItem ;
    rdfs:label "one trail jacket" ;
    :lineItemProduct ex:trail-jacket ;
    :lineItemQuantity "1"^^xsd:decimal ;
    :lineItemRevenue ex:jacket-revenue ;
    :costOfGoods ex:jacket-cost .

ex:jacket-revenue a adm:MonetaryAmount ;
    adm:amountValue "124.00"^^xsd:decimal ; adm:currencyCode "GBP" .
ex:jacket-cost a adm:MonetaryAmount ;
    rdfs:comment "Direct cost of supplying the goods only, excluding advertising, fulfilment, and overhead." ;
    adm:amountValue "61.00"^^xsd:decimal ; adm:currencyCode "GBP" .

ex:order-1-socks a :LineItem ;
    rdfs:label "two three-packs of socks" ;
    :lineItemProduct ex:wool-socks ;
    :lineItemQuantity "2"^^xsd:decimal ;
    :lineItemRevenue ex:socks-revenue ;
    :costOfGoods ex:socks-cost .

ex:socks-revenue a adm:MonetaryAmount ;
    adm:amountValue "30.00"^^xsd:decimal ; adm:currencyCode "GBP" .
ex:socks-cost a adm:MonetaryAmount ;
    adm:amountValue "11.50"^^xsd:decimal ; adm:currencyCode "GBP" .

# Less than the order's total, which is the case a boolean refunded flag cannot
# represent and a merged status reports as though everything came back.
ex:order-1-refund a :Refund ;
    rdfs:label "the jacket came back" ;
    :refundOf ex:order-1 ;
    :refundedAmount ex:refund-amount ;
    :refundedAt ex:t-refunded .

ex:refund-amount a adm:MonetaryAmount ;
    adm:amountValue "124.00"^^xsd:decimal ; adm:currencyCode "GBP" .


# --- Scenario B: the axes vary independently ---------------------------------
#
# These two orders agree on payment and differ on fulfilment. That pairing is
# what shows the axes are independent: two orders that were both paid, one
# delivered and one still waiting to be picked, are not at two points on a
# single progression.

ex:order-2 a :Order ;
    :orderIdentifier "NW-10318" ;
    rdfs:label "paid and delivered" ;
    :placedBy ex:returning-buyer ;
    :placedAt ex:t-ordered-later ;
    :orderTotal ex:order-2-total ;
    :paymentState :paid ;
    :fulfillmentState :delivered ;
    :orderLifecycle :placedOrder ;
    :orderContains ex:order-2-socks .

ex:order-2-total a adm:MonetaryAmount ;
    adm:amountValue "15.00"^^xsd:decimal ; adm:currencyCode "GBP" .

ex:order-2-socks a :LineItem ;
    :lineItemProduct ex:wool-socks ;
    :lineItemQuantity "1"^^xsd:decimal ;
    :lineItemRevenue ex:order-2-revenue ;
    :costOfGoods ex:order-2-cost .

ex:order-2-revenue a adm:MonetaryAmount ;
    adm:amountValue "15.00"^^xsd:decimal ; adm:currencyCode "GBP" .
ex:order-2-cost a adm:MonetaryAmount ;
    adm:amountValue "5.75"^^xsd:decimal ; adm:currencyCode "GBP" .

ex:order-3 a :Order ;
    :orderIdentifier "NW-10402" ;
    rdfs:label "paid, nothing sent yet" ;
    rdfs:comment "The commonest state in retail, and the one a merged status has no value for: it is neither pending nor complete." ;
    :placedBy ex:returning-buyer ;
    :placedAt ex:t-ordered-latest ;
    :orderTotal ex:order-3-total ;
    :paymentState :paid ;
    :fulfillmentState :unfulfilled ;
    :orderLifecycle :placedOrder ;
    :orderContains ex:order-3-jacket .

ex:order-3-total a adm:MonetaryAmount ;
    adm:amountValue "124.00"^^xsd:decimal ; adm:currencyCode "GBP" .

ex:order-3-jacket a :LineItem ;
    :lineItemProduct ex:trail-jacket ;
    :lineItemQuantity "1"^^xsd:decimal ;
    :lineItemRevenue ex:order-3-revenue ;
    :costOfGoods ex:order-3-cost .

ex:order-3-revenue a adm:MonetaryAmount ;
    adm:amountValue "124.00"^^xsd:decimal ; adm:currencyCode "GBP" .
ex:order-3-cost a adm:MonetaryAmount ;
    adm:amountValue "61.00"^^xsd:decimal ; adm:currencyCode "GBP" .


# --- An abandoned basket -----------------------------------------------------
#
# Never a sale. Counting it as an unpaid order overstates outstanding revenue,
# which is what happens when drafts share an enumeration with genuine states.

ex:abandoned a :Order ;
    rdfs:label "a basket that was never completed" ;
    :orderIdentifier "WEB-00841" ;
    :placedBy ex:first-time-buyer ;
    :placedAt ex:t-abandoned ;
    :orderTotal ex:abandoned-total ;
    :paymentState :awaitingPayment ;
    :fulfillmentState :unfulfilled ;
    :orderLifecycle :incompleteOrder .

ex:abandoned-total a adm:MonetaryAmount ;
    adm:amountValue "62.00"^^xsd:decimal ; adm:currencyCode "GBP" .
