Thursday, March 24, 2022

Sample Dialog Syntax - 1

 class AffiliationAutoAssignment extends RunBaseBatch

{    

// 1. Class Declaration and Pack variables

    #define.CurrentVersion(1)

    #define.Version1(1)

 

// 2. Dialog Method

/// <summary>

    /// Generate default dialog

    /// </summary>

    /// <returns>default framework dialog validation</returns>

    public Object dialog()

    {

        return super();

    }

// 2. getFromDialog Method

/// <summary>

    /// Get from dialog

    /// </summary>

    /// <returns>boolean</returns>

    public boolean getFromDialog()

    {

        return super();

    }

// 3. Construct Method

/// <summary>

    /// Class Construct method

    /// </summary>

    /// <returns>class AffiliationAutoAssignment </returns>

    public static AffiliationAutoAssignment construct()

    {

        return new AffiliationAutoAssignment();

    }

// 4 Pack method

/// <summary>

    /// Maintains state/version

    /// </summary>

    /// <returns>version and current list</returns>

    public container pack()

    {

        return [#CurrentVersion];

    }

// 5. UnPack method

 /// <summary>

    /// Gets the state/version

    /// </summary>

    /// <param name = "packedClass">container</param>

    /// <returns>true, if it gets previous version</returns>

    public boolean unpack(container packedClass)

    {

        Version version = runbase::getVersion(packedClass);

        ;

        switch (version)

        {

            case #CurrentVersion:

                [version] = packedClass;

                break;

            default:

                return false;

        }

        return true;

    }

// 7. CanRunInNewSession method

/// <summary>

    /// Describes whether the class is designed for execution in a new session.

    /// </summary>

    /// <returns>

    /// true if the class is designed for execution the operation in a new session; otherwise, false.

    /// </returns>

    protected boolean canRunInNewSession()

    {

        return false;

    }

// 8. Run method
/// <summary>
    /// Execute logic to update auto assignment for affiliations based on date range 
    /// </summary>
    public void run()
    {
        System.Exception ex;
        #OCCRetryCount

        try
        {
            this.processData();

            Info("@OperationCompleted");
        }
        catch (Exception::CLRError)
        {
            ex = CLRInterop::getLastException();
            error(ex.ToString());
        }
        catch (Exception::Deadlock)
        {
            retry;
        }
        catch (Exception::UpdateConflict)
        {
            if (appl.ttsLevel() == 0)
            {
                if (xSession::currentRetryCount() >= #RetryNum)
                {
                    throw Exception::UpdateConflictNotRecovered;
                }
                else
                {
                    retry;
                }
            }
            else
            {
                throw Exception::UpdateConflict;
            }
        }
    }

/// <summary>
    /// Entry point to process.
    /// </summary>
    /// <param name = "_args">Args</param>
    public static void main(Args _args)
    {
        AffiliationAutoAssignment affiliationAutoAssignment = new AffiliationAutoAssignment();
        
        if (affiliationAutoAssignment.prompt())
        {
            affiliationAutoAssignment.runOperation();
        }
    }


/// <summary>
    /// set description for batch run
    /// </summary>
    /// <returns>return class description string</returns>
    static ClassDescription description()
    {
        return "UpdateAffiliationAssignments";
    }

Exception Handling for Run Method in Runbase

 public void run()

    {

        System.Exception ex;

        #OCCRetryCount


        try

        {

            this.processData(); //Main logic


            Info("OperationCompleted");

        }

        catch (Exception::CLRError)

        {

            ex = CLRInterop::getLastException();

            error(ex.ToString());

        }

        catch (Exception::Deadlock)

        {

            retry;

        }

        catch (Exception::UpdateConflict)

        {

            if (appl.ttsLevel() == 0)

            {

                if (xSession::currentRetryCount() >= #RetryNum)

                {

                    throw Exception::UpdateConflictNotRecovered;

                }

                else

                {

                    retry;

                }

            }

            else

            {

                throw Exception::UpdateConflict;

            }

        }

    }

Exception Handling for Run Method in RunBase

Use Runbase class instance to get showBatchTab and use below for visiblity

 showBatchTab(True)

or 

showBatchTab(False)

Lookup Code

  

    [FormControlEventHandler(formControlStr(BOMExpandSales, ChargeCode), FormControlEventType::Lookup)]

    public static void ChargeCode_OnLookup(FormControl sender, FormControlEventArgs e)

    {

        Query                   query;

        QueryBuildDataSource    queryBuildDataSource;

        QueryBuildRange         queryBuildRange; 

        SysTableLookup          sysTableLookup;


        sysTableLookup = SysTableLookup::newParameters(tablenum(MarkupTable), sender);

        sysTableLookup.addLookupfield(fieldnum(MarkupTable, MarkupCode), true);

        sysTableLookup.addLookupfield(fieldnum(MarkupTable, Txt));


        query                   = new Query();

        queryBuildDataSource    = query.addDataSource(tablenum(MarkupTable));


        queryBuildRange = queryBuildDataSource.addRange(fieldnum(MarkupTable, ModuleType));

        queryBuildRange.value(queryValue(MarkupModuleType::Cust));

        

        sysTableLookup.parmQuery(query);

        sysTableLookup.performFormLookup();

    }

Standard Batch - adding our variable for Pack/UnPack - 1

1. 

[ExtensionOf(classStr(BomCalcJob))]

final class BomCalcJobBRU_Extension


 #define.CurrentVersion(1)

    #LOCALMACRO.CurrentList

        useCalcDate

    #ENDMACRO

2.

/// <summary>

    /// Maintains state/version

    /// </summary>

    /// <returns>vesion and current list</returns>

    private container currentPack()

    {

        return [#CurrentVersion, #CurrentList];

    }

3.

/// <summary>

    /// Maintains state/version

    /// </summary>

    /// <returns>vesion and current list</returns>

    public container pack()

    {

        container packedClass = next pack();

        return SysPackExtensions::appendExtension(packedClass, classStr(BomCalcJobBRU_Extension), this.currentPack());

    }

4.

 /// <summary>

    /// Gets the state/version

    /// </summary>

    /// <param name = "_packedClass">container</param>

    /// <returns>true, if it gets previous version</returns>

    private boolean currentUnpack(container packedClass)

    {

        Integer version = RunBase::getVersion(packedClass);

        switch (version)

        {

            case #CurrentVersion:

                [version, #currentList] = packedClass;

                break;

            default:

                return false;

        }

        return true;

    }

5.

/// <summary>

    /// Gets the state/version

    /// </summary>

    /// <param name = "_packedClass">container</param>

    /// <returns>true, if it gets previous version</returns>

    public boolean unpack(container _packedClass)

    {

        boolean result = next unpack(_packedClass);


        if (result)

        {

            container currentState = SysPackExtensions::findExtension(_packedClass, classStr(BomCalcJobBRU_Extension));

            //Also unpack the extension

            if (!this.currentUnpack(currentState))

            {

                result = false;

            }

        }


        return result;

    }

Update existing report logic in Process Record

 // <summary>

    ///  Post event handler for processReport method.

    /// </summary>

    /// <param name="args">The arguments</param>

    [PostHandlerFor(classStr(AssetInventoryWorkSheetDP), methodStr(AssetInventoryWorkSheetDP, processReport))]

    public static void AssetInventoryWorkSheetDP_Post_processReport(XppPrePostArgs args)

    {

//1. Get the DP class buffer using args.getThis(). 

//2. Get the temporary table variable using get method

        AssetInventoryWorkSheetDP   assetInventoryWorkSheetDP       = args.getThis() as AssetInventoryWorkSheetDP;

        AssetTmpInventoryWorkSheet  assetTmpInventoryWorkSheetLoc   = assetInventoryWorkSheetDP.getAssetTmpPhysicalInventory();

        AssetTable                  assetTable;


        ttsbegin;

        while select forupdate assetTmpInventoryWorkSheetLoc

            join Barcode, RecId from assetTable

                where assetTable.AssetId == assetTmpInventoryWorkSheetLoc.AssetId

        {

            AssetImage      assetImage      = AssetImage::findForAsset(assetTable.RecId);

            AssetSumCalc    assetSumCalc    = AssetSumCalc_Trans::newAssetYear(

                                            assetTmpInventoryWorkSheetLoc.AssetId,

                                            assetTmpInventoryWorkSheetLoc.BookId);


            assetTmpInventoryWorkSheetLoc.Barcode        = assetTable.Barcode;

            assetTmpInventoryWorkSheetLoc.NetBookValue   = assetSumCalc.netBookValue();

            assetTmpInventoryWorkSheetLoc.Image          = assetImage.Image;


            if (assetImage.RecId)

            {

                assetTmpInventoryWorkSheetLoc.ImageExists    = true;

            }

            else

            {

                assetTmpInventoryWorkSheetLoc.ImageExists    = false;

            }


            assetTmpInventoryWorkSheetLoc.update();

        }

        ttscommit;

    }

Num2Str - Number to String

 str num2Str(   real number,    int character,    int decimals,    int separator1,    int separator2)


Possible enumeration values for the separator1:

  • 1 – point (.)
  • 2 – comma (,)

Possible values for the separator2 :

  • 0 – no thousands separator
  • 1 – point (.)
  • 2 – comma (,)
  • 3 – space ( )
ParameterDescription
numberThe real number to convert to a string.
characterThe minimum number of characters required in the text.
decimalsThe required number of decimal places.
separator1A DecimalSeparator enumeration value.
separator2A ThousandSeparator enumeration value.

Monday, February 28, 2022

Process multiple selected record

1. Create a button ProcessSelected(Form Button Control , Text( On Hold(All Selected)), MultiSelect - Yes

2. Copy the event handler and remove static, We will be able to use this here.

 [FormControlEventHandler(formControlStr(VendTable, ProcessSelected), FormControlEventType::Clicked)]

    public void ProcessSelected_OnClicked(FormControl sender, FormControlEventArgs e)

    {

        this.processSelected(sender,e);

    }

3. ProcessSelected method

public void processSelected(FormControl sender,FormControlEventArgs e)

    {

        VendTable tmpVendTable, updateVendTable;         

        int recordUpdated;


        for(tmpVendTable = this.VendTable_ds.getFirst(true) ?

            this.VendTable_ds.getFirst(true) :

            this.VendTable_ds.cursor(); tmpVendTable; tmpVendTable =

            this.VendTable_ds.getNext())

        {

            ttsbegin;

            select firstonly forupdate updateVendTable where

                updateVendTable.AccountNum == tmpVendTable.AccountNum;

            updateVendTable.Blocked = CustVendorBlocked::All;

            updateVendTable.update();

            recordUpdated++;

            ttscommit;

        }

        info(strFmt("Total %1 records processed", recordUpdated));

    }


Combo Box selection at Form level and filtering records in D365 form

1. Create Main account Extension

2. Add a group Filter, Auto dec - Yes

3. Within the group add ComboBox control FilterType, Auto decl -Yes, Selection - 10(Profit Loss), Enum Type -  DimensionLedgerAccountType

4. Also Add Filter Name -> Type String, Edt - Account Name

4. Create a class extension MainAccountForm_Extension, Add below methods


    [FormControlEventHandler(formControlStr(MainAccount, FilterName), FormControlEventType::Modified)]

    public static void FilterName_OnModified(FormControl sender, FormControlEventArgs e)

    {

        FormDataSource mainAccount_ds = sender.formRun().dataSource(formdatasourcestr(MainAccount,MainAccount));

        mainAccount_ds.executeQuery();

    }


/// <summary>

    ///

    /// </summary>

    /// <param name="sender"></param>

    /// <param name="e"></param>

    [FormControlEventHandler(formControlStr(MainAccount, FilterType), FormControlEventType::Modified)]

    public static void FilterType_OnModified(FormControl sender, FormControlEventArgs e)

    {

        FormDataSource mainAccount_ds =sender.formRun().dataSource(formdatasourcestr(MainAccount,MainAccount));

        mainAccount_ds.executeQuery();

    }


 [FormDataSourceEventHandler(formDataSourceStr(MainAccount, MainAccount), FormDataSourceEventType::QueryExecuting)]
    public static void MainAccount_OnQueryExecuting(FormDataSource sender, FormDataSourceEventArgs e)
    {
        QueryBuildRange qbrName;
        QueryBuildRange qbrType;

        QueryBuildDataSource qbds = sender.query().dataSourceTable(tableNum(MainAccount));
        MainAccount::updateBalances();

qbrName = SysQuery::findOrCreateRange(qbds,fieldNum(MainAccount,Name));
        qbrType = SysQuery::findOrCreateRange( qbds,fieldNum(MainAccount,Type));

        str filterText = sender.formRun().design().controlName("FilterName").valueStr();
        if (filterText)
        {
            qbrName.value(SysQuery::valueLike(filterText));
        }
        else
        {
            qbrName.value(SysQuery::valueUnlimited());
        }
        FormComboBoxControl FilterType = sender.formRun().design().controlName("FilterType");
        if (FilterType.selection() == DimensionLedgerAccountType::Blank)
        {
            qbrType.value(SysQuery::valueUnlimited());
        }
        else
        {
            qbrType.value(queryValue(FilterType.selection()));
        }
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    [FormDataSourceEventHandler(formDataSourceStr(MainAccount, MainAccount), FormDataSourceEventType::QueryExecuted)]
    public static void MainAccount_OnQueryExecuted(FormDataSource sender, FormDataSourceEventArgs e)
    {

        FormRun formRun = sender.formRun();
        formRun.CreateTree();
    }

Points to remember

a. The control should be auto declared to Yes

b. On modified should call the execute query.

c. Execute query should define the range, it should check if the range exist if not create and then apply the range.

example qbrName = SysQuery::findOrCreateRange(qbds,fieldNum(MainAccount,Name)); 

d. In case of  text match, use qbrName.value(SysQuery::valueLike(filterText)); else make it value unlimited qbrName.value(SysQuery::valueUnlimited());



Monday, February 21, 2022

ADDING COLOR TO A FORM CONTROL

[FormDataSourceEventHandler(formDataSourceStr(SalesTable, SalesLine), FormDataSourceEventType::DisplayOptionInitialize)]
public static void SalesLine_OnDisplayOptionInitialize(FormDataSource sender, FormDataSourceEventArgs e)
{
FormDataSourceDisplayOptionInitializeEventArgs eventArgs = e as FormDataSourceDisplayOptionInitializeEventArgs;
eventArgs.displayOption().affectedElementsByControl(sender.formRun().design(0).controlName(“ControlName”).id());
eventArgs.displayOption().textColor(WinAPI::RGB2int(255,0,0));
}

Financial Dimension Function

Getting main account from ledger dimension.

 MainAccount mainAccount = MainAccount::findByLedgerDimension(trvCostType.LedgerDimension);


Dimension Value from Dimension name( cost center or )

 public DimensionValue getDimensionValues(DimensionDefault _defaultDimension, str _dimensionName)

    {

        DimensionAttributeValueSetStorage   dimStorage;

        DimensionAttribute                  dimensionAttribute;

        DimensionAttributeValue             dimensionAttributeValue;

        DimensionValue                      dimensionValue;


        dimStorage = DimensionAttributeValueSetStorage::find(_defaultDimension);

        

        dimensionAttribute.clear();

        dimensionAttributeValue.clear();

        dimensionAttribute = DimensionAttribute::findByName(_dimensionName);

        if (dimStorage != null && dimensionAttribute)

        {

            dimensionAttributeValue = DimensionAttributeValue::find(dimStorage.getValueByDimensionAttribute(dimensionAttribute.RecId));


            dimensionValue = dimStorage.getDisplayValueByDimensionAttribute(dimensionAttribute.RecId);

        }


        return dimensionValue;

    }

Saturday, February 19, 2022

Parameter Form - Table of Content(TOC)

 1. Create Parameter table -> Cache Lookup (Entire Table) -> Table Type(Parameter).

2. Add the required fields.

3. Add a field Key and EDT type Parameter Keys, make visibility to false.

4. Create a unique index KeyIdx with Key field.

5. We need to create 4 methods

    a. Find

public static WHSVehicleParameters find(boolean _forupdate = false )

    {

        WHSVehicleParameters parameter;


        parameter.selectForUpdate(_forupdate);


        select firstonly parameter

index KeyIdx

            where parameter.Key == 0;


if(!parameter && !parameter.isTmp())

        {

            Company::createParameter(parameter);

        }

  

        return parameter;

    }

    b Exist

 public static boolean exist()

    {

        

        return ((select firstonly RecId from WHSVehicleParameters).RecId != 0);

    }

    c Update

  public void update()

    {

        super();

        flush WHSVehicleParameters;

    }

    d delete

    public void delete()

    {

        throw Error("Not Allowed");

    }

6. Create a new form and add data source

7. Make allowcreate, allowdelete, insert if empty and insert at end to false.

8. Select form pattern - Table of Content.

9. Follow the pattern control suggestion or as shown in below pic.

10. Override the init method of form and add the find code before super to create one record.

 public void init()

    {

        WHSVehicleParameters::find();

        super();

    }








 Build and Run

    


  

   


 



    

  


Find and Exist Method

 /// <summary>

    ///

    /// </summary>

    public static ConWHSVehicleGroup find(ConWHSVehicleGroupId _groupId,boolean _forupdate = false )

    {

        ConWHSVehicleGroup vehGroup;


        vehGroup.selectForUpdate(false);


select firstonly * from vehGroup

            where vehGroup.WHSVehicleGroupId == _groupId;

        return vehGroup;

    }


    /// <summary>

    ///

    /// </summary>

    public static boolean exist(ConWHSVehicleGroupId _groupId)

    {

        ConWHSVehicleGroup vehGroup; 


if(_groupId)

        {

            select firstonly RecId from vehGroup

where vehGroup.WHSVehicleGroupId == _groupId;  

        }

       

        return (vehGroup.RecId !=0);

    }

Friday, February 18, 2022

OnValidated Event Handler

   [FormControlEventHandler(formControlStr(SalesTable, InventoryDimensionsGrid_inventBatchId), FormControlEventType::Validated)]

    public static void InventoryDimensionsGrid_inventBatchId_OnValidated(FormControl sender, FormControlEventArgs e)

    {

        SalesLine salesLine;

        InventDim inventDim;

        boolean ret;


        FormControlCancelEventArgs args = e as FormControlCancelEventArgs;


        FormRun formRun = sender.formRun();


        FormStringControl batchId = formRun.design(0).controlName("ControlName");

        InventBatchId inventBatchId = batchId.text();


        select firstonly RecId from salesLine

           join inventDim where inventDim.inventDimId == salesLine.InventDimId

            &&  inventDim.inventBatchId == inventBatchId && inventDim.inventBatchId !=''

            && salesLine.ProductionOrderReference !="";


        if(salesLine.RecId)

        {

ret = checkFailed("BatchAllocationError");

args.cancel(true);

        }

    }

How to generate inventory dimension from existing dimension with change in some dimension value

   public InventDimId getInventoryDimension(InventDimId _orignalDimId,EcoResItemConfigurationName _configId)

    {

        InventDim inventDim,inventDimLoc;


        inventDim = InventDim::find(_orignalDimId,false);


        select inventDimLoc where inventDimLoc.InventSiteId == inventDim.InventSiteId && inventDimLoc.InventLocationId == inventDim.InventLocationId

                    && inventDimLoc.InventColorId == inventDim.InventColorId && inventDimLoc.InventStyleId == inventDim.InventStyleId

                    && inventDimLoc.InventSizeId == inventDim.InventSizeId && inventDimLoc.configId == _configId

                    && inventDimLoc.inventBatchId == inventDim.inventBatchId && inventDimLoc.inventSerialId == inventDim.inventSerialId && inventDimLoc.LicensePlateId == inventDim.LicensePlateId

                    && inventDimLoc.wMSLocationId == inventDim.wMSLocationId

                    && inventDimLoc.InventStatusId == inventDim.InventStatusId;

        if(!inventDimLoc.RecId)

        {

            inventDimLoc.clear();

            inventDimLoc.InventSiteId       = inventDim.InventSiteId;

            inventDimLoc.InventLocationId   = inventDim.InventLocationId;

            inventDimLoc.InventColorId      = inventDim.InventColorId;

            inventDimLoc.InventStyleId      = inventDim.InventStyleId;

            inventDimLoc.InventSizeId       = inventDim.InventSizeId ;

            inventDimLoc.configId           = _configId;

            inventDimLoc.inventBatchId      = inventDim.inventBatchId;

            inventDimLoc.inventSerialId     = inventDim.inventSerialId;

            inventDimLoc.LicensePlateId     = inventDim.LicensePlateId;

            inventDimLoc.wMSLocationId      = inventDim.wMSLocationId;

            inventDimLoc.InventStatusId     = inventDim.InventStatusId;

        }


        inventDimLoc = InventDim::findOrCreate(inventDimLoc);


        return inventDimLoc.inventDimId;


    }

Releasing specific variant to legal entity using x++

  EcoResDistinctProductVariant   ecoResDistinctProductVariant;

        EcoResProductReleaseManagerBase   releaseManager;

        RefRecId   ecoResDistinctProductVariantRecId;

        EcoResProduct   ecoResProduct = EcoResProduct::findByProductNumber(_itemId);


        container productDimensions = EcoResProductVariantDimValue::getDimensionValuesContainer(_configId);


        ecoResDistinctProductVariant.DisplayProductNumber = EcoResProductNumberBuilderVariant::buildFromProductNumberAndDimensions(_itemId,productDimensions);


        if(EcoResProductVariantManager::existDistinctProductVariant(ecoResProduct.RecId,productDimensions))

        {

            ecoResDistinctProductVariantRecId = EcoResProductVariantManager::findDistinctProductVariant(ecoResProduct.RecId,productDimensions).RecId;

        }

        else

        {

            ecoResDistinctProductVariantRecId = EcoResProductVariantManager::createProductVariant(ecoResProduct.RecId,

                                                                                                    ecoResDistinctProductVariant.DisplayProductNumber,productDimensions);

        }


        ecoResDistinctProductVariant = ecoResDistinctProductVariant::find(ecoResDistinctProductVariantRecId);


        releaseManager = EcoResProductReleaseManagerBase::newFromProduct(ecoResDistinctProductVariant);

        releaseManager.release();

Production order Scheduling using x++

 public void productionOrdeOperationScheduling(ProdId _productionId)

    {

        ProdTable prodTable;

        ProdMultiSchedulingOperation ProdMultiSchedulingOperation;

        

        prodTable = ProdTable::find(_productionId);

        ProdMultiSchedulingOperation = ProdMultiScheduling::construct(ProdSchedMethod::OperationScheduling);

        RunBaseMultiParm::initParm(ProdMultiSchedulingOperation);

    

        ProdParmScheduling prodParmScheduling;

        prodParmScheduling = ProdMultiSchedulingOperation.defaultParmBuffer();

        prodParmScheduling.SchedDirection  = ProdSchedDirection::BackwardFromDeliveryDate;

        prodParmScheduling.MatLimited = NoYes::Yes;

        prodParmScheduling.SchedDate = prodTable.DlvDate;

        ProdMultiSchedulingOperation.insert(prodTable, prodParmScheduling);

       

        ProdMultiSchedulingOperation.runOperation();

    }

Production Order Estimate using x++

  public void productionOrderEstimation(ProdId _productionId)

    {

        ProdTable prodTable;

        ProdMultiCostEstimation prodMultiCostEstimation;


        prodTable = ProdTable::find(_productionId,false);


        prodMultiCostEstimation = ProdMultiCostEstimation::construct(new Args());


        RunBaseMultiParm::initParm(prodMultiCostEstimation);

        prodMultiCostEstimation.insert(prodTable, prodMultiCostEstimation.defaultParmBuffer());

        prodMultiCostEstimation.runOperation();

    }

Production Order Reset status functionality using X++

  public void prodStatusChange(ProdId _productionId)

    {

        ProdMultiStatusDecrease prodMultiStatusDecrease;

        ProdParmStatusDecrease prodParmStatusDecrease;

        ProdTable prodTable;        


        ProdId prodId = _productionId;

        Args   args    = new Args();

        ttsbegin;


        prodTable = ProdTable::find(prodId,true);


        if (prodTable.ProdStatus != prodStatus::Created)

        {

            args.record(prodTable);

                

            prodParmStatusDecrease.clear();


            prodParmStatusDecrease.initFromProdTable(prodTable);

            if(prodTable.ProdStatus == ProdStatus::CostEstimated)

            {

                prodParmStatusDecrease.WantedStatus = ProdStatus::Created;

            }

            else if (prodTable.ProdStatus == ProdStatus::Scheduled)

            {

                prodParmStatusDecrease.WantedStatus = ProdStatus::CostEstimated;


            }


            prodParmStatusDecrease.ParmId = NumberSeq::newGetNum(CompanyInfo::numRefParmId()).num();

            prodParmStatusDecrease.insert();


            prodMultiStatusDecrease = prodMultiStatusDecrease::construct();

            prodMultiStatusDecrease.initParmBuffer(prodParmStatusDecrease);

            prodMultiStatusDecrease.parmId(prodParmStatusDecrease.ParmId);

            prodMultiStatusDecrease.runOperation();

        }

        ttsCommit;      

    }

Creating Production Order using X++ in D365FO

 ProdTable       prodtable;

  InventTable     inventTable;

  InventDim       inventDim,inventDimLoc;

    ttsbegin;

            inventTable = inventTable::find("Provide ItemId");  

            prodtable.initValue();

            prodtable.ItemId                               = inventTable.ItemId;

            prodtable.DlvDate                             = _origProdTable.DlvDate;

            prodtable.QtySched                           = _origProdTable.QtySched;

            prodtable.RemainInventPhysical       = _origProdTable.RemainInventPhysical;

            prodtable.DlvDate        = _origProdTable.DlvDate;

            prodtable.DlvTime = _origProdTable.DlvTime;

            prodtable.InventDimId = _inventDimId;

            prodtable.GanttColorId = _origProdTable.GanttColorId;

            prodtable.initFromItemId();

            prodtable.initBOMVersion();

            prodtable.initRouteVersion();

            prodtable.insert();

       ttscommit;

Tuesday, February 15, 2022

Lookup - Unique value and Non repeating value after selection

 

   We need to Group by for distinct values :

   QueryBuildDataSource.orderMode(OrderMode::GroupBy);

QueryBuildDataSource.addGroupByField(fieldNum(TableName, FieldName));
For lookup to not show duplicate value after selection use below:
sysTableLookup.parmUseLookupValue(False);

Sunday, January 23, 2022

Ranges on DateAndTime Field


static void CreatedDateTimeRange(Args _args)
{
    Query                   query;
    QueryRun                queryRun;
    QueryBuildDataSource    qbds;
    QueryBuildRange         qbr;
    CustTable               custTable;
utcDateTime             userDateTime;

hours = 8;
    

userDateTime = DateTimeUtil::addHours(DateTimeUtil::getSystemDateTime(),hours);
 
    // Instance the class Query
    query =  new Query();
 
    // Add DataSource to Query
    qbds = query.addDataSource( tableNum(CustTable));
 
    // Add a range
    qbr = qbds.addRange( fieldNum(CustTable,CreatedDateTime));
 
    // Set range value
    qbr.value(SysQuery::range( "01/01/2012","30/12/2012" ));

or

qbr.value(SysQuery::range(userDateTime , DateTimeUtil::getSystemDateTime()));
 
    // Run Query
    queryRun = new QueryRun(query);
 
    // Retrieves the next record from the query.
    while(queryRun.next())
    {
        // Get Result
        custTable = queryRun.get( tableNum(CustTable));
 
        // Show AccountNum
        info(custTable.AccountNum);
    }
}

Sample Dialog Syntax - 1

 class AffiliationAutoAssignment extends RunBaseBatch {     // 1. Class Declaration and Pack variables     #define.CurrentVersion(1)     #de...