Wednesday, 8 July 2020

Extend Sales Invoice report

Step 1) Create a new project.

Step 2) Assume that I want to add AdditionalQty field on body of report so I am going to create a extension of SalesInvoiceTmp table and add required fields within it.







Step 3) Build and Synchronize the table.

Step 4) Create a new helper class in my case I have created SalesInvoiceHelper class and copy onInserting event handler of SalesInvoice tmp table. Add logic within the copied event handler.













Note : For the demo purpose I have added logic for this  field. Whereas as  you can add logic as per your requirements.













Step 4) Duplicate the report  and give it a new name. Make changes in design accordingly.



















Step 5)  Go to PrintMgmtDocType class and copy event handler of getDefaultReportFormatDelegate and subscribe to its event handler. Add logic in the method to call this new report in helper class.


























Step 6) Duplicate Sales invoice controller class  by creating new controller and change its logic in order to call your new report.

For instance in my class I have replaced SalesInvoicecontroller instance with salesInvoiceControllerDemo and called my report SalesinvoiceDemo with design Report.


















Step 7)  Extend sales invoice report menu item and change its controller property to your new controller.


Before creating new extension of menu item.











After creating new extension.












Build the complete project and execute your report.

Here comes the error.










Oops. Probably I missed something and that is deploying my report. Right click on your project and select deploy reports.

One more thing go to Account receivable ->Setup -> Form setup -> Select print management
Go to customer invoice node and select your design and report there too.














Final output with our custom column.













http://dynamicsaxtechnicalstuff.blogspot.com/2019/01/customize-design-and-business-logic-of.html

Monday, 8 June 2020

Power BI


Click on windows >> microsoft store >> Powerbi desktop (Search). Install the app.

Thursday, 28 May 2020

Cheque Report

If you want

[ExtensionOf(classStr(CustVendCheque))]
final class CustVendChequeCIT_Extension
{
    public ReportPosition          slipTop1;
    public ReportPosition          slipTop2;
    public ReportPosition          slipHeight;
    public Counter                 specTransLines;

    public AmountCur               totalDiscount;
    public AmountCur               totalAmount;
    public AmountCur               totalPaid;
    public AccountNum              vendAccount;
    public Name                    vendName;
    public int                     checkLines;   

    private str formatField(str _value, int _maxLength = 0, boolean _rightAlign = true)
    {
        str currentVal;
   
        currentVal = _value;
   
        if (_maxLength > 0)
        {
            if (_rightAlign)
            {
                currentVal = strRFix(currentVal, _maxLength);
            }
            else
            {
                currentVal = strLFix(currentVal, _maxLength);
            }
        }
   
        return currentVal;
    }

    public void output(CustVendPaym _custVendPaym)
    {
        // Trying to skip STD code execution by passing 'CustVendPaym' as blank
        //But CustVendPaym  is a ABSTRACT CLASS, so we are unable to re-initilize it to pass it as blank value
        //getting 'VendPaym' in buffer value so intilazed it and passed as parameter it seld
        VendPaym VendPaym = new VendPaym();
        //Getting 'Company not avaiable error', so we assigned curresnt compnay value to it
        VendPaym.ledgerJournalTrans().Company = curExt();

        next output(VendPaym);

        BankNegInstRecipientName    recipientName;
        VendTable                   vendTable;
        CustTable                   custTable;
        Counter                     endLines;
        Counter                     notesLines;
        Counter                     paymentNotesHeaderLinesPrinted;
        Counter                     i;

        LedgerJournalTrans ledgerJournalTrans = _custVendPaym.ledgerJournalTrans();
        BankAccountTable bankAccountTableCurrent;
        LogisticsLocationEntity location;
        LogisticsPostalAddress address;
        BankChequeNum slipChequeNum;
        List paymentNotesList;
        ListEnumerator le;

        str paymentNotesLine;
        ChequeSlipTxt slipText;

        boolean firstCheque = true;
        TmpChequePrintout   tmpChequePrintouttmp;
        chequetmp           ChequeTmp;
        delete_from ChequeTmp;
        delete_from tmpChequePrintouttmp;

        changecompany(ledgerJournalTrans.Company)
        {
            switch (ledgerJournalTrans.AccountType)
            {
                case LedgerJournalACType::Vend:
                    vendTable = VendTable::findByLedgerDimension(ledgerJournalTrans.parmLedgerDimension());

                    //Verify if the remittancelocation on the table is still active; if no remittancelocation exists or is invalid then default
                    ledgerJournalTrans.RemittanceLocation = this.setVendorOutputFieldsRemittanceLocation(ledgerJournalTrans, vendTable);

                    //get the vendors remit to address
                    location = this.setVendorOutputFieldsLocation(ledgerJournalTrans);
                    address = this.setVendorOutputFieldsAddress(location, address, ledgerJournalTrans);
                    ledgerJournalTrans.RemittanceAddress = address.RecId;
                    recipientName = this.setVendorOutputFieldsRecipientName(ledgerJournalTrans);
                    break;

                case LedgerJournalACType::Cust:
                    custTable = CustTable::findByLedgerDimension(ledgerJournalTrans.parmLedgerDimension());
                    address = this.setCustomerOutputFieldsAddress(custTable);
                    recipientName = this.setCustomerOutputFieldsRecipientName(address);
                    break;

                case LedgerJournalACType::Bank:
                    bankAccountTableCurrent = this.setBankAccountTableCurrentOutputFields(ledgerJournalTrans);
                    break;

                case LedgerJournalACType::Ledger:
                    this.initLedgerJournalTransLedger(ledgerJournalTrans);
                    break;

                default:
                    throw error(Error::wrongUseOfFunction(funcName()));
            }
        }

        BankAccountTable bankAccountTable = BankAccountTable::find(accountId);
        BankChequeLayout bankChequeLayout = BankChequeLayout::find(accountId);

        Currency currency = (bankChequeLayout.OtherCurrencies == NoYes::Yes ?
            Currency::find(ledgerJournalTrans.CurrencyCode) :
            Currency::find(bankAccountTable.CurrencyCode));

        AmountCur amountCur = ledgerJournalTrans.AmountCurDebit - ledgerJournalTrans.AmountCurCredit;

        if (TaxWithholdParameters_IN::checkTaxParameters())
        {
            AmountCur taxAmount;

            if (ledgerJournalTrans.OffsetLedgerDimension)
            {
                taxAmount = TaxWithholdUncommitted_IN::getActualTaxAmountForVoucher(ledgerJournalTrans.ledgerJournalTable().TableId, ledgerJournalTrans.ledgerJournalTable().RecId, ledgerJournalTrans.Voucher, false, '', ledgerjournalTrans.RecId);
            }
            else
            {
                taxAmount = TaxWithholdUncommitted_IN::getActualTaxAmountForVoucher(ledgerJournalTrans.ledgerJournalTable().TableId, ledgerJournalTrans.ledgerJournalTable().RecId, ledgerJournalTrans.Voucher, false);
            }

            ledgerJournalTrans.AmountCurDebit += taxAmount;
            amountCur += taxAmount;
        }

        if (TaxWithholdParameters_IN::checkTaxParameters() || TaxParameters::checkTaxParameters_IN())
        {
            AmountCur feeAmountTotal;
            VendPaymFee vendPaymFeeLoc;
            CustVendPaymJournalFee custVendPaymJournalFeeLoc;
            AmountCur feeAmount;

            while select FeeId, FeeValue from custVendPaymJournalFeeLoc
            where custVendPaymJournalFeeLoc.RefRecId == ledgerJournalTrans.RecId
            {
                select firstonly vendPaymFeeLoc
                where vendPaymFeeLoc.FeeId == custVendPaymJournalFeeLoc.FeeId
                    && (vendPaymFeeLoc.TaxWithholdFeeType_IN == TaxWithholdFeeType_IN::Interest
                        || vendPaymFeeLoc.TaxWithholdFeeType_IN == TaxWithholdFeeType_IN::Others);

                if (vendPaymFeeLoc)
                {
                    feeAmountTotal -= custVendPaymJournalFeeLoc.FeeValue;
                }
            }

            feeAmount = feeAmountTotal;
            //AmountCur feeAmount = this.calculatePaymentFee_IN(ledgerJournalTrans.RecId);
            amountCur += feeAmount;
            ledgerJournalTrans.AmountCurDebit -= feeAmount;
        }

        if (ledgerJournalTrans.BankNegInstRecipientName)
        {
            recipientName = ledgerJournalTrans.BankNegInstRecipientName;
        }

        if (!recipientName && (ledgerJournalTrans.AccountType == LedgerJournalACType::Vend || ledgerJournalTrans.AccountType == LedgerJournalACType::Cust))
        {
            recipientName = ledgerJournalTrans.LedgerDimensionName;
        }

        BankChequeTable::setChequeStatus(
            accountId,
            chequeNum,
            ChequeStatus::Payment,
            ledgerJournalTrans.TransDate,
            ledgerJournalTrans.Voucher,
            CustVendCheque::ledgerJournalACType2RecipientType(ledgerJournalTrans.AccountType),
            ledgerJournalTrans.Company,
            ledgerJournalTrans.parmAccount(),
            ledgerJournalTrans.CurrencyCode,
            amountCur,
            recipientName,
            ledgerJournalTrans.RemittanceAddress,
            ledgerJournalTrans.TableId,
            ledgerJournalTrans.RecId);

        BankChequeTable bankChequeTable = BankChequeTable::find(accountId, chequeNum);
        this.insertBankPaymentTrans(ledgerJournalTrans, _custVendPaym);

        Counter totalBankChequePaymTransLines = this.getInvoiceCount(bankChequeTable);

        CustVendChequeSlipTextCalculator slipTextCalculator = this.initCustVendChequeSlipTextCalculator(bankChequeLayout);

        Counter slipLines = slipTextCalculator.calculateSlipTextLines();

        Counter startLines = 0;
        Counter bankChequePaymTransLines = 0;

        if (slipLines < slipTextCalculator.getMinimumSlipLines(bankChequeLayout.ChequeFormType))
        {
            totalBankChequePaymTransLines = 0;

            if (this.shouldResetPaymentNotes(bankChequeLayout.ChequeFormType))
            {
                ledgerJournalTrans.PaymentNotes = '';
            }
        }

        CustVendPDCRegister custVendPDCRegister; 

        select firstonly MaturityDate from custVendPDCRegister
            where custVendPDCRegister.LedgerJournalTrans == ledgerJournalTrans.RecId;

        PDCMaturityDate maturityDate =  custVendPDCRegister.MaturityDate && CustVendPDCManager::allowPostDatedChecks(ledgerJournalTrans) ? custVendPDCRegister.MaturityDate : ledgerJournalTrans.TransDate;


        while (bankChequePaymTransLines < totalBankChequePaymTransLines || totalBankChequePaymTransLines == 0)
        {
            tmpChequePrintout.clear();
            this.initTmpChequePrintout(
                ledgerJournalTrans.AccountType,
                address,
                location,
                vendTable,
                custTable,
                bankAccountTableCurrent,
                ledgerJournalTrans.BankNegInstRecipientName,
                ledgerJournalTrans.RecId,
                bankChequeLayout.ChequeFormType,
                slipTextCalculator,
                true,
                true);

            if (firstCheque)
            {
                firstCheque = false;

                this.initBankDetails(
                    accountId,
                    bankChequeLayout,
                    bankAccountTable);

                this.setChequeAmount(
                    amountCur,
                    currency,
                    bankChequeLayout,
                    vendTable,
                    custTable);

                this.setSignatures(bankChequeLayout, amountCur);

                slipChequeNum = chequeNum;
            }
            else
            {
                this.setBlankCheque(ledgerJournalTrans);
                tmpChequePrintout.Void = NoYes::Yes;
                tmpChequePrintout.BankCopySignatureText = "@SYS53120";
                tmpChequePrintout.BankCopyCustomWatermark = "@SYS53120";
                tmpChequePrintout.AccountId = accountId;

                slipLines = this.adjustSlipTextLinesForAdditionalCheques(slipLines);
            }

            tmpChequePrintout.ChequeNum = chequeNum;
            tmpChequePrintout.TransDate = ledgerJournalTrans.TransDate;
            tmpChequePrintout.MaturityDate = maturityDate;

            if ((slipTextCalculator.getNumOfSlips() > 0 && bankChequeLayout.ChequeFormType != ChequeFormType::FRStyle)
                || (bankChequeLayout.UseGER == NoYes::Yes && bankChequeLayout.GERNumberOfSlipTxtLines > 0))
            {
                [slipText, bankChequePaymTransLines, endLines] = slipTextCalculator.fillSlipText(
                    bankChequeTable,
                    startLines,
                    slipLines,
                    totalBankChequePaymTransLines,
                    bankChequeLayout.ChequeFormType);

                tmpChequePrintout.SlipTxt = slipText;
                tmpChequePrintout.DiscountTaken = slipTextCalculator.totalDiscount;
                tmpChequePrintout.TotalPaid = slipTextCalculator.totalPaid;
                tmpChequePrintout.TotalAmount = slipTextCalculator.totalAmount;
                //Created and updated total fields in BankChequeTable, To fetch these vaules when running report from CHECKS.
                BankChequeTable bankChequeTableLoc = BankChequeTable::find(accountId, chequeNum);
                if(bankChequeTableLoc)
                {
                    ttsbegin;
                    bankChequeTableLoc.selectforupdate(true);
                    bankChequeTableLoc.TotalAmount     =   tmpChequePrintout.TotalAmount;
                    bankChequeTableLoc.TotalDiscount   =   tmpChequePrintout.DiscountTaken;
                    bankChequeTableLoc.TotalPaid       =   tmpChequePrintout.TotalPaid;
                    bankChequeTableLoc.update();
                    ttscommit;
                }

                if (this.shouldPrintPaymentNotes(ledgerJournalTrans, bankChequePaymTransLines, totalBankChequePaymTransLines))
                {
                    notesLines = this.notesLines(ledgerJournalTrans.PaymentNotes);

                    if (notesLines <= endLines - 1)
                    {
                        tmpChequePrintout.SlipTxt += this.formatSlipText(ledgerJournalTrans);
                        endLines -= notesLines;
                    }
                    else
                    {
                        if (endLines > 1)
                        {
                            tmpChequePrintout.SlipTxt += strRep('\n', endLines - 1);
                            endLines = 1;
                        }

                        this.insertTmpChequePrintout();
                        tmpChequePrintout.clear();

                        //Printing Payment notes but the payment notes won't fit on one check, spread it out to several checks
                        paymentNotesList = strSplit(ledgerJournalTrans.PaymentNotes, '\n');
                        notesLines = paymentNotesList.elements();
                        le = paymentNotesList.getEnumerator();

                        while (notesLines > 0)
                        {
                            endLines = slipLines;
                            this.initTmpChequePrintout(
                                ledgerJournalTrans.AccountType,
                                address,
                                location,
                                vendTable,
                                custTable,
                                bankAccountTableCurrent,
                                ledgerJournalTrans.BankNegInstRecipientName,
                                ledgerJournalTrans.ledgerJournalTable().RecId,
                                bankChequeLayout.ChequeFormType,
                                slipTextCalculator,
                                false,
                                false);

                            this.setBlankCheque(ledgerJournalTrans);

                            tmpChequePrintout.ChequeNum = chequeNum;
                            tmpChequePrintout.Void = NoYes::Yes;
                            tmpChequePrintout.BankCopySignatureText = "@SYS53120";
                            tmpChequePrintout.BankCopyCustomWatermark = "@SYS53120";
                            tmpChequePrintout.AccountId = accountId;
                            tmpChequePrintout.TransDate = ledgerJournalTrans.TransDate;

                            tmpChequePrintout.MaturityDate = maturityDate;

                            paymentNotesHeaderLinesPrinted = 0;

                            if (this.shouldUpdateSlipTextForChequePrinting(bankChequeLayout.ChequeFormType))
                            {
                                tmpChequePrintout.SlipTxt = strFmt('%1 %2\n\n', "@SYS22495", slipChequeNum);
                                paymentNotesHeaderLinesPrinted = 2;
                                endLines -= 2;
                            }

                            for (i = 0; i < slipLines - paymentNotesHeaderLinesPrinted; i++)
                            {
                                le.moveNext();
                                paymentNotesLine = le.current();

                                tmpChequePrintout.SlipTxt += paymentNotesLine;

                                if (endLines != 1)
                                {
                                    tmpChequePrintout.SlipTxt += '\n';
                                }

                                notesLines--;

                                endLines -= 1;

                                if (notesLines <= 0 || endLines == 0)
                                {
                                    break;
                                }
                            }

                            if (endLines > 1)
                            {
                                tmpChequePrintout.SlipTxt += strRep('\n', endLines - 1);
                                endLines = 1;
                            }

                            this.insertTmpChequePrintout();
                            tmpChequePrintout.SlipTxt = '';

                            if (notesLines <= 0)
                            {
                                return;
                            }
                        }
                    }

                    if (endLines > 1)
                    {
                        tmpChequePrintout.SlipTxt += strRep('\n', endLines - 1);
                        endLines = 1;
                    }
                }
                else
                {
                    if (endLines > 1)
                    {
                        tmpChequePrintout.SlipTxt += strRep('\n', endLines - 1);
                        endLines = 1;
                    }
                }
            }
            else
            {
                totalBankChequePaymTransLines = -1;
            }

            this.insertTmpChequePrintout();
            startLines = bankChequePaymTransLines;

            totalBankChequePaymTransLines = this.getRemainingTotalBankChequePaymentTransLines(totalBankChequePaymTransLines);
        }
    }

}

Thursday, 23 April 2020

Refreshing the caller form in d365

 public void close()
    {   
        next close();
        FormRun calledFomr = @this.localFormRun;
        Formdatasource  callingformdatasource = calledFomr.dataSource();
        callingformdatasource.refresh();
        callingformdatasource.reread();
        callingformdatasource.research(true);
    }

Sunday, 19 April 2020

AX7/D365/Operations: Data entities export data error

Error1


 Exception:

While exporting data from local VM of Dynamics 365 for Operations, you might get an error if the Azure storage emulator is not running.
Microsoft.WindowsAzure.Storage.StorageException: Unable to connect to the remote server —> System.Net.WebException: Unable to connect to the remote server —> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it.

Resolution:

You can start the Azure storage emulator by following the steps below:
  1. On OneBox VM, run command prompt as administrator.
  2. Navigate to “C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\”
  3. Run “AzureStorageEmulator.exe start”
This should resolve the issue reported above which surfaces while exporting data through data entities in Dynamics 365 for Operations.
Emulator

Thursday, 16 April 2020

Change Tracking For Entity Export

When we are trying to change track  the entity it is giving error like sql is not set to change tracking. Then we need to execute below code

AXDBECO - AX data base name

ALTER DATABASE AXDBECO
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON)

Tuesday, 31 March 2020

squish up the address using expressions in ssrs

=Replace(First(Fields!CompanyAddress.Value, "SalesInvoiceHeaderFooterDS")+"  Phone:  "+First(Fields!CompanyPhone.Value, "SalesInvoiceHeaderFooterDS"), Chr(10), ", ")