Create Invoice from GIR
Create Invoice from GIR: Description
The class GenericInvoiceRunFromSObjectInvocable can be used to create the invoice for a single source record via Salesforce flows or own Apex code.
Use it when a business event is supposed to bill a record immediately – an order is activated, a case is closed, a milestone is completed – without scheduling a full invoice run and without manual user input.
Event-based invoice creation concepts
The action reuses the generic invoice run configuration – the same filter and the same ON field mapping that a scheduled invoice run evaluates. The filter is resolved from the object type of the passed source record.
When invoked, JustOn Billing & Invoice Management will
- validate the resolved configuration for every passed record
- group the records by resolved filter, invoice date, period start date and period end date
- start one invoice run chain per group and return its chain ID for each record of the group
- have the chain create the invoice and write its ID back to the
ON_Invoicefield of the source record
The processing is asynchronous. When the call returns, the invoice does not exist yet.
The action does not create an invoice run record. The Invoice Run field of the produced invoices stays empty, and the ON_LastInvoiceRun field of the source record is not stamped.
For details, see Event-Based Invoice Creation.
Invocable Method
| Apex Class | Namespace | Flow Action Label | Description |
|---|---|---|---|
GenericInvoiceRunFromSObjectInvocable |
ONB2 |
Create Invoice from GIR (single source) |
Creates the invoice for a single source record based on a generic filter |
In an org where JustOn Billing & Invoice Management is installed, the action is registered as ONB2__GenericInvoiceRunFromSObjectInvocable.
Limitations
- The processing is asynchronous. The action returns a chain ID, not the produced invoice.
- A recurring filter requires a period start and end date. Invoked without them, the call fails.
- The validation is all-or-nothing. If the configuration of any passed record is invalid, no chain is started for any record.
- Source records that already have a live – that is, not canceled – invoice are skipped.
- For mass invoicing of an entire object, use the scheduled generic invoice run instead.
Request Parameters
| API Name | Required | Type | Label | Description |
|---|---|---|---|---|
| sourceRecordId | Id | Source Record Id | The reference to the ID field of the record to be invoiced Its object must have a configured generic filter. |
|
| filterName | String | Filter Name | The name of the generic filter to be applied Only required to disambiguate if the source object has more than one generic filter. Case-sensitive. |
|
| invoiceDate | Date | Invoice Date | The invoice date to be set on the produced invoices Defaults to the current date if empty. |
|
| periodStartDate | Date | Period Start Date | The start date of the billing period Required for recurring filters. For non-recurring filters, it defaults to the current month. |
|
| periodEndDate | Date | Period End Date | The end date of the billing period Required for recurring filters. For non-recurring filters, it defaults to the current month. |
Response Parameters
The action returns one result per passed record, index-aligned with the input. The result holds the chain ID only – there is no per-record error field, since configuration problems make the call fail as a whole.
| API Name | Type | Label | Description |
|---|---|---|---|
| chainId | Id | Chain Id | The ID of the BatchJobChain record that creates the invoice. Use it to track the progress. A blank value means that there is nothing to bill – the record already has a live invoice. |
Info
Since the passed records are grouped into chains by filter and dates, records of different groups receive different chain IDs, while records of the same group share one chain ID.
For details, see Chain Grouping.
Error Handling
| Situation | Behavior | How to detect it |
|---|---|---|
| Configuration error no matching filter, ambiguous filter, recurring filter without a billing period, missing source record ID |
The call fails, and no chain is started for any passed record | Flow: Fault connector, {!$Flow.FaultMessage}Apex: see the note on the two call paths below |
| Runtime error during the chain occurs asynchronously, after the dispatch |
The chain records the error on the source record | The ON_InvoiceBuildError field of the source record |
| Nothing to bill the record already has a live invoice |
Valid outcome, no chain is started | A result with a blank chain ID |
A configuration error message reads, for example, Multiple Generic filters match object Order (…). Provide Filter Name to disambiguate.
Note
How a configuration error surfaces in Apex depends on the call path:
- Calling the class directly validates all requests up front and throws before starting a chain. Wrap the call in a
try/catchblock and reade.getMessage(). - Calling the action dynamically via
Invocable.Actiondoes not throw. Instead, the returned result hasisSuccess() == false, holds the reason ingetErrors(), andgetOutputParameters()isnull.
Create Invoice from GIR: Example Use Cases
Using Salesforce Flow
Assume the following use case: Your business bills orders directly, without an intermediate subscription. As soon as an order is activated, the corresponding invoice is to be created. You use the status modification on the order to trigger a Salesforce flow that calls the Create Invoice from GIR (single source) action.
Following the example, you may set up the flow as follows:
| Flow Element | Option | Value |
|---|---|---|
| Start | Object | Order |
| Trigger | A record is updated |
|
| Conditions | All Conditions Are Met (AND)Status Equals Activated |
|
| Run | Only when a record is updated to meet the condition requirements |
|
| Action | Action | Create Invoice from GIR (single source) |
| Input Values | Source Record Id: {!$Record.Id}Filter Name: OrderActivationInvoiceInvoice Date: {!$Flow.CurrentDate} |
Depending on your specific use case, the flow setup will vary. Add a Fault connector to the Action element to catch configuration errors, as described in Enabling Event-Based Invoice Creation.
Using Apex Code
Assume your business has developed an own integration that manages the source records. Now you need a piece of Apex code that invokes the action after a record has been processed.
The following example uses the platform's Invocable.Action framework with string names only. This way, the calling code – a separate managed package, for example – does not require a compile-time dependency on JustOn Billing & Invoice Management.
// No compile-time dependency on ONB2 -- only the standard Invocable.Action class and string names.
Invocable.Action action =
Invocable.Action.createCustomAction('apex', 'ONB2', 'GenericInvoiceRunFromSObjectInvocable');
action.setInvocationParameter('sourceRecordId', sourceRecordId); // required
// optional, using the same names as the invocable variables:
// action.setInvocationParameter('filterName', 'OrderActivationInvoice');
// action.setInvocationParameter('invoiceDate', Date.today());
// action.setInvocationParameter('periodStartDate', Date.today().toStartOfMonth()); // required for recurring filters
// action.setInvocationParameter('periodEndDate', Date.today());
Invocable.Action.Result result = action.invoke()[0];
if (result.isSuccess()) {
Id chainId = (Id) result.getOutputParameters().get('chainId'); // null = nothing to bill (already invoiced)
} else {
// Configuration errors do not throw on this call path -- the reason is in getErrors()
String reason = String.valueOf(result.getErrors());
}
For details about the framework, see Invocable.Action Class in the Apex Reference Guide.