Friday, 27 September 2019

Extend Clicked method using Extensions/Evnthandler in D365 Finance and Operations

1. Create extension of 'CustInvoiceJour' form


2. Open extension of that form from the solution explorer and add a button



3. We have added a button, now we have to perform some operations on click of that button. And for that we need to write the 'OnClicked' event. In order to do that, expand the 'Event's under that control and right click on 'onClicked' event and select 'Copy Event Handler Method'

4. 'OnClicked' event handler is copied and now you can paste as a method in any of your custom class or you can create a new class. I am using one of my custom classes.

5. Now the question is, how we will get the selected record on that form or how would we get the form data source, if you take a look of this above method, you will seen we have a formContol as a parameter and by using that we can get the form data source and selected records.


After getting the table buffer and form data source, we can perform other operations.

Thursday, 19 September 2019

Post sales PickingList AX 2012/D365 X++

Step 1

Create WMSShipment record.
        WMSShipment                     wmsShipment;
    SalesTable                      salesTableLocal;
    salesTableLocal = SalesTable::find(‘SO-101328’);
    wmsShipment.clear();
    wmsShipment.initTypeOrderPick();
    wmsShipment.insert();

Step 2

Create WMSPickingRoute record.
    WMSPickingRoute                 wmsPickingRoute;
    wmsPickingRoute.clear();
    wmsPickingRoute.initTypeOrderPick(wmsShipment, WMSExpeditionStatus::Activated,                  WMSPickRequestTable::construct(salesTableLocal), ”, true);
    wmsPickingRoute.ActivationDateTime = DateTimeUtil::utcNow();
    wmsPickingRoute.insert();

Step 3

Create WMSPickingRouteLink record.
    WMSPickingRouteLink          wmsPickingRouteLink;
    wmsPickingRouteLink.initFromSalesTable(salesTableLocal);
    wmsPickingRouteLink.initFromWMSPickingRoute(wmsPickingRoute);
    wmsPickingRouteLink.insert();

Step 4

Create SalesPickingList line using WMSOrderCreate class.
    SalesLine                       salesLineLocal;
    InventMovement                  inventMovement;
    WMSOrder                        wmsOrder;
    WMSOrderCreate                  orderCreate;
    WMSOrderTrans                   wmsOrderTrans;

// Creating records for each salesline
while select salesLineLocal
        where salesLineLocal.SalesId == salesTableLocal.SalesId
    {
        // Inventory Movement object is required to create new           SalesPickingList lines
        inventMovement = InventMovement::construct(salesLineLocal);
        orderCreate = WMSOrderCreate::newMovement(inventMovement, -cancelQty);
        orderCreate.parmMustBeWMSOrderControlled(true);
        orderCreate.parmQty(cancelQty);
        orderCreate.parmRecalculateMaxQtyForValidation(false);
        orderCreate.parmMaxCWQty(cancelQty);
        orderCreate.parmMaxQty(cancelQty);
        orderCreate.run();
        wmsOrder = orderCreate.parmWMSOrder();
        wmsOrder.updateShipment(wmsShipment, cancelQty, wmsPickingRoute.PickingRouteID, false);

        // Updating status to activated 
        while select forupdate wmsOrderTrans
            where wmsOrderTrans.inventTransId ==  salesLineLocal.inventTransId
               && wmsOrderTrans.expeditionStatus == WMSExpeditionStatus::Registered
        {
            ttsBegin;
            wmsOrderTrans.expeditionStatus = WMSExpeditionStatus::Activated;
            wmsOrderTrans.update();
            ttsCommit;
        }
    }

Monday, 16 September 2019

How to get Exchange rate in D365 F&O x++ ?



public display Amount TIDF_ExchangeRate()
{
    ExchangeRate     exchangeRate;
    ExchangeRateType ExchangeRateType;
    ExchangeRateCurrencyPair exchangeRateCurrencyPair;
    real             exchRate;

    CurrencyCode fromCurrency  = this.CurrencyCode;
    CurrencyCode toCurrency    = Ledger::find(Ledger::current()).AccountingCurrency ; //"AED";
    TransDate    transDate     = this.TransDate;


    select firstonly exchangeRateCurrencyPair
    where
        exchangeRateCurrencyPair.ExchangeRateType == Ledger::find(Ledger::current()).DefaultExchangeRateType
    &&  exchangeRateCurrencyPair.FromCurrencyCode == fromCurrency
    &&  exchangeRateCurrencyPair.ToCurrencyCode   == toCurrency;

   // if ( date2str(this.TransDate ,1,1,1) == 5/9/2018);
    exchRate = exchangeRate::findByDate(exchangeRateCurrencyPair.RecId,transDate).ExchangeRate;
    //info(strFmt("%1",exchRate/100));

    return exchRate/100;

}








Thursday, 12 September 2019

How to get a unique record from a table without index in dynamics AX/D365 X++

Some times we need to find an unique record from a table. In this example I'm find an unique record based on created date time and grouping by salesId. Change the code according to your requirement.

Usually we use this format code when the primary index is not available in the table.


 while select maxof(LogCreatedDateTime) from SalesOrderLogView
                    join salesTable
                    group by SalesOrderLogView.SalesId
                     where  SalesOrderLogView.LogCreatedDateTime >= _fromdatetime
                                            && SalesOrderLogView.LogCreatedDateTime <= _todatetime

{
    info(SalesOrderLogView.salesID);
}

@Rahul

How to override the AX 2012 sales tax from 3rd party system using X++?

Most of the time we got the requirement to create Sales Orders in AX  (X++) using the input from the 3rd party system and in few case, we need to use the sales tax that is already calculated by the 3rd party financial system rather calculating it in AX. Here is the sample code which override the 3rd party sales tax rather use the AX sales tax calculation process.

2. After SO creation override the Sales tax provided by the 3rd party financial system.
Create and post SO Code2
After this if you want to check the sales tax , go to the invoice voucher and check the sales tax amount that has got invoice is equal to the 3rd party sales tax amount.

Get the last inserted record from table in Dynamics AX/D365 using x++

Sometimes we get a requirement to get latest inserted record from a table in dynamics AX.
Below is an example code for that. Here, I used order by desc to get the latest record.

select firstfast salesTable order by CreatedDateTime desc where salesTable.CustAccount == custTable.AccountNum
                    && salesTable.SalesType == SalesType::Sales
                    && salesTable.SalesStatus != SalesStatus::Canceled;

@Rahul

How to get previous year, current year and next year in dynamics AX/D365 X++

I got a requirement to show previous year and current year in a SSRS report.

Ex: If you are in 2019 . Need to show 2018 and 2019
    If we are in 2020. Need to show 2019 and 2020

To achieve this I just need to get previous year start, end dates and current year start and end dates.

I used the below code to get the result.

Variable declaration
-------------------------
int                     currentYear = year(systemDateGet());
int                     previousYear = currentYear - 1; // previous year
int nextYear = currentYear + 1; // Next year
// I have another way to get previous year and next year. But, this will match the exact date in the previous year and next year.
date                     prvyear = prevYr(systemDateGet());
date                     nextyear = nextYr(systemDateGet());

str                     CurrentYearStart = "01"+"/"+"01"+"/"+int2Str(currentYear);
str                     CurrentYearEnd = "12"+"/"+"31"+"/"+int2Str(currentYear);
str                     previousYearStart = "01"+"/"+"01"+"/"+int2Str(previousYear);
str                     previousYearEnd = "12"+"/"+"31"+"/"+int2Str(previousYear);



Coding
----------

//Invoiceamount previous year
select sum(InvoiceAmount) from custInvoiceJourPrvYear where custInvoiceJourPrvYear.InvoiceDate >= str2Date(previousYearStart, 213)
&& custInvoiceJourPrvYear.InvoiceDate <= str2Date(previousYearEnd, 213)
&& custInvoiceJourPrvYear.InvoiceAccount == salesTable.InvoiceAccount
&& custInvoiceJourPrvYear.InvoiceAmount > 0.00;

SalesActivityReportTmp.PreviousYearTotal = custInvoiceJourPrvYear.InvoiceAmount;

//Invoiceamount current year
select sum(InvoiceAmount) from custInvoiceJourCurrentYear where custInvoiceJourCurrentYear.InvoiceDate >= str2Date(CurrentYearStart, 213)
&& custInvoiceJourCurrentYear.InvoiceDate <= str2Date(CurrentYearEnd, 213)
&& custInvoiceJourCurrentYear.InvoiceAccount == salesTable.InvoiceAccount
&& custInvoiceJourCurrentYear.InvoiceAmount > 0.00;

SalesActivityReportTmp.CurrentYearTotal = custInvoiceJourCurrentYear.InvoiceAmount;

// SSRS changes
--------------------
To add previous and current year in the report header/column header I added the below logic.

-> In the header/column "Expression" and added the below logic for previous year
= today.AddYears(-1).year & " Total Sales"

-> In the header/column "Expression" and added the below logic for current year
= today.Year & " YTD Total Sales"

-> In the same way you can add for next year as well.
= today.AddYears(+1).year & " Total Sales"


@Rahul

Wednesday, 11 September 2019

Get customer address by type in Dynamics AX/D365 F&O X++

Below are the solutions to get customers by address type(Invoice , delivery)

Solution 1
------------------
display Addressing  InvoicingAddress()

{

Addressing address;

DirPartyRecId party;

party = CustTable::find(‘Account’).Party;

address = DirParty::getPostalAddressByType(party, LogisticsLocationRoleType::Invoice);

if (!address)

address = DirParty::getPostalAddressByType(party, LogisticsLocationRoleType::Delivery);

return address;

}


Solution 2
--------------
//LogisticsLocationRoleType (InvoiceDeliveryShipping etc.)
public static LogisticsPostalAddress getPostalAddressByType(DirPartyRecId _party, LogisticsLocationRoleType _type)
{
    DirPartyLocation        partyLocation;
    DirPartyLocationRole    partyLocationRole;
    LogisticsLocation       location;
    LogisticsLocationRole   locationRole;
    LogisticsPostalAddress  postalAddress;

    select firstonly postalAddress
        exists join location
            where location.RecId == postalAddress.Location
        exists join locationRole
            where locationRole.Type  == _type//LogisticsLocationRoleType::Invoice
        exists join partyLocation
            where 
                partyLocation.Location == location.RecId &&
                 partyLocation.IsPrimary    == NoYes::Yes && 
                partyLocation.Party == _party//custtable.party
        exists join partyLocationRole
            where partyLocationRole.PartyLocation == partyLocation.RecId &&
                partyLocationRole.LocationRole == locationRole.RecId;

    return postalAddress;
}

update Sales Order & Sales Line Financial Dimensions in Dynamics AX 2012 & D365 F&O X++

Use the below job for updating financial dimensions for sales  table and lines.


AX 2012 code
----------------------
static void RB_SLineFinDimensionUpdate(Args _args)
{
    SalesTable                          salesTable,salesTableUpd;
    SalesLine                           salesLine,salesLineUpd;
    CustAccount                      custAccount;
    DimensionDefault             defaultDimension,itemDefaultDimension,custDefaultDimension;


    salesTable   =  SalesTable::find('10000');
    salesLine    =  salesLine::find(salesTable.SalesId,1,true);

    if (salesLine)
    {
        itemDefaultDimension    =   InventTable::find(salesLine.ItemId).DefaultDimension;
        custDefaultDimension    =   CustTable::find(salesTable.CustAccount).DefaultDimension;

        defaultDimension        = DimensionDefaultingService::serviceMergeDefaultDimensions(custDefaultDimension,itemDefaultDimension);

        update_recordSet salesTableUpd
            setting defaultDimension =  custDefaultDimension
            where salesTableUpd.salesId == salesTable.SalesId;

            update_recordSet    salesLineUpd
                setting defaultDimension = defaultDimension
                where salesLineUpd.RecId == salesLine.RecId;

    }

}


D365 Code
-------------------
static void RB_SLineFinDimensionUpdate(Args _args)
{
    SalesTable                          salesTable,salesTableUpd;
    SalesLine                           salesLine,salesLineUpd;
    CustAccount                      custAccount;
    DimensionDefault             defaultDimension,itemDefaultDimension,custDefaultDimension;


    salesTable   =  SalesTable::find('10000');
    salesLine    =  salesLine::find(salesTable.SalesId,1,true);

    if (salesLine)
    {
        itemDefaultDimension    =   InventTable::find(salesLine.ItemId).DefaultDimension;
        custDefaultDimension    =   CustTable::find(salesTable.CustAccount).DefaultDimension;

defaultDimension        = LedgerDimensionDefaultFacade::serviceMergeDefaultDimensions(custDefaultDimension,itemDefaultDimension);;

        update_recordSet salesTableUpd
            setting defaultDimension =  custDefaultDimension
            where salesTableUpd.salesId == salesTable.SalesId;

            update_recordSet    salesLineUpd
                setting defaultDimension = defaultDimension
                where salesLineUpd.RecId == salesLine.RecId;

    }


}

@Rahul

Adding a newline into a string in C# and X++

Below is the sample code we can use for  adding a newline after every occurrence of "@" symbol in the string in C#   using System...