Sunday, February 16, 2014

Capturing infolog messages

I had a requirement to retrieve the content of infolog and store it in log tables, made to track the progress of a batch job and take action on any errors. I used the below method in a catch statement handling all unexpected errors and at the same time updating error log tables. The while loop retrieves all the infolog errors using SysInfologEnumerator and SysInfologMessageStruct infolog classes and concatenating a string with the error messages.

 private str getErrorStr()  
 {  
   SysInfologEnumerator enumerator;  
   SysInfologMessageStruct msgStruct;  
   Exception exception;  
   str error;  
   enumerator = SysInfologEnumerator::newData(infolog.cut());  
   while (enumerator.moveNext())  
   {  
     msgStruct = new SysInfologMessageStruct(enumerator.currentMessage());  
     exception = enumerator.currentException();  
     error = strfmt("%1 %2", error, msgStruct.message());  
   }  
   return error;  
 }  

And the catch statement calling the above method.

   catch (Exception::Error)  
   {  
     ttsbegin;  
     mmsStagingPurchImport.selectForUpdate(true);  
     mmsStagingPurchImport.Error = true;  
     mmsStagingPurchImport.ErrorLog = this.getErrorStr();  
     mmsStagingPurchImport.update();  
     ttscommit;  
     retry;  
   }  

Handy script to update storage & tracking dimension on an item

Below code snippet updates an item's storage and tracking dimensions.

 InventTableInventoryDimensionGroups::updateDimensionGroupsForItem(curext(), inventTable.ItemId,  
 5637144577,  
 5637144577);  

All you need is itemId and recIds of the storage and tracking dimensions to update, which can be found in EcoResStorageDimensionGroup and EcoResTrackingDimensionGroup tables holding the recIds of Storage and Tracking dimensions.

I had a recent requirement to make sure there are no itemIds in the system which dont have storage or tracking dimensions not set as I had to create and post some counting journals that  require these dimensions. Luckily all the items required the same storage and tracking dimensions so my job became easier.

I used the below job to run a while loop with notexists join finding out items that don't have these dimensions set and update the same.

 static void ScriptToUpdateStorageTrackingDimensions(Args _args)  
 {  
   InventTable                       inventTable;  
   EcoResStorageDimensionGroupItem   EcoResStorageDimensionGroupItem;  
   EcoResTrackingDimensionGroupItem  EcoResTrackingDimensionGroupItem;  
   int                               storageCount, trackingCount;  
   
     while select inventTable  
     notexists join EcoResStorageDimensionGroupItem  
     where EcoResStorageDimensionGroupItem.itemId == inventTable.itemId &&  
     EcoResStorageDimensionGroupItem.ItemDataAreaId == 'abc'  
   {  
     storageCount++;  
     InventTableInventoryDimensionGroups::updateDimensionGroupsForItem(  
       curext(), inventTable.ItemId,  
       5637144577,  
       0);  
   }  
     while select inventTable  
     notexists join EcoResTrackingDimensionGroupItem  
     where EcoResTrackingDimensionGroupItem.itemId == inventTable.itemId &&  
     EcoResTrackingDimensionGroupItem.ItemDataAreaId == 'abc'  
   {  
     trackingCount++;  
     InventTableInventoryDimensionGroups::updateDimensionGroupsForItem(  
       curext(), inventTable.ItemId,  
       5637144577,  
       5637144577);  
   }    
   //sw - storage - 5637144577  
   //none - tracking - 5637144577  
   info(int2str(storageCount));    
   info(int2str(trackingCount));  
   info('Done');   
 }