Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behavior CRM 2011 plugin

I have registered a plugin for our quote products. The plugin worked well in our test environment. I have tested it lots of times. Then registered the plugin in the main server. However, the below scenario occurs: When I create or update the quote products first the quote product form greys out:

enter image description here

After I click on the quote form the error appears. No log files are available (as you see). I debugged the plugin, but there is no error also. After I click the OK, the error disappears and the required business takes place on the quote product (for tax field). Means that the code of plugin has no errors and does its job well. The code is as:

using System;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Xrm;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk.Deployment;

public class Plugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        IPluginExecutionContext context = (IPluginExecutionContext)
        serviceProvider.GetService(typeof(IPluginExecutionContext));
        Entity entity;
        if (context.InputParameters.Contains("Target") &&
        context.InputParameters["Target"] is Entity)
        {
            entity = (Entity)context.InputParameters["Target"];
            if (entity.LogicalName != "quotedetail") { return; }
        }
        else
        {
            return;
        }
        try
        {
            IOrganizationServiceFactory serviceFactory =
                (IOrganizationServiceFactory)serviceProvider.GetService(
            typeof(IOrganizationServiceFactory));
            IOrganizationService service =
            serviceFactory.CreateOrganizationService(context.UserId);
            if (context.MessageName == "Create")
            {
                Entity QuoteProduct = (Entity)context.InputParameters["Target"];
                Guid QPID = QuoteProduct.Id;
                TaxCreator(service, QPID);
            }
            if (context.MessageName == "Update" && context.Depth < 3)
            {
                Entity QuoteProduct = (Entity)context.PostEntityImages["Target"];
                Guid QPID = QuoteProduct.Id;
                TaxUpdater(service, QPID);
            }
        }
        catch (FaultException<OrganizationServiceFault> ex)
        {
            throw new InvalidPluginExecutionException(
            "An error occurred in the plug-in.", ex);
        }
    }
    private static void TaxCreator(IOrganizationService service, Guid QPID)
    {
        using (var crm = new XrmServiceContext(service))
        {
            var QuoteProduct = crm.QuoteDetailSet.Where(c => c.QuoteDetailId == QPID).First();
            var SaleSetting = crm.new_salessettingSet.Where(c => c.statecode == 0).First();
            double TaxPercent = (Convert.ToDouble(SaleSetting.new_TaxPercent) / 100);
            if (QuoteProduct.IsPriceOverridden == false)
            {
                decimal Tax = (decimal)Convert.ToDecimal(Convert.ToDouble(QuoteProduct.BaseAmount - QuoteProduct.ManualDiscountAmount.GetValueOrDefault()) * TaxPercent);
                decimal PricePerUnit = (decimal)(QuoteProduct.PricePerUnit.GetValueOrDefault() - QuoteProduct.VolumeDiscountAmount.GetValueOrDefault());
                crm.UpdateObject(QuoteProduct);
                crm.SaveChanges();
                QuoteProduct.Attributes["tax"] = new Money(Tax);
                QuoteProduct.Attributes["new_result"] = new Money(PricePerUnit);
                crm.UpdateObject(QuoteProduct);
                crm.SaveChanges();
            }
        }
    }
    private static void TaxUpdater(IOrganizationService service, Guid QPID)
    {
        using (var crm = new XrmServiceContext(service))
        {
            var QuoteProduct = crm.QuoteDetailSet.Where(c => c.QuoteDetailId == QPID).First();
            var SaleSetting = crm.new_salessettingSet.Where(c => c.statecode == 0).First();
            double TaxPercent = (Convert.ToDouble(SaleSetting.new_TaxPercent) / 100);
            if (QuoteProduct.IsPriceOverridden == false)
            {
                decimal Tax = (decimal)Convert.ToDecimal(Convert.ToDouble(QuoteProduct.BaseAmount - QuoteProduct.ManualDiscountAmount.GetValueOrDefault()) * TaxPercent);
                decimal PricePerUnit = (decimal)(QuoteProduct.PricePerUnit.GetValueOrDefault() - QuoteProduct.VolumeDiscountAmount.GetValueOrDefault());
                crm.UpdateObject(QuoteProduct);
                crm.SaveChanges();
                QuoteProduct.Attributes["tax"] = new Money(Tax);
                QuoteProduct.Attributes["new_result"] = new Money(PricePerUnit);
                crm.UpdateObject(QuoteProduct);
                crm.SaveChanges();
            }
        }
    }
}

I also checked the event viewer on the server for the errors, and no result! I have registered my plugin on create and update of the quote product. Any help is greatly appreciated.

like image 672
Payman Biukaghazadeh Avatar asked Mar 11 '13 15:03

Payman Biukaghazadeh


1 Answers

I'd go shotgun debug on it. Implement the following tracing. Usually, I place the declaration of the tracer as a class member (so it's visible to all my help methods within the class) and write to it (when desperate and frustrated) after every operation (more or less). Then, when the program crashes by itself (or when I intentionally crash it to see the trace log), I can usually pin-point the problem area.

public class MyPlugin _ IPlugin
{
  private ITracingService _trace;

  public void Execute(IServiceProvider service)
  {
    _trace = (ITracingService)service.GetService(typeof(ITracingService));
    _trace.Trace("Commencing.");
    ...
    _trace.Trace("Right before an operation. " + someValue);
    PerformAnOperation();
    _trace.Trace("Right before an other operation. " + someOtherValue);
    PerformAnOtherOperation();
    ...
    throw new Exception("Intentional!");
  }
}

The, you can follow through to see exactly where the problem originates. In my experience, once one knows where it aches, one can easily suggest how to remedy the issue.

EDIT:

Since the OP requested more details, I'm taking his code and put in the tracing algorithm into it for him. A bit redundant but apparently, CRM can be very confusing. Been there myself.

public class Plugin : IPlugin
{
  // Here we declare our tracer.
  private ITracingService _trace;

  public void Execute(IServiceProvider serviceProvider)
  {
    // Here we create it.
    _trace = (ITracingService)serviceProvider
      .GetService(typeof(ITracingService));
    _trace.Trace("Commencing.");

    // Here we crash our plugin just to make sure that we can see the logs 
    // with trace information. This statement should be gradually moved down
    // the code to discover where exactly the plugin brakes.
    throw new Exception("Intentional!");

    IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider
      .GetService(typeof(IPluginExecutionContext));
    Entity entity;
    ...

    try { ... }
    catch (FaultException<OrganizationServiceFault> ex)
    {
      throw new InvalidPluginExecutionException(
        "An error occurred in the plug-in.", ex);
    }

    // Here we catch all other kinds of bad things that can happen.
    catch(Exception exception) { throw exception; }
  }

  private static void TaxCreator(IOrganizationService service, Guid QPID)
  {
    // Here we add a line to the trace hoping that the execution gets here.
    _trace.Trace("Entered TaxCreator.");

    using (var crm = new XrmServiceContext(service))
    {
      var QuoteProduct = crm.QuoteDetailSet.Where(...).First();
      var SaleSetting = crm.new_salessettingSet.Where(...).First();
      double TaxPercent = (Convert.ToDouble(...) / 100);

      // Here we add a line to the trace to see if we get past this point.
      _trace.Trace("Approaching if statement.");

      if (QuoteProduct.IsPriceOverridden == false) { ... }
    }
  }

  private static void TaxUpdater(IOrganizationService service, Guid QPID)
  {
    // Here we add a line to the trace hoping that the execution gets here.
    _trace.Trace("Entered TaxUpdater.");

    ...
  }
}
like image 198
Konrad Viltersten Avatar answered Oct 23 '22 05:10

Konrad Viltersten