Tuesday 25 August 2015

Update Dynamic Property Instance(Properties of QuoteProduct/OrderProduct/InvoiceProduct) in CRM 2015

Hi,

We all know that Product Properties is the new features in CRM 2015.

Internally, these records are created in the DynamicPropertyInstance Table.  There are two ways of updating these records.

1) Using Native Update Request.
2) Using UpdateProductProperties Message which expects EntityCollection as input.

The only we need to know is which field to update. Most of you will be surprised why I said which field to update. In this table, the data is update according to the type of the property.

When we add a property to the family, we select the type of the property like Single line of text, Whole Number, Decimal Number etc. And internally CRM has individual columns for each type like ValueString, ValueDecimal, ValueInteger etc.

Even we have DynamicPropertyInstanceId, the challenge is to know the field name to update.

For that thing, we can use RetrieveProductProperty Message which expects input of OrderProduct/QuoteProduct/InvoiceProduct GUID and returns the base property details of the Product. By this, we can determine the type of the property and then use the same to update.


public void UpdateDynamicProductProperty(IOrganizationService iService)
{
     // Get the base product properties.
     RetrieveProductPropertiesRequest objRequest = new RetrieveProductPropertiesRequest();
     objRequest.ParentObject = new EntityReference("salesorderdetail", new Guid(""));
     RetrieveProductPropertiesResponse obj = (RetrieveProductPropertiesResponse)iService.Execute(objRequest);
     EntityCollection entCol = obj.EntityCollection;

     // Retrieve the Properties of the SalesOrderProudct.
     QueryExpression objQueryExp = new QueryExpression();
     objQueryExp.EntityName = "dynamicpropertyinstance";
     objQueryExp.Criteria.AddCondition(new ConditionExpression("regardingobjectid", ConditionOperator.Equal, "CDF9CA4C-B53A-E511-80CE-000D3AA023B6"));
     objQueryExp.ColumnSet = new ColumnSet(true);
     EntityCollection entColDynamicProperties = iService.RetrieveMultiple(objQueryExp);

     // Get the Field name to update.
     EntityReference erfDynamicProperty = (EntityReference)entColDynamicProperties.Entities[0]["dynamicpropertyid"];
     string strAttributeName = GetDynamicPropertyDataType(erfDynamicProperty.Id, entCol);

     // Update the Value of the Dynamice Property Instance.
     Entity entProductProperty = entColDynamicProperties.Entities[0];
     entProductProperty.Attributes[strAttributeName] = "ABCD";
     iService.Update(entProductProperty);
}

private static string GetDynamicPropertyDataType(Guid guidDynamicProperty, EntityCollection entCol)
{
   var entity = entCol.Entities.Single(e => e.Id ==  guidDynamicProperty);
   string strAttributeName = string.Empty;
   if (entity.Contains("datatype"))
   {
        OptionSetValue opsDataType = (OptionSetValue)entity.Attributes["datatype"];
        switch (opsDataType.Value)
        {
            case 3:
               return "valuestring";
            case 4:
               return "valueinteger";
            default:
               return string.Empty;
         }
    }
    return string.Empty;
}

We can also use UpdateProductProperties Request in the same way,  but the request needs entitycollection as an input and updates the properties.

UpdateProductPropertiesRequest objUpdateProductPropertiesReq = new UpdateProductPropertiesRequest();
objUpdateProductPropertiesReq.PropertyInstanceList = entColProperties;
objUpdateProductPropertiesReq.PropertyInstanceList.EntityName = "dynamicpropertyinstance";
var vResponse = iService.Execute(objUpdateProductPropertiesReq);

Hope this helps.

--
Happy CRM'ing
Gopinath

1 comment:

  1. Excellent Artcle.. Thanks Gopinath.. Your Code helps me a lot.

    ReplyDelete