Setup at implementation time

Introduction

The implementation described here is based on the following assumptions:

  • In the Exchange scheme, the ASCII file name will be equivalent to the table code, and the ASCII field names will be equivalent to the column code.
  • A create XML file type of action is defined. This action has a transformation script defined. In that transformation script, the following is programmed:
    • The event type is changed: The standard events are replaced by a specific event.
    • The class is changed: The table code is replaced with a logical name.
    • The attributes that are not required in the output, but that only had to check the condition, are removed.
    • The attributes that are required in the output are renamed.

Note that these assumptions are not mandatory. For example, the user can use other, more descriptive ASCII file and field names, which reduces the transformations in the trigger. However, in that case, the limitations of the Exchange module must be taken into account. More specifically, the ASCII file and field names cannot be greater than eight characters in length and the ASCII file names will always be in lowercase.

In addition, for the transformation script, you can follow one of the following two approaches:

  • Adhere to the standard event structure. In this case, the incoming event is updated as described previously.
  • Use a proprietary structure: In this case, the attribute values are picked up from the incoming event, and a new XML is created. In this case, any XML can be created and can be completely tuned to the needs of the workflow engine that receives the XML files.
Audit setup

Audit is switched on for the tables involved: whwmd215 and tdsls400. For details about Audit Management, refer to the Web Help and to the Infor10 ERP Enterprise Server (LN) Technical Manual (U8172 US).

Achtung!

By default, unchanged columns are not audited in case of an update action. As a result, for example, if the stoc (inventory on hand) is changed in whwmd215, the values for the primary key fields ( cwar and item) and the changed field ( stoc) are included, but the unchanged fields are not included. Note that this can impact filtering by conditions, because you cannot check an attribute that is unavailable.

To avoid this limitation, use the Audit Fields by Table (ttaud3125m000) session to specify that unchanged fields must be audited (set the audit type to "Always"). For details, refer to "Unchanged table fields" in chapter 2, "To set up triggering".

Exchange scheme setup

A single exchange scheme is created to pick up the relevant changes. As a result, the job for each of these situations runs at the same frequency, which results in less overhead. If the frequency for checking the changes must differ for the tables, you can create multiple batches or exchange schemes.

The batch includes the two batch lines, covering the following table fields:

Tabletdsls400whwmd215

Fields

orno

ofbp

sotp

corg

item

stoc

allo

 

Exchange scheme properties
Exchange Schemeworkflow
DescriptionWorkflow Scheme for Triggering
Path for Exchange Objects/home/exchange/workflow
Path for Condition Errors/home/exchange/workflow
Path for Seq. Files/home/exchange/workflow
Path for Definition Files/home/exchange/workflow
Based on AuditYes
Based on IndicatorsYes
Default Date FormatYYYYDDMM
Control character y/nNo
Separator|
Enclosing Character
Parent Exchange Scheme

 

Control character, separator, and enclosing character are irrelevant because no file is created.

Batch properties
Exchange Schemeworkflow (Workflow Scheme for Triggering)
BatchBATCH
Sequence No.10
DescriptionWorkflow Export Batch
Company996
Exchange Using AuditYes

 

ASCII file formats
  • Exchange Scheme: workflow (Workflow Scheme for Triggering)
  • ASCII file: Item Inventory by Warehouse (whwmd215)
Field No.1020240260
Field NameCwarItemStocAllo
DescriptionWarehouseItemInventory on HandAllocated Inventory
Field TypeAlphanumericAlphanumericNumericNumeric
Start Pos14246286
Length3162020
Date Format
Floating Dec.NoNoNoNo
Dec.Pos.0000

 

  • Exchange Scheme: workflow (Workflow Scheme for Triggering)
  • ASCII file Sales Orders 9 (tdsls400)
Field No.10205070
Field Nameornoofbpcorgsotp
DescriptionSales OrderCustomerOriginOrder Type
Field TypeNumericAlphanumericNumericAlphanumeric
Start Pos172228
Length6633
Date Format
Floating Dec.NoNoNoNo
Dec.Pos.0000

 

Field Type, Start Position, Length, and so on are irrelevant, because no ASCII file is created.

Table and field relations (export)
  • Exchange Scheme: workflow (Workflow Scheme for Triggering)
  • Batch: BATCH (Workflow Export Batch)
Batch Line1020
ASCII Filewhwmd215tdsls400
Desc.Item Inventory by WarehouseSales Orders
Tablewhwmd215tdsls400
ASCII File Namewhwmd215.Stdsls400.S
ActiveYesYes
bdbpreNoNo
RangeNoNo
Index11
Cond.

 

  • Exchange Scheme: workflow (Workflow Scheme for Triggering)
  • Batch: BATCH (Workflow Export Batch)
  • Batch Line: 10 (whwmd215)
Serial No.1020240260
Field Namecwaritemstocallo
Table Fieldcwaritemstocallo
Array Element0000
Condition
Fixed value

 

  • Exchange Scheme: workflow (Workflow Scheme for Triggering)
  • Batch: BATCH (Workflow Export Batch)
  • Batch Line: 20 (tdsls400)
Serial No.10205070
Field Nameornoofbpcorgsotp
Table Fieldornoofbpcorgsotp
Array Element0000
Condition
Fixed value

 

Export triggers
  • Exchange Scheme: workflow (Workflow Scheme for Triggering)
  • Batch: BATCH (Workflow Export Batch)
Batch Line1020
Trigger for Each Rowwf_inventorywf_salesorder
Create ASCII FileNoNo
Trigger for Batch Line End

 

Optimizations

If required, to implement optimizations, you can move conditions from the Trigger to the Exchange scheme. For example, you can create a range for batch line 20 ( tdsls400) on the corg (origin) column to only include sales orders created by means of EDI. This reduces the number of XML events that the Exchange module creates. Note, however, that the Exchange export cannot filter on action type, in this example, only include inserts, skip updates, and deletes.

Application customization

To perform the implementation, you must customize the function(s) that check the credit limit of a Business Partner, which is used in the sales order related program scripts. The customization adds a check to see whether 80 percent of the credit limit is exceeded. If so, the function creates an event and invokes a trigger.

Hinweis

You must check that the previous value of the Credit in Use did not exceed the 80 percent threshold. Otherwise, the process will be triggered multiple times for the same customer, which is undesirable.

If the trigger you invoke is not in use for any other events, no conditions must be defined. The action that you must take is to create a file that contains the XML event.

Implementation
Hinweis

The information in this document is for educational purposes only, by way of example. The information is not intended to describe a complete and tested solution that will work in a live LN environment.

Assume that a library exists that contains a function to check the credit limit. Further assume that the following variables are available in that function:

  • invoice.to.bp: the business partner (customer) to which the invoice must be sent
  • order.number: The sales order being processed
  • credit.limit: The business partner’s credit limit
  • old.credit.in.use: The credit already used before processing the sales order
  • new.credit.in.use: The old.credit.in.use plus the order amount for the new sales order

The original version of the library function contains the following code:

if new.credit.in.use > credit.limit then
        return(true) | credit limit exceeded
    else
        return(false) | credit limit not exceeded
endif

In a customized version of library, if the usual credit limit check is passed, the 80 percent check is carried out:

if new.credit.in.use > credit.limit then
        return(true) | credit limit exceeded
    else
        if new.credit.in.use > 0.8 * credit.limit and
           old.credit.in.use <= 0.8 * credit.limit
        then
            generate.credit.trigger(invoice.to.bp,
                        order.number,
                        credit.limit,
                        old.credit.in.use,
                        new.credit.in.use)
        endif
        return(false) | credit limit not exceeded
endif

At the end of the DLL, the following function is added:

function generate.credit.trigger(
            domain  tccom.bpid  i.invoice.to.bp,
            domain  tcorno  i.order.number,
            domain  tcamnt  i.credit.limit,
            domain  tcamnt  i.old.credit.in.use,
            domain  tcamnt  i.new.credit.in.use)
{
#pragma used dll odatrgapi
#pragma used dll odatrgevent

#define MY_TRIGGER  "credit"
#define ERR_IF_NONZERO(value)
^           if value <> 0 then
^               | here some error logging can be implemented, 
^               | for example
^               return
^           endif

    long    event       |tree containing trigger event
    long    retl            |return value to be checked
    string  error.mess(256) |error message from trigger
    string  error.details(256)  |error details from trigger

    |add event to trigger
    retl = datrgevent.simpleevent.create("Customer", 
                    "creditLimitIsNear", event)
    ERR_IF_NONZERO(retl)
    retl = datrgevent.simpleevent.set.value(event,
            "customerID", i.invoice.to.bp)
    ERR_IF_NONZERO(retl)
    retl = datrgevent.simpleevent.set.value(event,
            "orderNumber", str$(i.order.number))
    ERR_IF_NONZERO(retl)
    retl = datrgevent.simpleevent.set.value(event,
            "creditLimit", str$(i.credit.limit))
    ERR_IF_NONZERO(retl)
    retl = datrgevent.simpleevent.set.value(event,
            "creditInIse", str$(i.new.credit.in.use))
    ERR_IF_NONZERO(retl)
    retl = datrgevent.simpleevent.set.old.value(event,
            "creditInUse", str$(i.old.credit.in.use))
    ERR_IF_NONZERO(retl)

    |invoke trigger
    retl = datrgapi.trigger.do(MY_TRIGGER, event, 
                    error.mess, error.details)
    ERR_IF_NONZERO(retl)
}
Trigger setup

Triggers

Assume that the following three triggers are defined:

  • wf_inventory (for whwmd215)
  • wf_salesorder (for tdsls400)
  • wf_creditlimit (for the application trigger)
Trigger conditions

In the trigger conditions, you do not have to check the class or table code. If a single trigger was used for multiple classes, you must include the class condition, and you must have the same action performed for each class.

The following conditions are defined:

Trigger wf_salesorder:

Seq Nr1020
And/OrAnd
Condition TypeEvent TypeAttribute
Attributecorg
Operator==
Valuecreate3
BecomesNo

 

Trigger wf_inventory:

Seq Nr10
And/Or
Condition TypeAttribute
Attributestoc
Operator<
Value20
BecomesYes

 

Trigger wf_creditlimit will not have any conditions specified, because the conditions are checked in the application.

Trigger actions

For each trigger, a create XML file action is specified. The local path, file transfer program, and target path are defined.

Additionally, if required, a transformation script is defined that translates the generic event into an event that the workflow engine can understand.

The minimum requirement will likely be simply to rename the event type into a specific event to enable the workflow engine to detect what event occurred. Note that the class and standard event type are insufficient. The event type will always be Create, Change, or Delete, and the class is not unique because two changes on the same table/class can result in two different workflow processes. If you do not rename the event, the workflow engine must duplicate the conditions as defined for the triggers.

In addition, the attributes must be renamed to UDAs that the workflow engine knows. The previous values can be moved to give the values a unique name. For more information, refer to "XML used at runtime," later in this chapter for examples.

Finally, rather than use the standard event structure, the transformation script can build up a new event structure.