Tuesday 28 August 2018

Chain of commands in D365

Using Chain of commands, we can  extend the logic of public and protected methods without having to use event handlers. When you wrap a method, you can also access public and protected methods, and variables of the base class.

First it goes to Standard method finds if there any extension method of same signature

and calls extension method then calls standard method if NEXT Word mentioned else

 It will not execute standard method. without NEXT word call

Rules


Ex :
[ExtensionOf(classStr(PurchLineType))]
final class PurchLineType_Extension

{


     public void initFromInventTable(
        InventTable     _inventTable,
        boolean         _searchPrice,
        boolean         _setAddressFromInventDim,
        boolean         _initDateFields,
        boolean         _executeOnlyIfProductIsFullySpecified)
    {
        InventTable     inventTable;
        purchline       purchlineLoc = purchline;
       
        if (purchlineLoc.itemId)
        {
            select DOMEndSupplier from inventTable
                where inventTable.ItemId == purchlineLoc.ItemId;

            purchlineLoc.EndSupplier = inventTable.EndSupplier;
        }

        next initFromInventTable(_inventTable, _searchPrice, _setAddressFromInventDim, _initDateFields, _executeOnlyIfProductIsFullySpecified);
    }

}
}

Tuesday 21 August 2018

Dimensions lookup based on dimension attribute name in D365

On Lookup Method


[FormControlEventHandler(formControlStr(EcoResCategory, EcoResCategory_DOMFinancialProductGroup), FormControlEventType::Lookup)]
    public static void EcoResCategory_DOMFinancialProductGroup_OnLookup(FormControl sender, FormControlEventArgs e)
    {
        EcoResProductParameters     ecoResProductParameters;

        select USMFFinancialProductGroup from ecoResProductParameters;

        DimensionValueLookupHelper::lookupDimensionValues(DimensionAttribute::findByName(ecoResProductParameters.USMFFinancialProductGroup), sender, curExt());

//USMFFinancialProductGroup can be BusinesUnit, Department, CostCenter etc
    }


Reference

https://community.dynamics.com/ax/b/dynamicsax7knowledge/archive/2016/10/17/dimension-lookup-in-ax7

Wednesday 4 July 2018

SSRS useful expression

Page 1 of 1

="Page " & Globals!PageNumber & " of " & Globals!TotalPages

Report header need to change based on report parameters


RowNumber() -- > to count no of rows in grid

Combating Blank Page in SSRS Reports – Dynamics AX 2012 (NEC Multiple pages fix solution)
https://community.dynamics.com/ax/b/axcasperkamals/archive/2013/11/07/ssrs-tips-combating-blank-page-in-ssrs-reports-dynamics-ax-2012

IF conditions

=IIF(Parameters!PurchaseReportDS_Include_Delivered.Value = true AND
Parameters!PurchaseReportDS_Include_Returns.Value = false AND
Parameters!PurchaseReportDS_Include_Invoiced.Value = false, "GOODS RECEIPT NOTE","PURCHASE REGISTER")

Multiple If Conditions

=IIF(Parameters!PurchaseReportDS_Include_Delivered.Value = true AND
        Parameters!PurchaseReportDS_Include_Returns.Value = false AND
Parameters!PurchaseReportDS_Include_Invoiced.Value = false, "GOODS RECEIPT NOTE",
IIF(Parameters!PurchaseReportDS_Include_Delivered.Value = false AND
Parameters!PurchaseReportDS_Include_Returns.Value = true AND
Parameters!PurchaseReportDS_Include_Invoiced.Value = false, "PURCHASE RETURN NOTE", "PURCHASE REGISTER"))


Monday 4 June 2018

Change Tracking in D365

Change tracking is a feature that enables incremental export of data from Microsoft Dynamics 365 for Finance and Operations, by using Data management.
In an incremental export, only records that have changed are exported. To enable incremental export, you must enable change tracking on entities. If you don't enable change tracking on an entity, you can enable only full export each time

Go to Data management >> Data entities >> select one entity >> Options >> Change tracking




Option
How changes are tracked
Enable primary table
Changes that are made to any fields in the primary table trigger a change in entity. Changes that are made to fields in secondary tables don't trigger a change in entity.
Enable entire entity
Changes that are made to any fields in any table in the entity trigger a change in entity.
Enable Custom query
Select a set of custom fields from any tables that must trigger a change in entity.

When adding an entity for data export, you have the ability to choose incremental export(called “incremental push”) or full push.
In an incremental push, only records that have changed are exported.
In an full push, all records will export.

In order for incremental push to work, you do need to enable Change tracking in the Dynamics AX database and specify an appropriate change tracking option as described above


Monday 23 April 2018

Create timesheet for worker using x++ code in Ax 2012 r3

static void TimesheetJob(Args _args)
{
     TSTimesheetTable            tsTimesheetTable;
    TSTimesheetLine             newTimesheetLine, existsTimesheetLine;

    ProjPeriodLine              projPeriodLine;
    HcmWorker                   worker;
    ProjPeriodTimesheetWeek     projPeriodTimesheetWeek, periodWeek;
    TSTimesheetLineWeek         lineWeek, existsLineWeek;
    DialogButton                dlgButton;
    Dialog                      dialog;
    DialogField                 dfFileName;
    //To filter the files while selecting
    container                   conFilter;
    FileIoPermission perm;
    SysExcelApplication         application;
    SysExcelWorkbooks           workbooks;
    SysExcelWorkbook            workbook;
    SysExcelWorksheets          worksheets;
    SysExcelWorksheet           worksheet;
    SysExcelCells               cells;
    COMVariantType              type;
    Filename                    fileName;
    int                         row;
    HcmPersonnelNumberId        personnelnumber;
    ProjId                      projId;
    smmActivityNumber           activityNumber;
    TransDate                   periodFrom, periodTo;
    Hours                       hourMon, hourTue, hourWed, hourThr, hourFri, hourSat, hourSun;
    TSWeeklyHours               weeklyHours;
    INT i;
    #File
    #define.FileMode('R')




    //flag = 0;
    startLengthyOperation();
    conFilter = ["@PM527" ,"@PM528"];
    dialog = new Dialog("Auto creation of timesheet");
    dfFileName = dialog.addField(extendedTypeStr(FileNameOpen));
    dialog.filenameLookupFilter(conFilter);
   // dialog.filenameLookupFilter(["@SYS28576",#XLSX,"@SYS28576",#XLS]);
    dialog.filenameLookupTitle("@PM529");
    dialog.caption("@PM530");
    if (dialog.run())
    {
        fileName = dfFileName.value();
        perm = new FileIOPermission(fileName, #FileMode);
        perm.assert();
        application = SysExcelApplication::construct();
        workbooks = application.workbooks();

    try
    {
        workbooks.open(filename);
    }
    catch (Exception::Error)
    {
        throw error("@SYS19358");
    }

    workbook = workbooks.item(1);
    worksheets = workbook.worksheets();
    worksheet = worksheets.itemFromNum(1);
    cells = worksheet.cells();


        row = 1;
    try
    {
        do
        {
            row++;
            tsTimesheetTable.clear();
            newTimesheetLine.clear();
            existsTimesheetLine.clear();
            worker.clear();
            projPeriodLine.clear();
            projPeriodTimesheetWeek.clear();
            lineWeek.clear();

            personnelnumber         = cells.item(row, 1).value().bStr();
            periodFrom              = cells.item(row, 2).value().date();
            periodTo                = cells.item(row,3).value().date();
            projId                  = cells.item(row,4).value().bStr();
            activitynumber          = cells.item(row,5).value().bStr();
            hourMon                 = cells.item(row,6).value().double();
            hourTue                 = cells.item(row,7).value().double();
            hourWed                 = cells.item(row,8).value().double();
            hourThr                 = cells.item(row,9).value().double();
            hourFri                 = cells.item(row, 10).value().double();
            hourSat                 = cells.item(row, 11).value().double();
            hourSun                 = cells.item(row, 12).value().double();

            if(personnelnumber != "Employee Id")
            {
                info(strFmt("personnelnumber -%1",personnelnumber));
                worker = HcmWorker::findByPersonnelNumber(personnelnumber);
                if (!worker.RecId)
                {
                    throw error("@SYS304951");
                }
                projPeriodLine = TSTimesheetTable::getValidWorkerPeriod(worker.RecId, periodFrom);
                // Check if the user has not exceeded the timesheet limit
                if (TSTimesheetTable::checkMaxTimesheets(projPeriodLine.PeriodFrom, worker.RecId, true))
                {
                tsTimesheetTable.initValue();
                tsTimesheetTable.Worker = worker.RecId;
                if(projPeriodLine != null && projPeriodLine.RecId != 0)
                {
                    tsTimesheetTable.ProjPeriodId = projPeriodLine.PeriodId;
                    tsTimesheetTable.PeriodFrom = projPeriodLine.PeriodFrom;
                    tsTimesheetTable.PeriodTo = projPeriodLine.PeriodTo;

                    projPeriodTimesheetWeek = ProjPeriodTimesheetWeek::findFromPeriod(projPeriodLine.PeriodId, periodFrom);
                    if(projPeriodTimesheetWeek.RecId == 0)
                    {
                        warning("@SYS338882");
                    }
                    else
                    {
                        tsTimesheetTable.ProjPeriodTimesheetWeek = projPeriodTimesheetWeek.RecId;
                    }

                }
                select forUpdate existsTimesheetLine
                order by RecId desc
                    where existsTimesheetLine.Worker == worker.RecId
                        && existsTimesheetLine.ProjPeriodTimesheetWeek == projPeriodTimesheetWeek.RecId;
                       // && existsTimesheetLine.ProjId == projId;
                if(!existsTimesheetLine.RecId)// && flag == 0)
                {
                    tsTimesheetTable.insert();
                    info(strFmt("created timesheet -%1",tsTimesheetTable.RecId));
                   // flag = 1;
                    if (ProjParameters::find().TimesheetAuditTrail)
                    {
                        TSTimesheetTableLog::createTableLog(tsTimesheetTable, '', TsTimesheetChangeType::Create);
                    }
                }
                else
                {
                    tsTimesheetTable = TSTimesheetTable::find(existsTimesheetLine.TimesheetNbr);
                    info(strFmt("exist timesheet -%1",tsTimesheetTable.RecId));
                }
                if(tsTimesheetTable.RecId)
                {
                    existsTimesheetLine.clear();
                    select forUpdate existsTimesheetLine
                    where existsTimesheetLine.TimesheetNbr == tsTimesheetTable.TimesheetNbr
                        && existsTimesheetLine.Worker == worker.RecId
                        && existsTimesheetLine.ProjId   == projId
                        && existsTimesheetLine.ActivityNumber   == activityNumber
                        && existsTimesheetLine.ProjPeriodTimesheetWeek == projPeriodTimesheetWeek.RecId;


                    newTimesheetLine.clear();
                    newTimesheetLine.initFromTSTimesheetTable(tsTimesheetTable);
                    newTimesheetLine.initFromWorkerTable(worker);
                    newTimesheetLine.initFromProjTable(ProjTable::find(projId));
                    newTimesheetLine.initValue();
                    newTimesheetLine.TimesheetNbr               = tsTimesheetTable.TimesheetNbr;
                    newTimesheetLine.ApprovalStatus             = TSAppStatus::Create;
                    newTimesheetLine.Worker                     = tsTimesheetTable.Worker;
                    newTimesheetLine.ProjId                     = projId;
                    newTimesheetLine.ActivityNumber             = activityNumber;
                    newTimesheetLine.ProjPeriodTimesheetWeek    = tsTimesheetTable.ProjPeriodTimesheetWeek;
                    info(strFmt("timesheet no -%1, worker -%2, proj - %3, activity numver - %4, peoj week -%5  --- %6", tsTimesheetTable.TimesheetNbr, tsTimesheetTable.Worker, projId,activityNumber, tsTimesheetTable.ProjPeriodTimesheetWeek, existsTimesheetLine.RecId));
                   // if(newTimesheetLine.validateWrite() && newTimesheetLine.ProjPeriodTimesheetWeek != 0)
                    {
                        if(!existsTimesheetLine.RecId)
                            newTimesheetLine.insert();
                        else
                            newTimesheetLine = existsTimesheetLine ;
                        for(i = 1; i <= 7; i++)
                        {
                            switch(i)
                            {
                                case 1:
                                    weeklyHours[1] = hourMon;
                                    break;
                                case 2:
                                    weeklyHours[2] = hourTue;
                                    break;
                                case 3:
                                    weeklyHours[3] = hourWed;
                                    break;
                                case 4:
                                    weeklyHours[4] = hourThr;
                                    break;
                                case 5:
                                    weeklyHours[5] = hourFri;
                                    break;
                                case 6:
                                    weeklyHours[6] = hourSat;
                                    break;
                                case 7:
                                    weeklyHours[7] = hourSun;
                                    break;
                            }
                        }
                    ttsbegin;

                    lineWeek.clear();
                    lineWeek.selectForUpdate(true);
                    lineWeek.TimesheetNbr   = newTimesheetLine.TimesheetNbr;
                    lineWeek.LineNum        = newTimesheetLine.LineNum;
                    lineWeek.tsTimesheetLine = newTimesheetLine.RecId;
                    lineWeek.Hours          = weeklyHours;
                    while select PeriodFrom, PeriodId, PeriodTo from periodWeek
                        where periodWeek.RecId == newTimesheetLine.ProjPeriodTimesheetWeek
                    {
                        if (!TSTimesheetLineWeek::existByTimesheetLineRecId(newTimesheetLine.RecId))
                        {
                            lineWeek.initValue();
                            lineWeek.ProjPeriodId   = periodWeek.PeriodId;
                            lineWeek.DayFrom        = periodWeek.PeriodFrom;
                            lineWeek.DayTo          = periodWeek.PeriodTo;
                            lineWeek.insert();

                        }
                    }

                    ttscommit;
                    info(strFmt("%1 Timesheet is created", tsTimesheetTable.TimesheetNbr));
                    }
                }
            }
            }

            type = cells.item(row+1, 1).value().variantType();
        }
        while (type != COMVariantType::VT_EMPTY);
        workbooks.close();
        application.quit();
    }
    catch (Exception::Error)
    {
        ttsabort;
    }
    }
}

Thursday 5 April 2018

Form Data source Modified field in D365


public static class InventTransferOrders_Extension
{

    /// <summary>
    /// Assign Barcode based on Item Id
    /// </summary>
    /// <param name="sender">
    /// </param>
    /// <param name="e">
    /// </param>
    
    [FormDataFieldEventHandler(formDataFieldStr(InventTransferOrders, InventTransferLine, ItemId), FormDataFieldEventType::Modified)]
    public static void ItemId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormDataSource          inventTransferLine_ds   = sender.datasource();
        InventTransferLine      inventTransferLine      = inventTransferLine_ds.cursor();
        InventDim               inventDim;
        InventItemBarcode       inventItemBarcode;

        inventDim           = InventDim::find(inventTransferLine.InventDimId);
        inventItemBarcode   = InventItemBarcode::findPurchBarcodeDimension(inventTransferLine.ItemId, inventDim, '', InventTableModule::find(inventTransferLine.ItemId, ModuleInventPurchSales::Invent).UnitId);

        if (!inventItemBarcode.RecId)
        {
            inventItemBarcode = InventItemBarcode::findPurchBarcodeDimension(inventTransferLine.ItemId, inventDim);
        }
        inventTransferLine.BarCode = inventItemBarcode.ItemBarCode;  //custom field
    }

}

Sunday 11 March 2018

GST, CGST, IGST,TCS, VAT using x++ code


Packing slip
this.insertGSTData(custPackingSlipJour.TableId, custPackingSlipJour.RecId, custPackingSlipTrans.TableId, custPackingSlipTrans.RecId);

Invoice
this.insertGSTData(custInvoiceJour.TableId, custInvoiceJour.RecId, custInvoiceTrans.TableId, custInvoiceTrans.RecId);


public void insertGSTData(RefTableId _headerTableID, RefRecId _headerRecId,RefTableId _transTableID, RefRecId _transRecId)
    {
        ITaxDocumentLine                    taxDocumentLine;
        ITaxDocument                        taxDocument;
        ITaxDocumentComponentLine           taxDocumentComponentLine;
        ITaxDocumentComponentLineEnumerator taxDocumentComponentLineEnumerator;
        ;
        taxDocument = TaxBusinessService::getTaxDocumentBySource(_headerTableID, _headerRecId);
       
        if (taxDocument)
        {
            taxDocumentLine = taxDocument.findLineBySource(_transTableID, _transRecId);
            if (taxDocumentLine)
            {
                taxDocumentComponentLineEnumerator = taxDocumentLine.componentLines("GST");
               
                while (taxDocumentComponentLineEnumerator.moveNext())
                {
                    taxDocumentComponentLine = taxDocumentComponentLineEnumerator.current();
                    if (taxDocumentComponentLine.metaData().taxComponent() == "CGST")
                    {
                        necSalesRegisterReportTmp.CGST      = taxDocumentComponentLine.getMeasure(TaxEngineModelLineMeasuresConstants::TaxAmount).value().value();
                        necSalesRegisterReportTmp.CGSTRate  = taxDocumentComponentLine.getMeasure(TaxEngineModelLineMeasuresConstants::TaxRate).value().value() * 100;
                    }
                    else if (taxDocumentComponentLine.metaData().taxComponent() == "SGST")
                    {
                        necSalesRegisterReportTmp.SGST      = taxDocumentComponentLine.getMeasure(TaxEngineModelLineMeasuresConstants::TaxAmount).value().value();
                        necSalesRegisterReportTmp.SGSTRate  = taxDocumentComponentLine.getMeasure(TaxEngineModelLineMeasuresConstants::TaxRate).value().value() * 100;
                    }
                    else if (taxDocumentComponentLine.metaData().taxComponent() == "CESS")
                    {
                        necSalesRegisterReportTmp.CESS      = taxDocumentComponentLine.getMeasure(TaxEngineModelLineMeasuresConstants::TaxAmount).value().value();
                    }
                    else if (taxDocumentComponentLine.metaData().taxComponent() == "IGST")
                    {
                        necSalesRegisterReportTmp.IGST      = taxDocumentComponentLine.getMeasure(TaxEngineModelLineMeasuresConstants::TaxAmount).value().value();
                        necSalesRegisterReportTmp.IGSTRate  = taxDocumentComponentLine.getMeasure(TaxEngineModelLineMeasuresConstants::TaxRate).value().value() * 100;
                    }
                    else if (taxDocumentComponentLine.metaData().taxComponent() == "SPCESS")
                    {
                        necSalesRegisterReportTmp.SPCCESS   = taxDocumentComponentLine.getMeasure(TaxEngineModelLineMeasuresConstants::TaxAmount).value().value();
                    }
                   
                }
            }
        }
       
    }

TCS, VAT 

TmpTaxWorkTrans         tmpTax;
PurchTotals             purchTotals;

purchTotals = purchTotals::newPurchTable(purchLine.purchTable());
purchTotals.calc();
tmpTax.setTmpData(purchTotals.tax().tmpTaxWorkTrans());

while select tmpTax
        where tmpTax.SourceRecId    == purchLine.RecId
            && tmpTax.SourceTableId == tablenum(PurchLine)
{
      if(tmpTax.TaxCode == "TCS")
      {
           PurchaseInvoiceTmp.TCSAmount = tmpTax.TaxAmount;
           PurchaseInvoiceTmp.TCSRate   = TaxData::percent(tmpTax.TaxCode,tmpTax.CalculationDate,tmpTax.TaxBaseAmount);
      }
      else
      {
           PurchaseInvoiceTmp.VATAmount = tmpTax.TaxAmount;
           PurchaseInvoiceTmp.VATRate   = TaxData::percent(tmpTax.TaxCode,tmpTax.CalculationDate,tmpTax.TaxBaseAmount);
      }

}


HSN Code

public void getTaxInfo(RefRecId _refRecId)
    {
        TransTaxInformationRelationView             taxRelation;
        TransTaxInformation                         taxInfo;
        TaxInformation_IN                           custTaxInfo;
       
        select firstonly taxRelation
            where taxRelation.TransactionRefRecId    == _refRecId
                && taxRelation.TransactionRefTableId == tablenum(SalesLine)
            join taxInfo
                where taxInfo.RecId == taxRelation.TransTaxInformationRefRecId
            join custTaxInfo
                where custTaxInfo.RecId == taxInfo.CustomerTaxInformation;

        custTaxInfo = TaxInformation_IN::find(taxInfo.CustomerTaxInformation);

        necSalesRegisterReportTmp.TIN       = TaxRegistrationNumbers_IN::find(custTaxInfo.TIN).RegistrationNumber;
        necSalesRegisterReportTmp.GSTNumber = TaxRegistrationNumbers_IN::find(custTaxInfo.GSTIN).RegistrationNumber;
        necSalesRegisterReportTmp.HSNCode   = HSNCodeTable_IN::find(taxInfo.HSNCodeTable).code;
    }