Waiting for UBE completion

Null Value

Well Known Member
Hi List,

Environment: XE SP23

Scenario:-
1) A RF application outside of JDE needs to call R42500 - Ship Confirmation.
2) The RF application can only call JDE BSFNs and hence I've developed a custom C BSFN.
3) The BSFN is C and not NER because I'm using the jdeLaunchUBEEx api and also because I'm passing in some values thru report interconnect to R42500. The R42500 report interconnect has been modified for our needs.
4) After R42500 is completed, the control should pass to the RF application which will invoice the orders. This also means that the custom BSFN needs to wait until R42500 is processed so that the RF application finds the processed orders in the right status (ship confirmed) to be invoiced.

Issue:-
The custom BSFN (part of code attached) does call the R42500 but appears to complete before R42500 is completed. i.e the RF application tries to invoice orders which have not yet ship confirmed.

Steps attempted:-
1) I created a JDE application to test the C BSFN and this worked well. i.e R42500 was called and orders got ship confirmed.
2) I ran a debug on the C BSFN when called from this JDE application and found that it returned the correct job number of R42500 and did retrieve the correct job status.
3) I assumed that the perhaps the jdeSleepSeconds api was probably not working for some reason and hence forced the BSFN to wait for 30 seconds. This time the control was passed to the RF application after the orders were ship confirmed.

The portion of the C code is given below:-

/*--------------------------------------------------------------------
* Load API JDELaunchUBEex Structure
*-------------------------------------------------------------------*/
jdeNIDcpy((char *)pUbeVar->szReport,(const char *)"R42500");
strcpy((char *)pUbeVar->szVersion, (const char *)lpDS->szVersion_VERS);
memset ( szLocalComputerName, (char) '\0', sizeof ( szLocalComputerName ));
jdeGetHostName ( szLocalComputerName, sizeof ( szLocalComputerName ), (int) 0 );
strcpy((char *)pUbeVar->szMachineKey, (const char *)szLocalComputerName);

GetLocalEnvironmentName(pUbeVar->szEnhv, 11);

/* changes 16 bit value to 32 bit value*/
pUbeVar->idRunTime = (GLRTID)lpBhvrCom->hDlg << 16;

/* Run the UBE Synchronously */
pUbeVar->bSynchFlag = TRUE;

/* Run the UBE in Batch Mode i.e suppress display of Printer Selection at submission time */
pUbeVar->bBatchFlag = TRUE;

/* Do not display PDF output to screen */
pUbeVar->bPreview = FALSE;

/*--------------------------------------------------------------------
* Load R42500 Structure
*-------------------------------------------------------------------*/
memset((void *)&ds42500, (int)'\0', sizeof(ds42500));
strcpy((char *)ds42500.sz58CostCenter_MCU, (const char *)lpDS->szCostCenter_MCU);
strcpy((char *)ds42500.sz58RouteCode_ROUT, (const char *)lpDS->szRouteCode_ROUT);

/*--------------------------------------------------------------------
* Launch the UBE
*-------------------------------------------------------------------*/
idJDBReturn = jdeLaunchUBEEx((HUSER)hUser, (PUBEVAR)pUbeVar, (LPVOID)&ds42500, lpBhvrCom);

if(idJDBReturn != JDEDB_PASSED)
{
lpDS->cErrorFlag_EV01 = 'Y';
strcpy((char *)lpDS->szErrorCode_DTAI, (const char *)"110V");
JDB_CloseTable(hReqF986110);
JDB_FreeBhvr(hUser);
return ER_ERROR;
}
else
{
MathCopy(&mnJobNum, &pUbeVar->mnJobNum);
strcpy(szHostName, pUbeVar->szHostName);
/*--------------------------------------------------------------------
* Get report data source
* 1) Call FetchUBEMapping - N98305 2) Pass OBNM(szReport) and get DATP(szLogicalDataSource)
*-------------------------------------------------------------------*/
memset((void *)(&dsD98305A),(int)('\0'),sizeof(DSD98305A));
strcpy((char *)(dsD98305A.szReport),(const char *)("R42500"));
idReturnValue = jdeCallObject("FetchUBEMapping",
NULL, lpBhvrCom,lpVoid,(LPVOID)&dsD98305A,
(CALLMAP *)NULL,(int)0,(char *)NULL,
(char *)NULL,(int)0);
if(idReturnValue != 0)
{
lpDS->cErrorFlag_EV01 = 'Y';
strcpy((char *)lpDS->szErrorCode_DTAI, (const char *)"143M");
JDB_CloseTable(hReqF986110);
JDB_FreeBhvr(hUser);
return ER_ERROR;
}
strcpy((char *)szUbeDataSource,(const char *)dsD98305A.szLogicalDataSource);

/*--------------------------------------------------------------------
* Assign data source for Job Status table
* 1) Call SetF986110DS - B9861101 2) Pass the DATP retrieved earlier
*-------------------------------------------------------------------*/
memset((void *)(&dsD9861101),(int)('\0'),sizeof(DSD9861101));
strcpy(dsD9861101.szDatabasepath,szUbeDataSource);
idReturnValue = jdeCallObject("SetF986110DS",
NULL, lpBhvrCom,lpVoid,(LPVOID)&dsD9861101,
(CALLMAP *)NULL,(int)0,(char *)NULL,
(char *)NULL,(int)0);
if(idReturnValue != 0)
{
lpDS->cErrorFlag_EV01 = 'Y';
strcpy((char *)lpDS->szErrorCode_DTAI, (const char *)"143M");
JDB_CloseTable(hReqF986110);
JDB_FreeBhvr(hUser);
return ER_ERROR;
}

/*--------------------------------------------------------------------
* Fetch F986110 record for specified Jobnumber and execution host
* until record found
*-------------------------------------------------------------------*/
/* Open F986110 table */
JDBResult = JDB_OpenTable(hUser, szTableIDF986110, idIndexIDF986110, NULL, 0, NULL, &hReqF986110);
if(JDBResult != JDEDB_PASSED)
{
lpDS->cErrorFlag_EV01 ='Y';
strcpy((char *)lpDS->szErrorCode_DTAI, (const char *)"3003");
JDB_CloseTable(hReqF986110);
JDB_FreeBhvr(hUser);
return ER_ERROR;
}

/* Fetch record from F986110 */
strcpy(dsKeyF986110.jcexehost,szHostName);
MathCopy(&dsKeyF986110.jcjobnbr, &mnJobNum);

cLoopYN = 'Y';
while(cLoopYN == 'Y')
{
JDBResult = JDB_FetchKeyed(hReqF986110, idIndexIDF986110, &dsKeyF986110, 1, &dsReqF986110, FALSE);
if(JDBResult != JDEDB_PASSED)
{
/* No record in job status table yet, wait and fetch again */
/* if wait more than 3 minutes, exit with error */
timecnt = timecnt + 1;
if(timecnt > 12)
{
lpDS->cErrorFlag_EV01 ='Y';
strcpy((char *)lpDS->szErrorCode_DTAI, (const char *)"017F");
JDB_CloseTable(hReqF986110);
JDB_FreeBhvr(hUser);
return ER_ERROR;
}
#ifdef JDENV_AS400 /* AS400 only */
jdeSleepMilliSeconds(15000);
#else /* NT, Unix */
jdeSleepSeconds(15);
#endif
}
else
{
/* Record fetched and job completed */
if(!jdeIsBlankOrNull(dsReqF986110.jcjobsts) &&
(jdestrcmpwithnull(dsReqF986110.jcjobsts,"D")== 0 || jdestrcmpwithnull(dsReqF986110.jcjobsts,"E")== 0))
{
cLoopYN = 'N';
if(jdestrcmpwithnull(dsReqF986110.jcjobsts,"E")== 0)
{
/* Job ended in error, then throw error */
lpDS->cErrorFlag_EV01 ='Y';
strcpy((char *)lpDS->szErrorCode_DTAI, (const char *)"142R");
JDB_CloseTable(hReqF986110);
JDB_FreeBhvr(hUser);
return ER_ERROR;
}
}
else
{
timecnt = timecnt + 1;
/* if wait more than 3 minutes, exit with error */
if(timecnt > 12)
{
lpDS->cErrorFlag_EV01 ='Y';
strcpy((char *)lpDS->szErrorCode_DTAI, (const char *)"0264");
JDB_CloseTable(hReqF986110);
JDB_FreeBhvr(hUser);
return ER_ERROR;
}
#ifdef JDENV_AS400 /* AS400 only */
jdeSleepMilliSeconds(15000);
#else /* NT, Unix */
jdeSleepSeconds(15);
#endif
}
} /* else - record fetched */
} /* while */

/*--------------------------------------------------------------------
* Revert data source for Job Status table
*-------------------------------------------------------------------*/
strcpy(dsD9861101.szDatabasepath," ");
idReturnValue = jdeCallObject("SetF986110DS",
NULL, lpBhvrCom,lpVoid,(LPVOID)&dsD9861101,
(CALLMAP *)NULL,(int)0,(char *)NULL,
(char *)NULL,(int)0);
if(idReturnValue != 0)
{
lpDS->cErrorFlag_EV01 = 'Y';
strcpy((char *)lpDS->szErrorCode_DTAI, (const char *)"2039");
JDB_CloseTable(hReqF986110);
JDB_FreeBhvr(hUser);
return ER_ERROR;
}
}
}

----------------------------
Appreciate any help.

Regards,

Shailesh
 
This was a very complex question... I hope I understand it. If you are running a UBE from an application (of any kind), doesn't the OCM have to be set up to run locally, otherwise the UBE submits to a server and then it is running asynchronously? If you are submitting through BV, you normally are able to specify local but from an application you are not, so you have to set the OCM so that it runs locally.
 
The Ship Confirm UBE is submitted to the server as needed. I don't want it to run locally. But after the UBE is submitted to the server, my code checks the F986110 Job Status table for the UBE completed job status every 15 seconds upto a max of 3 minutes. If in any of these fetches, the job status turns out to be D or E, the control exits out of the fetch loop and my function ends.

So everything else is executing just fine - The RF application calls my function, my function calls R42500 and R42500 completes successfully. The issue is that despite checking the Job status table and waiting until the job gets done, my functions ends and the RF application gets control before F4211 statuses are updated.

So assumptions:-
1) The job status fetches are failing - not possible since I throw an error if this happens and this would have got caught.
2) The child UBE process within R42500 i.e R47500 which does the actual ship confirmation still continues - not possible since it completes before the Parent R42500 process completes. (I checked the timings and tested in debug).
3) The Ship Confirm End Doc function (which updates the F4211 status) maybe running asynch and thus even though R42500 gets completed, the Ship Confirm End Doc is not completed - not possible since it is called in Synch mode in R47500.
4) The JdeSleepAPI which is used to wait 15 secs before fetching F986110 record is failing - not possible as I forced a 30 second wait using it and my function did wait for 30 seconds before handing control to the RF application.
 
Maybe a typo on your part, but your JDB_FetchKeyed is only looking at 1 key field (the hostname) which could give you the results you are seeing. You could be fetching any 'D' or 'E' job record for the given hostname and your code thinks it is your job and continues on its merry way PRIOR to your job finishing.

Good luck.
 
And without testing it yet, you are probably RIGHT !! A typo which has caused much headache.

I'll soon make the change, test it and let you know.

Thank you.
 
And that did it, Jeremy. It worked. Many thanks for your help. Good Catch !!
 
curious why you didn't fetch from F986113, or is that being nit-picky (spelling?)....
 
Just followed standard JDE process and whatever I gathered from this forum.

Also, it would've been an easy thing if I could do it from a NER but the requirements about changing the R42500 data structure necessitated a C function.
 
I am attempting to do the same thing in 8.11 on 8.97. The N98305 is set as a client only BSFN and given the web environment, it has to be run on the server. I have looked at the code and there is no apparent reason for it to be client only. Via OMW you can't change the BSFN to a Client and Server function.

I could duplicate the functionality into a custom BSFN, but was wondering if anyone has come up with any other solution.

Thanks
 
Back
Top