Thursday, December 15, 2022

AX2012 Create purchase order from sales order

 Create Purchase order from Sales order through X++


  public boolean modified()

  {

    boolean ret;

    PurchCreateFromSalesOrder purchCreateFromSalesOrder = PurchCreateFromSalesOrder::construct();

    //purchCreateFromSalesOrder.parm


    FormControl buttonControl = any2Object(this) as FormControl;

    FormRun formRun = buttonControl.formRun();

    TmpPurchLinePrice tmpPurchLinePrice;


    SalesLine salesLine, salesLineIterate;

    SalesTable salesTable;


    ret = next modified();


    salesTable = formRun.dataSource(formDataSourceStr(SalesTable, SalesTable)).cursor();


    salesLine = formRun.dataSource(formDataSourceStr(SalesTable, SalesLine)).cursor();


    if (SalesType::Sales == salesTable.SalesType)

    {

      while select salesLineIterate 

        where salesLineIterate.SalesId == salesLine.SalesId

      {

        tmpPurchLinePrice.clear();


          InventTable inventTable             = salesLineIterate.inventTable();

          tmpPurchLinePrice.SalesId           = salesLineIterate.SalesId;

          tmpPurchLinePrice.LineNum           = salesLineIterate.LineNum;

          tmpPurchLinePrice.SalesLineRefRecId = salesLineIterate.RecId;

          tmpPurchLinePrice.AccountNum        = inventTable.PrimaryVendorId;

          tmpPurchLinePrice.Included          = NoYes::Yes;

          tmpPurchLinePrice.ItemId            = salesLineIterate.ItemId;

          tmpPurchLinePrice.InventDimId       = salesLineIterate.InventDimId;

          tmpPurchLinePrice.initFromInventTable(inventTable);

          tmpPurchLinePrice.PurchUnit = salesLineIterate.SalesUnit;


          if (salesTable.SalesType == SalesType::ReturnItem)

          {

            tmpPurchLinePrice.PurchQty  = salesLineIterate.ExpectedRetQty;

            tmpPurchLinePrice.PdsCWQty  = salesLineIterate.PdsCWExpectedRetQty;

          }

          else

          {

            tmpPurchLinePrice.PurchQty  = salesLineIterate.RemainSalesPhysical;

            tmpPurchLinePrice.PdsCWQty  = salesLineIterate.PdsCWRemainInventPhysical;

          }


          tmpPurchLinePrice.PurchUnit = salesLineIterate.SalesUnit;

          tmpPurchLinePrice.PurchQty = EcoResProductUnitConverter::convertGivenUnitSymbolsForReleasedProduct(tmpPurchLinePrice.ItemId,

                                                                                                                        tmpPurchLinePrice.InventDimId,

                                                                                                                        tmpPurchLinePrice.PurchQty,

                                                                                                                        salesLine.SalesUnit,

                                                                                                                        tmpPurchLinePrice.PurchUnit,

                                                                                                                        NoYes::Yes);


          tmpPurchLinePrice.PriceSearched = NoYes::No;


          if (tmpPurchLinePrice.validateWrite())

          {

            tmpPurchLinePrice.insert();

          }

        }


        purchCreateFromSalesOrder = PurchCreateFromSalesOrder::construct();

        purchCreateFromSalesOrder.parmCallerRecord(salesTable);

        purchCreateFromSalesOrder.parmTmpPurchLinePrice(tmpPurchLinePrice);


        purchCreateFromSalesOrder.parmSalesTable(salesTable);

        purchCreateFromSalesOrder.tradeLineDlvType(tradeLineDlvType::None);

        purchCreateFromSalesOrder.run();

    }


      return ret;

  }

D365 Create Purchase Order from Sale Order ( Direct Delivery) X++

 In my requirement, when sale order type is changed from journal to Sales order. Then purchase order must be created. Below is the code to achieve that.

[ExtensionOf(formControlStr(SalesTable, SalesTable_SalesType))]

public final class CPlDdevSalesTableForm_SalesTable_SalesType_Extension

{

  public boolean modified()

  {

    boolean ret;

    PurchCreateFromSalesOrder purchCreateFromSalesOrder = PurchCreateFromSalesOrder::construct();

    FormControl buttonControl = any2Object(this) as FormControl;

    FormRun formRun = buttonControl.formRun();

    TmpPurchLinePrice tmpPurchLinePrice;


    SalesLine salesLine, salesLineIterate;

    SalesTable salesTable;


    ret = next modified();


    salesTable = formRun.dataSource(formDataSourceStr(SalesTable, SalesTable)).cursor();


    salesLine = formRun.dataSource(formDataSourceStr(SalesTable, SalesLine)).cursor();


    if (SalesType::Sales == salesTable.SalesType)

    {

      while select salesLineIterate

        where salesLineIterate.SalesId == salesLine.SalesId

      {

        tmpPurchLinePrice.clear();


        InventTable inventTable             = salesLineIterate.inventTable();

        tmpPurchLinePrice.SalesId           = salesLineIterate.SalesId;

        tmpPurchLinePrice.LineNum           = salesLineIterate.LineNum;

        tmpPurchLinePrice.SalesLineRefRecId = salesLineIterate.RecId;

        tmpPurchLinePrice.AccountNum        = inventTable.PrimaryVendorId;

        tmpPurchLinePrice.Included          = NoYes::Yes;

        tmpPurchLinePrice.ItemId            = salesLineIterate.ItemId;

        tmpPurchLinePrice.InventDimId       = salesLineIterate.InventDimId;

        tmpPurchLinePrice.initFromInventTable(inventTable);

        tmpPurchLinePrice.PurchUnit = salesLineIterate.SalesUnit;


        if (salesTable.SalesType == SalesType::ReturnItem)

        {

          tmpPurchLinePrice.PurchQty  = salesLineIterate.ExpectedRetQty;

          tmpPurchLinePrice.PdsCWQty  = salesLineIterate.PdsCWExpectedRetQty;

        }

        else

        {

          tmpPurchLinePrice.PurchQty  = salesLineIterate.RemainSalesPhysical;

          tmpPurchLinePrice.PdsCWQty  = salesLineIterate.PdsCWRemainInventPhysical;

        }


        tmpPurchLinePrice.PurchUnit = salesLineIterate.SalesUnit;

        tmpPurchLinePrice.PurchQty = EcoResProductUnitConverter::convertGivenUnitSymbolsForReleasedProduct(tmpPurchLinePrice.ItemId,

                                                                                                                        tmpPurchLinePrice.InventDimId,

                                                                                                                        tmpPurchLinePrice.PurchQty,

                                                                                                                        salesLine.SalesUnit,

                                                                                                                        tmpPurchLinePrice.PurchUnit,

                                                                                                                        NoYes::Yes);


        tmpPurchLinePrice.PriceSearched = NoYes::No;


        if (tmpPurchLinePrice.validateWrite())

        {

          tmpPurchLinePrice.insert();

        }

      }


      purchCreateFromSalesOrder = PurchCreateFromSalesOrder::construct();

      purchCreateFromSalesOrder.parmCallerRecord(salesTable);

      purchCreateFromSalesOrder.parmTmpPurchLinePrice(tmpPurchLinePrice);

      purchCreateFromSalesOrder.parmSalesTable(salesTable);

      purchCreateFromSalesOrder.parmSalesLine(salesLine);

      purchCreateFromSalesOrder.tradeLineDlvType(tradeLineDlvType::DropShip);

      

      PurchAutoCreate purchAutoCreate =  PurchAutoCreate::construct(tmpPurchLinePrice,      purchCreateFromSalesOrder);

      purchAutoCreate.create();

    }


    return ret;

  }

}

Saturday, December 10, 2022

Refresh the calling form code

  FormRun callerForm;

if (element.args() && element.args().caller() && element.args().caller().name() == formStr(SMAServiceOrderTableListPage))
    {
        callerForm = element.args().caller();
        callerForm.dataSource().research();
    }

Visual Studio Settings that needs to be done before starting development

 Graphical user interface, text, application

Description automatically generated


Graphical user interface, text, application

Description automatically generated

Graphical user interface, text, application

Description automatically generated

Graphical user interface, text, application

Description automatically generated

To make newly created elements appear in same like AOT


To have multiple tabs.











Useful Static methods

 DateTimeUtil::date(DateTimeUtil::applyTimeZoneOffset(DateTimeUtil::getSystemDateTime(), DateTimeUtil::getUserPreferredTimeZone()))


NumberSeq::newGetNum(InventParameters::numRefInventTransId()).num();

SQL query to get table name from table ID

 select NAME

     from SQLDICTIONARY

     where TABLEID = 366 and FIELDID = 0


Select * from SysTableIdView Where SystableIdView.Name = ‘PurchTable’

No Lock SQL query sample

 This sql query shows the records that are stored in SQL table buffer between the ttsbegin and ttscommit. In case, if there is failure to insert record into table. we can know what record was present before the failure

select REPLENISHMENTORDERNUMBER, * from ConsignmentDraftReplenishmentOrderJournalLine with (nolock) order by recid desc


Query to select last 10 records

  select TOP 10 itemid, QTY, INVENTTRANSORIGIN, INVENTDIMID, * from INVENTTRANS with (nolock) order by recid desc 

Visual Studio setting for having newly created objects to be like AOT

 













Form method sequence

 Event Method Sequences in Form Scenarios | Microsoft Learn


https://learn.microsoft.com/en-us/dynamicsax-2012/developer/event-method-sequences-in-form-scenarios

Deploy reports through powershell

 


cd K:\AosService\PackagesLocalDirectory\Plugins\AxReportVmRoleStartupTask\

./DeployAllReportsToSSRS.ps1 -Module XYZAX2012 -ReportName ProdCustPackingSheetRawMat.Report -PackageInstallLocation "K:\AosService\PackagesLocalDirectory"


Useful links

https://community.dynamics.com/365/financeandoperations/b/dynamics-365-fo-tech-talks/posts/how-to-manually-deploy-ssrs-reports-through-powershell-in-d365-fo


https://www.cloudfronts.com/blog/d365-enterprise/d365-finance-operations/d365-fo-different-ways-to-deploy-ssrs-reports/

How to run your integration through D365FO URL

 https://xyz-upg01a1da3be2829c0b74devaos.axcloud.dynamics.com/api/services/xyz_ICProdRcptServiceGroup/CPL_ICProductReceiptPosting



 https://xyz-dev-upg01a1da3be2829c0b74devaos.axcloud.dynamics.com/ <- upto this part is normal D365 FO URL. After that paste api/services/xyz_ICProdRcptServiceGroup/CPL_ICProductReceiptPosting



xyz_ICProdRcptServiceGroup/CPL_ICProductReceiptPosting< this will be your service class

Minimum required to models to reference


 

To Clear Caches

Enable hidden folders visible option






Clear Catches from below path to fix strange behaviours

C:\Users\User5a3d16e883d\AppData\Local\Microsoft\VisualStudio\16.0_e0fab5b4\ComponentModelCache\

C:\Users\User5a3d16e883d\AppData\Local\Microsoft\VisualStudio Services\8.0\Cache

C:\Users\User5a3d16e883d\AppData\Local\Microsoft\Team Foundation\8.0\Cache


SQL Syntax to find enum values of extended enum

 SELECT ev.NAME,ev.ENUMVALUE

  FROM ENUMIDTABLE ei

  INNER JOIN ENUMVALUETABLE ev

    ON ev.ENUMID = ei.ID

  WHERE ei.NAME = 'ProjTransStatus'

  ORDER BY ev.ENUMVALUE


Form Level COC syntax

 Useful COC syntax

1. Form level
2. Form Datasource level
3. Form DataField level
4. Form Control level

Form level CoC:

When extending a form, use formStr(<FormName>)

 Get Buffers:  

FormRun               formRun             =  this as  FormRun;
FormDataSource  dataSource_ds    =  formRun.datasource(FormDatasourceStr(FormName,DatasourceName));
TableName             tableName         =  dataSource_ds.Cursor();
FormControl          formControl      =  formRun.design().ControlName(FormControlStr(FormName,ControlName));

 Example:

[ExtensionOf(formStr(SalesTable))]
final class KSSalesTableFrm_Extension
{
    public int active()
    {
FormRun              formRun                  = this as  FormRun;


        //get any datasource from the base form
FormDataSource salesLine_ds            = formRun.datasource(FormDatasourceStr(SalesTable,SalesLine));  
SalesLine              salesLine                  = salesLine_ds.Cursor();

//get any formcontrol from the base form
FormControl      itemName= formRun.design().ControlName(FormControlStr(SalesTable, itemName));

//business Logic

 return next active();
      }
}

2. Form Datasource level CoC:

When extending a form Datasource, use formDataSourceStr(<FormName>, <DataSourceName>)

Example:

[ExtensionOf(formDatasourceStr(SalesTable, SalesLine))]
final class KSSalesTableFrm_SalesLineDS_Extension
{
    public void executeQuery()
    {
         next executeQuery();

        FormDataSource                  formDS                    = this;
        FormComboBoxControl      comboBoxControl;   

        //get form datasource       
        SalesLine             salesLineLocal  = this.cursor();               

//get any other datasource from the base form
        FormDataSource inventDim_ds  = formDS.formRun().dataSource(formDataSourceStr(SalesTable, InventDim));
        InventDim            inventDim      = inventDim_ds.cursor();

//get any formcontrol from the base form
        comboBoxControl     = formDS.formRun().design().controlName(formControlStr(SalesTable, SalesTable_SalesTypeGrid));

        //business logic
    }
}


3.  Form Datafield level CoC:

When extending a form Datasource Field, use formDataFieldStr(<FormName>, <DataSourceName>, <DataFieldName>)

Example:

[ExtensionOf(formDataFieldStr(SalesTable, SalesLine, BarCode))]
final class KSSalesTableFrm_SalesLineDS_BarCodeDF_Extension
{
    public void modified()
    {
         next modified();

         FormDataObject                    barCode_do = any2Object(this) as FormDataObject;
         FormComboBoxControl       comboBoxControl;        

         //get form datasource
        FormDataSource                 salesLine_ds   = barCode_do.datasource();
        SalesLine                              salesLine         salesLine_ds.cursor();

//get any other datasource from the base form
        InventDim    inventDim     = salesLine_ds.formRun().dataSource(formDataSourceStr(SalesTable, InventDim)).cursor();

//get any formcontrol from the base form
 comboBoxControl   = salesLine_ds.formRun().design().controlName(formControlStr(SalesTable, SalesTable_SalesTypeGrid));

        //business logic
      }
}


4.  Form DataControl level CoC:

When extending a form DataControl Field, use formDataControlStr(<FormName>, <ControlName>)

Example:

[ExtensionOf(formControlStr(SalesTable, PrintMgmt))]
final class KSSalesTableFrm_PrintMgmtCtl_Extension
{
    public void clicked()
    {

        FormControl                       buttonControl         any2Object(this) as FormControl;
        FormRun                             formRun                 buttonControl.formRun();
       
        InventDim                           inventDim
        FormComboBoxControl   formComboBoxControl;

//get any datasource from the base form
        inventDim     = formRun.dataSource(formDataSourceStr(SalesTable, InventDim)).cursor();

//get any formcontrol from the base form
 formComboBoxControl   = formRun.design().controlName(formControlStr(SalesTable, SalesTable_SalesTypeGrid));

        next clicked();
        //business logic
      }
}


Build Explained

Useful Blogs. https://axtechsolutions.blogspot.com/2018/08/performing-builds-in-d365.html https://community.dynamics.com/blogs/post/?postid=...