Tuesday, February 5, 2019

Customer transaction automatic settlement for specific customer groups only

Hi Friends,
Recently I come to the requirement of my company
where I have to automatic settle the customer transaction for
the specific group of customer, So here is the customization details,
May be it help to some one to understand the logic behind it.

Here basically we have to update settleVoucher (For journal in LedgerJournalTrans table and For Sales order invoice SalesTable) field with OpenTrasact (For Auto settlement) or None based on customer user group, All other posting done based on this field, Here are the class and table method used
LedgerJournalEngine (Class) - InitFromCustTable
LedgerJournalEngine_CustPayment (Class) - InitFromCustTable
SalesTableType (Class) - InitValue
LedgerJournalTrans (Table) - InitFromCustTable
LedgerJournalTrans (Table) - setSettleVoucher

Best Regards
B K Sharma | Dynamics AX Technical Architect |  My blog  | LinkedIn
Phone : 9950068421
Udaipur, India

Sunday, September 17, 2017

Microsoft Dynamics Ax 2012: Difference between modifiedField and modifiedFieldValue methods

Problem description
In a project for a customer I had an issue that some business logic didn’t work. During an import of related data we found out that everything in test and debugger worked fine, but it didn’t work in batch.
Solution
To solve this we moved the code from the modifiedFieldValue method to the modifiedField method and this solved the issue.
So this means that the code in the modifiedFieldValue isn’t executed in batch (CIL) which is different from the modifiedField method. This method is executed on the client, server and the batch.
I couldn’t find documentation on the internet about this. So be aware that the client execution of code can differ from the batch.

Reference : http://www.van-veldhuizen.eu/blog/2012/06/08/microsoft-dynamics-ax-2012-difference-between-modifiedfield-and-modifiedfieldvalue-methods/

Thanks

Thursday, September 14, 2017

Custom workflow in ax 2012

Dear Friends,

I have come to know a very good blog for a custom workflow in ax 2012, you can go to the blog reference and check

http://www.axpulse.com/dynamics-ax-2012-custom-workflow/

Thanks
B K Sharma

Monday, September 11, 2017

Upload excel data to Ax Table

Hi,

To upload excel data to ax table we use following x++ code

static void UploadExceldatatoTable(Args _args)
{
   SysExcelRange                       sysExcelRange;
   #AviFiles
   #define.Star('*')
   #define.ExcelDataRange("A1:IV65536")
   SysOperationProgress                _progressBar = new SysOperationProgress();
   int                                 record;
   DialogField                         dialogPath;
   Dialog                              dialog;
   Filename                            filename;
   CommaIO                             inFile;
   SysExcelApplication                 xlsApplication;
   SysExcelWorkBooks                   xlsWorkBookCollection;
   SysExcelWorksheets                  xlsWorkSheetCollection;
   SysExcelWorksheet                   xlsWorkSheet;
   SysExcelCells                       Cells;
   SysExcelCell                        RCell;
   int                                 nRow; //,i;
   NoYes                               _NoYes;
   TimeOfDay                           time;
   S3_FrequencyIdentifier                      _frequency;
   S3_EquipmentTypes                           eqptTypeMaster;
   WCL_bk_EqptTaskLastInspectionDate           _eqptTaskLastInspDate;
   WCL_SS_RouteEquipment                       _RouteEquipment;
   S3_EquipmentTable                           _eqptTable;
   WCL_InspectionCheckListHeader               _inspChkLstHeader;
   WCL_InspectionCheckListLines                _inspChkLstLine;
   #Excel
   // convert into str from excel cell value
   str COMVariant2Str(COMVariant _cv, int _decimals = 0, int _characters = 0, int _separator1 = 0, int _separator2 = 0)
   {
       switch (_cv.variantType())
       {
           case (COMVariantType::VT_BSTR) :
           return _cv.bStr();
           case (COMVariantType::VT_R4):
           return num2str(_cv.float(),_characters,_decimals,_separator1,_separator2);
           case (COMVariantType::VT_R8):
           return num2str(_cv.double(),_characters,_decimals,_separator1,_separator2);
           case (COMVariantType::VT_DECIMAL):
           return num2str(_cv.decimal(),_characters,_decimals,_separator1,_separator2);
           case (COMVariantType::VT_DATE):
           return date2str(_cv.date(),123,2,1,2,1,4);
           case (COMVariantType::VT_EMPTY):
           return "";
           default:
           throw error(strfmt("@SYS26908", _cv.variantType()));
       }
   return "";
   }
   ;
   dialog = new Dialog('Equipment task Last inspection date import');
   dialogPath = dialog.addField(extendedTypeStr(Filenameopen), 'File Name');
   dialog.run();
   if (dialog.run())
   {
       filename = (dialogPath.value());
   }
   inFile = new CommaIO (filename, 'R');
   if (!inFile || infile.status() != IO_Status::Ok )
   {
       throw error (strfmt("@SYS19312",filename));
   }
   try
   {
       xlsApplication          = SysExcelApplication::construct();
       xlsWorkBookCollection   = xlsApplication.workbooks();
       xlsWorkBookCollection.open(filename);
       xlsWorkSheetCollection  = xlsApplication.worksheets();
       xlsWorkSheet            = xlsWorkSheetCollection.itemFromNum(1);
       Cells                   = xlsWorkSheet.Cells();
       nRow = 2;
       RCell = Cells.Item(nRow, 1);
       sysExcelRange           = xlsWorkSheet.cells().range("A1:IV65536");
       sysExcelRange           = sysExcelRange.find(#Star, null, #xlFormulas, #xlWhole, #xlByRows, #xlPrevious);
       if (sysExcelRange)
       {
           record = sysExcelRange.row();
       }
       _progressBar.setCaption("Last inspection date uploading. . .");
       _progressBar.setAnimation(#AviUpdate);
       _progressBar.setTotal(record);
       ttsBegin;
       while (COMVariant2Str(RCell.value()) != "")
       {
           _progressBar.setText(strfmt("Step %1", nRow));
           _progressBar.setCount(nRow, 1);
           if(WCL_SS_RouteMaster::find(strLTrim(strRTrim(COMVariant2Str(Cells.item(nRow,1).value())))))
           {
               while select _RouteEquipment join _eqptTable join _inspChkLstHeader join _inspChkLstLine
                 where _RouteEquipment.EquipmentId           == _eqptTable.S3_EquipmentId &&
                       _eqptTable.EquipmentType              == _inspChkLstHeader.EquipmentType &&
                       _eqptTable.EquipmentSubType           == _inspChkLstHeader.EquipmentSubType &&
                       _inspChkLstHeader.CheckListHeaderID   == _inspChkLstLine.CheckListHeaderID &&
                       _RouteEquipment.RouteID               == strLTrim(strRTrim(COMVariant2Str(Cells.item(nRow,1).value()))) &&
                       _inspChkLstLine.Frequency             == _frequency
               {
                   if(!WCL_bk_EqptTaskLastInspectionDate::find(_RouteEquipment.EquipmentId, _inspChkLstLine.TaskCode))
                   {
                       _eqptTaskLastInspDate.EquipmentId           = _RouteEquipment.EquipmentId;
                       _eqptTaskLastInspDate.TaskCode              = _inspChkLstLine.TaskCode;
                       _eqptTaskLastInspDate.LastInspectionDate    = str2Date(strLTrim(strRTrim(COMVariant2Str(Cells.item(nRow,3).value()))),123);
                       _eqptTaskLastInspDate.insert();
                   }
               }
           }
           else
           {
               error(strFmt("%1 - Route not found in the master",strLTrim(strRTrim(COMVariant2Str(Cells.item(nRow,1).value())))));
           }
           nRow++;
           RCell = Cells.Item(nRow, 1);
       }
       ttsCommit;
       info("Equipment Task last inspection date uploaded successfully");
   }
   catch
   {
       error('Error!');
       xlsApplication.quit ();
       xlsApplication.finalize ();
       return;
   }
}

Thanks
B K Sharma

Print/Insert Image (.jpeg) object in SSRS Report (AX 2012 R3) attach via Document handling

Hi Friends,
I am presenting a process to print/Insert the Ax document handling attached image/file in a SSRS report in ax 2012 r3. Below example taken from purchase order attached file in document handling.

1. When we open purchase order list page than we can open document handling form from attachment menu item where we can add any type of file to this form, here we are attaching a image file.
2. After attachment of file now we want to print this image to our SSRS report, so basic method we are using to complete this task is to use image URL as image source in ssrs report. To get the image url we will use this query from DocuRef table and join it to the PurchTable
- This query is used in ProcessReport method of RDP class of SSRS report.

select docuRef where docuRef.RefCompanyId == PurchTable::find(vendInvoiceJour.PurchId).dataAreaId &&
docuRef.RefRecId == PurchTable::find("TestPO0001").RecId && 
docuRef.RefTableId == PurchTable::find("TestPO0001").TableId;

this table method will provide us the file url
DocuRef.CompleteFikleName() - after getting file name we will save it to our temp table of ssrs report.

3. Now open SSRS report design in visual studio and add an image in report body or footer as per our requirement and set the Image source property to External and add the dataset field (File path) here in expression (fx) and deploy the report, now it will display in your report.
after set this property just build and deploy report and we will get the attached image to the ssrs report.

Regards
B K Sharma

Thursday, April 9, 2015

Debug Batch job in Ax 2012

Debug Batch job in Ax 2012

Like services that you create in Microsoft Dynamics AX, batch jobs are compiled into CIL and run on the server. Therefore, you must use Visual Studio to debug batch jobs.
Batch jobs are used when you have code that you want to schedule to run at a specific time or in regular intervals. One example is if you have code that performs lots of processing that you want to run when the system is not heavily used. Code that runs as a batch job must be contained in a class that extends the RunBaseBatch class. For more information.
The process for debugging a batch job is similar to debugging a service. When you create your class in X++, you can use the standard Microsoft Dynamics AX debugger. To debug a class that is running as a batch job, you then use the Visual Studio debugger.
The high-level process for debugging a batch job from Visual Studio is as follows:
  1. Open Visual Studio. In Application Explorer, locate the batch job class and open the source code.
  2. Set a breakpoint in the code.
  3. Attach the Visual Studio debugger to the Microsoft Dynamics AX server process (Ax32Serv.exe).
  4. In Microsoft Dynamics AX, schedule the batch job that calls your class to run.
  5. When code execution hits the breakpoint that you set, the context switches to Visual Studio and you can continue to step through the code.

Thanks
B K

Thursday, November 6, 2014

Send report pdf as email in ax 2009 using batch job configuration

Hi friends,

if you want to send your report pdf as email to user through batch job than below code important for you.

First we have make a class for batch job configuration.

After it we have to save the file to server in a share folder using below method.


Static void SaveReport(str fileName)
{
    fileName = @'\\myPc\\testfile.pdf'; // it should be in UNC format
    Args                args = new Args("PMExceptionReport");
    reportRun reportRun = new reportRun(args);
    ;

    reportRun.query().interactive(False);
    reportRun.report().interactive(False);
    reportRun.setTarget(printMedium::File);
    reportRun.printJobSettings().setTarget(PrintMedium::File);
    reportRun.printJobSettings().preferredTarget(PrintMedium::File);
    reportRun.printJobSettings().format(PrintFormat::PDF);

    reportRun.printJobSettings().warnIfFileExists(False);
    reportRun.printJobSettings().suppressScalingMessage(True);
    reportRun.printJobSettings().packPrintJobSettings();
    reportRun.printJobSettings().fileName(filename);
    reportRun.run();
    //info("Done");
}

if our file is saved to shared folder than we can send it as mail attachment and for it code is listed below

static void SendMail(str email, str filename)
{
    InteropPermission permission = new InteropPermission(InteropKind::ComInterop);
    SysMailer   mailer;
    SysEmailParameters parameters;
    ;

    CodeAccessPermission::revertAssert();
    permission.assert();
    mailer = new SysMailer();
    parameters = SysEmailParameters::find();

    if (parameters.SMTPRelayServerName)
    {
        mailer.SMTPRelayServer(parameters.SMTPRelayServerName, parameters.SMTPPortNumber, parameters.SMTPUserName, SysEmailParameters::password(), parameters.NTLM);
    }
    else
    {
        mailer.SMTPRelayServer(parameters.SMTPServerIPAddress, parameters.SMTPPortNumber, parameters.SMTPUserName, SysEmailParameters::password(), parameters.NTLM);
    }

    mailer.fromAddress('donotreply@wondercement.com');
    mailer.tos().appendAddress(email);

    mailer.htmlBody('Please find attached exception report. <Br>\n do not reply this mail.');
    mailer.subject('Exception Report');
    mailer.attachments().add(filename);
    mailer.sendMail();

    CodeAccessPermission::revertAssert();
}


Printing reports from a server can be more efficient than printing from a client. When printing a report from a client, Microsoft Dynamics AX must upload details about page size, report dimensions, fonts, and string sizes to the client before the report can print. When printing a report from a server, these details are readily available. No extra processing is required.
To enable users to print reports from the server, you must configure the AOS server and each client.
Complete the following steps on the AOS server:
  1. Open the Server Configuration Utility (Start > All Programs > Microsoft Dynamics AX).
  2. Select the Allow clients to connect to printers on this server option.
  3. Click OK.
Complete the following steps on each client computer:
  1. Open the Client Configuration Utility (Start > All Programs > Microsoft Dynamics AX).
  2. Click the Connection tab.
  3. Select Connect to printers on the server.
  4. Click OK.

Thanks
B K 

Customer transaction automatic settlement for specific customer groups only

Hi Friends, Recently I come to the requirement of my company where I have to automatic settle the customer transaction for the speci...