Epicor Functions, BPMs or customizations?
In short. Use BPMs to react to what the system is doing, Epicor Functions to package reusable operations and Application Studio layers for presentation only.
Written for Developers, administrators.
Kinetic gives you three main places to put custom behavior: BPMs that react to what the system is doing, Epicor Functions that package reusable server-side operations, and UI customizations built as Application Studio layers. They overlap enough that the same requirement could be built in any of them, so the choice matters. Logic in the wrong layer is harder to test, harder to reuse and more likely to break at upgrade.
Where each requirement belongs
Section titled: Where each requirement belongsThe table gives our default home for common requirements.
| Requirement | Best home |
|---|---|
| Enforce a rule whenever data changes, no matter which screen, import or integration changed it | BPM (usually a data directive or a method directive on the update) |
| Adjust or extend what a specific business object method does | BPM method directive |
| An operation that several places need to call: screens, BPMs, integrations, schedules | Epicor Function |
| An operation an external system should call over REST | Epicor Function |
| Change what a user sees or how a screen behaves | Application Studio layer |
| A screen action that needs server logic | Layer that calls an Epicor Function |
Put simply, BPMs react, Functions act and layers present.
BPMs react to the system
Section titled: BPMs react to the systemBusiness Process Management directives run on the server in response to something Kinetic is already doing. There are two broad families.
Method directives
Section titled: Method directivesA method directive attaches to a business object method, such as the update on a sales order. It can run at three points:
| Stage | When it runs | Good for |
|---|---|---|
| Pre-processing | Before the method runs | Validation that should stop the call, and setting values before the standard logic sees them |
| Base processing | In place of the standard method | Rarely the right choice. It is powerful, but you take on responsibility for what the method would have done |
| Post-processing | After the method has run | Follow-on actions such as notifications or updating related records |
Data directives
Section titled: Data directivesA data directive attaches to a table and fires when rows change, regardless of which method changed them.
In-transaction directives run inside the save and can change the data or stop the transaction. They affect every save of that table, so keep them lean.
Standard directives run after the change is committed. They suit notifications and follow-on work that must not slow down or block the save.
When a BPM is right
Section titled: When a BPM is rightChoose a BPM when the rule must hold however the data arrives: a screen, an import, a REST call or another process. A credit rule enforced only in a screen layer can be bypassed by an integration. The same rule in a BPM cannot.
BPM cautions
Section titled: BPM cautions- Scope tightly. Add conditions so the directive only does work when it needs to. A directive on a busy method that runs heavy logic on every call slows the whole system.
- Avoid chains you cannot see. A BPM that triggers a method that triggers another BPM creates behavior nobody can explain later. If logic is getting long, move it to a Function and call it from the BPM.
- Name and document every directive. Include what it does and why in its description, and keep an inventory.
Epicor Functions package operations
Section titled: Epicor Functions package operationsAn Epicor Function is a named server-side routine with defined inputs and outputs, kept in a library. Libraries have owners and security, and must be published before their functions can be called. Once published, a function can be called from BPMs, from Application Studio events, from other functions and over REST.
When a Function is right
Section titled: When a Function is right- The logic is used in more than one place. Write it once, and call it from the BPM, the screen and the integration.
- An external system needs a custom operation. Exposing a Function over REST is cleaner than asking the external system to orchestrate a series of business object calls, and it keeps the business logic inside Kinetic.
- A BPM is getting long. Move the body into a Function and keep the BPM as a thin trigger with a condition and a call.
- You want testable units. A Function with clear inputs and outputs is easier to test in isolation than logic embedded in a directive.
Function cautions
Section titled: Function cautions- Design the signature carefully. Inputs and outputs are a contract. Changing them later breaks every caller.
- Draw library boundaries by purpose, not by who wrote the functions. A library per integration or per business area is usually right.
- Treat security as part of the design. Decide who can call each library, and when exposing a Function over REST, pair it with a scoped API key. See Calling the Kinetic REST v2 API.
- Plan promotion between environments. Libraries can be exported and imported. Decide how a change moves from test to production and who approves it.
Application Studio layers handle presentation
Section titled: Application Studio layers handle presentationIn the Kinetic browser interface, screen changes are made in Application Studio and saved as layers over the base application. A layer can add, hide or rearrange fields, call server logic and add buttons and events.
When a layer is right
Section titled: When a layer is right- The requirement is about what a user sees or does on a screen: layout, defaults on the form, guidance, a button that runs an action.
- The behavior is specific to one screen or one group of users.
Layer cautions
Section titled: Layer cautions- Keep server logic on the server. A layer should call a Function for anything non-trivial, rather than stringing together many business object calls from the screen.
- Retest after upgrades. Base screens change between releases. Even when a layer carries forward cleanly, behavior that depends on specific components deserves a check.
Customizations from the older Windows client
Section titled: Customizations from the older Windows clientMoving to the Kinetic web UI means deciding for each one whether to convert it, rebuild it as a layer plus server logic or retire it. Treat it like any other report or customization triage, because many old customizations exist for problems that no longer apply.
One requirement across three layers
Section titled: One requirement across three layersSay that when a sales order is saved for a customer on a particular program, the order must carry a program code, and an external portal needs to look up program pricing.
| Piece | What it does |
|---|---|
| BPM | A pre-processing method directive on the sales order update stops the save with a clear message if the program code is missing, for screens, imports and REST alike |
| Function | A GetProgramPrice function in a pricing library returns the price for a customer, part and quantity. The portal calls it over REST with a scoped API key |
| Layer | The order entry screen gets a visible program code field and a button that calls the same Function to show the price to the user |
Each piece sits in the layer designed for it, and the pricing logic exists in one place.
Decision questions
Section titled: Decision questions- Must this hold no matter how data arrives? BPM.
- Will more than one caller need this operation, or will an external system call it? Function.
- Is it only about the screen? Layer.
- Is a BPM or layer getting long? Move the logic into a Function and call it.
Keep an inventory of every directive, library and layer, with its purpose and owner. At upgrade time, that list is your test plan.