Logo

    Home

    Documentation

    Use Cases

    Training

    Applications

    Release Notes

    ProCode backend logic- ServerEventHandler

    ProCode backend logic- ServerEventHandler

    1 Context:

    🧠
    In this example, we will write our own ABL server logic to enhance the data fetched through an ABL datasource. We will populate the customer datasource ‘Comments’ field with the number of orders, the number of shipped orders and the balance of each customer in part.

    2 Step by step guide:

    1. For this task we will use the screen we used for the Frontend button again. Please use your copy of TrainingDay5_OrderOverview
    2. In your ProCode Workspace create a new folder src/backend/Training/
    3. Create a new file in that folder src/backend/Training/CustomerEventHandler.cls
    4. Start typing “b1-datasourceEventhandler” and select the template, then save your code by pressing “CTRL+ S”
    5. Navigate back to your Low-Code Workspace and go to “Integrate” -> “Datasources” and select the button “Dataset-Definiton” in the toolbar
    6. Search for the “Data Source Object” -> “CustomerDSO” and click on “Generate Definition”
    7. Copy the “Dataset Definition”
    8. Navigate back to your Pro-Code Workspace and create a new file in your newly created folder src/backend/Training/ and call it dsCustomer.i and paste your copied “Dataset Definition” in there, then press “CTRL + S”
    9. Include the dsCustomer.i in the class:
    CLASS Training.CustomerEventHandler
      INHERITS Akioma.Swat.OERA.Dynamic.BaseServerEventHandler: 
      { <YourFolder>/dsCustomer.i &ACCESS="PRIVATE" }
    1. Insert the term “dsData” in the dataset
     CONSTRUCTOR CustomerEventHandler():
        SUPER(DATASET dsData :HANDLE).
        THIS-OBJECT:TriggerOnBeforeSave = TRUE.
        THIS-OBJECT:TriggerOnAfterFetch = TRUE.
      END CONSTRUCTOR.
    1. Write the following code for your method:
    1. Now press “CTRL + S” and execute a “b1 trim” in the terminal -> This will restart the “PASOE” without loosing your current session
    2. Now go back to your Low-Code Workspace and navigate to “Integrate” -> “Datasources”
    3. Search for the “CustomerDSO” and open the designer for it
    4. Search for the attribute “ServerEventsHandler” in the “Attributes” panel and fill in the value -> Training.CustomerEventHandler, then select “Save”
    5. Navigate to “Design” -> “Screens” and launch your screen to see the result

    Full Code Example:

    3 Explanation:

    ☝
    Every time data is retrieved, our defined event handler is called and our defined logic is executed. This demonstrates how easy it is to integrate and use custom code in the backend. The message gets generated in the defined field with every fetch.
    Logo
    METHOD PROTECTED OVERRIDE VOID OnAfterFetch():
        DEF VAR iCount AS INT NO-UNDO.    
        DEF VAR iNumShipped AS INT NO-UNDO.
    
        /* go through every CustTable record read from the DB */
        FOR EACH eCustomer:
          
          ASSIGN iCount = 0 iNumShipped = 0.
          // for each fetched Customer, go through all contacts in the DB     
          FOR EACH sportsdb.order WHERE sportsdb.order.custNum = eCustomer.custNum NO-LOCK:
            iCount = iCount + 1.
            IF sportsdb.order.orderStatus = "Shipped" THEN ASSIGN iNumShipped = iNumShipped + 1.
          END.
          ASSIGN eCustomer.Comments = SUBSTITUTE("Customer has &2 orders, &3 shipped. Balance is $ &4", eCustomer.CustNum, STRING(iCount, "99"), STRING(iNumShipped, "99"), eCustomer.Balance).
        END. 
    END METHOD.
    BLOCK-LEVEL ON ERROR UNDO, THROW.
    
    CLASS Training.CustomerEventHandler
      INHERITS Akioma.Swat.OERA.Dynamic.BaseServerEventHandler: 
      { Training/dsCustomer.i &ACCESS="PRIVATE" }
    
      CONSTRUCTOR CustomerEventHandler():
        SUPER(DATASET dsData:HANDLE).
        THIS-OBJECT:TriggerOnBeforeSave = TRUE.
        THIS-OBJECT:TriggerOnAfterFetch = TRUE.
      END CONSTRUCTOR.
    
      METHOD PROTECTED OVERRIDE VOID OnBeforeSave():
        // enter before save code here
        
      END METHOD.
    
      METHOD PROTECTED OVERRIDE VOID OnAfterFetch():
        DEF VAR iCount AS INT NO-UNDO.    
        DEF VAR iNumShipped AS INT NO-UNDO.
    
        /* go through every CustTable record read from the DB */
        FOR EACH eCustomer:
          
          ASSIGN iCount = 0 iNumShipped = 0.
          // for each fetched Customer, go through all contacts in the DB     
          FOR EACH sportsdb.order WHERE sportsdb.order.custNum = eCustomer.custNum NO-LOCK:
            iCount = iCount + 1.
            IF sportsdb.order.orderStatus = "Shipped" THEN ASSIGN iNumShipped = iNumShipped + 1.
          END.
          ASSIGN eCustomer.Comments = SUBSTITUTE("Customer has &2 orders, &3 shipped. Balance is $ &4", eCustomer.CustNum, STRING(iCount, "99"), STRING(iNumShipped, "99"), eCustomer.Balance).
        END.
      END METHOD.
    END CLASS.