Wednesday, 27 October 2021

Create customer payment journal from code in D365 Fno

Hi Guys,

This is a very common requirement to create Journal from code(X++) but in D365fno some dimension classes are eliminated so here is the code to create and post a customer payment journal in D365 FnO.


1. Create journal header from click method then call below method to create journal lines.

        public void clicked()

        {

            LedgerJournalTable      ledgerJournalTable;

            CustomerCreditTable  customerCreditTable;

            CreateJournal        createJournal;

            LedgerjournalCheckPost  LedgerjournalCheckPost;

            super();

            try

            {

                ttsbegin;

                ledgerJournalTable.initValue();

                ledgerJournalTable.initFromLedgerJournalName("@Ext:CustPay");

                ledgerJournalTable.JournalNum =  JournalTableData::newTable(ledgerJournalTable).nextJournalId();

                ledgerJournalTable.Name = strFmt("@Ext:WriteOff",DateTimeUtil::getToday(DateTimeUtil::getUserPreferredTimeZone()));

                createJournal =  new CreateJournal();


                int numlines = createJournal.createJournalLines(ledgerJournalTable.JournalNum,customerCreditTable.JournalNum);


                if(numlines > 0)

                {

                    ledgerJournalTable.insert();

                    if (ledgerJournalTable)

                    {

                        LedgerjournalCheckPost      =   LedgerjournalCheckPost::newLedgerJournalTable(ledgerJournalTable,NoYes::Yes);

                        LedgerjournalCheckPost.runOperation(); 

                    }

                    ttsbegin;

                    select firstonly forupdate customerCreditTable

                        where customerCreditTable.JournalNum == customerCreditTable.JournalNum &&

                        customerCreditTable.IsProcessed == NoYes::No;

                    if (customerCreditTable)

                    {    

                        customerCreditTable.IsProcessed = NoYes::Yes;

                        customerCreditTable.JournalNumRef = ledgerJournalTable.JournalNum;

                        customerCreditTable.doUpdate();

                    }

                    customerCreditTable_ds.research();

                    customerCreditTable_ds.refresh();

                    ttscommit;

                    info(strFmt("@Ext:JVCreated",ledgerJournalTable.JournalNum, numlines));

                }

                ttscommit;

            }

            catch (Exception::Error)

            {

                throw Exception::Error;

            }

        }

2. Call this method in the clicked method to create journal lines as per requirement.

    public int createJournalLines(LedgerJournalId   journalId,LedgerJournalId journalIdOrig)

    {

        LedgerJournalTrans              transJournal;

        RecordInsertList                ledgerJournalTransList;

        NumberSeq                       numberseq;

        Voucher                         voucherNum;

        int                             counter;

        CustomerCreditTable          customerCreditTable;

        //CustInvoiceJour                 custInvoiceJour;

        //SalesLine                       salesLine;

        //LedgerDimensionDefaultAccount   getReasonDim;


        LedgerJournalName ledgerJournalName = ledgerJournalName::find("@Ext:CustPay");

        ledgerJournalTransList = new RecordInsertList(transJournal.TableId);

        numberseq = NumberSeq::newGetVoucherFromCode(NumberSequenceTable::find(ledgerJournalName.NumberSequenceTable).NumberSequence);

        voucherNum = numberseq.voucher();


        while select customerCreditTable where customerCreditTable.IsProcessed == NoYes::No && customerCreditTable.JournalNum == journalIdOrig

        {

            transJournal.clear();

            transJournal.initValue();

            transJournal.JournalNum               =  journalId;

            transJournal.TransDate                =                         DateTimeUtil::getToday(DateTimeUtil::getUserPreferredTimeZone());

            transJournal.AccountType              =  LedgerJournalACType::Cust;

            transJournal.LedgerDimension          = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(customerCreditTable.Customer,LedgerJournalACType::Cust);//Journal_Tmp.LedgerDimension;

            transJournal.DefaultDimension         = LedgerDimensionFacade::getDefaultDimensionFromLedgerDimension(transJournal.LedgerDimension);

            transJournal.OffsetAccountType        = customerCreditTable.AccountType;//LedgerJournalACType::Ledger;


            //select firstonly InvoiceId,SalesId from custInvoiceJour

            //    where custInvoiceJour.InvoiceId == customerCreditTable.InvoiceId

            //        join firstonly DefaultDimension from salesLine

            //            where salesLine.SalesId == custInvoiceJour.SalesId;


            //getReasonDim = CustWriteOffFinancialReasonsSetup::findByReasonCode(customerCreditTable.Reason).WriteOffLedgerDimension;

            //transJournal.OffsetLedgerDimension    = LedgerDimensionFacade::ServiceCreateLedgerDimension(getReasonDim, salesLine.DefaultDimension);//22565422738);

            transJournal.OffsetLedgerDimension    = customerCreditTable.LedgerDimension;

            transJournal.CurrencyCode             = customerCreditTable.Currency;

            transJournal.AmountCurCredit          = customerCreditTable.Credit;

            transJournal.MarkedInvoice            = customerCreditTable.InvoiceId;

            transJournal.Txt                      = customerCreditTable.TransactonTxt;

            transJournal.Approved                 = NoYes::Yes;

            transJournal.Approver                 = HcmWorker::userId2Worker(curUserId());

            transJournal.SkipBlockedForManualEntryCheck  = true;

            transJournal.defaultRow();

            if(!transJournal.Voucher)

            {

                transJournal.Voucher                  = voucherNum;

            }

            ledgerJournalTransList.add(transJournal);

            counter++;

        }

        ledgerJournalTransList.insertDatabase();

        numberseq.used();


        return counter;

    }


Thanks,

Code to get default dimension from Ledger dimension in D365 FnO

 Hi Guys,

Fetch default dimensions from Ledger dimension in D365 FnO.

        tmpTable.Dimension = LedgerDimensionFacade::getDefaultDimensionFromLedgerDimension(LedgerjournalTrans.LedgerDimension);


Thanks,





Wednesday, 2 January 2019

Import DATA from excel in D365FO

HI Guys,

Here is the sample code to import excel sheet in D365FO 

using System.IO;
using OfficeOpenXml;
using OfficeOpenXml.ExcelPackage;
using OfficeOpenXml.ExcelRange;

class DMSImportFromExcel
{        

    /// <summary>
    /// Runs the class with the specified arguments.
    /// </summary>
    /// <param name = "_args">The specified arguments.</param>
    public static void main(Args _args)
    {            
        System.IO.Stream            stream;
        ExcelSpreadsheetName        sheeet;
        FileUploadBuild             fileUpload;
        DialogGroup                 dlgUploadGroup;
        FileUploadBuild             fileUploadBuild;
        FormBuildControl            formBuildControl;
        Dialog                      dialog = new Dialog("Import the data from Excel");

        dlgUploadGroup          = dialog.addGroup("Group");
        formBuildControl        = dialog.formBuildDesign().control(dlgUploadGroup.name());
        fileUploadBuild         = formBuildControl.addControlEx(classstr(FileUpload), "Upload");
        fileUploadBuild.style(FileUploadStyle::MinimalWithFilename);
        fileUploadBuild.fileTypesAccepted(".xlsx");

        if (dialog.run() && dialog.closedOk())
        {
            FileUpload fileUploadControl     = dialog.formRun().control(dialog.formRun().controlId("Upload"));
            FileUploadTemporaryStorageResult fileUploadResult = fileUploadControl.getFileUploadResult();

            if (fileUploadResult != null && fileUploadResult.getUploadStatus())
            {
                stream = fileUploadResult.openResult();
                using (ExcelPackage Package = new ExcelPackage(stream))
                {
                    int                         rowCount, i;
                    Package.Load(stream);
                    ExcelWorksheet  worksheet   = package.get_Workbook().get_Worksheets().get_Item(1);
                    OfficeOpenXml.ExcelRange    range       = worksheet.Cells;
                    rowCount                  = worksheet.Dimension.End.Row - worksheet.Dimension.Start.Row + 1;

                    for (i = 2; i<= rowCount; i++)
                    {
                        info(range.get_Item(i, 1).value);
                        info(range.get_Item(i, 2).value);
                    }
                }
            }
            else
            {
                error("Error here");
            }
        }
    }

}



Happy DAXing :-)

Tuesday, 24 July 2018

Query in AX 2012

Runtime query in AX 2012


// Code using X++ to build the query
Query                   query;
QueryRun                queryRun;
QueryBuildDataSource    qbds;
SalesTable              salesTable;
;

query    = new Query();
// Add a datasource to the query
qbds     = query.addDataSource(tableNum(SalesTable));
// Add a range to the newly added datasource.
qbds.addRange(fieldNum(SalesTable,SalesId)).value("00403_1036..00412_1036");
 
queryRun = new QueryRun(query);
 
while(queryRun.next())
{
   salesTable  =   queryRun.get(tableNum(SalesTable));
   info(SalesTable.SalesId + ", " + SalesTable.CustAccount);
}


// Code using a query string
static void Job14(Args _args)
{
    Query                           query;
    QueryRun                        queryRun;
    QueryBuildDataSource            qbds;
    QueryBuildRange                 qbr;   
    EcoResDistinctProductVariant    ecoResDistinctProductVariant; 
 
    query = new query(queryStr(EcoResProductVariantsPerCompany));
    queryRun = new QueryRun(query);
 
    while (queryRun.next())
    {
        ecoResDistinctProductVariant = queryRun.get(tableNum(ecoResDistinctProductVariant));
     
        info (strFmt("%1 - %2", EcoResDistinctProductVariant.SearchName, EcoResDistinctProductVariant.ProductMaster));
    } 
}


http://kashperuk.blogspot.com/2011/10/tutorial-ax2012-new-way-of-accessing.html

Sunday, 13 May 2018

Calculate purchase/sales confirmation GST tax at line level (IGST/CGST/SGST) in AX 2012 R3

Hi guys,
It's very tricky to calculate GST percent at line level on purchase/sales confirmation because there is no direct table to fetch the GST percentage and value.

Here I am going to show you how we can calculate GST % at the line level.


In Data provider class creates a new method and this method calculate GST % and value


//#method1
private void getMeasures(ITaxDocument taxDocumentObject,RefRecId _PurchLinerecId)
{
    ITaxDocumentLineEnumerator          lineEnumerator;
    ITaxDocumentLine                    lineObject;
    ITaxableDocumentLine                taxableDocumentLine;
    ITaxDocumentComponentLineEnumerator componentLineEnumerator;
    ITaxDocumentComponentLine           componentLineObject;
    ITaxDocumentMeasureEnumerator       measureEnumerator;
    ITaxDocumentMeasure                 measureObject;

    LedgerVoucher                   ledgerVoucher;
    ITaxDocumentLine                taxDocumentHeaderLineObject;
    PurchLine_IN                    PurchLine_IN1;

    #TaxEngineModelLineMeasures


    if (taxDocumentObject)
    {
        lineEnumerator = taxDocumentObject.lines();
        while (lineEnumerator.moveNext())
        {
            lineObject = lineEnumerator.current();
            if (taxDocumentHeaderLineObject == null && lineObject.metaData().isHeaderLine())
            {
                taxDocumentHeaderLineObject = lineObject;
            }
            taxableDocumentLine = TaxableDocumentLineObject::construct(lineObject.sourceTableId(), lineObject.sourceRecId());
            componentLineEnumerator= lineObject.componentLines();

            if(lineObject.originSourceTableId() == 340 && lineObject.originSourceRecId() == _PurchLinerecId)
            {
                    //info(strFmt("%1-%2",lineObject.originSourceRecId(),lineObject.originSourceTableId()));
                    totval=0;
                    while (componentLineEnumerator.moveNext())
                    {
                        componentLineObject = componentLineEnumerator.current();
                        measureEnumerator = componentLineObject.measures();
                        while (measureEnumerator.moveNext())
                        {
                            measureObject = measureEnumerator.current();
                            if(measureObject.metaData().name() == strFmt("Rate") && componentLineObject.metaData().taxType() == "GST"
                              &&
                              (componentLineObject.metaData().taxComponent() == "CGST" ||
                              componentLineObject.metaData().taxComponent() == "IGST" ||
                              componentLineObject.metaData().taxComponent() == "SGST")
                              )
                            {
                                totval += measureObject.value().value();
                                //info(strFmt("%1--%2--%3",componentLineObject.metaData().taxComponent(),measureObject.metaData().name(),measureObject.value().value()));

                            }
                        }
                       // getTotal = totval*100;
                       // info(strFmt("%1",getTotal));
                    }
                    getTotal = totval*100;
                    //info(strFmt("%1",getTotal));
            }
        }
    }
}
___________________________

//#method2
Create another method in DP class with recid as a parameter and we will call earlier created getMeasures method in this class

private void getMeasuresforPurchLine(RefRecId _PurchLinerecId)
{
    ClassName                   bundlerClassName;
    TaxableDocumentDescriptor   bundler;
    ClassId                     bundlerId;
    ITaxableDocument            taxableDocumentObject;
    ITaxableDocumentLine        taxableDocumentLineObject;
    Common                      transactionTable =  PurchTable::find(PurchLine::findRecId(_PurchLinerecId).PurchId) ;  //SalesTable::find('F898-000626');
    SalesPurchJournalLine_IN    transactionLineTable;
    TaxValue                    gstTaxValue;
    ITaxDocument                taxDocumentObject;
    ITaxableDocument            taxableDocumentObjectLoc;
    TaxableDocumentDescriptor   descriptor;
    TaxDocumentProxy            taxDocProxy;
    ITaxDocumentLineEnumerator  taxDocLineEnumerator;
    ITaxDocumentLine            taxDocLine;
    SalesLineAmount             salesLineAmount,salesLineBaseAmt;
    ITaxDocumentComponentLineEnumerator cLineEnum;
    ITaxDocumentComponentLine           cLine;
    //str                         taxComponent;

    bundlerClassName = 'TaxableDocDescriptorPurchaseOrder';
    bundlerId = className2Id(bundlerClassName);

    if (SysDictTable::isTableMapped(tableNum(SalesPurchJournalLine_IN), transactionTable.TableId)
        && transactionTable.TableId != tableNum(LedgerJournalTrans))
    {
        transactionLineTable = transactionTable;
        transactionTable = transactionLineTable.SalesPurchJournalLine_IN::salesPurchJournalTable();
    }

    if (bundlerId != 0)
    {
        bundler = TaxableDocumentDescriptor::getTaxDocumentdescriptorServer(bundlerId, transactionTable);

        if (!bundler.skipTaxDocument())
        {
            taxableDocumentObject = TaxableDocumentObject::constructServer(bundler);
            taxDocumentObject = TaxBusinessService::recalculateTax(taxableDocumentObject, false);
        }

        if (taxDocumentObject)
        {
            // calling the above method
            this.getMeasures(taxDocumentObject,_PurchLinerecId);
        }
    }
}
____________________________

//#method3
Here we will create a new method getGSTpercent and call getMeasuresforPurchLine to get the punchline records.

private void getGSTPercent(PurchLineAllVersions     _purchLineAllVersions)
{
    PurchTable          PurchTableLoc;
    PurchLine           PurchLineLoc;
    VendPurchOrderJour  vendPurchOrderJourLoc;
    PurchLineAllVersions    purchLineAllVersions;

    select vendPurchOrderJour
        where vendPurchOrderJour.PurchId == purchid;

        select PurchLine
            where PurchLine.InventTransId == _purchLineAllVersions.InventTransId;

        this.getMeasuresforPurchLine(purchline.RecId);
}

With this above logic, we can calculate GST percent and value at line level.


Happy DAxing:-)

Monday, 19 February 2018

Get financial dimension by Recid.

Get financial dimension by Recid.

public static container getFinancialDimensionsByRecId(RecId     _defaultDimension)
{
    DimensionAttributeValueSetStorage    dimStorage;
    Counter                              i;
    container                            ctr;
    ;

    dimStorage = DimensionAttributeValueSetStorage::find(_defaultDimension);

    for (i=1 ; i<= dimStorage.elements() ; i++)
    {
        ctr   += [DimensionAttribute::find(dimStorage.getAttributeByIndex(i)).Name, dimStorage.getDisplayValueByIndex(i)];
    }

    return ctr;
}


Thursday, 28 September 2017

Get vendor's and customer's GST number in AX 2012 R3

Hi guys,
IN GST era, It is very common term GST. So here I'm discussing how to get vendor's GST number in X++ AX 2012 R3 and It is very simple to refer below sample code.

 And similarly, you can get Customer's GST number and sometimes we get requirement from client to print warehouse or Company GST number so just refer this below job and modify as per the requirement.

Static void   getVendorGST(AccountNum     _accountNum)
{
    VendTable           vendTable;
    DirPartyTable       dirPartyTable;
    LogisticsLocation   logisticsLocation;
    TaxInformation_IN   taxInformation_IN;

    select vendTable where vendTable.AccountNum == _accountNum
        join dirPartyTable
            where dirPartyTable.RecId == vendTable.Party
        join logisticsLocation
            where logisticsLocation.RecId == dirPartyTable.PrimaryAddressLocation;


    taxInformation_IN   = TaxInformation_IN::findDefaultbyLocation(logisticsLocation.RecId);
    return TaxRegistrationNumbers_IN::find(taxInformation_IN.GSTIN).RegistrationNumber;
}

Happy DAxing......

Import General journal from excel in D365 F&O

 Hi Guys, Import General journal from excel in D365 F&O Code:  using System.IO; using OfficeOpenXml; using OfficeOpenXml.ExcelPackage; u...