16 Using Guaranteed XAPI Events

This chapter contains the following topics:

16.1 Understanding Guaranteed XAPI Events

XAPI is a JD Edwards EnterpriseOne service that captures transactions as the transaction occurs and then calls third-party software, end users, and other JD Edwards systems to obtain a return response. A XAPI event is very similar to a real-time event and uses the same infrastructure to send an event. The difference between a real-time event and a XAPI event is that the subscriber to a XAPI event returns a reply to the originator. The XAPI event contains a set of structured data that includes a unique XAPI event name and a business function to be invoked upon return. Like real-time events, XAPI events can be generated on a JD Edwards EnterpriseOne server using a JD Edwards EnterpriseOne HTML client. XAPI events also can be generated by a third-party system and sent to a JD Edwards EnterpriseOne system for a response.

The XAPI structure sends outbound events and receives replies. An event is first generated by the XAPI originator and then sent to a separate system, the XAPI executor, for processing. The XAPI executor then sends a response back to the XAPI originator. The XAPI structure provides for these three possibilities of originator and executor combinations:

  • JD Edwards EnterpriseOne to third-party.

  • Third-party to JD Edwards EnterpriseOne.

  • JD Edwards EnterpriseOne to JD Edwards EnterpriseOne.

When you use JD Edwards EnterpriseOne-to-EnterpriseOne events processing, you must map business functions and APIs.

16.1.1 JD Edwards EnterpriseOne to Third-Party

This diagram shows a logical representation of the XAPI process from JD Edwards EnterpriseOne to a third-party system:

Figure 16-1 JD Edwards EnterpriseOne to a third-party system XAPI even

Description of Figure 16-1 follows
Description of "Figure 16-1 JD Edwards EnterpriseOne to a third-party system XAPI even"

In summary:

  1. JD Edwards EnterpriseOne (XAPI originator) sends a request.

  2. The request is sent to a third-party system.

  3. The third-party system (XAPI executor) processes the request and sends a response back to the XAPI originator.

16.1.2 Third-Party to JD Edwards EnterpriseOne

This diagram shows a logical representation of the XAPI process from a third-party system to JD Edwards EnterpriseOne:

Figure 16-2 Third-party system to JD Edwards EnterpriseOne XAPI event

Description of Figure 16-2 follows
Description of "Figure 16-2 Third-party system to JD Edwards EnterpriseOne XAPI event"

In summary:

  1. The third-party system (XAPI originator) sends a request using the JD Edwards EnterpriseOne XAPI request form.

  2. The request is sent to JD Edwards EnterpriseOne.

  3. JD Edwards EnterpriseOne (XAPI executor) processes the request and sends a response back to the XAPI originator.

16.1.3 JD Edwards EnterpriseOne-to-EnterpriseOne

This diagram shows a logical representation of the XAPI process from one JD Edwards EnterpriseOne system to another JD Edwards EnterpriseOne system:

Figure 16-3 JD Edwards EnterpriseOne-to-EnterpriseOne XAPI event

Description of Figure 16-3 follows
Description of "Figure 16-3 JD Edwards EnterpriseOne-to-EnterpriseOne XAPI event"

In summary:

  1. The first JD Edwards EnterpriseOne system (XAPI originator) sends a request.

  2. The request is sent to a second JD Edwards EnterpriseOne system, which might share the same or different environment as the first JD Edwards EnterpriseOne system.

  3. The second JD Edwards EnterpriseOne system (XAPI executor) processes the request and sends a response back to the first JD Edwards EnterpriseOne system (XAPI originator).

  4. The first JD Edwards EnterpriseOne system (XAPI originator) processes the response.

16.2 Using JD Edwards EnterpriseOne as a XAPI Originator

This diagram illustrates the flow of a XAPI event when JD Edwards EnterpriseOne functions as the XAPI originator:

Figure 16-4 JD Edwards EnterpriseOne as XAPI originator

Description of Figure 16-4 follows
Description of "Figure 16-4 JD Edwards EnterpriseOne as XAPI originator"

In summary:

  1. A JD Edwards EnterpriseOne client calls a business function on the JD Edwards EnterpriseOne server.

  2. The business function uses XAPI APIs to create the XAPI request.

    The CallObject kernel in which the XAPI APIs are executing creates the XAPI request data, adding the callback function. If the XAPI executor is another JD Edwards EnterpriseOne system, the host and port of the JD Edwards EnterpriseOne server that is functioning as the XAPI originator is added to the data. The data is then sent to the Transaction server.

  3. The Transaction server sends the document to the subscriber, which is the XAPI executor.

    If the XAPI executor is another JD Edwards EnterpriseOne system, the document is sent through JDENET.

  4. The XAPI XML response document is sent by the XAPI executor through JDENET to the XML Dispatch kernel of the XAPI executor.

  5. The XML Dispatch kernel receives the response XML document and sends the response to the XML Service kernel.

  6. The XML Service kernel stores the response document and creates a file handle.

  7. The XML Service kernel invokes the callback business function with the file handle.

  8. The business function parses the response document using XAPI APIs, which use the XML Service kernel to load the document into memory.

  9. The business function uses XAPI APIs to process the response and send it to the JD Edwards EnterpriseOne client.

16.3 Using JD Edwards EnterpriseOne as a XAPI Executor

This diagram illustrates the flow of a XAPI event when JD Edwards EnterpriseOne functions as the XAPI executor.

Figure 16-5 JD Edwards EnterpriseOne as XAPI executor

Description of Figure 16-5 follows
Description of "Figure 16-5 JD Edwards EnterpriseOne as XAPI executor"

In summary:

  1. The XAPI originator sends the XAPI XML request document to the XML Dispatch kernel through JDENET.

  2. The XML Dispatch kernel receives the document and sends the event request and routing information to the XML Service kernel.

  3. The XML Service kernel stores the document and creates a file handle for the XAPI request.

    The XML kernel also creates XML-based routing information. The XML Service kernel uses the F907012 table to find the business function that will process the request.

  4. The XML Service kernel invokes the business function with the XML request handle and the routing information handle.

  5. The business function uses XAPI APIs to parse and process the document. XAPI APIs load the XAPI XML request document into memory.

  6. The business function processes the XAPI event request.

    The business function also creates a XAPI response. The message type for the response must be xapicallmethod. The business function also passes the routing information handle.

  7. The business function uses XAPI APIs to send the XAPI response data including the routing information, to the Transaction server.

  8. The Transaction server creates the XAPI XML response document and uses the routing information to send the response document to the XAPI originator.

    If the XAPI originator is another JD Edwards EnterpriseOne system, the document is sent through JDENET.

16.4 Working with JD Edwards EnterpriseOne and Third-Party Systems

This section provides an overview of XAPI processing and discusses:

  • XAPI outbound request APIs.

  • XAPI outbound request API usage code samples.

  • XAPI Inbound response APIs.

  • XAPI inbound response API usage code samples.

See Also:

16.4.1 Understanding XAPI Processing between JD Edwards EnterpriseOne and Third-Party Systems

You can use XAPI processing to capture JD Edwards EnterpriseOne transactions as the transaction occurs, and then call third-party software to obtain a return response. In this scenario, JD Edwards EnterpriseOne is the originator, and the third-party system is the executor.

16.4.2 XAPI Outbound Request APIs

These APIs are available for you to generate a XAPI outbound request:

  • jdeXAPI_Init

  • jdeXAPI_Add

  • jdeXAPI_Finalize

  • jdeXAPI_Free

  • jdeXAPI_SimpleSend

  • jdeXAPI_ISCallTypeEnabled

  • jdeXAPI_CALLS_ENABLED

16.4.3 XAPI Outbound Request API Usage Code Sample

This code sample illustrates how to create a XAPI outbound request:

/* Header files required */

#include <B4205010.h>

/*************************/ 
      BOOL bXAPIInUse, bExit;
#ifdef jdeXAPI_CALLS_ENABLED
      XAPI_CALL_ID ulXAPICallID = 0;
      XAPI_CALL_RETURN eXAPICallReturn = eEventCallSuccess;
#endif
      DSD4205010A dsD4205010A = {0}; /*Query Header*/
      DSD4205010B dsD4205010B = {0}; /*Query Detail*/
#ifdef jdeXAPI_CALLS_ENABLED
      if(jdeXAPI_IsCallTypeEnabled("XAPIOPOUT") && jdeXAPI_IsCallTypeEnabled
("XAPIOPIN") )
      {
            bXAPIInUse = TRUE;
      }
#endif
      /*-----------------------------------------------------*/
      /* Call XAPIInit */
#ifdef jdeXAPI_CALLS_ENABLED
      if(bXAPIInUse == TRUE)
      {
            ulXAPICallID = jdeXAPI_Init( lpBhvrCom, "SendOrderPromiseRequest",
 "XAPIOPOUT", NULL, &eXAPICallReturn);
            if (eXAPICallReturn != eEventCallSuccess)
            {
                  bExit = TRUE;
            }
      }
#endif
      /*-------------------------------------------------*/
      /* Adding Header Information */
#ifdef jdeXAPI_CALLS_ENABLED
      if(bXAPIInUse == TRUE)
      {
            eXAPICallReturn = jdeXAPI_Add( lpBhvrCom, ulXAPICallID, 
"SendOrderPromiseRequest", "D4205010A", &dsD4205010A, 
sizeof(DSD4205010A));
            if (eXAPICallReturn != eEventCallSuccess)
            {
                  bExit = TRUE;
            }
      }
#endif
      /*-------------------------------------------------*/
      /* Loading Detail Information */
#ifdef jdeXAPI_CALLS_ENABLED
      if(bXAPIInUse == TRUE)
      {
            eXAPICallReturn = jdeXAPI_Add( lpBhvrCom, ulXAPICallID, 
"SendOrderPromiseRequest", "D4205010B", &dsD4205010B, 
sizeof(DSD4205010B));
            if (eXAPICallReturn != eEventCallSuccess)
            {
                  bExit = TRUE;
            }
      }
#endif
#ifdef jdeXAPI_CALLS_ENABLED
      if(bXAPIInUse == TRUE)
      /*-------------------------------------------------*/
      /* Finalize */
      {
            eXAPICallReturn = jdeXAPI_Finalize( lpBhvrCom, ulXAPICallID, 
"SendOrderPromiseRequest", "OrderPromiseCallback");
            if (eXAPICallReturn != eEventCallSuccess)
            {
                  bExit = TRUE;
            }
      }
#endif
#ifdef jdeXAPI_CALLS_ENABLED
      if (eXAPICallReturn != eEventCallSuccess)
      {
      /*-------------------------------------------------*/
      /* CleanUp */
            if(bXAPIInUse == TRUE)
            {
                  jdeXAPI_Free( lpBhvrCom, ulXAPICallID, "SendOrderPromiseRequest");
            }
      }
#endif

16.4.4 XAPI Inbound Response APIs

These APIs are available for you to read an inbound XAPI response:

  • jdeXML_GetDSCount

  • jdeXML_GetDSName

  • jdeXML_ParseDS

  • jdeXML_DeleteXML

16.4.5 XAPI Inbound Response API Usage Code Sample

This code sample illustrates how the business function uses the XML Service APIs to read and parse the XML data:

#include <B4205030.h>

      int iCurrentRecord;
      int iHeaderCount;
      int iRecordCount;
      NID nidDSName;
      DSD4205030A dsD4205030A = {0};
      DSD4205030B dsD4205030B = {0};
#ifdef jdeXAPI_CALLS_ENABLED
      if(jdeXAPI_IsCallTypeEnabled("XAPIOPOUT") &&      jdeXAPI_IsCallTypeEnabled
("XAPIOPIN") )
      {
            iRecordCount = jdeXML_GetDSCount(lpDS->szXMLHandle);
            if (iRecordCount > 0)
            {
                  for (iCurrentRecord = 0; iCurrentRecord < iRecordCount;      iCurrentRecord++)
                  {
                        jdeXML_GetDSName(lpDS->szXMLHandle,iCurrentRecord,nidDSName);
                        if (jdestrcmp(nidDSName,(const char*)"D4205030A") == 0)//mod
                        {
                              jdeXML_ParseDS( lpDS->szXMLHandle,iCurrentRecord,&dsD4205030A,
sizeof(DSD4205030A));
                        }
                        else
                        {
                              jdeXML_ParseDS( lpDS->szXMLHandle,iCurrentRecord,&dsD4205030B,
sizeof(DSD4205030B));
                              
                        }
                  }
            }
            if (iCurrentRecord == iRecordCount)
            {
                  jdeXML_DeleteXML(lpDS->szXMLHandle);
            }
      }
#endif

16.5 Using JD Edwards EnterpriseOne-to-EnterpriseOne Connectivity

This section provides an overview of the JD Edwards EnterpriseOne-to-EnterpriseOne connectivity for XAPI events and discusses:

  • XAPI outbound request handling APIs.

  • XAPI outbound request parsing API usage sample code.

  • XAPI inbound response generation APIs.

  • XAPI inbound response parsing API usage sample code.

  • XAPI error handling APIs.

See Also:

16.5.1 Understanding JD Edwards EnterpriseOne-to-EnterpriseOne Connectivity

The XAPI structure provides the capability for two different JD Edwards EnterpriseOne systems to communicate with each other. The first JD Edwards EnterpriseOne system (XAPI originator) generates a XAPI request (event). Instead of the request being distributed to a third-party system, JDENET sends the request to a second JD Edwards EnterpriseOne system. A JD Edwards EnterpriseOne to JD Edwards EnterpriseOne XAPI event must be sent through a subscriber with the JDENET transport type. The second JD Edwards EnterpriseOne system (XAPI executor) processes the event and returns a response to the first JD Edwards EnterpriseOne system (XAPI originator).

16.5.1.1 Modify Element Name for XML Documents

Before XAPI event processing, any document that was sent from JD Edwards EnterpriseOne was considered to be a response document, and any document coming in to JD Edwards EnterpriseOne was considered to be a request document. However, with XAPI, request documents are generated by the JD Edwards EnterpriseOne originating system and can be sent to a JD Edwards EnterpriseOne executor system. Response documents are generated and sent out by the JD Edwards EnterpriseOne executor system and received by the JD Edwards EnterpriseOne originating system. To support XAPI and to enable the XML dispatch kernel to be able to distinguish between a response and reply, JD Edwards created these type attributes to be used with the jdeResponse element:

Element and Type Attribute Description
jdeResponse=RealTimeEvent Use this element and attribute to identify a XAPI request that is sent from the JD Edwards EnterpriseOne originating system and sent to the JD Edwards EnterpriseOne executor system.
jdeResponse=xapicallmethod Use this element and attribute to identify a XAPI response that is sent from the JD Edwards EnterpriseOne executor system and sent to the JD Edwards EnterpriseOne originating system.

When the XML Dispatch kernel receives a document with the jdeResponse element and a RealTimeEvent or xapicallmethod type attribute, XML Dispatch sends the document to the XML Service kernel. XML Service can distinguish a response or a reply based on the type attribute that is associated with the jdeResponse element and then processes the document appropriately.

16.5.1.2 Security for Originator and Executor

Access to the JD Edwards EnterpriseOne originator and JD Edwards EnterpriseOne executor systems is based on:

  • Security token

  • Environment

  • Role

The JD Edwards EnterpriseOne originating system verifies that the security information is valid and creates an hUser object with an encrypted token to send to the JD Edwards EnterpriseOne executor. Encryption APIs (jdeEncypher and jdeDecypher) are used to encrypt and decode the password. The security information is sent in the XAPI request XML document.

Note:

The user ID, password, environment, and role must be the same on both JD Edwards EnterpriseOne systems (originator and executor).

16.5.1.3 Error Processing for Originator and Executor

You might encounter these two errors during XAPI error processing between two JD Edwards EnterpriseOne systems:

Type of Error Explanation
Business-related errors The business function or the business function specs cannot be found.
System errors These errors occur in other parts of the system (for example, message delivery failure).

The system handles XAPI error processing for business-related errors in these ways:

  • XAPI logs business-related errors in the JD Edwards EnterpriseOne server log, and the errors are delivered as part of the XAPI reply

  • XAPI APIs parse business errors from the response document.

  • XAPI logs all information that is available about the error in the JD Edwards EnterpriseOne server log.

16.5.2 XAPI Outbound Request Handling APIs

These outbound request handling APIs are available for you to generate a JD Edwards EnterpriseOne-to-EnterpriseOne XAPI outbound request:

  • jdeXMLRequest_GetDSCount

  • jdeXMLRequest_GetDSName

  • jdeXMLRequest_ParseDS

  • jdeXMLRequest_DeleteXML

  • jdeXMLRequest_ParseNextDSByName

  • jdeXMLRequest_PrepareDSListForIterationByName

16.5.3 XAPI Outbound Request Parsing API Usage Sample Code

This code sample shows the API usage for parsing an outbound request by the JD Edwards EnterpriseOne XAPI executor:

#include <jde.h>

#define b0000310_c


/*****************************************************************************
*    Source File:  b0000310
*
*    Description:  Company Real Time Notification Outbound Wrapper Source File
*
*****************************************************************************/

#include <b0000310.h>
#include <B4206030.h>
#include <B4206000.h>
/**************************************************************************
*  Business Function:  CompanyRealTimeWrapper
*
*        Description:  Company Real Time Notification Outbound Wrapper
*
*         Parameters:
*           LPBHVRCOM           lpBhvrCom    Business Function Communications
*           LPVOID              lpVoid       Void Parameter - DO NOT USE!
*           LPDSD0000310A        lpDS         Parameter Data Structure Pointer  
*
*************************************************************************/

      int iXMLRecordCount = 0;
      int iCurrentRecord = 0;
      NID nidDSName;
      ID idReturnValue = ER_SUCCESS;
      ID idSORecordCount = ER_ERROR; /*Return Code*/
      LPDSD4206000A lpDS;
      int lpmnJobNumber;

      MATH_NUMERIC mnBatchNumber = {0};
      unsigned long lBatchNumber = {0};
      DSD4206030A dsD4206030A = {0};
      
      /* CacheProcessInboundDemandRequest B4206030.c */
      DSD4206000I dsD4206000I = {0};
      
      /* Demand scheduling inbound DSTR */
      iXMLRecordCount = jdeXMLRequest_GetDSCount(lpDS->szXMLHandle);
      if( iXMLRecordCount > 0)
      {
            for ( iCurrentRecord = 0; iCurrentRecord < iXMLRecordCount; iCurrentRecord++)
            {
                  memset((void *)(&dsD4206000I), (int)(_J('\0')), sizeof(DSD4206000I));
                  memset((void *)(nidDSName), (int)(_J('\0')), sizeof(NID));
                  if(jdeXMLRequest_GetDSName(lpDS->szXMLHandle,iCurrentRecord,nidDSName))
                  {
                        /* Retrieving data*/
                        if (jdeStricmp(nidDSName, (const JCHAR *)_J("D40R0180B")) == 0)
                        {
                              if (jdeXMLRequest_ParseDS(lpDS->szXMLHandle,iCurrentRecord,
&dsD4206000I,sizeof(DSD4206000I)))
                              {
                                    /* Get next number for the batch number of the inbound INVRPT 
record*/
                                    if ( dsD4206000I.cInventoryAdvisement == _J('1'))
                                    {
                                          lBatchNumber = JDB_GetInternalNextNumber();
                                          LongToMathNumeric(lBatchNumber, &mnBatchNumber);
                                          FormatMathNumeric(dsD4206000I.szBatch,&mnBatchNumber);
                                    }
                                    /* Setup cancel flag for pending delete record */
                                    if ( dsD4206000I.cPendingDelete == _J('1'))
                                    {
                                          /* Flag set as 1 for any cancel demand record */
                                          dsD4206000I.cCancelFlag = _J('1');
                                    }
                                    else
                                    { /* Flag set as 9 for any non cancel demand record */
                                          dsD4206000I.cCancelFlag = _J('9');
                                    }
                                    /* Load parms for cache */
                                    //memset((void *)(&dsD4206030A), (int)(_J('\0')), 
sizeof(DSD4206030A));
                                    I4206000_LoadParmsToCache(&dsD4206000I, &dsD4206030A);
                                    MathCopy(&dsD4206030A.mnJobnumberA, lpmnJobNumber);
                                    /* Add the DSTR to cache */
                                    idReturnValue = jdeCallObject( _J("CacheProcessInboundDemand
Request") ,(LPFNBHVR)NULL ,lpBhvrCom ,lpVoid ,(LPVOID)&dsD4206030A,
(CALLMAP *)NULL, (int)0,(JCHAR*)NULL ,(JCHAR*)NULL ,(int)0 );
                                    /* Write XML DSTR to cache fail */
                                    if (idReturnValue == ER_ERROR)
                                    {
                                          jdeErrorSet(lpBhvrCom, lpVoid, (ID)0, _J("032E"), (LPVOID)NULL);
                                    }
                              }
                              else
                              { /* warning XML parse fail */
                                    jdeErrorSet(lpBhvrCom, lpVoid, (ID)0, _J("40R46"), (LPVOID) NULL);
                              }
                        } /* end if */
                  }/* end if DS name */
            }/* end for - looping all matching XML DSTR */
            /* Ensure there is at least one record */
            idSORecordCount = ER_SUCCESS;
      }/*if( iXMLRecordCount > 0) */
      return idSORecordCount;

16.5.4 XAPI Inbound Response Generation APIs

These outbound request handling APIs are available for you to generate a JD Edwards EnterpriseOne-to-EnterpriseOne XAPI outbound request:

  • jdeXAPIResponse_SimpleSend

  • jdeXAPIResponse_Init

  • jdeXAPIResponse_Add

  • jdeXAPIResponse_Finalize

  • jdeXAPIResponse_Free

16.5.5 XAPI Inbound Response Parsing API Usage Sample Code

This code sample shows the API usage for generating an inbound response from the JD Edwards EnterpriseOne XAPI executor to the JD Edwards EnterpriseOne originator:

JDEBFRTN (ID) JDEBFWINAPI SendOrderPromiseRequest (LPBHVRCOM lpBhvrCom, 
LPVOID lpVoid, LPDSD4205010 lpDS)
{
/****************************************************************
 * Variable declarations
****************************************************************/
  char    cPromisableLine          = ' ';
  int     nHeaderBackOrderAllowed  = ' ';
  HUSER   hUser;
  ID      JDEDBResult              = JDEDB_PASSED;
  BOOL    bExit                    = FALSE;   
  BOOL    bB4001040Called          = FALSE;
  BOOL    bXAPIInUse               = FALSE;
  BOOL    bAtLeastOneDetail        = FALSE;
  
  #ifdef jdeXAPI_CALLS_ENABLED
  XAPI_CALL_ID ulXAPICallID        = 0;
  XAPI_CALL_RETURN eXAPICallReturn = eEventCallSuccess;
  #endif
/****************************************************************
 * Declare structures
****************************************************************/
  DSD4001040   dsD4001040     = {0};
  DSD4205020   dsD4205020     = {0};
  DSD4205040   dsD4205040     = {0}; /* Header Info */
  DSD4205050   dsD4205050     = {0}; /* Detail Info */
  DSD4205010A   dsD4205010A   = {0}; /* Query Header */
  DSD4205010B   dsD4205010B   = {0} /* Query Detail */
  DSD0100042   dsD0100042     = {0};
  LPDSD4205040H  lpDSD4205040H    = (LPDSD4205040H) NULL;
  LPDSD4205050D  lpDSD4205050D    = (LPDSD4205050D) NULL;
  
/****************************************************************
 * Declare pointers
****************************************************************/
/****************************************************************
 * Check for NULL pointers
****************************************************************/
if ((lpBhvrCom == (LPBHVRCOM) NULL) ||
 (lpVoid == (LPVOID)  NULL) ||
 (lpDS == (LPDSD4205010) NULL))
{
jdeErrorSet (lpBhvrCom, lpVoid, (ID) 0, "4363", (LPVOID) NULL);
return ER_ERROR;
}

/* Retrieving hUser */
JDEDBResult = JDB_InitBhvr (lpBhvrCom, &hUser, (char *)NULL, 
JDEDB_COMMIT_AUTO ) ;

if ( JDEDBResult == JDEDB_FAILED )
{
jdeSetGBRError ( lpBhvrCom, lpVoid, (ID) 0, "4363" ) ;
return ER_ERROR ;
}
/****************************************************************
 * Set pointers
****************************************************************/
/****************************************************************
 * Main Processing
****************************************************************/
 /*-----------------------------------------------------*/
 /* Setting Up ErrorCode
      */
 lpDS->cErrorCode = '0';
 /*-----------------------------------------------------*/
 /* Determining if XAPI is ready to be used             */
               
 bXAPIInUse = FALSE;          
    
 #ifdef jdeXAPI_CALLS_ENABLED
 if(jdeXAPI_IsCallTypeEnabled("XAPIOPOUT") &&
     jdeXAPI_IsCallTypeEnabled("XAPIOPIN") )
 {          
     bXAPIInUse = TRUE;
 }
 #endif

 /*------------------------------------------------------*/
 /* Data validation and default values.                  */
 /* When Display Before Accept Mode is on, validate Key  */
 /* Information. Otherwise retrieve it from Header Record*/

 if((lpDS->cDisplayBeforeAcceptMode == '1')   &&
      ((MathZeroTest(&lpDS->mnOrderNumber) == 0) ||
       (IsStringBlank(lpDS->szOrderType))   ||
       (IsStringBlank(lpDS->szOrderCompany))))
 {  
      bExit = TRUE;
 }
 else
 {
     MathCopy(&dsD4205040.mnOrderNumber,&lpDS->mnOrderNumber);
     strncpy(dsD4205040.szOrderType,
       lpDS->szOrderType,
        sizeof(dsD4205040.szOrderType));
     strncpy(dsD4205040.szComputerID,
       lpDS->szOrderCompany,
        sizeof(dsD4205040.szOrderCompany));
     dsD4205040.cUseCacheOrWF = lpDS->cUseCacheOrWF;
     strncpy(dsD4205040.szComputerID,
       lpDS->szComputerID,
        sizeof(dsD4205040.szComputerID));
     MathCopy(&dsD4205040.mnJobNumber,&lpDS->mnJobNumber);
     jdeCallObject( "GetSalesOrderHeaderRecord",
          NULL,
          lpBhvrCom, lpVoid,
          (LPVOID)&dsD4205040,
          (CALLMAP *) NULL,
          (int) 0,
          (char *) NULL,
          (char *) NULL,
          (int) 0 ) ;

     lpDSD4205040H = (LPDSD4205040H)jdeRemoveDataPtr(hUser,
(ulong)dsD4205040.idHeaderRecord);

     if (lpDSD4205040H == NULL)
     {
          bExit = TRUE;
     }
 }

 /*-----------------------------------------------------*/
 /* Set error if exiting at this point                  */  
 if (bExit == TRUE)
 {
     lpDS->cErrorCode = '1';
     /* Sales Order Header Not Found */
     strncpy(lpDS->szErrorMessageID,
        "072T",
          sizeof(lpDS->szErrorMessageID));
     if (lpDS->cSuppressError != '1')
     {
        jdeErrorSet (lpBhvrCom, lpVoid, (ID) 0, "072T", (LPVOID) NULL);
     }
 }

 /*-----------------------------------------------------*/
 /* Default Promising Flag is always 1                  */
 lpDS->cDefaultPromisingFlags = 1;
 if (bExit == FALSE)
 {
  /*-----------------------------------------------------*/
  /* Call XAPIInit   */
  #ifdef jdeXAPI_CALLS_ENABLED
  if(bXAPIInUse == TRUE)
  {
     ulXAPICallID = jdeXAPI_Init( lpBhvrCom,
                   SendOrderPromiseRequest,
                "XAPIOPOUT",
                NULL,
                &eXAPICallReturn);
     if (eXAPICallReturn != eEventCallSuccess)
     {
          bExit = TRUE;
     }
  }
  #endif
  if (bExit == FALSE)
  {

     /*------------------------------------------------*/
     /* Loading Header Information                     */
     I4205010_PopulateQueryHeader(lpDS,&dsD4205010A
       lpDSD4205040H,&dsD0100042,hUser,lpVoid,lpBhvrCom);
     nHeaderBackOrderAllowed = dsD4205010A.nAllowBackorders;

     /*-------------------------------------------------*/
     /* Adding Header Information                       */
     #ifdef jdeXAPI_CALLS_ENABLED
     if(bXAPIInUse == TRUE)
     {
        eXAPICallReturn = jdeXAPI_Add( lpBhvrCom,
                   ulXAPICallID,
                   "SendOrderPromiseRequest",
                   "D4205010A",
                   &dsD4205010A,
                   sizeof(DSD4205010A));
        if (eXAPICallReturn != eEventCallSuccess)
        {
           bExit = TRUE;
        }
     }
     #endif
  }
 }
 if (bExit == FALSE)
 {

  /*-----------------------------------------------------*/
  /* Loading Detail Information                          */ 
  MathCopy(&dsD4205050.mnOrderNumber,&lpDS->mnOrderNumber);
  strncpy(dsD4205050.szOrderType,lpDS->szOrderType,
              sizeof(dsD4205050.szOrderType));
  strncpy(dsD4205050.szOrderCompany,lpDS->szOrderCompany,
              sizeof(dsD4205050.szOrderCompany));
  dsD4205050.cUseCacheOrWF = lpDS->cUseCacheOrWF;
  strncpy(dsD4205050.szComputerID,lpDS->szComputerID,
              sizeof(dsD4205050.szComputerID));
  MathCopy(&dsD4205050.mnJobNumber,&lpDS->mnJobNumber);
  if (lpDSD4205040H->cActionCode != 'A')
  {
     dsD4205050.cCheckTableAfterCache = '1';
  }
  else
  {
     dsD4205050.cCheckTableAfterCache = '0';
  }
  jdeCallObject( "GetSalesOrderDetailRecordOP",
     NULL,
     lpBhvrCom, lpVoid,
     (LPVOID)&dsD4205050,
     (CALLMAP *) NULL,
     (int) 0, (char *) NULL,
     (char *) NULL, (int) 0 ) ;

  if (dsD4205050.cRecordFound != '1')
  {
     bExit = TRUE;
     lpDS->cErrorCode = '1';

     /* Sales Order Detail Not Found */
     strncpy(lpDS->szErrorMessageID,"4162",
              sizeof(lpDS->szErrorMessageID));
     if (lpDS->cSuppressError != '1')
     {
        jdeErrorSet (lpBhvrCom, lpVoid, (ID) 0, "4162", (LPVOID) NULL);
     }
  }
  while ((dsD4205050.cRecordFound == '1') && (bExit == FALSE))
  {
     lpDSD4205050D = (LPDSD4205050D)jdeRemoveDataPtr( hUser, 
(ulong)dsD4205050.idDetailRecord);
     /* Reset flags */
     cPromisableLine = '0';     
     bB4001040Called = FALSE;

     /*-------------------------------------------------*/
     /* Evaluate the Record from F4211 (cDataSource = 2)*/   
     /*  to find out if we should promise the line      */
     /*  else find out from Order Promising Detail.     */

     if(dsD4205050.cDataSource == '1')
     {
        if (lpDSD4205050D->cOPPromiseLineYN == 'Y')
        {
           cPromisableLine = '1';
        }
     }
     else if(dsD4205050.cDataSource == '2')
     {     
        MathCopy ( &dsD4001040.mnShortItemNumber,
             &lpDSD4205050D->mnShortItemNumber);
        strncpy ( dsD4001040.szBranchPlant,
           lpDSD4205050D->szBusinessUnit,
              sizeof(dsD4001040.szBranchPlant));
                
        jdeCallObject  ( "GetItemMasterDescUOM",
                 NULL,
                 lpBhvrCom, lpVoid,
                  (LPVOID)&dsD4001040,
                  (CALLMAP *) NULL,
                  (int) 0, (char *) NULL,
                  (char *) NULL, (int) 0 ) ;
       
        bB4001040Called = TRUE;
       
        cPromisableLine = I4205010_IsLinePromisable(lpBhvrCom,lpVoid,
                   hUser,lpDS,lpDSD4205050D, dsD4001040.cStockingType);
     }
     if (cPromisableLine == '1')
     {

       /* Set this flag if at least one promisable */
       /*   detail record exists.                  */
       bAtLeastOneDetail = TRUE;

       if (bB4001040Called == FALSE)
       {
         MathCopy (&dsD4001040.mnShortItemNumber,
              &lpDSD4205050D->mnShortItemNumber);
         strncpy ( dsD4001040.szBranchPlant,
              lpDSD4205050D->szBusinessUnit,
              sizeof(dsD4001040.szBranchPlant));
                
       jdeCallObject  ( "GetItemMasterDescUOM",
                NULL,
                lpBhvrCom, lpVoid,
                (LPVOID)&dsD4001040,
                (CALLMAP *) NULL,
                (int) 0, (char *) NULL,
                (char *) NULL, (int) 0 ) ;
       }

       I4205010_PopulateQueryDetail( lpDS,&dsD4205010B,
                   lpDSD4205050D,
                &dsD4001040,
                &dsD4205010A,
                   &dsD0100042,
                cPromisableLine,
                   hUser,
                   lpVoid,
                lpBhvrCom);

       #ifdef jdeXAPI_CALLS_ENABLED
       if(bXAPIInUse == TRUE)
       {
         eXAPICallReturn = jdeXAPI_Add( lpBhvrCom,
                   ulXAPICallID,
                   "SendOrderPromiseRequest",
                   "D4205010B",
                   &dsD4205010B,
                   sizeof(DSD4205010B));
         if (eXAPICallReturn != eEventCallSuccess)
         {
              bExit = TRUE;
         } 
       }
       #endif
     }
   
     /*-------------------------------------------------*/
     /* Fetching the next Detail Record         */
     MathCopy(&dsD4205050.mnOrderNumber,&lpDS->mnOrderNumber);
     strncpy(dsD4205050.szOrderType,lpDS->szOrderType,
               sizeof(dsD4205050.szOrderType));
     strncpy(dsD4205050.szOrderCompany,lpDS->szOrderCompany,
              sizeof(dsD4205050.szOrderCompany));
     dsD4205050.cUseCacheOrWF = lpDS->cUseCacheOrWF;
     strncpy(dsD4205050.szComputerID,lpDS->szComputerID,
              sizeof(dsD4205050.szComputerID));
     MathCopy(&dsD4205050.mnJobNumber,&lpDS->mnJobNumber);
     if (lpDSD4205040H->cActionCode != 'A')
     {
        dsD4205050.cCheckTableAfterCache = '1';
        }
        else
        {
            dsD4205050.cCheckTableAfterCache = '0';
        }
        jdeCallObject( "GetSalesOrderDetailRecordOP",
                NULL,
                lpBhvrCom, lpVoid,
                (LPVOID)&dsD4205050,
                (CALLMAP *) NULL,
                (int) 0, (char *) NULL,
                (char *) NULL, (int) 0 ) ;
     }
     if (!bAtLeastOneDetail)
     {
        bExit = TRUE;
        lpDS->cErrorCode = '1';
        /* Sales Order Detail Not Found */
        strncpy(lpDS->szErrorMessageID,"4162",
                sizeof(lpDS->szErrorMessageID));
        if (lpDS->cSuppressError != '1')
        {
           jdeErrorSet (lpBhvrCom, lpVoid, (ID) 0, "4162", (LPVOID) NULL);
        }
     }
     if (bExit == FALSE)
     {
        #ifdef jdeXAPI_CALLS_ENABLED
        if(bXAPIInUse == TRUE)
        {
           eXAPICallReturn = jdeXAPI_Finalize( lpBhvrCom,
                   ulXAPICallID,
                   "SendOrderPromiseRequest",
                   "OrderPromiseCallback)";
           if (eXAPICallReturn != eEventCallSuccess)
           {
              bExit = TRUE;
           }
        }
        #endif
     }

     /*-------------------------------------------------*/
     /* Call B4205020 in Add Mode                       */
     if((bExit == FALSE) &&
         (lpDS->cDisplayBeforeAcceptMode != '1') &&
         (lpDS->cUseCacheOrWF == '2'))
     {
         MathCopy(&dsD4205020.mnOrderNumber,&lpDS->mnOrderNumber);
         strncpy(dsD4205020.szOrderType,lpDS->szOrderType,
              sizeof(dsD4205020.szOrderType));
         strncpy(dsD4205020.szOrderCompany,lpDS->szOrderCompany,
              sizeof(dsD4205020.szOrderCompany));
        strncpy(dsD4205020.szComputerID,lpDS->szComputerID,
              sizeof(dsD4205020.szComputerID));
        MathCopy(&dsD4205020.mnJobNumber,&lpDS->mnJobNumber);
    
        jdeCallObject( MaintainOPWorkFile,
            NULL,
            lpBhvrCom, lpVoid,
            (LPVOID)&dsD4205020,
            (CALLMAP *) NULL,
            (int) 0, (char *) NULL,
            (char *) NULL, (int) 0 ) ;
     }
  }

/***************************************************************
 * Function Clean Up
****************************************************************/
  #ifdef jdeXAPI_CALLS_ENABLED
  if (eXAPICallReturn != eEventCallSuccess)
  {
   /*-----------------------------------------------------*/
   /* CleanUp */
   if(bXAPIInUse == TRUE)
   {   
    jdeXAPI_Free( lpBhvrCom,
        ulXAPICallID,
        "SendOrderPromiseRequest");
   }

   lpDS->cErrorCode = '1';
   /* System Error - no reasonable error messages exist. */
   strncpy(lpDS->szErrorMessageID,"018Y",
                sizeof(lpDS->szErrorMessageID));
   if (lpDS->cSuppressError != '1')
   {
       jdeErrorSet (lpBhvrCom, lpVoid, (ID) 0, "018Y", (LPVOID) NULL);
   }
  }
  #endif
  if(lpDSD4205040H != (LPDSD4205040H)NULL)
  {
     jdeFree((void *)lpDSD4205040H);
  }
  if(lpDSD4205050D != (LPDSD4205050D)NULL)
  {
     jdeFree((void *)lpDSD4205050D);
  }
 return (ER_SUCCESS);
}

16.5.6 XAPI Error Handling APIs

These APIs are used for error handling in the XAPI executor system.

  • jdeXML_CheckSystemError

    The check system error API is for system errors. It tells the JD Edwards EnterpriseOne originator system that a system error occurred in the JD Edwards EnterpriseOne executor system:

  • jdeXML_GetErrorCount

  • jdeXML_SetErrors

    The get error count and set errors APIs are for business errors. These two APIs, when used together, find the number of business errors and then send the errors to the BHVRCOM structure for you to resolve.

16.6 Mapping a Business Function

This section provides an overview of mapping business functions and discusses how to add mapping information.

16.6.1 Understanding how to Map a Business Function

When the JD Edwards EnterpriseOne executor system receives an event from the JD Edwards EnterpriseOne originator, the JD Edwards EnterpriseOne executor needs to know what business function or system API to invoke to process the request. You must map the business function or system API to the XAPI event name. You map business functions and system APIs in the F907012 table. You use the Event Request Definition program (P907012) to map business functions and APIs.

If you are mapping business functions, you enter the name of the business function. If you are mapping APIs, you must enter the name of the API and the library where it is defined. In addition, the signature of the API must be made common, similar to the business function.

Mapping business functions enables you to point a XAPI event to a business function or system API that you wrote. You do not need to modify source code of a business function that JD Edwards delivered to you.

16.6.2 Forms Used to Add Mapping Information

Form Name FormID Navigation Usage
Work With Definition W907012A Enter P907012 in the Fast Path Command Line. Locate and review existing mappings.
Request Definition W907012B On Work With Definition, click Add. Add or change business function or API mapping for the XAPI event.

16.6.3 Adding Mapping Information

Access the Request Definition form.

Event Name

The name of the event (for example JDERTSOOUT). Some events are part of other events.

BSFN Definition

An option that specifies the type of processing for an event.

API Definition

An option that specifies the type of processing for an event.

When you select the API definition option, the DLL Name field appears on the form.

Function Name

The actual name of the function. It must follow standard ANSI C naming conventions (for example, no space between words).

DLL Name

Specifies the name of the database driver file. This file is specified in the [DB SYSTEM SETTINGS] section of the enterprise server jde.ini file. The file you specify depends upon the platform and the database. Values for specific machines and databases are:

DBDR: IBM i to DB2 for IBM i

JDBNET: IBM i to any other server DBMS

libjdbnet.so: HP-UX to DB2 for IBM i

libjdbnet.so: HP-UX to Microsoft SQL Server on Windows

libora80.so: HP-UX to Oracle (Version 11) UNIX

libjdbnet.so: AIX to DB2 for IBM i

libjdbnet.so: AIX to Microsoft SQL Server

jdbodbc.dll: Intel to DB2 for IBM i

dbodbc.dll: Intel to Microsoft SQL Server on Windows