Saturday, August 27, 2016

Job to calculate batch duration

In support role, batch duration value is used when we need to plan batch schedule. I will show the simple code to find it.

Below picture tell us, the average duration of this batch is 14.02 seconds.







Simple code is here.

Before run it, check these points:

  • Name of job(Batch)
  • Output file location
  • Capturing time (From.. To..)


Have a nice day! :)

static void checkTimeDiff(Args _args)
{
    // ------------- Declaration -------------
    BatchJob            batchJob;
    BatchJobHistory     batchJobHistory,
                        batchJobHistoryNonDaily;
    BatchCaption        jobName;

    int                 i=0,
                        iMax=0,
                        posOfDot,
                        numPerJob;
    int64               numOfSecs;
    Real                sumPerJob,
                        avgValue;

    container           listOfJobName   = ['aaaaa', 
                                           'bbbbb'
                                           ],
                        recurrenceData;   

    date                parmBeginDate,
                        parmEndDate;
    utcDateTime         utcStartDate,
                        utcEndDate,
                        utcParmBeginDate,
                        utcParmEndDate;
    TimeOfDay           recurTime;
    str                 strCaption,
                        strDescription,
                        strRecurPeriod,
                        strRecurTime,
                        strCurStartEnd,
                        strStart,
                        strEnd,
                        strPerJob,
                        strBatchStatus;

    // Declaration: CSV file
    CommaTextIo file;
    container           line,
                        lineHeader      = ['Job Name', 'Start time', 'End time', 'Diff', 'Status'];    
    CustTable custTable;
    #define.filename(@'C:\Test\checkTimeDiff.csv')
    #File
    ;


    // ------------- Process -------------

    // Check file availability
    file = new CommaTextIo(#filename, #io_write);
    if (!file || file.status() != IO_Status::Ok)
    {
       throw error("File cannot be opened.");
    }

    
    parmBeginDate   = 01\07\2016;    // it's 01-Jul-2016
    parmEndDate     = 31\07\2016;    // it's 31-Jul-2016    


    utcParmBeginDate  = DateTimeUtil::newDateTime(parmBeginDate,0);
    utcParmEndDate    = DateTimeUtil::newDateTime(parmEndDate,86400);    
    

    // Write header
    line = lineHeader;
    file.writeExp(line);

    // Write line
    iMax = conLen(listOfJobName);
    while (i < iMax)
    {
        i++;
        jobName = conPeek(listOfJobName,i);
        batchJob = null;
        batchJobHistory = null;

        select  *
        from    batchJob
        where   batchJob.Caption == jobName && batchJob.Status == BatchStatus::Waiting;       
        
        numPerJob = 0;
        sumPerJob = 0.0;
        avgValue  = 0.0;
        while 
        select  *
        from    batchJobHistory
            order by    batchJobHistory.EndDateTime desc
            where       batchJobHistory.BatchJobId == batchJob.RecId  &&
                        batchJobHistory.StartDateTime >= utcParmBeginDate && batchJobHistory.EndDateTime <= utcParmEndDate            
        {           
            numPerJob++;
            strCaption      = strFmt('"%1"',batchJob.Caption);
            numOfSecs       = DateTimeUtil::getDifference(batchJobHistory.EndDateTime, batchJobHistory.StartDateTime);
            sumPerJob       += numOfSecs;
            utcStartDate    = DateTimeUtil::applyTimeZoneOffset(batchJobHistory.StartDateTime, Timezone::GMTPLUS0700_BANGKOK_HANOI_JAKARTA);
            utcEndDate      = DateTimeUtil::applyTimeZoneOffset(batchJobHistory.EndDateTime, Timezone::GMTPLUS0700_BANGKOK_HANOI_JAKARTA);
            strStart        = strFmt('%1', utcStartDate);
            strEnd          = strFmt('%1', utcEndDate);        
            strBatchStatus  = strFmt('%1',batchJobHistory.Status);

            // Write to file
            line = [strCaption,
                    strStart,
                    strEnd,
                    strfmt('%1',numOfSecs),
                    strBatchStatus
                   ];
            file.writeExp(line);            
        }    
        avgValue = sumPerJob / numPerJob;
        // Write to file
        line = [strCaption,
                '',
                '',
                strfmt('%1',avgValue),
                ''
                ];
        file.writeExp(line);

        
    }

    info('Done');

}

AX Retail(POS) logical topology

Hi, Retail module of AX 2012 comes up with a lot of details. I'm showing below its logical topology. Without diagram connection, service accounts and etc. make me very headache. :-)

Basically, there are 2 type of connection from/to AX and retail components. Async is for batch transfer, day end transactions, etc. Real-time, as its name, it's for the connection need to do immediately.

The component naming vary to the app version. I'm writing this on AX 2012 R3.

Single store













Multi store