ZuloOne
English
Sign in
Menu

Create a command

Updated

A document command is the only user entry into a subtype change. After Save, the card does not let the user pick a subtype. The button checks, then sets the target Subtype; the engine replaces movements (Mix) and runs the posting scripts of the target only.

Note

Without that command the document stays a draft in the UI, however many scripts hang on "Posted". Events (OnBeforePostAsync, …) still run for any transition, including API. The command is what the user presses.

How to#

Three files in Commands/Document/<Name>/:

  1. <Name>.json — the command (kind: "DocumentCommand") and subtypeBindings (the subtype it is available from). An empty bindings array means every subtype — almost never what a guarded transition wants.
  2. <Name>Script.script.json — scriptType: "DocumentCommand", objectMetaId = the command's metaId.
  3. <Name>Script.cs — the platform generates the base DocumentCommandBase<Document>:
public partial class ApproveOrderCommand
{
    public override async Task ExecuteAsync(SalesOrder document, CommandContext context)
    {
        var error = await context.GetService<ISalesOrderService>()
            .ValidateForApproveAsync(document.MetaId);
        if (error != null)
        {
            CreateUserMessage(error);
            return;
        }

        document.Subtype = SalesOrder.Subtypes.Confirmed;
        await DocumentManager.SaveDocumentAsync(document);
    }
}

Check first. Transition only when the check passed. On failure, CreateUserMessage (a resource, not a literal) and return without changing the subtype.

Use <Document>.Subtypes.<Name>, never the string "Posted".

Commands that do not change subtype (fill prices, explode a BOM) are fine. They do not post the document.

A dictionary command is the same trio under Commands/Dictionary/<Name>/, with dictionaryMetaId instead of subtypeBindings. No menu item — the button appears on the dictionary card.

Tip

Apply the script file before the command file. The command points at scriptMetaId; the other order hits FOREIGN KEY … MetaScripts.

Do not copy somebody else's command "next to it". Wrap it with Chain of Command (nextAsync<CommandResult>). A missing next on a wrap is ZOCOC003.

A static "Are you sure?" is requiresConfirmation on the json. A question that depends on data is context.Confirm(…) — Ask from a command. The two-run contract is Asking the user from a command.

What's not there yet#

document.Subtype = … from a service or a test is for system transitions, not a substitute for the button.

Where next#

Was this page helpful?