Frameworks: SysOperation & Workflows
SysOperation for batch processing and workflows for business approvals β the two essential F&O frameworks.
Frameworks: SysOperation & Workflows
SysOperation is a restaurant kitchen. The Controller is the head chef (decides when to cook). The Contract is the order ticket (parameters). The Service is the line cook (does the work). Workflows are approval forms passed desk to desk β requester to manager to finance.
SysOperation β Controller + Contract + Service
Contract
[DataContractAttribute]
public class CustReportContract
{
private CustGroupId custGroup;
private FromDate fromDate;
[DataMemberAttribute, SysOperationLabelAttribute("Customer group")]
public CustGroupId parmCustGroup(CustGroupId _v = custGroup) { custGroup = _v; return custGroup; }
[DataMemberAttribute, SysOperationLabelAttribute("From date")]
public FromDate parmFromDate(FromDate _v = fromDate) { fromDate = _v; return fromDate; }
}
Service
public class CustReportService
{
[SysEntryPointAttribute(true)]
public void generate(CustReportContract _contract)
{
CustTable ct;
while select ct where ct.CustGroup == _contract.parmCustGroup()
{
info(strFmt("Customer: %1", ct.Name));
}
}
}
Controller
public class CustReportController extends SysOperationServiceController
{
public void new()
{
super();
this.parmClassName(classStr(CustReportService));
this.parmMethodName(methodStr(CustReportService, generate));
}
public static void main(Args _args)
{
CustReportController c = new CustReportController();
c.parmArgs(_args);
c.startOperation();
}
}
The dialog is auto-generated from the contract. Add a parm method = dialog gets a new field.
| SysOperation (Modern) | RunBase (Legacy) | |
|---|---|---|
| Architecture | Controller + Contract + Service | Single monolithic class |
| Parameters | Data contracts (auto-serialized) | Manual pack/unpack |
| Dialog | Auto-generated | Manually built |
| Testability | Service independently testable | Tightly coupled |
| Use for new code | Always | Never |
π¨βπ» Elena: βEvery batch job at PacificForge uses SysOperation. The auto-dialog alone saves hours.β
Exam tip: SysOperation is the modern pattern
If the exam asks about batch functionality, answer SysOperation unless RunBase is explicitly mentioned. RunBase is legacy β never use for new development.
Workflow Framework
| Component | Purpose |
|---|---|
| Workflow type | Overall structure for a document |
| Category | Groups related workflow types |
| Approval element | Approve/reject step |
| Task element | Complete-a-task step |
| Condition | Branch routing logic |
| Document class | Exposes fields for conditions |
| Event handlers | React to state changes |
Document class
[WorkflowDocumentAttribute(tableStr(PurchReqTable))]
public class PurchReqDocument extends WorkflowDocument
{
public Amount parmTotalAmount()
{
return this.getTable().calculateTotalAmount();
}
}
Event handler
public class PurchReqWFHandler implements WorkflowStartedEventHandler, WorkflowCompletedEventHandler
{
public void started(WorkflowEventArgs _args)
{
PurchReqTable pr = PurchReqTable::find(_args.parmWorkflowContext().parmRecId());
pr.updateStatus(PurchReqStatus::InReview);
}
public void completed(WorkflowEventArgs _args)
{
PurchReqTable pr = PurchReqTable::find(_args.parmWorkflowContext().parmRecId());
pr.updateStatus(PurchReqStatus::Approved);
}
}
SysExtensionSerializer
Enables extensible enums β ISVs can add enum values without modifying the base definition. The framework discovers new values at runtime.
Sophie needs a batch job with date range parameters. Framework?
Where is the total amount calculation for workflow routing?
Next up: Testing: SysTest & Task Recorder