Extending it

Handler reference

Two methods you must answer, nine you may. The defaults are chosen so that a handler which only answers the two behaves as a document type that is received and never processed automatically.

Required

MethodWhat it decides
documentFormatWhich wire format this type belongs to. Drives acknowledgement routing and the format-keyed conversions
businessProcessWhere in the order flow it sits, per direction. Returning one of the two acknowledgement processes is what puts the type on the acknowledgement lane instead

On the outbound base there is a third: buildOutboundContract, which produces the report contract the export format runs against.

Optional, with defaults

MethodDefaultWhat it is for
supportsAutoProcessingFalseWhether a staged document of this type may become a record without a person. False is the guard that keeps an unfinished type out of the automatic path
processFromStagingDoes nothingTurns a staged document into a record. Return the order id it produced
compareEngineNoneThe comparison that produces the verdict before processing. Without one there is no compare and the gate is unaffected
resolveOutboundAnchorNoneWhich order the message belongs to. This is what puts it on the flow tracker
shipFromWarehousesNoneWhich warehouse the document ships from, when every line agrees
unhMessageTypeEmptyThe EDIFACT message type string a CONTRL acknowledging this type must echo
ackReferenceQualifierEmptyThe qualifier an APERAK uses when referring to this type. The built-ins use ON, AAK and IV
isAckAcceptanceCodeFalse for every codeOnly asked when this type is itself an acknowledgement. Whether one code off the wire means accepted

The two with rules

resolveOutboundAnchor must not throw

It is called while the posting that produced the document is still open, and a throw there is not caught the way you would expect. Return the empty anchor when you cannot resolve one.

public LunoLakeEDIOutboundAnchor resolveOutboundAnchor(RefRecId _sourceRecId)
{
    VendPackingSlipJour jour;
    select firstonly jour
        where jour.RecId == _sourceRecId;

    if (!jour.RecId)
    {
        return LunoLakeEDIOutboundAnchor::none();
    }

    return LunoLakeEDIOutboundAnchor::newFromValues(
        LunoLakeEDIOrderType::PurchaseOrder,
        jour.PurchId,
        jour.PackingSlipId);
}
No exception, even when the row is gone.

Returning none costs you the tracker card for that message. Throwing costs the posting.

buildOutboundContract may throw, and that is the point

Where the agreement's validation mode is not off, this runs inside the posting, and a throw here refuses the posting with your message in front of the user. Throw when the document genuinely cannot be built, with text that tells them what to fix.

processFromStaging is called more than once

A failure leaves the staged document retryable, and pressing Process again calls this method a second time on the same rows. Write it so that running twice does not produce two orders: check for what a previous run would have created before creating it.

shipFromWarehouses answers three ways

One warehouse when every line agrees. No warehouse when two lines disagree, because a single wrong answer is worse than none. No warehouse when the lines name none at all. The distinction between the last two is recorded on the message, so a partner asking why the field is empty gets a reason.