Microsoft Dynamics AX Support

This blog contains posts by the Microsoft Dynamics AX Support teams Worldwide

Calling the Update Operation on Services in AX 2012

Calling the Update Operation on Services in AX 2012

Rate This
  • Comments 5

Calling the update operation on web services can range from simple
to very complicated depending on the entities/tables you are updating.  If the entity you are calling is not a date
effective entity, then the service's update method is easy to call. 

You can tell if a table is date effective by going in the
AOT to the Data Dictionary > Tables > Find the tables that comprise the
service > Right-click on the table and choose Properties.  In the property sheet, look for the
ValidTimeStateFieldType property.  If the
property is set to "None" then the table is NOT date effective.  You will need to look at every table in the
service to see if that property is set to none.

If the service is not date effective, like the sales order
service, then you can call the service using the find and then the update operations.  In the example below, I retrieve a sales
order using the find method and then I update the SalesQty and SalesPrice
fields on each sales line in the retrieved sales order.

        static void Main(string[] args)

        {

            //First find the order

            AxdSalesOrder salesOrder = Program.FindOrder();

            //Now update it

            Program.UpdateOrder(salesOrder);

        }

 

        static AxdSalesOrder FindOrder()

        {

            CallContext context = new CallContext();

           
            context.Company = "ceu";

 

            string salesId = "SO-101244";

            AxdSalesOrder foundSalesOrder = null;

 

            //Instantiate an instance of the service client class

            SalesOrderServiceClient proxy = new SalesOrderServiceClient();

 

            try

            {

               
                 foundSalesOrder = proxy.find(context, Program.createQueryCriteria(salesId));

               
                Console.WriteLine("The sales order was found.");

            }

            catch (Exception e)

            {

               
Console.WriteLine("The sales order was not found.");

            }

 

            return foundSalesOrder;

        }

 

  private static QueryCriteria createQueryCriteria(string salesIdValue)

        {

            CriteriaElement[] criteriaElements = new CriteriaElement[1];

           
criteriaElements[0] = new CriteriaElement();

           
criteriaElements[0].DataSourceName = "SalesTable";

           
criteriaElements[0].FieldName = "SalesId";

           
criteriaElements[0].Value1 = salesIdValue;

 

            QueryCriteria queryCriteria = new QueryCriteria();

           
queryCriteria.CriteriaElement = criteriaElements;

            return queryCriteria;

        }

 

        static void
UpdateOrder(AxdSalesOrder salesOrder)

        {

            CallContext context = new
CallContext();

           
context.Company = "ceu";

 

            SalesOrderServiceClient proxy = new SalesOrderServiceClient();

            foreach (AxdEntity_SalesTable
salesTable in salesOrder.SalesTable)

            {

               
foreach (AxdEntity_SalesLine
salesLine in salesTable.SalesLine)

               
{

                        salesLine.SalesQty =
salesLine.SalesQty + 1;

                        salesLine.SalesPrice =
salesLine.SalesPrice + 2;

                       
salesLine.SalesPriceSpecified = true;

               
}

            }

 

            try

            {

               
proxy.update(context, Program.createEntityKeyList(),
salesOrder);

               
Console.WriteLine("The sales order was successfully updated");

            }

            catch (Exception
e)

            {

               
Console.WriteLine("The sales order was not updated.");

            }

        }

 

private static EntityKey[] createEntityKeyList()

        {

           
EntityKey[] entityKeyList = new EntityKey[1];

           
EntityKey entityKey = new EntityKey();

           
KeyField[] keyDataList = new KeyField[1];

           
KeyField keyField = new KeyField();

           

keyField.Field = "SalesId";

    
       keyField.Value = "SO-101244";

           

keyDataList[0] = keyField;

           

entityKey.KeyData = keyDataList;      

entityKeyList[0] = entityKey;

          
return entityKeyList;

        }

Unlike the sales order service, the customer service is date
effective because it contains the DirPersonName, DirOrganizationName,
DirPartyLocation, etc. tables which have their ValidTimeStateFieldType
properties set to something other than None. 
Date effective services have properties added at the document level (the
highest level in the service) to indicate how you want to set the date effective
entities.  The properties are ValidTimeStateType,
ValidAsOfDateTime, ValidFromDateTime and ValidToDateTime.  Either you can set those at the document
level or you can set the date effective fields on each entity in the service
that is date effective.  In the example
code below, I call the read method to retrieve a customer and then I create a
new instance of a customer, set the date effective properties on the document according
to what they are on the retrieved customer and then update the CreditMax field
on the customer.

 

static void
Main(string[] args)

        {

            string customer = "1104";

            AxdCustomer foundCustomer = null;

            CallContext context = new
CallContext();

           
context.Company = "ceu";

 

            CustomerServiceClient proxy = new CustomerServiceClient();

            try

            {

               
foundCustomer = proxy.read(context, Program.readCritera(customer));

               
Console.WriteLine("Read worked");

 

               Program.updateCustomer(foundCustomer);

 

            }

            catch (Exception
e)

            {

                Console.WriteLine(e.Message);

            }

 

        }

 

private static
EntityKey[] readCritera(string customerAccount)

        {

            AxdEntity_CustTable custTable = new AxdEntity_CustTable();

            EntityKey[] entityKeyList = new EntityKey[1];

            EntityKey key = new
EntityKey();

            KeyField[] keyFields = new
KeyField[1];

            KeyField keyField = new
KeyField();

           
keyField.Field = "AccountNum";

            keyField.Value = customerAccount;

           
keyFields[0] = keyField;

           
key.KeyData = keyFields;

           
entityKeyList[0] = key;

            return entityKeyList;

        }

 

 

       private static void
updateCustomer(AxdCustomer customer)

        {

            CustomerServiceClient proxy = new CustomerServiceClient();

            CallContext context = new
CallContext();

           
context.Company = "ceu";

 

            AxdEntity_CustTable custTable =
customer.CustTable[0];

 

            AxdCustomer axdCustomer2 = new AxdCustomer();

           
axdCustomer2.ValidTimeStateType = customer.ValidTimeStateType;

           
axdCustomer2.ValidTimeStateTypeSpecified = true;

           
axdCustomer2.ValidAsOfDateTime = customer.ValidAsOfDateTime;

            axdCustomer2.ValidFromDateTime =
customer.ValidFromDateTime;

           
axdCustomer2.ValidToDateTime = customer.ValidToDateTime;

 

            AxdEntity_CustTable custTableNew = new AxdEntity_CustTable();

           
custTableNew._DocumentHash = custTable._DocumentHash;

           
custTableNew.RecId = custTable.RecId;

           
custTableNew.RecVersion = custTable.RecVersion;

           
custTableNew.action = AxdEnum_AxdEntityAction.update;

           
custTableNew.actionSpecified = true;

           
custTableNew.CreditMax = custTable.CreditMax + 10;

           
custTableNew.CreditMaxSpecified = true;

           
custTableNew.CustGroup = custTable.CustGroup;

 

           
axdCustomer2.CustTable = new AxdEntity_CustTable[1] { custTableNew };

 

            try

            {

               
proxy.update(context, Program.readCritera("1104"), axdCustomer2);

               
Console.Write("Worked");

               
Console.ReadLine();

            }

            catch (Exception
e)

            {

               
Console.WriteLine("Failed");

               
Console.ReadLine();

            }

        }

 

As an alternative to setting the properties at the document
level (AxdCustomer) I can set the date effective properties on each table in
the service that is date effective.  As
you'll notice the code get clunkier and more difficult to do programmatically.  The example code below accomplishes the same
goal of retrieving the customer using the read method and then it updates the
CreditMax for that customer.

 

static void Main(string[]
args)

       {

            string customer = "1104";

            AxdCustomer foundCustomer = null;

            CallContext context = new
CallContext();

           
context.Company = "ceu";

 

            CustomerServiceClient proxy = new CustomerServiceClient();

            try

            {

               
foundCustomer = proxy.read(context, Program.readCritera(customer));

               
AxdEntity_DirParty_DirPartyTable
returnedPartyTable = foundCustomer.CustTable[0].DirParty[0];

               
Console.WriteLine("Read worked");

 

               
Program.updateCustomer(foundCustomer);

 

            }

            catch (Exception
e)

            {

               
Console.WriteLine(e.Message);

            }

 

       }

 

             private static EntityKey[] readCritera(string
customerAccount)

            
{

                
AxdEntity_CustTable custTable = new AxdEntity_CustTable();

                
EntityKey[] entityKeyList = new EntityKey[1];

                
EntityKey key = new EntityKey();

                
KeyField[] keyFields = new KeyField[1];

                
KeyField keyField = new KeyField();

                
keyField.Field = "AccountNum";

                
keyField.Value = customerAccount;

                
keyFields[0] = keyField;

                
key.KeyData = keyFields;

                
entityKeyList[0] = key;

                 return
entityKeyList;

            
}

 

             private static void updateCustomer(AxdCustomer
customer)

            
{

                
CustomerServiceClient proxy = new CustomerServiceClient();

                
CallContext context = new CallContext();

                
context.Company = "ceu";

 

                
foreach (AxdEntity_CustTable
custTable in customer.CustTable)

                
{

 

                    
custTable._DocumentHash = custTable._DocumentHash;

                    
custTable.RecId = custTable.RecId;

                    
custTable.RecVersion = custTable.RecVersion;

                    
custTable.action = AxdEnum_AxdEntityAction.update;

                    
custTable.actionSpecified = true;

                     custTable.CreditMax =
custTable.CreditMax + 10;

                    
custTable.CreditMaxSpecified = true;

 

                     #region Update the date effective
entities

                    
AxdEntity_DirParty_DirOrganization
dirPartyTable = (AxdEntity_DirParty_DirOrganization)custTable.DirParty[0];

                    
dirPartyTable.action = AxdEnum_AxdEntityAction.update;

                    
dirPartyTable.actionSpecified = true;

 

                    
AxdEntity_OrganizationName orgName =
dirPartyTable.OrganizationName[0];

                    
orgName.action = AxdEnum_AxdEntityAction.update;

                    
orgName.actionSpecified = true;

                    
orgName.updateMode = AxdEnum_ValidTimeStateUpdate.Correction;

                    
orgName.updateModeSpecified = true;

 

 

                    
//Update the postal addresses

                    
AxdEntity_DirPartyPostalAddressView[]
postalAddresses = dirPartyTable.DirPartyPostalAddressView;

                    
foreach (AxdEntity_DirPartyPostalAddressView
postalAddress in postalAddresses)

                    
{

                         postalAddress.action =
AxdEnum_AxdEntityAction.update;

                        
postalAddress.actionSpecified = true;

                        
postalAddress.updateMode = AxdEnum_ValidTimeStateUpdate.Correction;

                        
postalAddress.updateModeSpecified = true;

                         postalAddress.RecId =
postalAddress.RecId;

                         postalAddress.RecVersion
= postalAddress.RecVersion;

                         postalAddress.Roles = "Home";

                        

                    
}

 

                    
//Update the electronic addresses

                    
AxdEntity_DirPartyContactInfoView[]
electronicAddresses = dirPartyTable.DirPartyContactInfoView;

                    
foreach (AxdEntity_DirPartyContactInfoView
electronicAddress in electronicAddresses)

                    
{

                        
electronicAddress.action = AxdEnum_AxdEntityAction.update;

                        
electronicAddress.actionSpecified = true;

                        
electronicAddress.updateMode = AxdEnum_ValidTimeStateUpdate.Correction;

                        
electronicAddress.updateModeSpecified = true;

                        
electronicAddress.RecId = electronicAddress.RecId;

                        
electronicAddress.RecVersion = electronicAddress.RecVersion;

 

                    
}

                
}

                     #endregion

 

 

                 try

                
{

                    
proxy.update(context, Program.readCritera("1104"), customer);

                    
Console.Write("Worked");

                    
Console.ReadLine();

                
}

                
catch (Exception
e)

                
{

                    
Console.WriteLine("Failed");

                    
Console.ReadLine();

                
}

            
}

    }

Leave a Comment
  • Please add 6 and 3 and type the answer here:
  • Post
  • Hi,

    I am trying to add contact info to an existing customer (trying to attach the contact info at the postal address level and not customer(party) level ).

    I am able to successfully follow this tutorial and add contact info but have found no way to associate it to a particular address using the web service.

    I believe in AX, the LogisticsLocation.ParentLocation field needs to be populated with the desired postal address rec id.

    Also I would like to know if there is a way to do this when creating a new customer.

    Any help would be apprciated.

  • Becky,

    Thanks for your great information. One question, is is possible to update party name for a customer through the AIF, as a part of the process listed above?

  • Hi Tim,

    Yes you should be able to update the party name through the Customer service.  The PersonName and OrganizationName tables are party of the AxdCustomer query which this service is built upon.  If you go in the AOT to the Queries node and find the AxdCustomer query and then find those tables, you'll see the Update property is set to Yes which means you should be able to update fields within those tables.

  • I have tried to use this to set the OrganizationName and tried to use the correction attribute but when i do this it adds another record in that name field with the effective from date being the date that it was updated.  I am trying to set an attribute on the DirParty so I dont' think the first option will work.  I think i need to set the update mode to Correction for all the child nodes or at least the OrganizationName one.  Is there a way to update without it adding a new record in the effective date table for the OrganizationName?

  • Hi Jason,

    I haven't tried that on the sales order service and I think that is a little weird to try that update through the sales order service.  The DirOrganization and DirOrganizationName tables are not data sources on the sales order service.  Also where in the AX UI would you change the name of a company through a sales order?  To me that is something that should be done through the customer (or vendor) service.

Page 1 of 1 (5 items)