Plugins Logic Suggestion
-
11 iunie 2009 09:50Hi ,
I am here to get some suggestions from you regarding Plugins so that i can be sure that the logic i am using is correct.
I have a parent form which is a custom Entity. I am creating Appointment as a child form for the custom entity.
I need to calculate the sum of a particular field in Appointmemt and need to do an update in the corresponding Parent form which is the custom entity
i did a plugin in Pre event(tried Post event also) in Upgrade of Appointment synchronous mode child entity , but i can see i am not able to retrieve the value from the Appointment.
I read in some blog that this is unsupported. If any of you have any inputs please share with me since am trying hard for the same for the past 1 month
Thanks, Aarch
Toate mesajele
-
11 iunie 2009 10:12
I can’t find anything unsupported in your requirement. I do however suggest that the parent entity is updated in an asynchronous operation. I suggest you post your code and error (if any) here and we’ll try to help you out.
Blog: http://mscrm4ever.blogspot.com/ * Website: http://gicrm.upsite.co.il/ -
11 iunie 2009 10:12Hi Aarch
From my undestanding, you need to register as post event (update/create) message.
triggle pipeline select child.
regards,
Toong Yang
http://eastoceantechnical.blogspot.com/ -
11 iunie 2009 10:42Hi adi,
Heres my code...am getting generic sql error in after line retrieveresponse
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Query;
//using participantplugin.crm;
//using participantplugin.Prope
//using MyCrmService = participantplugin.crm;
using Microsoft.Win32;
namespace participantplugin
{
public class plugin:IPlugin
{
public void Execute(IPluginExecutionContext context)
{
Guid presemId = GetRegardingLeadId(context.PreEntityImages, "appointment");
Guid postsemId = GetRegardingLeadId(context.PostEntityImages, "appointment");
// ICrmService crmService = context.CreateCrmService(true);
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = AuthenticationType.AD;
token.OrganizationName = context.OrganizationName;
CrmService crmService = new CrmService();
crmService.UseDefaultCredentials = true;
crmService.Url = (string)(Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\MSCRM").GetValue("ServerUrl")) + "/2007/crmservice.asmx";
crmService.CrmAuthenticationTokenValue = token;
UpdateNextCallDueDate(crmService, presemId);
if (presemId != postsemId)
{
UpdateNextCallDueDate(crmService, postsemId);
}
}
private Guid GetRegardingsemId(PropertyBag images, string entityAlias)
{
Guid regardingsemId = Guid.Empty;
if (images.Contains(entityAlias))
{
DynamicEntity entity = (DynamicEntity)images[entityAlias];
if (entity.Properties.Contains("seminarid"))
{
Lookup regardingsemId = (Lookup)entity["seminarid"];
if (regardingObjectId.type == "seminar")
{
regardingsemId = regardingObjectId.Value;
}
}
}
return regardingsemId;
}
private void UpdateNextCallDueDate(CrmService crmService, Guid semId)
{
if (semId != Guid.Empty)
{
DynamicEntity sem= new DynamicEntity("seminar");
sem["seminarid"] = new Key(semId);
int part = GetNextScheduledPhoneCallForLead(crmService, semId);
if (part != 0)
{
sem["max_attendance"] = new CrmNumber(part);
}
crmService.Update(sem);
}
}
private int GetNextScheduledPhoneCallForLead(CrmService crmService, Guid semId)
{
try
{
ColumnSet cols = new ColumnSet(new string[] { "noofparticipants", "seminarid" });
ConditionExpression regardingCondition = new ConditionExpression();
regardingCondition.AttributeName = "seminarid";
regardingCondition.Operator = ConditionOperator.Equal;
regardingCondition.Values = new object[] { semId };
ConditionExpression scheduledCondition = new ConditionExpression();
scheduledCondition.AttributeName = "subject";
scheduledCondition.Operator = ConditionOperator.NotNull;
FilterExpression filter = new FilterExpression();
filter.Conditions.Add(regardingCondition);
filter.Conditions.Add(scheduledCondition);
QueryExpression query = new QueryExpression();
query.ColumnSet = cols;
query.EntityName = EntityName.appointment.ToString();
query.Criteria = filter;
RetrieveMultipleRequest request = new RetrieveMultipleRequest();
request.Query = query;
request.ReturnDynamicEntities = true;
RetrieveMultipleResponse response;
response = (RetrieveMultipleResponse)crmService.Execute(request);
DynamicEntity appointment= null;
int part = 0;
if (response.BusinessEntityCollection.BusinessEntities.Count > 0)
{
for (int i = 0; i < response.BusinessEntityCollection.BusinessEntities.Count; i++)
{
appointment= (DynamicEntity)response.BusinessEntityCollection.BusinessEntities[i];
part = part + ((CrmNumber)appointment["noofparticipants"]).Value;
}
}
return part;
}
catch (System.Web.Services.Protocols.SoapException ex)
{
throw new Exception(ex.Detail.InnerText);
}
}
}
}
Thanks, Aarch- Editat de Aarch 11 iunie 2009 11:50
-
11 iunie 2009 11:12
Hi Aarch,
I see a few things in your code that you need to consider:
First of all, Toong Yang suggestion is correct. This type of operation is more suitable for a post update / create message.
The second thing I see is that you use PreImage. the Create message does not have a preImage in a pre event since the instance is not yet created. so you need to wrap the GetRegarding method with a if (images != null) { }.
I would actually not use a preImage - if you register the plug-in filtering attributes to fire only when the noofparticipents is changes you won’t need the know what the previous value was. in other words you can remove this statement:
if (presemId != postsemId)
{
UpdateNextCallDueDate(crmService, postsemId);
}And only use (don’t forget to set the noofparticipants filtering attribute when you register the step)
UpdateNextCallDueDate(crmService, postsemId);
Also, CRM already facilitates the creation of CrmService. So instead of usingCrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = AuthenticationType.AD;
token.OrganizationName = context.OrganizationName;
CrmService crmService = new CrmService();
crmService.UseDefaultCredentials = true;
crmService.Url = (string)(Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\MSCRM").GetValue("ServerUrl")) + "/2007/crmservice.asmx";
crmService.CrmAuthenticationTokenValue = token;Use
IcrmSerivce service = context.CreateCrmService();
Good luck.
Blog: http://mscrm4ever.blogspot.com/ * Website: http://gicrm.upsite.co.il/ -
11 iunie 2009 11:23Hi Adi,
First of all thanks for the comments
your first comment -to use post update ---> i tried that also,but invain
second comment--i tried removing the image also no use( but i dont feel the issue is in the image since during debugging it flows smoothly woithout any bug there)
Finally regardingIcrmSerivce service = context.CreateCrmService();
i tried this But there are one issue in child pipeline - to create crmservice you have to use instance of CrmService instead of context.CreateCrmService method. i got this suggestion from andy(a33ik) and yes it shows error when i use context . the thread is here
Thanks, Aarch -
11 iunie 2009 11:29
Why do you need to register the appointment in the child pipeline?
Just to recap. You have a field called noofparticipants in the appointment entity. when the appointment is created or updated you want to retrieve the field from all appointments that are related to your custom entity and update a field on the custom entity. is this correct?
I’ll also post a blog post about this later on. you can use it as reference in your code.
Blog: http://mscrm4ever.blogspot.com/ * Website: http://gicrm.upsite.co.il/ -
11 iunie 2009 11:32yes adi, i need to get the sum of values of a particular field in appointment and get the calculated value and update in the parent form
also i tried doing in parent pipeline but the plugin was not even trigerring
Thanks, Aarch -
11 iunie 2009 14:23
Just to make sure its not a typo. is "seminar" your custom entity. is it possible that you forgot to include the prefix e.g. new_seminar?
Blog: http://mscrm4ever.blogspot.com/ * Website: http://gicrm.upsite.co.il/ -
12 iunie 2009 04:12Hi Adi,
yes seminar is my customentity and it is new_seminar ..i have written it correct in my code.
Just that i gave my client name instead of new,i edited it
Thanks, Aarch -
12 iunie 2009 11:22Hi Aarch, i posted a solution which address the summarization of appointment fields to a parent entity.
mine is called gi_custom so you should change that to new_seminar.
http://mscrm4ever.blogspot.com/2009/06/summarizing-appointment-field-on-parent.html
Good luck
Blog: http://mscrm4ever.blogspot.com/ * Website: http://gicrm.upsite.co.il/ -
17 iunie 2009 11:55Hi Adi,
it was very informative ..thnks alot...
but when i tried the plugin itself is not getting triggered...the same issue came when i tried to do my first plugin in parent pipeline..lter when i tried in child pipeline it triggered. But this plugin i am not able to trigger by registering in parent or child pipeline
did it worked for you??
Thanks, Aarch -
17 iunie 2009 12:59
Yes, this is a working solution. Are you able to register any plug-in on the appointment parent pipeline? You should try to register an empty plug-in on the book, reschedule ,create and update messages and see If the plug-in fires.
if it does not then enable CRM trace and search for common errors. If that does not reveal the problem you can also elevate the trace level to verbose and follow MS execution path.
Blog: http://mscrm4ever.blogspot.com/ * Website: http://gicrm.upsite.co.il/- Marcat ca răspuns de Jim Wang MVPMVP, Owner 18 iunie 2009 10:32
- Anulare marcare ca răspuns de Aarch 19 iunie 2009 03:21
-
18 iunie 2009 05:17hi adi,
i found that target.properties does not contacin the custom attributes!!!!!
why am i not getting the custom attributes inside the trarget.properties??
Thanks, Aarch