Oihana PHP System

documents

Table of Contents

Functions

hydrateAdjustment()  : mixed
Hydrate an array definition with the Adjustment class.
hydrateBusinessDocument()  : mixed
Hydrate an array definition with the BusinessDocument class, or one of its subclasses ({@see \xyz\oihana\schema\business\documents\Quote}, {@see \xyz\oihana\schema\business\documents\PurchaseOrder}, {@see Invoice}, {@see \xyz\oihana\schema\business\documents\CreditNote}, {@see \xyz\oihana\schema\business\documents\DebitNote}, {@see \xyz\oihana\schema\business\documents\DeliveryNote}, {@see \xyz\oihana\schema\business\documents\GoodsReceiptConfirmation}, {@see \xyz\oihana\schema\business\documents\Receipt}, {@see \xyz\oihana\schema\business\documents\RemittanceAdvice}, {@see \xyz\oihana\schema\business\documents\Statement}).
hydrateDocumentLine()  : mixed
Hydrate an array definition with the BusinessDocumentLine class.
hydrateDocumentLineItem()  : mixed
Hydrate an array definition with the product or service class of a document line item.
hydrateDocumentTotals()  : mixed
Hydrate an array definition with the DocumentTotals class.

Functions

hydrateAdjustment()

Hydrate an array definition with the Adjustment class.

hydrateAdjustment([mixed $init = null ]) : mixed

Handles both a single adjustment array and an array of them — the second is the usual shape, since a document commonly carries a carriage charge beside an environmental fee.

The adjustment is built through Reflection::hydrate() rather than the Adjustment constructor : only that path honors the #[HydrateAs] / #[HydrateWith] attributes declared on the class, so amount and taxes come out typed. The resolution goes one level deeper on its own — each TaxDetail declares its own basisAmount and taxAmount, and reflection recurses — so the whole « what it costs / what it owes » pair is typed by this single call.

🔑 An empty list is kept as an empty list, where the rest of the family answers null. « This document has no adjustment » is an answer, and it is not the answer « nothing here was readable » : a consumer mapping over the value deserves the empty list it can map over. A non-empty list that hydrates to nothing keeps the family's null — there, nothing usable was found, which is a different statement.

🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.

Parameters
$init : mixed = null

Single adjustment data or array of adjustment data.

Tags
throws
HydrationException
ReflectionException
example
$adjustments = hydrateAdjustment
([
    [
        'type'   => PriceComponentType::SHIPPING_FEE ,
        'amount' => [ 'value' => 52 , 'currency' => 'EUR' ] ,
        'taxes'  => [ [ 'rate' => 20 , 'taxAmount' => [ 'value' => 10.4 , 'currency' => 'EUR' ] ] ] ,
    ] ,
]) ;

$adjustments[ 0 ]->amount instanceof MonetaryAmount            ; // true
$adjustments[ 0 ]->taxes[ 0 ]->taxAmount instanceof MonetaryAmount ; // true

hydrateBusinessDocument()

Hydrate an array definition with the BusinessDocument class, or one of its subclasses ({@see \xyz\oihana\schema\business\documents\Quote}, {@see \xyz\oihana\schema\business\documents\PurchaseOrder}, {@see Invoice}, {@see \xyz\oihana\schema\business\documents\CreditNote}, {@see \xyz\oihana\schema\business\documents\DebitNote}, {@see \xyz\oihana\schema\business\documents\DeliveryNote}, {@see \xyz\oihana\schema\business\documents\GoodsReceiptConfirmation}, {@see \xyz\oihana\schema\business\documents\Receipt}, {@see \xyz\oihana\schema\business\documents\RemittanceAdvice}, {@see \xyz\oihana\schema\business\documents\Statement}).

hydrateBusinessDocument([mixed $init = null ][, string $class = BusinessDocument::class ]) : mixed

Handles both a single document array and an array of documents. The document itself is built through Reflection::hydrate(), which honors every #[HydrateAs]/#[HydrateWith] attribute declared across the hierarchy (adjustments, taxes, totals, documentLines...).

customer, seller and author are the exception, on every document class : their Organization|Person union cannot be resolved from the property type alone — reflection always picks Organization, even for a Person payload — so they are re-resolved from the raw payload through hydrateOrganizationOrPerson(). On an Invoice, broker and provider carry the same union and get the same treatment.

The document's ParcelDelivery carries the same union one level down, on its own provider — the carrier. Reflection builds the delivery through #[HydrateAs], so nothing inside it was ever re-resolved : orderDelivery.provider is therefore given the same treatment from the raw payload, once the delivery itself has been hydrated.

Each of those re-resolutions happens only when the raw payload holds an array under the property — when there is something to hydrate. The resolved value is then written as is, null included : an array that resolves to nothing (an empty list, a list of unhydratable entries) becomes null, never a leftover raw array. Anything else is left to whatever Reflection::hydrate() made of it.

🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.

Parameters
$init : mixed = null

Single document data or array of document data.

$class : string = BusinessDocument::class

The BusinessDocument subclass to hydrate into. Defaults to BusinessDocument itself.

Tags
throws
HydrationException
ReflectionException
example
hydrateBusinessDocument( $raw ) ;                          // BusinessDocument
hydrateBusinessDocument( $raw , Invoice::class ) ;          // Invoice — also resolves broker/provider
hydrateBusinessDocument( $raw , Quote::class ) ;            // Quote

hydrateDocumentLine()

Hydrate an array definition with the BusinessDocumentLine class.

hydrateDocumentLine([mixed $init = null ]) : mixed

Handles both a single line array and an array of lines — the two shapes a BusinessDocument documentLines payload can take.

The line is built through Reflection::hydrate() rather than the BusinessDocumentLine constructor : only that path honors the #[HydrateAs] / #[HydrateWith] attributes declared on the class, so adjustments, price (and its priceComponent breakdown), quantity, subtotal, taxes and total come out typed instead of staying raw arrays.

The item property is the exception : its Product|Service union cannot be resolved from the property type alone, so it is delegated to hydrateDocumentLineItem() which reads the payload's @type. That delegation happens only when the raw payload holds an array under item — when there is something to hydrate — and its answer is then written as is, null included : an array that resolves to nothing becomes null, never a leftover raw array. Anything else is left to whatever Reflection::hydrate() made of it.

🔑 An empty list is kept as an empty list, where the rest of the family answers null. « This document has no line » is an answer, and it is not the answer « nothing here was readable » : a consumer mapping over the value deserves the empty list it can map over, and a document born empty is the ordinary state of a draft rather than an anomaly. A non-empty list that hydrates to nothing keeps the family's null — there, nothing usable was found, which is a different statement.

🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.

Parameters
$init : mixed = null

Single line data or array of line data.

Tags
throws
HydrationException
ReflectionException

hydrateDocumentLineItem()

Hydrate an array definition with the product or service class of a document line item.

hydrateDocumentLineItem([mixed $init = null ]) : mixed

The item of a BusinessDocumentLine is typed as a Product|Service union, which no property type can resolve on its own : the target class is therefore read from the payload's JSON-LD @type.

  • a @type ending with Service (e.g. Service, FoodService) gives a Service ;
  • anything else gives a Product — the commerce-enriched product of this package, which is a org\schema\Product and so satisfies the line's declared type.

🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.

Parameters
$init : mixed = null

Single item data or array of item data.

Tags
throws
HydrationException
ReflectionException

hydrateDocumentTotals()

Hydrate an array definition with the DocumentTotals class.

hydrateDocumentTotals([mixed $init = null ]) : mixed

The totals are built through Reflection::hydrate() rather than the DocumentTotals constructor : only that path honors the #[HydrateAs] attributes declared on the class, so allowanceTotal, balanceDue, chargeTotal, prepaidAmount, subtotal, total and totalTax come out as MonetaryAmount instances instead of staying raw arrays. The constructor assigns flat, and a flat assignment is exactly what leaves an amount as [ 'value' => 62.4 , 'currency' => 'EUR' ].

Handles both a single totals array and an array of them — the second shape has no consumer today, and is accepted all the same so the helper answers like every other one of the family rather than being the one that throws a list back at the caller.

An empty array yields null : a document that carries no totals says so with an absent value, not with an object of empty amounts.

🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.

Parameters
$init : mixed = null

Single totals data or array of totals data.

Tags
throws
HydrationException
ReflectionException
example
$totals = hydrateDocumentTotals
([
    'subtotal' => [ 'value' => 100.0 , 'currency' => 'EUR' ] ,
    'total'    => [ 'value' => 120.0 , 'currency' => 'EUR' ] ,
]) ;

$totals->subtotal instanceof MonetaryAmount ; // true
On this page

Search results