Skip to content

Save Operations within BPOs and WBOs

Business Processes and Web Business Processes often require that you write your own save processes. This section will explain how to do this.

You will use the Request_Validate and Request_Save messages to save records.

A manually coded save operation consists of the following steps:

  1. If editing, find a record. If adding a new record, clear the DDO.
  2. If it’s a new record, find any parent DDO records as needed.
  3. Update all DDO values using Set [File_Field_Changed_Value](Commonly_Used_Data_Dictionary_Object_Properties_and_Functions.md#Field_Changed_Value).
  4. Check that all fields in all participating DDOs are valid, using Request_Validate.
  5. Tell the DDO to save the record using Request_Save.
  6. Check the status of the save and react accordingly.

The following example shows a typical save operation for a new record.

Function NewOrder Integer iCustNo String sShip Returns Integer
    Integer iOrderNo
    Boolean bErr
    Handle hoOrderDD hoCustDD hoSalesPDD

    Move oOrderHea_DD to hoOrderDD
    Move oCutomer_DD to hoCustDD
    Move oSalesP_DD to hoSalesPDD

    // Step 1: clear all DDOs
    Send Clear of hoOrderDD

    // Step 2: Find all required parent records
    Move iCustNo to Customer.Customer_Number
    Send Find of hoCustDD EQ 1
    Move "INET" to SalesP.Id
    Send Find of hoSalesPDD EQ 1

    // Step 3: Update DDO with changed values
    Set Field_Changed_Value of hoOrderDD Field OrderHea.Terms to "COD"
    Set Field_Changed_Value of hoOrderDD Field Orderhea.Ship_Via to sShip

    // Step 4: Validate all fields
    Get Request_Validate of hoOrderDD to bErr

    // Step 5: If no error, save new record
    If (not(bErr)) Begin
        Send Request_Save of hoOrderDD
        // if save failed, the Global Err indicator is set True
        Move (Err) to bErr
    End

    // Step 6: Post save processing
    If (Err) Begin
        Move 0 to iOrderNo
    End
    Else Begin
        Move OrderHea.Order_Number to iOrderNo
    End

    Function_Return iOrderNo
End_Function

The messages Request_Validate and Request_Save are almost always used in this fashion. First, you must verify that all fields are valid. If the fields are valid, you save the record. If you do not include the Request_Validate as part of a save, it is possible to save records with improperly validated data.

Why do we even allow this condition? There may be times when a programmer is sure that a change in a process is valid and may wish to bypass the overhead of validation. The choice is yours – if you bypass validations, be careful. The following example clears the last_access date field in all records. If we are quite sure that this is a valid operation, we may skip the validation as follows:

Function ClearUserDates returns integer
    Handle hoDD
    Move oUser_DD to hoDD
    Send Clear of hoDD
    Send Find of hoDD Ge 1

    While (Found)
        Set Field_Changed_Value of hoDD Field User.Last_access to 0
        Send Request_Save of hoDD
        Send Find of hoDD GT 1
    Loop
End_Function

Save errors can occur in two places:

  • If the return value from Request_Validate is non-zero, the field validation failed.
  • If the Err global indicator is returned true after a Request_Save, an error occurred during the save and the transaction was rolled back. This error might have occurred inside the Validate_Save event, any of the other save events, or an unexpected error may have occurred.

As a final example, this function from a WebApp shopping cart sample will change the quantity of an order detail item. This would be called within a Web Browser object, and the message IncOrderDtl will have been registered as an external interface message.

// This function is called by a button from the shopping cart
// and increases the quantity of an item by one
Function IncOrderDtl Integer iOrderNo Integer iDetailNo Returns Integer
    Boolean bErr
    Integer iTmpQty

    Move oOrderDtl_DD to hoDtlDD
    Send Clear of hoDtlDD
    Move iOrderNo to Orderdtl.Order_Number
    Move iDetailNo to Orderdtl.Detail_Number
    Send Find of hoDtlDD EQ 1

    If (Found) Begin
        Move Orderdtl.Qty_Ordered to iTmpQty
        Increment iTmpQty
        Set Field_Changed_Value of hoDtlDD Field Orderdtl.Qty_Ordered to iTmpQty
        Get Request_Validate of hoDtlDD to bErr

        If not bErr Begin
            Send Request_Save to hoDtlDD
            Move (Err) to bErr
        End
    End

    Function_Return bErr
End_Function

This could be called from an ASP page as follows:

<%
If shopAction = ">" then
    bErr = oOrder.Call("Get_IncOrderDtl", iOrderNo, iDetailNo)
End If
%>

See Also