Quantcast
Channel: Microsoft Dynamics 365 and Power Platform Library
Viewing all 102 articles
Browse latest View live

AX 2012: How to use JumpRef method

$
0
0
JumpRef method is mostly used with fields which are not linked with an EDT however,  this depends on the design of the code and the requirement.

I got a requirement to show 'View Details' options to the field of type notes (memo). There can be multiple ways to accomplish it but its always better to have your code at a central location (best to have it in Class or at table level) to reuse it.

JumpRef method can be overridden at form level under control itself but we are not going to do [avoid code changes at form level]



















Better to override JumpRef method at datasource field level and call method from table.




















JumpRef Method:

public void jumpRef()
{
    JumpRef::peformJumpRef(JumpRef.Notes);

}

PerformJumpRef method at table

static void peformJumpRef(Notes _notes)
{
    MenuFunction    menuFunction;
    Args            args = new Args();
        
    DocumentNotes   documentNotes; // This is the table of the master where view details option will take you. Change table name here, this is just for sample
    ;

    if (_notes)
    {
        documentNotes = DocumentNotes::find(_notes);
    }

    args.record(documentNotes);
    args.lookupRecord(documentNotes);
    
    menuFunction = new MenuFunction(menuitemDisplayStr(DocumentNotes), MenuItemType::Display);
    menuFunction.run(args);
}

Dynamics 365 AX7 - Configure Visual Studio for better expereince

$
0
0
Few settings to configure in Microsoft Visual Studio to make the development experience with AX a little smoother.

Go to Dynamics 365 Options
























Set Projects Options - organize project by element type























Set Text Editor Options - Line number and word wrap


























Set Best practice options
























The definition of best practice rules set is per model, by default it is set to Application Common model and can be switched between different model from combo box in the upper right corner. For example; to work with Customization Analysis you have to check Microsoft.Dynamics.AX.Framework.CustomizationAnalysisRules best practice rule. 

Build process itself does BP checking - there is an option to enable it. [To take into effect you might have to rebuild the solution/project in contrast to we usually do - build].





Dynamics 365 AX7 - Create Model and Project - Development Part 1

$
0
0
This post describes how to create model with correct selection of package which leads to correct development approach either Extension or Overlayering (Customization)

Go to Dynamics 365 or AX7 | Deploy | Create model



Enter required information as shown



Choose correct package




If you decided to go with overlayering, existing package will be selected from dropdown.

 

Select referenced packages

For this example; I will go with extension development approach, it is easy to upgrade with new versions or updates coming from MS.

Marked all required packages (models) which can be referenced through your new created model. Through these references, you can actually use the element living in those packages (models), without these references you cannot access any element belongs to a different model.

Lets' say you want to access CustTable which belongs to Application Suite package then you have to checked Application Suite package in referenced package list.




Create model Summary

Create new project option will open a new window where you can put the project name linked with this model.

NOTE: A project can only be linked with one model




Project created in Visual Studio




Update model parameters

You may require to update model parameters by adding more reference packages. This can be done as follows;



Select model name to update



Add or remove reference packages 


Click Next will take you model summary screen and will update the project in Visual Studio with updated references.


MS D365 - Development Exam - A brief outlook

$
0
0
Having passed the Microsoft Dynamics 365 Development Introduction exam (MB6-890), here are few thoughts on the exam which might help someone who is planning to appear in this exam.

If you are an experienced AX developer and have worked on AX 2012 - you don't need to worry.

Having said this "You don't need to worry", It would be the wiser step to watch all videos from https://mbspartner.microsoft.com/AX/CourseOverview/1181.

Exam will consist of 90 Questions and you will have 115 minutes to complete.

Brief outlook of the exam;

1. Basic X++ knowledge - For , do...while and while loops understanding and code flow
2. Extended data types - what properties can be extended from parent EDT
3. Menu item properties - key properties of menu items
4. Types of menu items and which one used for what purpose
5. Base enumeration - how these get stored in database
6. Table relationship and indexes
7. Class inheritance - spend more time on this topic (worth to read https://ax.help.dynamics.com/en/wiki/xpp-classes-and-methods/) 
8. Best practices and advantages of creating labels instead hard code text
10. Understand Application stack and Server architecture
11. Update model dependencies 
12. Check Break statement in switch cases
13. Exception handling
14. How to check properties of an element in Visual Studio
15. Security structure in AX
16. Form Patterns https://ax.help.dynamics.com/en/wiki/how-to-select-a-form-pattern/
17. See ttsbegin and ttsCommit statement in insert statements
18. Naming convention - check camelCase naming convention
19. How to configure build option in Visual Studio
20. Projects, model and Packages
21. Use of resources

Additionally and the most important step towards success is; Download D365 virtual machine (link) and practice with creating a small project. This really gives you hands-on experience rather purchasing dumps.

Finally, If you ever need any help from my side please feel free to contact me. Wish you best of luck!!!

Happy Dax!ng

MS Dynamics 365 - Configure Visual Studio for better expereince

$
0
0
Few settings to configure in Microsoft Visual Studio to make the development experience with AX a little smoother.

Go to Dynamics 365 Options























Set Projects Options - organize project by element type
























Set Text Editor Options - Line number and word wrap






















Set Best practice options






















The definition of best practice rules set is per model, by default it is set to Application Common model and can be switched between different models from the combo box in the upper right corner.

Let's say if you are working with Customization Analysis you have to check Microsoft.Dynamics.AX.Framework.CustomizationAnalysisRules best practice rule.


Set BP rules at Build level


Build process itself does BP checking - there is an option to enable it. To take this into effect you might have to rebuild the solution/project rather build it.






Microsoft Dynamics 365 for Operations - Selecting a correct form pattern - A another benchmark!!!

Microsoft Dynamics 365 for Operations - Number sequence

$
0
0
Number sequence framework in there for a while with the release of AX 2012 however, with the arrival of D365 we need to make a small addition on top of what we have been doing in AX 2012.

All steps remain same as summarize below to generate number sequence for the newly developed module. 

1. Create a new class similar to NumberSeqModuleCust but suffix it with your module name e.g. NumberSeqModuleMyModule extended from NumberSeqApplicationModule

2. Added loadModule() method

3. Add numberSeqModule() method with your new added enum value (for your module) in NumberSeqModule_extension (You should create an extension of NumberSeqModule base enum and not customizing it and add new element for your module into that extension)

4. This is an additional step for D365 you would need to perform otherwise it will claim "The value does not exist in map".

Create a new delegate method which will append the current class to the map that links modules to number sequence data type generators.

This delegate will look like as below;









[SubscribesTo(Classstr(NumberSeqGlobal), delegateStr(NumberSeqGlobal, buildModulesMapDelegate))]


    staticvoid buildModulesMapSubscriber(Map   _numberSeqModuleNamesMap)


    {


        NumberSeqGlobal::addModuleToMap(classNum(NumberSeqModuleMyModule), _numberSeqModuleNamesMap);


    }











How to: Generate number sequence for new developed module in AX 2012

$
0
0
In this post I am going to create a number sequence for newly developed module in AX 2012. 

1. Add a new element in NumberSeqModule baseenum with your new module name

2. Create a new Class NumberSequenceModuleModuleName extends NumberSequenceModule

3. Override loadModule method by adding the parameters of the sequence

    NumberSeqDatatype datatype = NumberSeqDatatype::construct();

//Message ID: MessageID is a new EDT of string type
datatype.parmDatatypeId(extendedtypenum(MessageID));
datatype.parmReferenceHelp(literalstr("MessageId"));
datatype.parmWizardIsManual(NoYes::No);
datatype.parmWizardIsChangeDownAllowed(NoYes::No);
datatype.parmWizardIsChangeUpAllowed(NoYes::No);
datatype.parmSortField(2);

datatype.addParameterType(NumberSeqParameterType::DataArea, true, false);
this.create(datatype);

4. Override numberSeqModule method

   public NumberSeqModule numberSeqModule()  
{
return NumberSeqModule::NewModule;
}

5. Create new job to load number sequence

   static void MessageIDNumSeqLoad(Args _args)
{
NumberSeqApplicationModule::loadAll();
}

6. Go to Organisation Administration | Common Forms | Number sequences | Number Sequences | Generate and follow the wizard to end to generate number sequence for new module.

AX 2012 : Add/Remove Dynalink through X++

$
0
0
DynaLinks can be removed and added between datasources on form using this code;

ClearDynaLinks() will remove all existing dynaLinks [these can be seen by right click on the click > Personalise > Query tab > under dataSource node

AddDynalink() method has three parameters;


1. Source table field

2. Destination table
3. Destination table field


The following code is implemented in the Click event of a button.

void clicked()
{
    SalesQuotationLine_ds.query().dataSourceNo(1).clearDynalinks();
    SalesQuotationLine_ds.query().dataSourceNo(1).addDynalink(fieldNum(SalesQuotationLine, QuotationId),
                                                         SAB_DocQuoteGroupRelation,
                                                         fieldNum(SAB_DocQuoteGroupRelation,SalesQuotationId));
        
}

D365O - Import CSV data through Data entity

$
0
0
Data entity is a new concept comes with D365O release where each entity related data can be accessed from a single view.

A data entity is an abstraction from the physical implementation of database tables. For example, customer related data is stored in different tables in AX which could be customer address (access from  LogisticsPostalAddress), customer name (access from DirPartyTable), and customer electronic address (access from LogisticsElectronicAddress).

Complete details are well explained here 
https://ax.help.dynamics.com/en/wiki/data-entities/

Let's create new data entity to import data from a CSV file, this data entity uses only one table to keep it simple. My following posts will show how to import data into through data entities using multiple tables.

Create a new table [Optional step]

I created a new table for this example.
















Create new data entity

Method 1:

























Method 2:

Add new item for Data entity






















Provide table as primary datasource



















Click Next and mark convert labels to field names


















Data entity will look like this in Visual Studio














With both above methods (whatever you choose) it created few artifacts in your project.

- data entity
- security privileges
- staging table
















Build your project

Press Ctrl + Shift + B or Right click on project and Build

Synchronize your tables by Right click on project and Sync 

Validate staging table properties

Set the configuration key to DMF and all other properties should be same as set below.
















Import data using this data entity

System administration | Data management





















Provide a name, choose data source as CSV, and select entity name from the list. Upload file to import.

My sample file has this data

101, Faisal
102, Fareed
103, Mohammad














It prompts with fields mapping error














Click on View map and connect fields as shown














Refresh page to view this screen and click Run project.






















Follow next few prompts and execute the batch job to import data into the staging table, verify data in the staging table. Import data into the target which will change the transfer status to completed.







































Open DataImport data from table browser to see data.

This data entity creates view in SQL server, you can even play around with the created view in SQL server.


Refernceshttps://ax.help.dynamics.com/en/wiki/building-and-consuming-data-entities/

D365O - How to add financial dimension in grid

$
0
0
This post outlines the steps; how to add financial dimensions (segmented control) in a grid in D365O.

Let's assume we are adding new table and form for below explanation;

New table contains two fields AccountType and LedgerDimension with relation to DimensionAttributeValueCombination table 


Form looks like this;













Set properties for segmented control under form design;

- Auto declaration = Yes
- Account type field = AccountType
- Controller class = DimensionDynamicAccountController
- Filter expression = %1

















1. Override modified method for LedgerDimension field under form's datasource
2. Override lookup and checkUserCustomLookup method on ledger dimension segmented control in form desgin















Datasource | D365O_FinancialDimension | LedgerDimension | modified

[DataSource]
    classD365O_FinancialDimension
    {
        [DataField]
        class LedgerDimension
        {
            void modified()
            {
                super();

                D365O_FinancialDimension_ds.refresh();
            }

        }

    }

Desgin | D365O_FinancialDimension_LedgerDimension | lookup

        publicvoid lookup()
        {
            switch (D365O_FinancialDimension.AccountType)
            {
                caseLedgerJournalACType::Bank:
                    BankAccountTable::lookupBankAccount(this);
                    break;
                caseLedgerJournalACType::Cust:
                    CustTable::lookupCustomer(this);
                    break;
                caseLedgerJournalACType::FixedAssets:
                    AssetTable::lookupAccountNum(this);
                    break;
                caseLedgerJournalACType::Project:
                    ProjTable::lookupProjId(this, D365O_FinancialDimension);
                    break;
                caseLedgerJournalACType::Vend:
                    VendTable::lookupVendor(this);
                    break;
                default:
                    super();
                    break;
            }
        }

Desgin | D365O_FinancialDimension_LedgerDimension | checkUserCustomLookup

publicboolean checkUseCustomLookup(int _accountTypeEnumValue, int _secondaryAccountTypeEnumValue)
        {
            boolean returnValue;
           
            LedgerJournalACType accountType = any2Enum(_accountTypeEnumValue);
            switch (accountType)
            {
                caseLedgerJournalACType::Bank:
                caseLedgerJournalACType::Cust:
                caseLedgerJournalACType::FixedAssets:
                caseLedgerJournalACType::Project:
                caseLedgerJournalACType::Vend:
                    returnValue = true;
                    break;
                default:
                    returnValue = false;
                    break;
            }
           
            return returnValue;
        }


Set D365O_FinancialDimensions form as startup object and run the form.























If you just want to see MainAccount in segmented control.

set the segmented control property Is default account = True






AX 2012 - Username and password keeps prompt on Home | Role center page

$
0
0
After Enterprise portal in being installed and have configured in AX 2012, sometimes username and password keeps prompt for Home | Role Center page. However, this is irrespective to AX as any web application can be configured in IE settings for username and password.

First option Steps outlined on this MSDN page resolves this issue.

Second option
IE explorer | Internet options | Security | Intranet (or your settings), Select custom level scroll to the bottom | User Authentication and select autologon depending upon your setup




AX 2012: StrFind and StrScan functions

$
0
0

Two standard functions strFind and strScan can be used based on business requirement for find a special character from an input string.

Here is an example with both functions;

Both functions return integer value.

StrScan Function

Int found = 0;
Str target= "Dynamics AX 365 operation";
found = strScan(target, "365", 0, strLen(target));


where parameters are;
1. string
2. string
3. position
4. number

StrFind Function

Int found = 0;
Str target= "Dynamics AX 365 operation";
found = strFind(target, "X", 0, strLen(target));

where parameters are;
1. string
2. character
3. position
4. number

AX 2012: Attach documents or creates notes through X++

$
0
0
Came across a requirement to attach documents and create notes for a sales order after reading files from directories.

Documents can be attached to a sales order manually from the following button.








Code snippet to create notes or attach documents


 DocuRef             docuRef;
 DocuActionArchive   docuArchive;
 SalesTable          salesTable = SalesTable::find("SO00001");

 Filename            fileName = @"C\Temp\SalesOrder.docx";

 ttsbegin;

 // Code to create notes
 docuRef.TypeId = 'Note';
 docuRef.Name = "Sales order notes";
 docuRef.Notes = "Checked Postcode: 2000, Select resident type";
 docuRef.Restriction = DocuRestriction::External;
 docuRef.RefTableId = tableNum(SalesTable);
 docuRef.RefRecId = salesTable.RecId;
 docuRef.RefCompanyId = curext();
 docuRef.insert();

 //Code to attach file
 docuArchive = newDocuActionArchive();
 docuArchive.add(docuRef, fileName);

 ttscommit;


DocuRef Table has field RefTable and RefRecId which could be referenced by any table in AX and with any record respectively.

Do set RefCompanyId field in DocuRef table otherwise records will not create.


AX 2012: Reading XML Nodes through X++

$
0
0

XML to read

















X++ Code








       XmlDocument    
doc;


    XmlNodeList     xmlScriptList;


    XmlNodeList     xmlResponseList;


    XmlNodeList     xmlTemplateList;




    XmlElement      nodeScript;


    XmlElement      nodeResponse;


    XmlElement      nodeTemplate;




    XMLParseError   xmlError;




    // Define
temporary variables


    str
_xmlMsg;


    int
i, j;


    ;


   


    // Create the
XML Document


    doc = new
XmlDocument();


    doc.loadXml(_xmlMsg);








    // Verify XML
Document Structure


    xmlError 
= doc.parseError();





    if(xmlError
&& xmlError.errorCode() != 0)


    {


        throw
error(strFmt("XML Error: %1", xmlError.reason()));


    }








    // Get the
root element and its child nodes


    nodeScript = doc.getNamedElement("ns2:return");


    xmlScriptList = nodeScript.childNodes();








    for(i=0; i < xmlScriptList.length(); i++)


    {


        nodeResponse = xmlScriptList.item(i);


        xmlResponseList =
nodeResponse.childNodes();




        for
(j=0; j < xmlResponseList.length();
j++)


        {


            nodeTemplate =
xmlResponseList.item(j);


            xmlTemplateList =
nodeTemplate.childNodes();















            if
(nodeTemplate.selectSingleNode('id'))


            {


                info(strFmt("ID: %1",
nodeTemplate.getNamedElement("id").text()));


            }












            

           if
(nodeTemplate.selectSingleNode('messageTemplateName'))


           {




                info(strFmt("messageTemplateName:
%1"
, nodeTemplate.getNamedElement("messageTemplateName").text()));


           }




        }


    }









AX 2012: Reading XML Nodes under specific tag through X++

$
0
0

XML to read




















X++ Code 

For above XML structure, I will read all nodes exist within each InstructorAPIModel node. The getElementsByTagName() method of XmlDocument class can be used which returns XmlNodeList which can then be iterated to get node's values.








  XmlDocument doc = new XmlDocument();

XmlNodeList         apiModelList;
XmlNodeListIterator iterator;
XmlElement apiModel;
XmlElement firstName;
XmlElement lastName;

doc.loadXml(_xmlMsg);

apiModelList = doc.getElementsByTagName('InstructorApiModel');
iterator= new XmlNodeListIterator(apiModelList);

while (iterator.moreValues())
{
apiModel = iterator.value();

firstName = apiModel.getNamedElement('FirstName');
if (firstName)
{
info(strFmt("First Name: %1", firstName.text()));
}

lastName = apiModel.getNamedElement('LastName');
if (lastName)
{
info(strFmt("Last Name: %1", lastName.text()));
}

iterator.nextValue();
}

AX 2012: Create sales order with delivery address from an XML file

$
0
0
Code snippet to create a sales order from an XML file.

privatevoid createSOFromFile()
{
    AxdSalesOrder   salesOrder;
    AifEntityKey    key;
   
    Filename        fileName;
    RecId           salesTableRecId;
    SalesTable      salesTable;
   
    XmlDocument     xmlDoc;
   
    salesOrder  = new AxdSalesOrder();
    fileName    = @"C:\Temp\SalesOrder.XML";
   
    xmlDoc = XmlDocument::newFile(fileName);
   
    key = salesOrder.create(xmlDoc.xml(),  
              new AifEndPointActionPolicyInfo(), 
              new AifConstraintList());

    salesTableRecId = key.parmRecId();
   
    info(strFmt("Sales order created: %1", SalesTable::findRecId(salesTableRecId).SalesId));
}

Sample XML file
<?xml version="1.0" encoding="UTF-8"?>
<SalesOrder xmlns:n="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder">
   <SalesTable class="entity">
      <CustAccount>C000002</CustAccount>
      <InventLocationId>EMU</InventLocationId>
      <CustomerRef>Cash on Delivery (COD)</CustomerRef>
      <PurchOrderFormNum>4669286216,1021</PurchOrderFormNum>
      <ReceiptDateRequested>2011-11-11</ReceiptDateRequested>
      <DeliveryName>team03qa@gmail.com</DeliveryName>
      <TableDlvAddr class="entity">
         <City>southbank</City>
         <CountryRegionId>AUS</CountryRegionId>
         <LocationName>delivery address</LocationName>
         <State>VIC</State>
         <Street>13075 MANCHESTER RD STE</Street>
         <ZipCode>3006</ZipCode>
      </TableDlvAddr>
      <SalesLine class="entity">
         <ItemId>CANO</ItemId>
         <SalesQty>20</SalesQty>
         <SalesPrice>82.25</SalesPrice>
         <SalesUnit>ltr</SalesUnit>
         <LineAmount>1</LineAmount>
         <LineNum>8966003144</LineNum>
      </SalesLine>
      <SalesLine class="entity">
         <ItemId>CANO</ItemId>
         <SalesPrice>9.9</SalesPrice>
         <SalesQty>1</SalesQty>
         <SalesUnit>ltr</SalesUnit>
         <LineAmount>9.9</LineAmount>
         <LineNum>8966003208</LineNum>
      </SalesLine>
   </SalesTable>
</SalesOrder> 

How does it work

AxdSalesOrder class uses AifEntity classes to create sales order, these classes internally map the datasources of an AOT query AxdSalesOrder with the element tags in XML with attribute class = "entity". For example; for delivery address, the XML node name is TableDlvAddr which is the datasource name in AxdSalesOrder query.


Similarly, if you want to add notes or attach documents with sales order you can add DocuRefHeader node in XML file.

AX 2012: Reading files from directory through X++

$
0
0
Following code can be used to read files from the specified path. With this example, I am reading a CSV files from a directory.

Class declaration











class readFilesFromDirectory extends RunBase






{




    FilePath            filePath;



    Filename            filename;


    CommaTextIo         fileIO;




    Set                 fileSet;


    CommaIo             commaIo;


    str                 currentFile;




    container           lineCon;




    #File


    #AviFiles




}








main method











Publicstatic
void main(Args _args)






{




    readFilesFromDirectory  readFiles =
readFilesFromDirectory::construct();





    readFiles.readFilesFromDirtecory();

}







Construct












Publicstatic
readFilesFromDirectory construct()






{




    return
new readFilesFromDirectory();


}







readFileFromDirectory method












privatevoid
readFilesFromDirtecory()






{




    SetEnumerator           sE;



    int                     row = 1;




    filePath = @"C:\Temp\FilesToRead";




    this.getFiles();




    sE = fileSet.getEnumerator();




    while
(sE.moveNext()) // loop through all files


    {


        filename = sE.current();




        this.openFile();




        while(this.readLine())
// loop through all lines from current file


        {


            this.processRow(row, lineCon);




            row++;


        }


    }


}








getFiles method












privatevoid
getFiles()


{


    System.String[]                 files;


    System.Collections.IEnumerator  enumerator;


    str
file;





    try


    {


        fileSet = new
Set(Types::Container);





        files =
System.IO.Directory::GetFiles(filePath, '*.csv');


        enumerator = files.GetEnumerator();





        while
(enumerator.MoveNext())


        {


            file = enumerator.get_Current();





            fileSet.add([file]);


        }





    }


    catch
(Exception::Internal)


    {


        this.processCLRErrorException();


    }


    catch
(Exception::CLRError)


    {


        this.processCLRErrorException();


    }

}








openFile method












privatevoid
openFile()






{




    FileIOPermission fileIOPermission;





    fileIOPermission = new FileIOPermission(filename, #io_read);


    fileIOPermission.assert();




    commaIo = new
CommaIo(filename, #io_read);


    if
(commaIo && commaIo.status() == IO_Status::Ok)


    {


       
commaIo.inRecordDelimiter(#delimiterCRLF);


    }


    else


    {


        throw
error(strFmt("Error when opening file %1", filename));


    }

}







readLine method











privateboolean
readLine()






{




    boolean
readLine;





    if
(commaIo && commaIo.status() == IO_Status::Ok)


    {


        lineCon = commaIo.read();


        readLine = lineCon != conNull();


    }


    else


    {


        lineCon = conNull();


        readLine = false;


    }




    return
readLine;


}








processRow method











privatevoid
processRow(int _rowIdx, container 
_row)






{




    //conpeek(_row,
1);



    //conpeek(_row,
2);


    //conpeek(_row,
3);


    //conpeek(_row,
4);


    //conpeek(_row,
5);


    //conpeek(_row,
6);


    //conpeek(_row,
7);


    //conpeek(_row,
8);


    //conpeek(_row,
9);


    //conpeek(_row,
10);


}








processCLRErrorException method







privatevoid
processCLRErrorException(


    boolean
_throw = true


    )


{


    str
strError;


    CLRObject exc;


    CLRObject innerExc;


    CLRObject clrExcMessage;




    exc = CLRInterop::getLastException();


    if
(exc)


    {


        clrExcMessage = exc.get_Message();


        innerExc = exc.get_InnerException();




        while
(innerExc != null)


        {


            clrExcMessage =
innerExc.get_Message();


            innerExc =
innerExc.get_InnerException();


        }




        strError =
CLRInterop::getAnyTypeForObject(clrExcMessage);




        error(strError);




        if (_throw)


        {


            throw
error("Update has been cancelled");


        }


    }


}









AX 2012 : Remove an XML node through X++

$
0
0
Following code snippet may help you to remove an XML node from an XML message string.


privatestr removeXMLTag(str xml)
{
    XmlDocument         doc = new XmlDocument();
    XmlElement          nodeScript;
    XmlNode             parentNode, childNode;
    XmlNodeList         xmlScriptList,
                        parentNodeList,
                        childNodeList;

    int                 i,j;

    doc.loadXml(xml);

    // Get the root element and its child nodes
    nodeScript = doc.getNamedElement("SalesOrder");
    xmlScriptList = nodeScript.childNodes();

    for(i=0; i < xmlScriptList.length(); i++)
    {
        parentNode = xmlScriptList.item(i);
        childNodeList = parentNode.childNodes();

        for (j=0; j < childNodeList.length(); j++)
        {
            childNode = childNodeList.item(j);
            if (childNode.selectSingleNode("Notes"))
            {
                parentNode.removeChild(childNode);
            }
        }
    }

    return doc.outerXml();
}

This will remove DocuRef node along with its child nodes. 

Original XML message

<?xml version="1.0" encoding="utf-8"?>                            
<SalesOrder xmlns = "http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder">                                        
<DocuRef class = "entity">
        <Notes>Business Name</Notes>
</DocuRef>

</SalesOrder>

XML message after node being removed

<?xml version="1.0" encoding="utf-8"?>                            
<SalesOrder xmlns = "http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder">                                  
</SalesOrder>

D365O - How to get current worker through X++

$
0
0
The current user or worker could be retrieved through following code since AX 2012

DirPersonUser::currentWorker()

However, In Dynamics 365 for operation this has refactored to;

HcmWorkerLookup::currentWorker()

Viewing all 102 articles
Browse latest View live