12.06.2009, 15:05 | #1 |
Участник
|
mscrm4ever: Summarizing an Appointment field on a Parent Entity
Источник: http://mscrm4ever.blogspot.com/2009/...on-parent.html
============== Imagine you have a custom field called number of participants on and appointment entity and you want to summarize this field for all the appointments under the same regarding parent. This looks simple at first glance i.e. register a plug-in on the parent post Create and Update messages and you’re done. However, since this entity is part of dynamics scheduling engine and affects rescheduling you also need to register your plug-in on the Book and Reschedule messages. Actually the Book and Reschedule messages somewhat replace the Create and Update messages. That means that when you create a new Appointment the Book message is fired and when you Update an existing appointment the reschedule message is fired. So why do we need to also register the plug-in on the Create and Update messages? The answer is that when you reschedule or book an appointment and the user is not available at that point in time the scheduling engine halts the execution and enables the user to cancel the operation. If the user decide to disregard (ignore) that warning and save anyway then the Create or Update are fired to complete the operation. Since the summarizing of the field can be a long operation you should also register the plug-in for asynchronous execution. Another thing that is worth mentioning is code synchronization. Since CRM does not lock record and two users can update the same appointment at the same time it is also advisable to lock the process that updates the parent field to avoid data corruption. Last Important remark: the regarding lookup (parent entity) is required for this operation. Since the Book and Reschedule messages don’t allow you to register Post Images you need to send the regarding field in each operation. E.g. //Put this code in the appointment onload event handler if (crmForm.regardingobjectid.DataValue != null) { crmForm.regardingobjectid.ForceSumbit = true; } Plug-in Registered on the Reschedule, Book, Create and Update Asynchronous Parent Pipeline using System; using System.Collections.Generic; using System.Text; using Microsoft.Crm.Sdk; using Microsoft.Crm.SdkTypeProxy; using Microsoft.Crm.Sdk.Query; namespace GI.Crm.Sandbox { public class SummarizeAppointmentFieldHandler : IPlugin { private Object SyncObject = new Object(); public void Execute(IPluginExecutionContext context) { /* Validates that the user is available */ if (context.OutputParameters.Contains(ParameterName.ValidationResult)) { ValidationResult validationResult = context.OutputParameters[ParameterName.ValidationResult] as ValidationResult; if (validationResult.ValidationSuccess == false) { return; } } /* Validate Target Entity */ if (!context.InputParameters.Contains(ParameterName.Target)) { return; } DynamicEntity Target = context.InputParameters[ParameterName.Target] as DynamicEntity; /* We need both regarding (parent) entity id and number of participants field Client side must Force Submit on regarding field */ if (!Target.Properties.Contains("regardingobjectid") || !Target.Properties.Contains("gi_noofpart")) { return; } Lookup regardingObjectId = Target.Properties["regardingobjectid"] as Lookup; CrmNumber noofPart = Target.Properties["gi_noofpart"] as CrmNumber; /* Validate the number of Participants */ if (noofPart.Value == 0) { return; } /* Synchronize access to this code block */ lock(SyncObject) { #region Retrieve all Regarding entity Appointments QueryExpression allPartQuery = new QueryExpression(); allPartQuery.ColumnSet = new ColumnSet(); allPartQuery.ColumnSet.AddColumn("gi_noofpart"); allPartQuery.Criteria.AddCondition( "regardingobjectid" , ConditionOperator.Equal , regardingObjectId.Value ); allPartQuery.Distinct = false; allPartQuery.EntityName = EntityName.appointment.ToString(); RetrieveMultipleRequest retMultiRequest = new RetrieveMultipleRequest(); retMultiRequest.Query = allPartQuery; retMultiRequest.ReturnDynamicEntities = true; RetrieveMultipleResponse retMultiResponse = (RetrieveMultipleResponse)context.CreateCrmService(true).Execute(retMultiRequest); #endregion #region Summaries all Appointments Number of Participants Int32 Summery = 0; foreach(DynamicEntity appointment in retMultiResponse.BusinessEntityCollection.BusinessEntities) { if (appointment.Properties.Contains("gi_noofpart")) { Summery += ((CrmNumber)appointment.Properties["gi_noofpart"]).Value; } } #endregion #region Update Parent entity Number of Participants /* Key Property */ Key parentEntityKey = new Key(regardingObjectId.Value); KeyProperty parentEntityKeyProp = new KeyProperty("gi_customid", parentEntityKey); /* Number of participants Property */ CrmNumberProperty noofPartProp = new CrmNumberProperty("gi_noofpart",new CrmNumber(Summery)); DynamicEntity parentEntity = new DynamicEntity(regardingObjectId.type); parentEntity.Properties.Add(parentEntityKeyProp); parentEntity.Properties.Add(noofPartProp); TargetUpdateDynamic targetEntity = new TargetUpdateDynamic(); targetEntity.Entity = parentEntity; UpdateRequest updateRequest = new UpdateRequest(); updateRequest.Target = targetEntity; context.CreateCrmService(true).Execute(updateRequest); #endregion } } } } Источник: http://mscrm4ever.blogspot.com/2009/...on-parent.html
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
|
|