26 July 2019

Display inventory dimensions dynamically in D365 / Add display inventory dimensions in form

Display inventory dimensions dynamically in D365

Please click here for link

and use the below code to 

InventDimCtrl_Frm_EditDimensions    inventDimFormSetup;

 /// <summary>
    /// Inventory dimension group method.
    /// </summary>
    /// <returns>
    /// A <c>InventDimCtrl_Frm_EditDimensions</c> object.
    /// </returns>
    InventDimCtrl_Frm_EditDimensions inventDimSetupObject()
    {
        return inventDimFormSetup;
    }

 /// <summary>
    /// Initializes the range and inventory dimensions to be display while opening the form
    /// </summary>
    public void init()
    {
        super();
        // Add a filter to the query. Specify the field to use in the filter.
       
        //This method will be used to show default fields at the form setup
        element.updateDesign(InventDimFormDesignUpdate::Init);
    }
/// <summary>
    /// Update design mode as per inventory dimension
    /// </summary>
    /// <param name="_mode">
    /// Inventory dimension design mode.
    /// </param>
    void updateDesign(InventDimFormDesignUpdate _mode)
    {
        switch (_mode)
        {
            // Form Init
            case InventDimFormDesignUpdate::Init    :
                if (!inventDimFormSetup)
                {
                    inventDimFormSetup  = InventDimCtrl_Frm_EditDimensions::newFromForm(element);
                    inventDimFormSetup.parmSkipOnHandLookUp( true);
                }

            // Datasource Active
            case InventDimFormDesignUpdate::Active  :
                inventDimFormSetup.formActiveSetup(InventDimGroupSetup::newItemId(DataSourceTable.ItemId)); //InventDimDisplay is the datasource name.
                inventDimFormSetup.formSetControls( true);
                break;

            // Datasource Field change
            case InventDimFormDesignUpdate::FieldChange :
                inventDimFormSetup.formActiveSetup(InventDimGroupSetup::newItemId(DataSourceTable.ItemId)); //InventDimDisplay is the datasource name.
                InventDim.clearNotSelectedDim(inventDimFormSetup.parmDimParmEnabled()); // InventDim is referring to datasource name
                inventDimFormSetup.formSetControls( true);
                break;

            default :
                throw error(strFmt ("@SYS54195", funcName()));

        }
    }
Add the below code in the DS active method.
int  active()
        {
            int ret;

            ret = super();

            element.updateDesign(InventDimFormDesignUpdate::Active);

            return ret;

        }


24 July 2019

How to populate form data source with temp table. D365 FO and AX7

Create new form, add temptable as DataSource.

DS-> Init()

public void init() // init method of form data source. 
{
   CustGroupTmp tmpTable; 
   super();
   tmpTable.CustGroupId= "Test1";
   tmpTable.insert();
   tmpTable.CustGroupId= "Test2";
   tmpTable.insert(); 
   CustGroupTmp.linkPhysicalTableInstance(tmpTable); // CustGroupTmp is the form datasource name this cursor

//or 
CustGroupTmp.setTmpData(tmpTable);
TableType should be: InMemory
}

work in class inserting temptable records.

// to use the same logic in the class, pass the formDatasource-CustGroupTmp to class
if (_args.record().TableId == tableNum(CustGroupTmp))
{
 FormDataSource formDS = _args.caller().datasource(formDataSourceStr(CustGroupTmpForm, CustGroupTmp)) as FormDataSource;
 CustGroupTmp = formDS.cursor();
 formDS.executeQuery();
}

// FormDataSource fds
// CustGroupTmp custGroupTempBuffer = fds.cursor()
// custGroupTempBuffer.linkPhysicalTableInstance(tmpTable);

18 July 2019

X++ code to write data to Notepad or CSV file in D365FO or AX7

TextStreamIo                        streamIO;
FileName                            fileNameWithExt;
    FileName                            fileName;

 public void initFile()
    {
        #define.validationFileSuffix('-data-validation-errors.txt')
        InteropPermission perm = new InteropPermission(InteropKind::ClrInterop);
       
        perm.assert();
        streamIO = TextStreamIO::constructForWrite(#utf8format);
        streamIO.outRecordDelimiter(#delimiterCRLF);

        fileName += #validationFileSuffix;
    }

boolean validationFailed(FreeTxt _errorTxt)
    {
        boolean ret;

        if(!streamIO)
        {
            this.initFile();
        }
           
        streamIO.write(_errorTxt);

        return ret;
    }


 public void downloadFile()
    {
        if (streamIo != null)
        {
            File::SendFileToUser(streamIo.getStream(), fileName);
        }

        CodeAccessPermission::revertAssert();
    }

10 July 2019

How to calculate Available physical of an item given the inventLocationId that shown on the on hand form


How to get available physical for an Item and for Warehouse in AX 2012 / D365 FO 
InventDimParm       invDimParm;
   InventDim           invDim;
   Qty                 availPhys;

   invDim.InventLocationId = 'INVENTLOCATIONID';
   invDim = InventDim::findOrCreate(invDim);
   invDimParm.initFromInventDim(InventDim::find(invDim.inventDimId));
   availPhys = InventSum::findSum("ITEMID",invDim,invDimParm).availPhysical();
   info(strfmt("availPhys:%1 ",availPhys));
========
InventDim           inventDim;
   InventDimParm       inventDimParm;
   InventOnhand        inventOnhand;
  
   inventDim.InventLocationId = 'Yourwarehouse';
   inventDimParm.initFromInventDim(inventDim);
   inventOnhand = InventOnhand::newParameters('Youritem', inventDim, inventDimParm);
   info(strfmt("Available Physical: %1", inventOnhand.availPhysical()));

08 July 2019

Credit limit check on Sales Quotation based on the customer credit limit in D365 FO of AX7


class TRG_SalesQuotationTableWriteEventHandler
{
    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    [FormDataSourceEventHandler(formDataSourceStr(SalesQuotationTable, SalesQuotationLine), FormDataSourceEventType::Written)]
    public static void SalesQuotationLine_OnWriting(FormDataSource sender, FormDataSourceEventArgs e)
    {
        SalesQuotationTable salesQuotationTable;
        SalesQuotationLine  salesQuotationLine,salesQuotationLineLoc;
        CustTransOpenSum    custTransOpenSum;

        salesQuotationLineLoc = sender.cursor();
        salesQuotationTable = salesQuotationTable::find(salesQuotationLineLoc.QuotationId);

        if(smmParametersTable::find().CheckCreditLimitOnQuotation == NoYes::Yes)
        {
            Amount creditLimit  = CustTable::find(salesQuotationLineLoc.CustAccount).CreditMax;
            select sum(LineAmount) from salesQuotationLine
                group by QuotationId
                where salesQuotationLine.QuotationId == salesQuotationTable.QuotationId;
           
            select AccountNum,AmountMST from custTransOpenSum
                where custTransOpenSum.AccountNum == salesQuotationTable.CustAccount;

            Amount newBalance = custTransOpenSum.AmountMST + salesQuotationLine.LineAmount;
            Amount creditExcess = newBalance - creditLimit;
            if(newBalance  > creditLimit)
            {
                warning(strFmt("Quotation:%1 Creit limit exedded Opening balance %2 Current order:%3 New balance:%4 Credit limit:%5 Credit excess:%6 ",
                    salesQuotationLineLoc.QuotationId,
                    custTransOpenSum.AmountMST,
                    salesQuotationLine.LineAmount,
                    newBalance,
                    creditLimit,
                    creditExcess));
            }
        }
    }

}

Ledger Voucher creation Framework and x++ code to create ledger voucher

 Please click her for MS reference file Below is the out of the box example reference and code. SalesInvoiceJournalPostSubBill_Extension->...