locked
Modifying a Plugin to Sum Values of a Record and populate the total RRS feed

  • Question

  • Hello, 

    I have an entity called new_accrued_billing that I've setup as a sub grid in the project module so you can click in the grid from within a project and create a record. My next requirement involves summing the values of 1 field in the Subgrid Records and summing them into a field on the project module. I've modified an existing plugin (that does the same thing for Time Entries on a project). 

     decimal Billed = 0;
                   // decimal NonBillable_Total = 0;
                    lastAction += "\nRun Totals For loop";
                    if (Project_Billing != null)
                    {
                        lastAction += "\nTime Entry is not null " + Project_Billing.Count.ToString();
                        if (Project_Billing.Count > 0)
                        {
                            lastAction += "\nCount is not null eric " + Project_Billing.Count.ToString();
                            foreach (Entity Project_Billings in Project_Billing)
                            {
                              Billed += (Convert.ToDecimal(Project_Billings["new_billed"].ToString()));
                            }
                                   
                         }
                     }
    
                    Entity updateProject = new Entity();
                    updateProject.LogicalName = "new_project";
                    updateProject.Id = parentEvent.Id;
                    updateProject["new_billing_summary"] = Convert.ToDecimal(Billed.ToString());
                   // updateProject["new_nonbillabletime"] = Convert.ToDecimal(NonBillable_Total.ToString());
                    lastAction += "\nAttempting Update " + updateProject.Id.ToString();
    
                    try 
                    {
                        crmService.Update(updateProject);
                    }
                    catch (FaultException e)
                    {
                        lastAction += "\nError: " + e.Message;
                        throw new InvalidPluginExecutionException("Fault Exception: " + lastAction);
                    }
    
    	}//try
                    try 
                    {
                        crmService.Update(updateProject);
                    }
                    catch (FaultException e)
                    {
                        lastAction += "\nError: " + e.Message;
                        throw new InvalidPluginExecutionException("Fault Exception: " + lastAction);
                    }
    
    	}//try

    It compiles successfully and registers however I receive the following error:

    Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Catch All Exception: 
    tracingService setup for Project_Billing_Rollup
    serviceFactory set
    service set
    MessageName = Create
    Create Message
    Comes to Billing Entry
    Parent Obtained 
    Run Totals For loop
    Time Entry is not null 3
    Count is not null eric  3Detail: 
    <OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
      <ErrorCode>-2147220891</ErrorCode>
      <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
        <KeyValuePairOfstringanyType>
          <d2p1:key>OperationStatus</d2p1:key>
          <d2p1:value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:string">0</d2p1:value>
        </KeyValuePairOfstringanyType>
      </ErrorDetails>
      <Message>Catch All Exception: 
    tracingService setup for Project_Billing_Rollup
    serviceFactory set
    service set
    MessageName = Create
    Create Message
    Comes to Billing Entry
    Parent Obtained 
    Run Totals For loop
    Time Entry is not null 3
    Count is not null eric  3</Message>
      <Timestamp>2013-05-02T20:29:43.7746617Z</Timestamp>
      <InnerFault i:nil="true" />
      <TraceText>

    [Billing_Summary_Rollup: Project_Billing_Rollup.Project_Billing_Rollup]
    [ Project_Billing_Rollup.Project_Billing_Rollup: Create of new_accrued_billing]
    </TraceText>
    </OrganizationServiceFault>

    Any suggestions would be great! 

    Thanks!

    Eric

    Thursday, May 2, 2013 8:48 PM

Answers

  • Ok then you have to check the correct format.

    Here is a possible solution with updating the currency field:

                Money TotalItemMoney = new Money();
                Money TotalCalulatedSum = new Money();
                decimal totalprice = 0;
                object moneyobject = new object();
                decimal totalpricedecvalue = 0;
      			[...]
                foreach (Entity Project_Billings in Project_Billing)
                {
                    if (Project_Billings.Contains("new_billed")) 
    				{
    					TotalItemMoney = null;
    					TotalItemMoney = (Money)Project_Billings.Attributes["new_billed"];
    					totalpricedecvalue = TotalItemMoney.Value;
    					totalprice = totalprice + totalpricedecvalue;
    				}
    				else
    				{ continue;}
                };
    			 TotalCalulatedSum.Value = totalprice;
    			 
    			 [... Service.Update .. etc]

    I hope this will help you to sum up the currency field.


    AM


    Thursday, May 16, 2013 6:48 AM

All replies

  • Hi Eric,

        From what I see is the problem is on the following line:

    Billed += (Convert.ToDecimal(Project_Billings["new_billed"].ToString()));
       

         This could be due to few things:

    1) you have misspelled new_billed

    2) new_billed is null or empty as you are attempting ToDecimal conversion there.


    Hope this helps.
     
    -----------------------------------------------------------------------
     Minal Dahiya
     
    If this post answers your question, please click "Mark As Answer" on the post and "Vote as Helpful"

    • Proposed as answer by Minal Dahiya Friday, May 3, 2013 12:29 AM
    Friday, May 3, 2013 12:29 AM
  • Unfortunately, I checked both of those items and they appear to be correct. 

    Is there anything to look out for when modifying an existing plugin? I took the code from the previous one changed the Assembly Name and then modified the fields.

             
    • Edited by Eric Brady Friday, May 3, 2013 4:11 PM
    Friday, May 3, 2013 4:09 PM
  • Hi!

    I think it is the best way to profile your custom plugin.

    Here is the documentation for profiling plugins. Then you can debug your code line by line.

    http://support.microsoft.com/kb/2778280?wa=wsignin1.0

    What is your trigger for the plugin?
    Update of the child entity or a custom button (Recalculate) in the parent entity?

    Andreas Müller


    AM

    Monday, May 6, 2013 6:46 AM
  • Hi Andreas, 

    The plugin kicks off on create , on delete and on update. I've been trying to get into debugging today...it looks like it makes it to the following:

    MessageName = Create
    Create Message
    Comes to Billing Entry

     {
                        case "Create":
                            lastAction += "\nCreate Message";
                            entity = (Entity)context.InputParameters["Target"];
    
                            if (context.PrimaryEntityName.ToLower() == "new_accrued_billing")
                            {
                                lastAction += "\nComes to Billing Entry";
                                Entity CurrentBillingEntry = new Entity("new_accrued_billing");
                                ColumnSet attributes = new ColumnSet(new string[] { "new_project" });
                                CurrentBillingEntry = crmService.Retrieve(CurrentBillingEntry.LogicalName, entity.Id, attributes);
                                parentEvent = ((EntityReference)CurrentBillingEntry["new_project"]);
                                lastAction += "\nParent Obtained ";
                            }
                            else
                            {
                                lastAction += "\nSet Entity with Target data";
                                parentEvent = ((EntityReference)entity["new_project"]);
                            }
                            if (context.PrimaryEntityName.ToLower() == "new_accrued_billing")
                            {
                                Project_Billing = getRelatedEntities(crmService, "new_accrued_billing", parentEvent.Id, "new_project", Guid.Empty, null);
                            }
                            else
                            {
                                return;
                            }
                            break;


    however I'm pretty new to debugging so i'm not sure where to go from there.

    Error from profile:

    Microsoft.Xrm.Sdk.InvalidPluginExecutionException was unhandled by user code
      Message=Fault Exception: 
    tracingService setup for Billing
    serviceFactory set
    service set
    MessageName = Create
    Create Message
    Comes to Billing Entry
      Source=Billing
      ErrorCode=-2146233088
      StackTrace:
           at Billing.Billing.Execute(IServiceProvider serviceProvider)
           at PluginProfiler.Library.PluginAppDomainProxy.ExecuteCore(Stopwatch watch, ProfilerExecutionReport report, Object instance, Object executionParameter)
           at PluginProfiler.Library.AppDomainProxy.Execute(ProfilerExecutionConfiguration configuration, ProfilerExecutionReport report)
      InnerException: 


    • Edited by Eric Brady Monday, May 6, 2013 11:31 PM
    Monday, May 6, 2013 11:26 PM
  • Hi Eric,

        Here is the link to the article which explains how to debug plug-in.

    http://msdn.microsoft.com/en-us/library/gg328574.aspx

         This will help you find out the cause of the issue.


    Hope this helps.
     
    -----------------------------------------------------------------------
     Minal Dahiya
     
    If this post answers your question, please click "Mark As Answer" on the post and "Vote as Helpful"

    Monday, May 6, 2013 11:47 PM
  • Hi!

    Here at this line you should check the attribute status:

                            foreach (Entity Project_Billings in Project_Billing)
                            {
    if (Project_Billings.Contains("new_billed")) //is the new billed attribute filled up? otherwise continue with the next data
    {                          
    Billed += (Convert.ToDecimal(Project_Billings["new_billed"].ToString()));
    }
    else
    continue;
                            }

    With this line of code you check that the new_billed attribute is filled up and that is in the entity collection Project_Billing and the Entity Project_Billings.

    I hope this helps you? Otherwise please check the links for the Debugging and Profiling with this tool you can check your code line by line and you can find the failure point.


    AM

    Wednesday, May 8, 2013 11:30 AM
  • I was able to get this working by changing the datatype of the field (new_billed) from currency to decimal. Can anyone point me in the direction of what I'd change to make it work with currency datatypes?


    • Edited by Eric Brady Wednesday, May 15, 2013 10:22 PM
    Wednesday, May 15, 2013 9:44 PM
  • Ok then you have to check the correct format.

    Here is a possible solution with updating the currency field:

                Money TotalItemMoney = new Money();
                Money TotalCalulatedSum = new Money();
                decimal totalprice = 0;
                object moneyobject = new object();
                decimal totalpricedecvalue = 0;
      			[...]
                foreach (Entity Project_Billings in Project_Billing)
                {
                    if (Project_Billings.Contains("new_billed")) 
    				{
    					TotalItemMoney = null;
    					TotalItemMoney = (Money)Project_Billings.Attributes["new_billed"];
    					totalpricedecvalue = TotalItemMoney.Value;
    					totalprice = totalprice + totalpricedecvalue;
    				}
    				else
    				{ continue;}
                };
    			 TotalCalulatedSum.Value = totalprice;
    			 
    			 [... Service.Update .. etc]

    I hope this will help you to sum up the currency field.


    AM


    Thursday, May 16, 2013 6:48 AM
  • Hi,

    You can update the money field as

    Billed += new Money((Convert.ToDecimal(Project_Billings["new_billed"].ToString())));


    Thanks, Ranjan,Dynamics CRM Developer

    Thursday, May 16, 2013 7:26 AM