Skip to main content

Scenario: Drive a workflow approval from outside

Goal. Let an external system run a Finance and Operations approval workflow end to end: submit a purchase requisition to its approval workflow, find out who must act on it, approve, reject or delegate as that person, recall the workflow when the request is withdrawn, and read the workflow's state at any point, without anyone opening the Finance and Operations client.

When to use. An approval portal, a mobile approval app or a procurement system that owns the user experience while Finance and Operations owns the document and its workflow. Submission is supported for purchase requisitions (workflow type PurchReqReview); an expense report is submitted when it is created (createExpenseReport with SubmitToWorkflow, see Expense reports), which returns the correlation id the steps below take. The work-item actions, recall and the status query key on the workflow's correlation id or the work item's record id, so they work the same way on a workflow that someone submitted in the client. To send many actions in one call use the ...Batch variants (Batch and async operations).

Prerequisites​

  1. Security. MGCLatticeWorkflowServiceMaintain grants submitToWorkflow, approveWorkItem, rejectWorkItem, delegateWorkItem, recallWorkflow and their batch variants; it is in MGCLatticeIntegrationServiceOperationsDuty (operator and administrator roles). getWorkflowStatus is granted by MGCLatticeWorkflowServiceView in MGCLatticeIntegrationServiceQueryDuty (all three Lattice roles). See Security model.
  2. The calling user is the preparer. The Finance and Operations user your app registration maps to must be linked to a worker, and that worker must be the requisition's preparer. In USMF the Admin user is worker 000020.
  3. Recall rights. Only the workflow's originator (the user who submitted it) can recall it, or a user who holds the workflow history's Cancel (WorkflowStatusCancel).
  4. An active workflow configuration of type PurchReqReview that applies to the requisition (Procurement and sourcing > Setup > Procurement and sourcing workflows). USMF ships one whose approval step is assigned to two users.
  5. The Workflow message processing batch job is running. Finance and Operations creates work items asynchronously, in that batch job. In System administration > Inquiries > Batch jobs the job Workflow message processing must be Waiting or Executing.
  6. External completion is allowed. Approve and reject complete the work item through the platform's external work-item completion, which honors the workflow parameter Prevent external work item completion. Leave it off for the workflows you drive from outside.
  7. A draft requisition with lines whose items pass the buying legal entity's procurement policy. In USMF, item C0002 from the Office Supplies USMF catalog passes; D0001 does not.
  8. License. Every action is a write and can be refused with LicenseNotValid; getWorkflowStatus never is.

Steps​

  1. Create the requisition in the client (Procurement and sourcing > Purchase requisitions > All purchase requisitions) or through the standard entities PurchaseRequisitionHeaders and PurchaseRequisitionLines (standard Finance and Operations security, not a Lattice role):

    { "RequisitionName": "Office keyboards", "RequisitionPurpose": "Consumption", "PreparerPersonnelNumber": "000020" }
    { "RequisitionNumber": "000981", "RequisitionLineNumber": 1, "ItemNumber": "C0002", "RequestedPurchaseQuantity": 10,
    "PurchasePrice": 50, "BuyingLegalEntityId": "USMF", "ReceivingSiteId": "1", "ReceivingWarehouseId": "11" }

    The header's response carries the RequisitionNumber you use below.

  2. Submit it. submitToWorkflow on MGCLatticeWorkflowActionService, service group MGCLatticeWorkflowServiceGroup:

    POST https://<your-environment>/api/services/MGCLatticeWorkflowServiceGroup/MGCLatticeWorkflowActionService/submitToWorkflow

    {
    "_request": {
    "RequestId": "6f1e2d3c-4b5a-4968-8776-a5b4c3d2e1f0",
    "LegalEntityId": "USMF",
    "WorkflowTypeName": "PurchReqReview",
    "TableName": "PurchReqTable",
    "DocumentNumber": "000981",
    "Comment": "Submitted from the procurement portal"
    }
    }

    On success DocumentId is the workflow's correlation id, a lower-case GUID without braces (for example be1322c8-5c4f-4a0e-9d0b-7f3e2a1c6d84). Keep it: every later step takes it. The requisition is In review at once. submitPurchaseRequisition on MGCLatticePurchaseRequisitionService (PurchReqId) runs the same checks and submit; it returns the requisition number in DocumentId, and getWorkflowStatus by that number gives you the correlation id.

  3. Wait for the work items and read the assignees. The work items do not exist yet when the submit returns. Poll getWorkflowStatus (same service) with the correlation id, the requisition number or the record id in DocumentId:

    { "_request": { "RequestId": "0a9b8c7d-6e5f-4a3b-9c2d-1e0f9a8b7c6d", "LegalEntityId": "USMF",
    "DocumentId": "be1322c8-5c4f-4a0e-9d0b-7f3e2a1c6d84" } }

    DocumentStatus is the workflow's tracking status (Pending while it runs). StatusDetails carries one PendingWorkItem_<RecId> entry per pending work item, whose value is its assignee, and WorkflowCorrelationId:

    {
    "Success": true,
    "DocumentType": "WorkflowTracking",
    "DocumentStatus": "Pending",
    "StatusDetails": [
    { "Name": "TrackingStatus", "Value": "Pending" },
    { "Name": "WorkflowType", "Value": "PurchReqReview" },
    { "Name": "WorkflowCorrelationId", "Value": "be1322c8-5c4f-4a0e-9d0b-7f3e2a1c6d84" },
    { "Name": "PendingWorkItem_5637145326", "Value": "Inga" },
    { "Name": "PendingWorkItem_5637145327", "Value": "Sara" }
    ]
    }

    The response also carries ContextTableId, ContextRecId and User entries, left out here.

    The work items usually appear within a minute or two, and on a busy environment it can take several minutes. Poll with a back-off (for example every 10 to 30 seconds) for up to about 10 minutes before you investigate. You can also read the standard WorkflowWorkItems entity: filter on RootCorrelationId eq <correlation id> and keep the rows with Status Pending and Type WorkItem, Escalated or FinalApprover; UserId is the assignee.

  4. Act as the assignee. approveWorkItem, rejectWorkItem and delegateWorkItem take the same request. ActingUserId is required and must be the work item's assignee; the action runs as that user, so the workflow history records the assignee. UserContext is informational only.

    {
    "_request": {
    "RequestId": "2c4e6a8b-1d3f-4b5a-8c7e-9f0a1b2c3d4e",
    "LegalEntityId": "USMF",
    "WorkflowCorrelationId": "be1322c8-5c4f-4a0e-9d0b-7f3e2a1c6d84",
    "ActingUserId": "Inga",
    "Comment": "Approved in the procurement portal"
    }
    }

    Instead of WorkflowCorrelationId you can send WorkItemRecId (the number in PendingWorkItem_<RecId>). For delegateWorkItem add DelegateToUserId: an enabled user other than the acting user, who holds no pending work item on the same step. Each action returns the work item's record id in DocumentId. A reject sends the document back to the workflow's originator.

  5. Follow the workflow to its end. Completing a work item is also processed asynchronously. Keep polling getWorkflowStatus: a further approval step shows new PendingWorkItem_<RecId> entries (act on them as in step 4); a finished workflow shows DocumentStatus Completed. Depending on the step's completion policy, one approval may be enough or every assignee may have to approve.

  6. Recall the workflow when the requester withdraws it. recallWorkflow:

    { "_request": { "RequestId": "7d8e9f0a-1b2c-4d3e-8f4a-5b6c7d8e9f0a", "LegalEntityId": "USMF",
    "WorkflowCorrelationId": "be1322c8-5c4f-4a0e-9d0b-7f3e2a1c6d84",
    "Comment": "Requester withdrew the request" } }

    The platform cancels the instance asynchronously; the requisition returns to Draft when the cancellation is processed.

How to verify​

  • Submit: Success true and a GUID in DocumentId; PurchaseRequisitionHeaders shows RequisitionStatus InReview for the requisition.
  • Approve: getWorkflowStatus reaches DocumentStatus Completed, and the requisition is Approved, or Closed when the purchasing policy creates the purchase order automatically on approval. An approved requisition is converted with convertPurchaseRequisitionToOrder (the created order is in PostedDocumentId).
  • Reject: the requisition leaves In review (Rejected or Draft, as the workflow configuration decides), or the originator gets a pending work item of type Return.
  • Delegate: a pending work item of the workflow is assigned to DelegateToUserId.
  • Recall: DocumentStatus Cancelled, and the requisition is Draft again.
  • In the client: the requisition's workflow history shows each action with the assignee's name and your comment. The Workflow lifecycle action and Purchase requisition approved business events report the same moments to subscribers (React to business events).

When it goes wrong​

OperationErrorCodeMeaning and what to do
submitValidationFailedA required member is missing, or the table is not PurchReqTable ("Submitting ... to workflow is not supported.").
submitDocumentNotFoundNo requisition with that number in LegalEntityId.
submitInvalidStatusThe requisition is not a draft, or a workflow is already in progress for it.
submitBusinessRuleNo lines; the caller is not the preparer ("can only be submitted by its preparer (worker ...)"); or the requisition fails the submission rules (the reasons are in Errors).
submitConfigurationMissingNo active PurchReqReview configuration applies to the requisition.
actionValidationFailedActingUserId or DelegateToUserId missing, unknown or disabled; neither WorkflowCorrelationId nor WorkItemRecId sent; delegation to the acting user.
actionInvalidStatus, IsRetryable true"Workflow ... has no work items yet." The workflow is still waiting for its work items. Wait and retry; a failed call releases its RequestId, so you can resend it unchanged.
actionBusinessRule"The pending work items of workflow ... are assigned to Inga, Sara, not to ..." Act as one of the users named. Also returned when the platform refuses the completion (the document's checks, or Prevent external work item completion); Errors carries the platform's text.
actionInvalidStatusThe workflow is no longer pending (completed or canceled).
action, recallDocumentNotFoundUnknown correlation id or work item record id.
recallAccessDeniedThe caller is neither the originator nor allowed to cancel workflows from the workflow history.
anyPreviewUnsupportedNone of these operations has a preview; send them without PreviewMode.
  • No work item ever appears. Call getWorkflowStatus: a Faulted instance creates no work items and its FaultMessage entry carries the fault text the workflow history shows (for example an assignment that could not be resolved). Fix the cause and resume or cancel the instance from the workflow history. If the instance is still Pending with no work items, the Workflow message processing job is not running: set it back to Waiting (System administration > Inquiries > Batch jobs > Change status).
  • Retries are safe. Each call is idempotent on its RequestId: a repeated successful action returns the recorded result and does not act twice. Use a new RequestId for each new action; reusing the submit's RequestId on an approve is refused as DuplicateRequest.
  • Stalled approvals. Activate the Workflow stalled or failed business event. It is raised for faulted instances and work items pending more than 24 hours by the Lattice workflow stalled or failed alerts background process (hourly; System administration > Setup > Process automations, Background processes); nothing to schedule.

Reference​