Showing posts with label AX7. Show all posts
Showing posts with label AX7. Show all posts

Sunday, 13 January 2019

AX 7 Nice links

https://shyamkannadasan.blogspot.com/2017/04/form-control-event-handler-methods-in.html

Tuesday, 26 June 2018

To enable and disable a field based on value in other field


To enable and disable a field based on value in other field :


class PurchTableFormExtension
{
    [FormDataSourceEventHandler(formDataSourceStr(PurchTable, PurchLine), FormDataSourceEventType::Activated)]
    public static void PurchLine_OnActivated(FormDataSource sender, FormDataSourceEventArgs e)
    {
        FormRun             formRun          = sender.formRun();
        FormDataSource      PurchTable_ds   = formRun.dataSource(formDataSourceStr(PurchTable, PurchTable)) as FormDataSource;
        PurchTable          purchTable= PurchTable_ds.cursor();

        FormStringControl    NCMRNo = formRun.design(0).controlName("NCMR_OINCMRNum_011");
        FormStringControl    NCMRDispositionCode = formRun.design(0).controlName("NCMR_OINCMRDispositionCodeId_011");
        if(NCMRNo.text() != "")
            NCMRDispositionCode.enabled(true);
        else
        {
            NCMRDispositionCode.text(" ");
            NCMRDispositionCode.enabled(false);
         
        }
    }

        /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    [FormControlEventHandler(formControlStr(PurchTable, NCMR_OINCMRNum_011), FormControlEventType::Modified)]
    public static void NCMR_OINCMRNum_011_OnModified(FormControl sender, FormControlEventArgs e)
    {
        FormRun             formRun          = sender.formRun();
        FormDataSource      PurchTable_ds   = formRun.dataSource(formDataSourceStr(PurchTable, PurchTable)) as FormDataSource;
        PurchTable          purchTable= PurchTable_ds.cursor();
        FormDataSource      PurchLine_ds   = formRun.dataSource(formDataSourceStr(PurchTable, PurchLine)) as FormDataSource;
        PurchLine           purchline= PurchLine_ds.cursor();

        FormStringControl    NCMRNo = formRun.design(0).controlName("NCMR_OINCMRNum_011");
        FormStringControl    NCMRDispositionCode = formRun.design(0).controlName("NCMR_OINCMRDispositionCodeId_011");
        if(NCMRNo.text() != "")
            NCMRDispositionCode.enabled(true);
        else
        {
            purchline.OINCMRDispositionCodeId_011   =   "";
            NCMRDispositionCode.enabled(false);
        }
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    [FormControlEventHandler(formControlStr(PurchTable, NCMR_OINCMRNum_011), FormControlEventType::LostFocus)]
    public static void NCMR_OINCMRNum_011_OnLostFocus(FormControl sender, FormControlEventArgs e)
    {
        FormRun             formRun          = sender.formRun();
        FormDataSource      PurchTable_ds   = formRun.dataSource(formDataSourceStr(PurchTable, PurchTable)) as FormDataSource;
        PurchTable          purchTable= PurchTable_ds.cursor();

        FormStringControl    NCMRNo = formRun.design(0).controlName("NCMR_OINCMRNum_011");
        FormStringControl    NCMRDispositionCode = formRun.design(0).controlName("NCMR_OINCMRDispositionCodeId_011");
        if(NCMRNo.text() != "")
            NCMRDispositionCode.enabled(true);
        else
        {
            NCMRDispositionCode.text(" ");
            NCMRDispositionCode.enabled(false);
         
        }
    }
===============================================================
//Enable and Disable field "Extra Calculationday" based on Enum value for the field "CreditCheckType".

[FormControlEventHandler(formControlStr(CustParameters, FormGroupControl1_FINCustCreditCheckType), FormControlEventType::Modified)]
    public static void FormGroupControl1_FINCustCreditCheckType_OnModified(FormControl sender, FormControlEventArgs e)
    {
        FormRun             formRun          = sender.formRun();
        FormComboBoxControl    finCreditCheckType = formRun.design(0).controlName("FormGroupControl1_FINCustCreditCheckType");
        FormIntControl    extraCalculationDays = formRun.design(0).controlName("FormGroupControl1_EQNExtraCalculationDays");
     
        if(finCreditCheckType.valueStr() == enum2str(FINCustCreditCheckType::BasedonExposure))
        {
            extraCalculationDays.enabled(true);
        }
        else
        {
            extraCalculationDays.enabled(false);
        }
    }

==============================================================

    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    [FormControlEventHandler(formControlStr(PurchTable, NCMR_OINCMRDispositionCodeId_011), FormControlEventType::Lookup)]
    public static void NCMR_OINCMRDispositionCodeId_011_OnLookup(FormControl sender, FormControlEventArgs e)
    {
        FormRun             formRun          = sender.formRun();
        FormStringControl    NCMRDispositionCode = formRun.design(0).controlName("NCMR_OINCMRDispositionCodeId_011");
        Query query = new Query();
        QueryBuildDataSource qbds;
        SysTableLookup sysTableLookup;
        sysTableLookup = SysTableLookup::newParameters(tableNum(OINCMRDispositionCode), sender);
        sysTableLookup.addLookupfield(fieldNum(OINCMRDispositionCode,NCMRDispositionCodeId));
        sysTableLookup.addLookupfield(fieldNum(OINCMRDispositionCode, Description));
        qbds = query.addDataSource(tableNum(OINCMRDispositionCode));
        sysTableLookup.parmQuery(query);
        sysTableLookup.performFormLookup();
    }

}

Code to execute DMF through Code

Move Data from File to staging :

 Void fileToDMStaging()
    {
       
        DMFDefinitionGroupExecution     groupExecution;
        DMFDefinitionGroupEntity    dMFDefinitionGroupEntity;
        definitionGroup = DMFDefinitionGroup::find(CustParameters::find().CITImportProject); 
// Field of Extended Data type : "DMFDefinitionGroupName" Created in CustParameters which //should be selected . - Process group created can be shown in this field.

        executionId             = DMFUtil::generateExecutionId(CustParameters::find().CITImportProject);
        Description description = strFmt('Execution - %1 for Definition Group - %2', executionId, CustParameters::find().CITImportProject);
        DMFDefinitionGroupExecution::insertOrDisplay(definitionGroup, executionId, description, false);
        select entity from dMFDefinitionGroupEntity where dMFDefinitionGroupEntity.DefinitionGroup == definitionGroup.DefinitionGroupName;
        ttsbegin;
        groupExecution = DMFDefinitionGroupExecution::find(definitionGroup.DefinitionGroupName,dMFDefinitionGroupEntity.Entity,executionId,true);

// Below code is written , as it takes filepath set to process group instead we need to use contract //parameter file path :

        groupExecution.FilePath = /*"C4PCUATTF";*/filePath;
        groupExecution.FilePath = groupExecution.applyTransforms(groupExecution.FilePath);
       
        groupExecution.ExcelLookUp =
                        DMFDefinitionGroupEntity::insertExcelLookUpValue(
                        groupExecution.DefinitionGroup,
                        groupExecution.Entity,
                        groupExecution.FilePath,
                        groupExecution.Source);
        groupExecution.update();
        ttscommit;
        DMFStagingWriterContract        contract = new DMFStagingWriterContract();
        DMFQuickImportExport::doPGImport(definitionGroup.DefinitionGroupName ,executionId);//Need to create extension of class DMFQuickImportExport to pass File path and assign it to the contract variable
    }


Move Data from Staging to Target :

 Void stagingToTarget()
        {
            DmfDefinitionGroupExecution dmfDefinitionGroupExecution;
            dmfDefinitionGroupExecution=dmfDefinitionGroupExecution::find(CustParameters::find().CITImportProject,'Customer payment journal line',executionId);
            if (dmfDefinitionGroupExecution.ExecutionId)
            {
                ttsbegin;
                DMFDefinitionGroupExecution defGroupExec;

                update_recordset defGroupExec
                setting IsSelected = NoYes::yes,
                    ExecuteTargetStep = NoYes::Yes
                where defGroupExec.ExecutionId == DMFDefinitionGroupExecution.ExecutionId;

                ttscommit;
            }

            DMFentitywriter  Dmfentitywriter = new DMFentitywriter();
            Dmfentitywriter.parmEntityTableName('CustomerPaymentJournalLineStaging');
            Dmfentitywriter.parmDMFExecution(DMFExecution::find(executionId));
            Dmfentitywriter.parmDMFDefinitionGroupExecution(dmfDefinitionGroupExecution);
            Dmfentitywriter.parmExecutionId(executionId);
            Dmfentitywriter.run();
           
        }

Using DMF while creating Payment journal settle the Invoice with out posting

Using DMF creating Payment journal and mark the settle lines :

We need to extend CustomerPaymentJournalLineEntity - Data entity.

[ExtensionOf(tableStr(CustomerPaymentJournalLineEntity))]
Final class CustomerPaymentJournalLineEntity_CIT_Extension
{
    [PostHandlerFor(tableStr(CustomerPaymentJournalLineEntity), tableMethodStr(CustomerPaymentJournalLineEntity, mapEntityToDataSource))]
    public static void CustomerPaymentJournalLineEntity_Post_mapEntityToDataSource(XppPrePostArgs args)
    {
        CustTable   custtable;
        CustomerPaymentJournalLineEntity    customerPaymentJournalLineEntity = args.getThis() as CustomerPaymentJournalLineEntity;
        custtable   =   CustTable::find(customerPaymentJournalLineEntity.AccountDisplayValue);
        DataEntityDataSourceRuntimeContext dataSourceCtx    = args.getArg(identifierStr(_dataSourceCtx));
        switch (dataSourceCtx.name())
        {
            case dataEntityDataSourceStr(CustomerPaymentJournalLineEntity, LedgerJournalTrans):
                LedgerJournalTrans ledgerJournalTrans = dataSourceCtx.getBuffer();
                ledgerJournalTrans.initFromCustTable(custtable);
                /*if(!ledgerJournalTrans.MarkedInvoice)
                {
                    ledgerJournalTrans.CITErrorLog  =   NoYes::Yes; // if any error occurs while importing record from file a  field added to ledgerjournaltrans to notify it.
                }*/
                if ( LedgerJournalTrans.MarkedInvoice)
                {
                    if(!CustTrans::findFromInvoice(ledgerJournalTrans.MarkedInvoice).RecId)
                    {
                        ledgerJournalTrans.CITErrorLog  =   NoYes::Yes;
                    }
                }
                break;
        }

    }

    [DataEventHandler(tableStr(CustomerPaymentJournalLineEntity), DataEventType::PersistedEntity)]
    public static void CustomerPaymentJournalLineEntity_onPersistedEntity(Common _sender, DataEventArgs _eventArgs)
    {
        CustomerPaymentJournalLineEntity customerPaymentJournalLineEntity = _sender;
        LedgerJournalTrans      ledgerJournalTrans;
                     
        while select ledgerJournalTrans where customerPaymentJournalLineEntity.JournalBatchNumber == ledgerJournalTrans.JournalNum
            && customerPaymentJournalLineEntity.LineNumber == ledgerJournalTrans.LineNum
        {
            CustomerPaymentJournalLineEntity::insertLinesForLineLevelSettlement(ledgerJournalTrans,customerPaymentJournalLineEntity.CITDiscountAmount);
        }
    }

    private static void insertLinesForLineLevelSettlement(LedgerJournalTrans _ledgerJournalTrans, Amount _cashDisc)
    {
        CustTransOpen               custTransOpen;
        custTrans                   custTrans;
        CustVendOpenTransManager    manager;
        CustTransCashDisc           custTransCashDisc;

        Select custTransOpen where custTransOpen.accountNum == _ledgerJournalTrans.accountDisplay()
            Join custTrans where custTrans.Invoice == _ledgerJournalTrans.MarkedInvoice && custTrans.RecId == custTransOpen.RefrecId;
        If (custTransOpen)
        {
            if (_cashDisc)
            {
                custTransCashDisc.CashDiscAmount = _cashDisc;
                custTransCashDisc.CashDiscdate = systemdateget();
                custTransCashDisc.RefRecId = custTransOpen.RecId;
                custTransCashDisc.RefTableId = custTransOpen.TableId;
                custTransCashDisc.insert();
            }
            /*
            manager = CustVendOpenTransManager::construct(_ledgerJournalTrans);
            manager.updateSettleAmount(custTransOpen,_ledgerJournalTrans.AmountCurCredit);
            manager.updateTransMarked(custTransOpen,true);
            */
            SpecTrans specTrans;

            specTrans.SpecCompany = _ledgerJournalTrans.DataAreaId;
            specTrans.SpecRecId = _ledgerJournalTrans.RecId;
            specTrans.SpecTableId = _ledgerJournalTrans.TableId;
            specTrans.RefCompany = custTransOpen.DataAreaId;
            specTrans.RefRecId = custTransOpen.RecId;
            specTrans.RefTableId = custTransOpen.TableId;
            specTrans.code = _ledgerJournalTrans.CurrencyCode;
            specTrans.Balance01 = _ledgerJournalTrans.AmountCurCredit;
            specTrans.Payment = NoYes::No;
            specTrans.SelectedDateUsedToCalcCashDisc = today();
            specTrans.insert();

            ttsBegin;

            _ledgerJournalTrans.selectForUpdate(true);
            _ledgerJournalTrans.SettleVoucher    = SettlementType::SelectedTransact;
            _ledgerJournalTrans.update();

            ttsCommit;
        }
    }

}

=======================================================================

To Address discount while importing File:

Extend CustomerPaymentJournalLineEntity and add CITDiscountAmount.

If you want any of the fields to get populated from file values we need to add these fields if not exists
Ex: Document Number



Call other form/ Class with Button Click

Call other form/ Class with Button Click 


 [FormControlEventHandler(formControlStr(LedgerJournalTransCustPaym, CustInRemitance), FormControlEventType::Clicked)]
    public static void CustInRemitance_OnClicked(FormControl sender, FormControlEventArgs e)
    {
   
        FormDatasource          fds;
        MenuFunction            menuFunction;
        LedgerJournalTrans ljt;
        Args    args =  new Args();
       
        fds                 = sender.formRun().datasource('LedgerJournalTrans');
         ljt   = fds.cursor();
        args.parm(ljt.JournalNum);
        menuFunction = new MenuFunction(menuItemActionStr(CITCustPaymImport),
            MenuItemType::Action);
        if (menuFunction.hasRunPermissions(args))
        {
            menuFunction.run(args);
        }


    }

Filter Grid in D365 based on lookup of Some unbound control

I have  a task to filter the grid based on unbound Enum control ( Show - All/ErrorLines)

class CITLedgerJournalTransCustPaym
{
    QueryBuildRange        citErrorLog;

   
    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    [FormControlEventHandler(formControlStr(LedgerJournalTransCustPaym, Show), FormControlEventType::SelectionChanged)]
    public static void Show_OnSelectionChanged(FormControl sender, FormControlEventArgs e)
    {
        FormDatasource          fds;
        FormControl             CITError;
        FormRun                 element;
        QueryBuildRange        citErrorLog;
       
        element     = sender.FormRun();
        CITError    =   element.design(0).controlName('Show');
        fds         = element.dataSource(formDataSourceStr(LedgerJournalTransCustPaym, LedgerJournalTrans)) as FormDataSource;
        citErrorLog = fds.query().dataSourceTable(tableNum(LedgerJournalTrans)).findRange(fieldNum(LedgerJournalTrans,CITErrorLog));
       
        if(citErrorLog == null)
        {
            citErrorLog  = fds.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldNum(LedgerJournalTrans, CITErrorLog));
        }
     
        if(CITError.valueStr() == enum2Str(CITShow::Errorlines))
        {
            citErrorLog.value(enum2Str(NoYes::Yes));
        }
        else
        {
            citErrorLog.value(SysQuery::valueUnlimited());
           // ;
        }
       
        fds.executeQuery();
        fds.reread();
        fds.refresh();
       
        //QueryBuildRange = Table_ds.query().dataSourceName(“datasource name”).addRange(fieldNum(Table,field)).value(enum2str(enum.selection()));
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    [FormDataSourceEventHandler(formDataSourceStr(LedgerJournalTransCustPaym, LedgerJournalTrans), FormDataSourceEventType::Initialized)]
    public static void LedgerJournalTrans_OnInitialized(FormDataSource sender, FormDataSourceEventArgs e)
    {
        //fds                 = sender.formRun().datasource('LedgerJournalTrans');
        //citErrorLog = fds.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldNum(LedgerJournalTrans,CITErrorLog));

    }


}

Disable and enable Menu items on form

Disable and enable menu item in form using record data :

class CITLedgerJournalTransCustPaym
{
    QueryBuildRange        citErrorLog;
// Below code is used to get
    [FormDataSourceEventHandler(formDataSourceStr(LedgerJournalTransCustPaym, LedgerJournalTrans), FormDataSourceEventType::Activated)]
    public static void LedgerJournalTrans_OnActivated(FormDataSource sender, FormDataSourceEventArgs e)
    {
        FormDatasource      fds;
        LedgerJournalTrans  LedgerJournalTrans;
        LedgerJournalName   ledgerJournalName;
        FormControl         CITRemitImport,CITCustImport;
        FormRun             element;
     
        fds                 = sender.formRun().datasource('LedgerJournalTrans');
        LedgerJournalTrans   = fds.cursor();
        element             = sender.FormRun();
        CITRemitImport      = element.design(0).controlName('CustInRemitance');
        CITCustImport       = element.design(0).controlName('CustInpayment');
        ledgerJournalName   = LedgerJournalName::find(ledgerJournalTrans.ledgerJournalTable().JournalName);

        if(ledgerJournalName.CITRemitImport)
        {
            CITRemitImport.visible(true);
            CITCustImport.visible(false);
        }
        else
        {
            CITRemitImport.visible(false);
            CITCustImport.visible(true);
        }
    }

 

}

Batch Job In D365

Batch Job In D365 :

Contract Class:
[
    DataContractAttribute,
    SysOperationContractProcessingAttribute(classStr(CITCustPaymImportUIBuilder))
]
    class CITCustPaymImportContract implements SysOperationValidatable
{
    CustAccount     custAccount;
    FilePath        filePath;
    FileUpload      filepath1;
    JournalId       journalNum;
    TransDate       postingDate;
    CustGroupId     custGroup;
    [
        //DataMemberAttribute(identifierStr(Filepath)),     
        DataMemberAttribute('Filepath'),
         SysOperationLabelAttribute('Upload document'),
        SysOperationDisplayOrderAttribute('3'),
        SysOperationHelpTextAttribute(literalStr("Assign file path"))
    ]
    public FilePath parmFilePath(FilePath _filePath = filePath)
    {
        filePath = _filePath;
        return filePath;
    }

    [
        //DataMemberAttribute(identifierStr(CustAccount))
        DataMemberAttribute('CustAccount'),
        SysOperationLabelAttribute('Customer Account'),
        SysOperationDisplayOrderAttribute('1'),
        SysOperationHelpTextAttribute(literalStr("Customer Account no."))
    ]
    public CustAccount parmCustAccount(CustAccount _custAccount = custAccount)
    {
        custAccount = _custAccount;
        return custAccount;
    }

    [
        //DataMemberAttribute(identifierStr(JournalNum)),
        DataMemberAttribute('JournalNum'),
        SysOperationControlVisibilityAttribute(false),
        SysOperationDisplayOrderAttribute('4'),
        SysOperationHelpTextAttribute(literalStr("JournalNum"))
    ]
    public JournalId parmJournalNum( JournalId _journalNum = journalNum)
    {
        journalNum = _journalNum;
        return journalNum;
    }

    [
        //DataMemberAttribute(identifierStr(Postingdate)),
        DataMemberAttribute('Postingdate'),
        SysOperationLabelAttribute('Posting Date'),
        SysOperationDisplayOrderAttribute('2'),
        SysOperationHelpTextAttribute(literalStr("Posting Date"))
    ]
    public TransDate parmPostingDate(TransDate _postingDate = postingDate)
    {
        postingDate = _postingDate;
        return postingDate;
    }

    public boolean validate()
    {
        boolean isValid = true;
        if (!custAccount)
        {
            isValid = checkFailed(strFmt("@SYS84753", custAccount));
        }
        /*if (!filePath)
        {
            isValid = checkFailed(strFmt("@SYS84753", filePath));
        }*/
       
        return isValid;
    }

}
=======================================================================
Controller : 

class CITCustPaymImportController extends SysOperationServiceController
{
    Common  callerRecord;
   
 
    void new()
    {
        super();

        this.parmClassName(classStr(CITCustPaymImportService));
        this.parmMethodName(methodStr(CITCustPaymImportService, process));
        this.parmDialogCaption('Customer payments Import');
    }

    public static void main(Args _args)
    {
        CITCustPaymImportController controller;
        controller = new CITCustPaymImportController();
     
        controller.parmShowDialog(true);
        CITCustPaymImportContract contract;
        contract    =   controller.getDataContractObject();
        //contract    =   this.parmReportContract().parmRdpContract() as CITCustPaymImportContract;
        if(_args.parm())
        {
            //ledgerJournalTrans = this.parmCallerRecord() as LedgerJournalTrans;
            contract.parmJournalNum(_args.parm());
        }
        //controller.initFromCaller(); 
        controller.startOperation(); 
        //controller.refreshCallerRecord();
    }

    public LabelType parmDialogCaption(LabelType _dialogCaption = "")
    {
        LabelType caption;
        caption = "Customer payments Import";
        return caption;
    }

    public boolean canGoBatch()
     {
        return false;
     }

    public Common parmCallerRecord(Common _callerRecord = callerRecord)
    {
        callerRecord = _callerRecord;
        return callerRecord;
    }

    ///    Refreshes the calling form data source.
    protected void refreshCallerRecord()
    {
        FormDataSource callerDataSource;
        if (this.parmCallerRecord() && this.parmCallerRecord().dataSource())
        {
            callerDataSource = this.parmCallerRecord().dataSource();
            callerDataSource.research(true);
        }
     }

}
======================================================================
Service :

class CITCustPaymImportService extends SysOperationServiceBase
{
    DMFExecutionId      executionId;
    DMFDefinitionGroup  definitionGroup;
    CustAccount     custAccount;
    FilePath        filePath,filepath1;
    JournalId       journalNum;
    TransDate       postingDate;
    Map                 uniqueKeyFieldListStagingMap,stagingTargetFieldListMap, autoGenStagingMap;
    Map                 entityPermissionMap;
    guid                scopeIdentifier;
    boolean             processComposite;
    Batch           currentBatch;
FileUpload             fileUpload;
map                           mapInv;
boolean             isMapEnd;
    public void process(CITCustPaymImportContract _contract)
    {
        filePath        = _contract.parmFilePath();
        custAccount     = _contract.parmCustAccount();
        journalNum      = _contract.parmJournalNum();
        postingDate     = _contract.parmPostingDate();
        try
        {
            This.processOperations(custAccount,filePath,journalNum,postingDate);
        }
        catch (Exception::Deadlock)
        {
            retry;
        }

        catch (Exception::UpdateConflict)
        {
            if (appl.ttsLevel() == 0)
            {
                /*   if (xSession::currentRetryCount() >= #RetryNum)
                {
                throw Exception::UpdateConflictNotRecovered;
                }
                else
                {
                retry;
                }*/
            }
                else
                {
                    throw Exception::UpdateConflict;
                }
        }

        catch (Exception::Error)
        {
            error(strFmt("Error occured"));
            retry;
        }
    }

    Void processOperations(CustAccount _custAccount,FilePath  _filePath,JournalId _journalNum,TransDate _postingDate)
    {
 
        This. fileToDMStaging ();
        This. ProcessStagingData(_custAccount,_journalNum,_postingDate);
        This. stagingToTarget();
    }

    //This method execution will import the data from file to staging table
    Void fileToDMStaging()
    {
       
        DMFDefinitionGroupExecution     groupExecution;
        DMFDefinitionGroupEntity    dMFDefinitionGroupEntity;
        definitionGroup = DMFDefinitionGroup::find(CustParameters::find().CITImportProject);
        executionId             = DMFUtil::generateExecutionId(CustParameters::find().CITImportProject);
        Description description = strFmt('Execution - %1 for Definition Group - %2', executionId, CustParameters::find().CITImportProject);
        DMFDefinitionGroupExecution::insertOrDisplay(definitionGroup, executionId, description, false);
        select entity from dMFDefinitionGroupEntity where dMFDefinitionGroupEntity.DefinitionGroup == definitionGroup.DefinitionGroupName;
        ttsbegin;
        groupExecution = DMFDefinitionGroupExecution::find(definitionGroup.DefinitionGroupName,dMFDefinitionGroupEntity.Entity,executionId,true);
        groupExecution.FilePath = /*"C4PCUATTF";*/filePath;
        groupExecution.FilePath = groupExecution.applyTransforms(groupExecution.FilePath);
       
        groupExecution.ExcelLookUp =
                        DMFDefinitionGroupEntity::insertExcelLookUpValue(
                        groupExecution.DefinitionGroup,
                        groupExecution.Entity,
                        groupExecution.FilePath,
                        groupExecution.Source);
        groupExecution.update();
        ttscommit;
        DMFStagingWriterContract        contract = new DMFStagingWriterContract();
        DMFQuickImportExport::doPGImport(definitionGroup.DefinitionGroupName ,executionId);//Need to create extension of class DMFQuickImportExport to pass File path and assign it to the contract variable
    }

    public NoYes parmError(NoYes  _errorStatus = NoYes::NO)
    {
        //  errorStatus = _errorStatus;

        return  NoYes::NO;
    }

    //This method execution will process the staging data for particular execution Id
    Void processStagingdata(CustAccount _custAccount,JournalId _journalId,TransDate _postingDate)
    {
        customerPaymentJournalLineStaging       customerPaymentJournalLineStaging;
        LedgerJournalTable                      ledgerjournaltable;
        JournalTableData                        journalTableData;
        ledgerjournaltable  =   LedgerJournalTable::find(journalNum,false);
        Voucher voucher;
     
        if(ledgerjournaltable)
        {
               
            voucher     =      JournalTableData::newTable(ledgerjournaltable).journalVoucherNum().getNew(true);
           
        }
       
        Update_recordSet customerPaymentJournalLineStaging
                setting DefaultDimensionsForAccountDisplayValue= _custAccount,
                AccountDisplayValue = _custAccount,
                JournalBatchNumber = _journalId,
                TransactionDate = _postingDate,
                Voucher = voucher,
                CurrencyCode = 'USD',
                DocumentNumber = customerPaymentJournalLineStaging.MarkedInvoice
                where customerPaymentJournalLineStaging.executionId == executionId;
        select customerPaymentJournalLineStaging
                where customerPaymentJournalLineStaging.executionId == executionId;

        if (!this.isInvoiceExists(customerPaymentJournalLineStaging.MarkedInvoice))
        {
            This.assignInvoiceFromPO();
        }

        /* Else
        {
        // This.sumInvoiceId();
        }*/
    }

        //Assign InvoiceId based on PO number provided in file
        Boolean isInvoiceExists(InvoiceId   _invoiceid)
        {
            boolean invexists;
            CustInvoiceJour custInvoiceJour;
            select RecId from custInvoiceJour
                where custInvoiceJour.InvoiceId ==  _invoiceid;
            if(custInvoiceJour)
                invexists   =   true;
            else
                invexists   =   false;
            return invexists;
        }

        Void assignInvoiceFromPO()
        {
            CustomerPaymentJournalLineStaging   customerPaymentJournalLineStaging;
            SalesTable                          SalesTable;
            Amount                              invoiceAmount;
            CustTransOpen                       CustTransOpen;
            CustInvoiceJour                     custInvoiceJour;
            CustTrans                           custTrans;
            CustomerPaymentJournalLineStaging   customerPaymentJournalLineStagingLoc,customerPaymentJournalLineStagingins;
           
            MapEnumerator                   mapEnum;

            While select sum(CreditAmount) from customerPaymentJournalLineStaging 
                    group by markedInvoice
                    where customerPaymentJournalLineStaging.executionId == executionId
               
            {
                select SalesTable
                    where salesTable.PurchOrderFormNum==customerPaymentJournalLineStaging.MarkedInvoice;
            mapInv = new Map(Types::String, types::Real);
                While select custInvoiceJour where custInvoiceJour.SalesId == SalesTable.SalesId
        Join custTrans where custTrans.Invoice == custInvoiceJour.InvoiceId
                    && custTrans.AccountNum == custInvoiceJour.InvoiceAccount
                    && custTrans.TransDate == custInvoiceJour.InvoiceDate
                    && custTrans.Voucher == custInvoiceJour.LedgerVoucher
                join CustTransOpen where CustTransOpen.AccountNum == custTrans.AccountNum
                                    && CustTransOpen.RefRecId == custTrans.RecId
            {
                mapInv.insert(custInvoiceJour.InvoiceId,custTransOpen.amountMST);
            }
            mapEnum = new MapEnumerator(mapInv);
            isMapEnd = false;
            if(mapEnum.moveNext())
            while select forupdate customerPaymentJournalLineStagingLoc
                where customerPaymentJournalLineStagingloc.MarkedInvoice == customerPaymentJournalLineStaging.MarkedInvoice
                                && customerPaymentJournalLineStagingloc.executionId == executionId
                {
                    mapEnum = this.assignInvoice(customerPaymentJournalLineStagingloc,mapEnum);
                    if (isMapEnd)             
                        break;
                }
            }
        }

        MapEnumerator assignInvoice(customerPaymentJournalLineStaging customerPaymentJournalLineStagingLoc,MapEnumerator mapenum)
    {
        Amount invoiceAmount;
        customerPaymentJournalLineStaging   customerPaymentJournalLineStagingins;
        invoiceAmount = mapEnum.CurrentValue();
        if (invoiceAmount >= customerPaymentJournalLineStagingLoc.CreditAmount)
        {
            ttsbegin;
            customerPaymentJournalLineStagingLoc.MarkedInvoice = mapEnum.CurrentKey();
            customerPaymentJournalLineStagingLoc.update();
            ttscommit;
            /*if (!mapenum.moveNext())
            {
                isMapEnd = true;
                return mapEnum;
            }*/
           
            if(customerPaymentJournalLineStagingloc.CreditAmount == invoiceAmount)
            {
                if (!mapenum.moveNext())
                {
                    isMapEnd = true;
                    return mapEnum;
                }
            }
           
            else
            {
                mapinv.insert(mapEnum.currentKey(),invoiceAmount-customerPaymentJournalLineStagingloc.CreditAmount);
            }
        }
        else
        {
            invoiceAmount = customerPaymentJournalLineStagingLoc.CreditAmount-invoiceAmount;
            ttsbegin;
            customerPaymentJournalLineStagingLoc.selectForUpdate(true);
            customerPaymentJournalLineStagingLoc.MarkedInvoice = mapEnum.Currentkey();
            customerPaymentJournalLineStagingLoc.CreditAmount = mapEnum.CurrentValue();
            customerPaymentJournalLineStagingLoc.update();
            ttscommit;
            customerPaymentJournalLineStagingins.data(customerPaymentJournalLineStagingloc);
            customerPaymentJournalLineStagingins.LineNumber += 0.01;
            customerPaymentJournalLineStagingins.CreditAmount =   invoiceAmount;
            customerPaymentJournalLineStagingins.RecId  =   0;
            customerPaymentJournalLineStagingins.CITDiscountAmount = 0;
            customerPaymentJournalLineStagingins.MarkedInvoice = '';
            customerPaymentJournalLineStagingins.insert();
            if (!mapenum.moveNext())
            {
                isMapEnd = true;
                return mapenum;
            }
            mapenum = this.assignInvoice(customerPaymentJournalLineStagingins,MapEnum);
        }
        return mapenum;
    }

        Void stagingToTarget()
        {
            DmfDefinitionGroupExecution dmfDefinitionGroupExecution;
            dmfDefinitionGroupExecution=dmfDefinitionGroupExecution::find(CustParameters::find().CITImportProject,'Customer payment journal line',executionId);
            if (dmfDefinitionGroupExecution.ExecutionId)
            {
                ttsbegin;
                DMFDefinitionGroupExecution defGroupExec;

                update_recordset defGroupExec
                setting IsSelected = NoYes::yes,
                    ExecuteTargetStep = NoYes::Yes
                where defGroupExec.ExecutionId == DMFDefinitionGroupExecution.ExecutionId;

                ttscommit;
            }

            DMFentitywriter  Dmfentitywriter = new DMFentitywriter();
            Dmfentitywriter.parmEntityTableName('CustomerPaymentJournalLineStaging');
            Dmfentitywriter.parmDMFExecution(DMFExecution::find(executionId));
            Dmfentitywriter.parmDMFDefinitionGroupExecution(dmfDefinitionGroupExecution);
            Dmfentitywriter.parmExecutionId(executionId);
            Dmfentitywriter.run();
           
        }

}
=======================================================================

UI Builder : 

class CITCustPaymImportUIBuilder extends SysOperationAutomaticUIBuilder
{
    Dialog      dlg;
    DialogField     dialogCustAcc;
    DialogField     dialogFilePath;
    DialogField     dialogPostingDate;
    DialogField     dialogJournalNum;
    str FileUploadName = 'FileUpload';
    private const str OkButtonName = 'Upload';
    str fileUrl;
    FileUploadBuild  dialogFileUpload;
    //dialogField     dialogFileUpload;


    CITCustPaymImportContract   contract;
    public void build()
    {
        DialogGroup dlgGrp;
        contract = this.dataContractObject();
       

        //get the current dialog
        dlg = this.dialog();

        dialogCustAcc = this.addDialogField(methodStr(CITCustPaymImportContract, parmCustAccount),contract);
        dialogCustAcc.value('');
        //dialogFilePath = this.addDialogField(methodStr(CITCustPaymImportContract, parmFilePath),contract);
        dialogPostingDate = this.addDialogField(methodStr(CITCustPaymImportContract, parmPostingDate),contract);
        dialogPostingDate.value(systemDateGet());
        dialogJournalNum = this.addDialogField(methodStr(CITCustPaymImportContract, parmJournalNum),contract);
        //make required modifications to the dialog
        dlgGrp = dlg.addGroup('FileUpload');
        dlgGrp.columns(2);
       
        FormBuildControl formBuildControl = dlg.formBuildDesign().control(dlgGrp.name());
       
        /*FileUploadBuild*/  dialogFileUpload = formBuildControl.addControlEx(classstr(FileUpload), FileUploadName);
        dialogFileUpload.baseFileUploadStrategyClassName(classstr(FileUploadTemporaryStorageStrategy));
        dialogFileUpload.fileNameLabel("@SYS308842");
        dialogFileUpload.resetUserSetting();
        dialogFileUpload.style(FileUploadStyle::MinimalWithFilename);
        dialogFileUpload.fileTypesAccepted('.xlsx');
    }

    public void dialogPostRun(DialogRunbase _dialog)
    {
        //super(_dialog);
        FileUpload fileUpload = this.getFormControl(_dialog, FileUploadName);
       // fileUpload.notifyUploadCompleted += eventhandler(dlg.uploadCompleted);
        //this.setDialogOkButtonEnabled(_dialog, false);
        FileUploadTemporaryStorageResult fileUploadResult = fileUpload.getFileUploadResult() as FileUploadTemporaryStorageResult;
        info(strfmt("-%1",fileUploadResult));
        if (fileUploadResult != null && fileUploadResult.getUploadStatus())
        {
            fileUrl = fileUploadResult.getDownloadUrl();
            info(strfmt("%1", fileUrl));
            contract.parmFilePath(fileUrl);
           
           
        }
    }

    protected FormControl getFormControl(DialogRunbase _dialog, str _controlName)
    {
        return _dialog.formRun().control(_dialog.formRun().controlId( _controlName));
    }

    private void setDialogOkButtonEnabled(DialogRunbase _dialog, boolean _isEnabled)
    {
        FormControl okButtonControl = this.getFormControl(_dialog, OkButtonName);

        if (okButtonControl)
        {
            okButtonControl.enabled(_isEnabled);
        }
    }

    public void run()
    {
       
        try
        {
            ttsbegin;
            FileUpload fileUploadControl = this.getFormControl(dlg, FileUploadName);
            FileUploadTemporaryStorageResult fileUploadResult = fileUploadControl.getFileUploadResult() as FileUploadTemporaryStorageResult;
            info(strfmt("-%1",fileUploadResult));
            if (fileUploadResult != null && fileUploadResult.getUploadStatus())
            {
                fileUrl = fileUploadResult.getDownloadUrl();
                info(strfmt("%1", fileUrl));
           
           
            }
            ttscommit;
        }
        catch (Exception::Deadlock)
        {
            retry;
        }
    }

    public void postBuild()
    {
        contract            =   this.dataContractObject();
        dialogCustAcc = this.bindInfo().getDialogField(
        this.dataContractObject(), methodStr(CITCustPaymImportContract, parmCustAccount));
        dialogFilePath = this.bindInfo().getDialogField(
        this.dataContractObject(), methodStr(CITCustPaymImportContract, parmFilePath));
        dialogPostingDate = this.bindInfo().getDialogField(
        this.dataContractObject(), methodStr(CITCustPaymImportContract, parmPostingDate));
        dialogJournalNum = this.bindInfo().getDialogField(
        this.dataContractObject(), methodStr(CITCustPaymImportContract, parmJournalNum));
       
    }

    private void custAccLookup(FormStringControl custAcclookup)
    {
        Query query = new Query();
        QueryBuildDataSource qbds_CustTable;
        QueryBuildRange         qbrBlocked;
        SysTableLookup sysTableLookup;

        // Create an instance of SysTableLookup with the current calling form control.
        sysTableLookup = SysTableLookup::newParameters(tableNum(CustTable), custAcclookup);
        // Add fields to be shown in the lookup form.
        sysTableLookup.addLookupfield(fieldNum(CustTable,AccountNum));
        //sysTableLookup.addLookupfield(fieldNum(CustTable,Name));
        qbds_CustTable = query.addDataSource(tableNum(CustTable));
        //this.query().dataSourceTable(tablenum(PurchTable)).addRange(fieldnum(PurchTable, PurchStatus)).value(strfmt('!%1,!%2',enum2str(PurchStatus::Canceled),enum2str(purchstatus::Invoiced)));
        //qbds_CustTable.addRange(fieldNum(CustTable, Blocked)).value(enum2str(CustVendorBlocked::All),enum2str(CustVendorBlocked::Payment));
        qbds_CustTable.addRange(fieldNum(CustTable, Blocked)).value(strfmt('!%1,!%2',enum2str(CustVendorBlocked::All),enum2str(CustVendorBlocked::Payment)));
        sysTableLookup.parmQuery(query);
        // Perform the lookup
        sysTableLookup.performFormLookup();
    }

    public void postRun()
    {
        super();

        //Register overrides for form control events
        dialogCustAcc.registerOverrideMethod(
        methodstr(FormStringControl, lookup),
        methodstr(CITCustPaymImportUIBuilder, custAccLookup),
        this);
    }

    /// <summary>
    ///
    /// </summary>
    public void getFromDialog()
    {
       
        FileUpload fileUploadControl = dlg.formRun().control(dlg.formRun().controlId(FileUploadName));
         
        FileUploadTemporaryStorageResult fileUploadResult = fileUploadControl.getFileUploadResult() as FileUploadTemporaryStorageResult;
        if (fileUploadResult != null && fileUploadResult.getUploadStatus())
        {
            fileUrl = fileUploadResult.getFileId();
        }
        contract.parmFilePath(fileUrl);
        super();
    }


}
======================================================================

Thursday, 21 June 2018

Remove Cache in AX7

Remove all files in below folders :

In my case Administrator is my user.

C:\Users\Administrator\AppData\Local\Microsoft\VisualStudio\14.0\ComponentModelCache
C:\Users\Administrator\AppData\Local\Microsoft\Team Foundation\6.0\Cache
C:\Users\Administrator\AppData\Local\Temp

Wednesday, 7 March 2018

ReferenceGroupControl Creation

https://devmusings.blog/2018/02/09/reference-group-controls-in-dynamics-365-for-operations/

Microsoft introduced the reference group control in Microsoft Dynamics AX 2012 that is unchanged in Microsoft Dynamics 365 for Finance and Operations. The control is a hybrid between a regular form control and a form group. It acts as a control during form design. At runtime, it appears as a group of controls. There are several reasons to use a reference group control.
  • It simplifies adding a look up to a record identifier field (RefRecId).
  • It reduces the need for coding display methods.
  • Users can filter and sort on fields exposed by the control.
  • It provides additional lookup logic (filters data if the entry is ambiguous).
  • It is smart enough to resolve table inheritance.
With these advantages, there are a couple disadvantages. As the fields store record identifiers, it is more difficult to analyze data using the table browser or SQL. Additionally, these goodies require additional setup such as creating a special data type and setting properties.
For this example, we have a pair of tables: MK_Pirates and MK_Ninjas.
For both tables, we have a unique index using the PirateId and NinjaId fields. Both indexes have the Alternate Key property set and the ReplacementKey property is the respective index.
We need to create a table and form to record encounters between the pirates and ninjas. The table should record a pirate, a ninja, and a result. Our MK_PirateVsNinja table already has the fields for pirate and result. We will be adding the field for ninja.
The first step is to create a new data type for the ninja field. For this, we create a new Int64 data type that extends RefRecId. We name this data type MK_NinjaRecId. On this data type, we set the ReferenceTable property to our MK_Ninja table.
After creating the data type, we need to add it to our encounter table. We can drag the MK_NinjaRecId onto the MK_PirateVsNinja table to create the field. Visual Studio should ask if you want to create a relationship. Click Yes and rename the newly created field to something more readable.
In the editor for the form, drag the newly created Ninja field into the grid. This will create a reference group control. Compile the project and open the form in the browser. We should be able to select pirates and ninja using the drop-down buttons.
Even though the underlying table stores record identifiers, the form shows the identifier of the pirates and ninjas.
Unfortunately, seeing just the identifier is not helpful in this case. We need to show the pirate’s name and ship and ninja’s name and dojo on the form. There are a couple ways we can accomplish this. One way is to modify the AutoIdentification field group on the parent tables. This field group populates automatically based on the replacement key. We can modify it to show the fields we want.
Another way is to change the ReplacementFieldGroup property on the reference group control. This property, that defaults to AutoIdentification, determines which field group from the parent table to display.
After changing either the AutoIdentification field group or the ReplacementFieldGroup property, the form will change to display our intended fields from the parent tables.

Tuesday, 26 September 2017

Customizing App Suite reports using extensions

https://blogs.msdn.microsoft.com/dynamicsaxbi/2017/01/02/customizing-app-suite-reports-using-extensions/


Microsoft Dynamics 365 for Operations now offers an expanded set of tools to support custom solutions. Customizations to reporting solutions in the standard application are fully supported using a pure ‘Extension’ model.  This article offers guidance on how to add the most common customizations to standard application reports without over-layering Application Suite artifacts.  Here are some of the key benefits in using an ‘Extension’ based approach when customizing the application
  • Reduces the footprint of your application solutions by minimizing code duplication
  • Custom reports benefit from enhancements made to standard solutions including updates to business logic in Report Data Provider (RDP), data contracts, and UI Builder classes
  • Standard application solutions are unaffected and continue to be available in concert with custom reports
Microsoft Dynamics 365 for Operations (Platform Update3)
______________________________________________________________________________
Report extensions do NOT break or prevent access to standard application reports.  Instead, the platform supports run-time selection of the target report allowing you to choose the appropriate report design based on the context of the user session.  For more information on customizations using extensions, Customization: Overlayering and extensions
SCENARIOS - There are four key scenarios that we’ll focus on which demonstrate the flexibility available in Platform Update3. The first two scenarios involve extending existing RDP classes for our custom reporting solutions. The others offer insights on how to use extensions to redirect application navigations to your custom solutions.
  1. Expanding existing datasets - use table extensions and integrate custom business logic to add custom columns to an existing dataset
  2. Composing custom datasets - add more data to application reports by extending an existing RDP class to return a custom dataset
  3. Extending report menu items - customize application menu items to redirect references to a custom report design
  4. Custom designs for business documents - delegate handlers allow you to add custom report designs to an existing Print Management document instance
Use the following techniques to create custom reporting solutions for the application without over-layering any of the Application Suite objects.

Expanding datasets returned from standard RDP classes

REQUIREMENT
Application report needs more data in
an existing section of a report or visualization.
PROCEDURE
  • Add table extension
  • Add columns to store the data
  • Supply logic to populate the new columns
  • Create custom design
  • Extend report menu items
  • - OR -
  • Extend report controllers
Click here to learn more
extendingdatasets

Extending standard RDP classes to return custom datasets

REQUIREMENT
Use this approach to introduce new data
regions to existing Application reports.
PROCEDURE
  • Create new TMP table
  • Add columns to store the data
  • Extend the RDP class to populate the data
  • Create custom design
  • Extend report menu items
  • - OR -
  • Extend report controllers
customdataset

Redirect application menu item to custom report design

REQUIREMENT
Menu Item extensions allow you to redirect
navigations in the application to custom
reporting solutions
PROCEDURE
  • Create custom report
  • Extend report menu items
  • Add reference to the custom report
Click here to learn more
extendingmenuitem

Adding custom report designs for business documents

REQUIREMENT
This solution is appropriate for making
custom report designs available for business
documents backed by Print Management.
PROCEDURE
  • Create custom report
  • Register delegate handler
  • Add logic to override Print Management Settings
Click here to learn more
extendingprintmgt



Friday, 8 September 2017

Event handlers for Table methods in Dynamics 365 / AX7

Event handlers for table methods in Dynamics 365 / AX 7


In the below code, You can see a class which is included with one method for post event handling for ReqPO->ValidateQuantity() method.
According to the D365 concept, have to use the static method for event handler but, in this case, need to return value.
Using the below function we can return value even in a static method.

Below method is to execute after ReqPO->ValidateQuantity() method as a post event method.



Ref: Method for the above event method.