Hello everybody,
I have a simple task that require to prevent the addition of a product in the inline editing view of the order if the considered product does not have enough quantity (quantity of the order product > quantity on hand of the product), I've created a plugin on create and update of order product and implemented the business logic.
The plugin worked on both message(create, update), but there is a problem with displaying a message to the user to clarify the error when the plugin fire fromcreate message.
The problem is that instead of displaying my custom message defined in "invalidpluginexecutionexception" the inline editing view show an error but with a message "ISV code aborted the operation" i did test my code carefully to make sure that my code is working and this problem is not occurring from it.
After searching and a lot of thinking i think that i have an idea on whats going on, the reason is that my plugin is running under the context of order product so the exception is occurring in order product context and we are in the context of order entity(creating an order product from inline editing view) there for the exception is not being forwarded to order entity.
I would appreciate if someone suggest me a solution for this problem
This is my code:
public class PreOrderProductCreate: Plugin
{
/// <summary>
/// Initializes a new instance of the <see cref="PreOrderProductCreate"/> class.
/// </summary>
public PreOrderProductCreate()
: base(typeof(PreOrderProductCreate))
{
base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>(20, "Create", "salesorderdetail", new Action<LocalPluginContext>(ExecutePreOrderProductCreate)));
// Note : you can register for more events here if this plugin is not specific to an individual entity and message combination.
// You may also need to update your RegisterFile.crmregister plug-in registration file to reflect any change.
}
/// <summary>
/// Executes the plug-in.
/// </summary>
/// <param name="localContext">The <see cref="LocalPluginContext"/> which contains the
/// <see cref="IPluginExecutionContext"/>,
/// <see cref="IOrganizationService"/>
/// and <see cref="ITracingService"/>
/// </param>
/// <remarks>
/// For improved performance, Microsoft Dynamics CRM caches plug-in instances.
/// The plug-in's Execute method should be written to be stateless as the constructor
/// is not called for every invocation of the plug-in. Also, multiple system threads
/// could execute the plug-in at the same time. All per invocation state information
/// is stored in the context. This means that you should not use global variables in plug-ins.
/// </remarks>
protected void ExecutePreOrderProductCreate(LocalPluginContext localContext)
{
if (localContext == null)
{
throw new ArgumentNullException("localContext");
}
// TODO: Implement your custom Plug-in business logic.
IPluginExecutionContext context = localContext.PluginExecutionContext;
IOrganizationService service = localContext.OrganizationService;
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity targetEntity = (Entity)context.InputParameters["Target"];
if (targetEntity.LogicalName != "salesorderdetail")
{
return;
}
else
{
try
{
if (targetEntity.Attributes.Contains("quantity"))
{
Decimal quantity = targetEntity.GetAttributeValue<Decimal>("quantity");
if (targetEntity.Attributes.Contains("productid"))
{
EntityReference productReference = targetEntity.GetAttributeValue<EntityReference>("productid");
Entity product = service.Retrieve("product", productReference.Id, new ColumnSet(true));
if (product.Attributes.Contains("quantityonhand"))
{
Decimal quantityOnHand = product.GetAttributeValue<Decimal>("quantityonhand");
if (quantity > quantityOnHand)
{
throw new InvalidPluginExecutionException("Product quantity is not sufficient");
}
}
}
}
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw ex;
}
}
}
}
}
Thanks All, Best Regards