cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Anthony_Dob
Continued Contributor
Continued Contributor

Identic Delete Plugins | One works, One doesn't work

Hi experts,

 

I have a issue on my delete plugins. I have 2 delete plugins. Both are identical.

  • Delete of ExtraCost
  • Delete of Duration

2022-01-13 11_15_10-Plugin Registration Tool.png

2022-01-13 11_12_15-.png2022-01-13 11_12_26-.png

 

As you can see both are identical. Both having the same pre Image with the ID, TrainingID and Cost/Hours.

Both plugins also have the same code running. Only difference is that Extra Costs will update Remaining Budget and Duration will update Remaining Days.


Here's a code snippet of Extra Costs:

 

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Linq;

namespace TrainingBudget.Plugin
{

    public class DeleteExtraCost : IPlugin
    {
        private static IOrganizationService _service;
        private IOrganizationServiceFactory _serviceFactory;
        private IPluginExecutionContext _context;

        public void Execute(IServiceProvider serviceProvider)

        {
            _context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            if (_context.Depth > 1)
            {
                return;
            }

            if (_context.MessageName != "Delete")
            {
                return;
            }
            _serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            _service = _serviceFactory.CreateOrganizationService(_context.UserId);

            UpdateBudgets();
        }
        private void UpdateBudgets()
        { 
                var extraKost = EntityMapper.Map<ExtraKost>(_context.PreEntityImages.FirstOrDefault(q => q.Key == "cref8_extrakost").Value);
                EntityReference extraKostERef = ((EntityReference)_context.PreEntityImages.FirstOrDefault(q => q.Key == "cref8_extrakost").Value.Attributes["cref8_extrakosttraining"]);
                var training = EntityMapper.Map<Training>(_service.Retrieve("cref8_opleiding", extraKostERef.Id, new ColumnSet("cref8_jaarstartopleiding")));

                var cursists = GetCursists("cref8_cursist", "cref8_extrakost_cref8_cursist", "cref8_cursistid", "cref8_extrakostid", training.Id);

                foreach (var cursist in cursists)
                {
                    var traineeBudget = GetTraineeBudget(cursist, training);

                    double nieuwBudget = traineeBudget.RemainingBudget + extraKost.Price;

                    Entity budget = new Entity("cref8_jaarlijkbudget");
                    budget["cref8_jaarlijkbudgetid"] = traineeBudget.Id;
                    budget["cref8_overigebudget"] = nieuwBudget;

                    _service.Update(budget);
                }
        }
        private static List<Cursist> GetCursists(string entityName, string linkToEntityName, string linkAttributeName, string attributeName, Guid id)
        {
            var query = new QueryExpression()
            {
                EntityName = entityName,
                ColumnSet = new ColumnSet("cref8_cursistid")
            };
            var link = query.AddLink(linkToEntityName, linkAttributeName, linkAttributeName);
            link.LinkCriteria = new FilterExpression()
            {
                Conditions =
                                    {
                                        new ConditionExpression(attributeName, ConditionOperator.Equal, id)
                                    }
            };

            return _service.RetrieveMultiple(query).Entities.Select(e => EntityMapper.Map<Cursist>(e)).ToList();
        }
        private static TraineeBudget GetTraineeBudget(Cursist cursist, Training training)
        {
            ConditionExpression ceYearlyBudgetFromTrainee = new ConditionExpression("cref8_cursist", ConditionOperator.Equal, cursist.Id);
            ConditionExpression ceYearlyBudgetYear = new ConditionExpression("cref8_jaar", ConditionOperator.Equal, (int)training.Year);
            FilterExpression filter = new FilterExpression();
            filter.Conditions.Add(ceYearlyBudgetFromTrainee);
            filter.Conditions.Add(ceYearlyBudgetYear);
            QueryExpression qeYearlyBudget = new QueryExpression("cref8_jaarlijkbudget");
            qeYearlyBudget.ColumnSet = new ColumnSet("cref8_jaarlijkbudgetid", "cref8_overigebudget");
            qeYearlyBudget.Criteria.AddFilter(filter);
            EntityCollection yearlyBudgetResult = _service.RetrieveMultiple(qeYearlyBudget);

            return EntityMapper.Map<TraineeBudget>(yearlyBudgetResult.Entities.First());
        }

    }
}

 

 

Here's code snippet of Duration:

 

 

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Linq;

namespace TrainingBudget.Plugin
{
    public class DeleteDuration : IPlugin
    {
        private static IOrganizationService _service;
        private IOrganizationServiceFactory _serviceFactory;
        private IPluginExecutionContext _context;

        public void Execute(IServiceProvider serviceProvider)

        {
            _context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            if (_context.Depth > 1)
            {
                return;
            }

            if (_context.MessageName != "Delete")
            {
                return;
            }

            _serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            _service = _serviceFactory.CreateOrganizationService(_context.UserId);

            UpdateBudgets();
        }

        private void UpdateBudgets()
        {
            var duration = EntityMapper.Map<Duration>(_context.PreEntityImages.FirstOrDefault(q => q.Key == "cref8_duratie").Value);
            EntityReference duratieERef = ((EntityReference)_context.PreEntityImages.FirstOrDefault(q => q.Key == "cref8_duratie").Value.Attributes["cref8_opleidingduratie"]);
            var training = EntityMapper.Map<Training>(_service.Retrieve("cref8_opleiding", duratieERef.Id, new ColumnSet("cref8_jaarstartopleiding")));

            var cursists = GetCursists("cref8_cursist", "cref8_opleiding_cref8_cursist", "cref8_cursistid", "cref8_opleidingid", training.Id);

            foreach (var cursist in cursists)
            {
                var traineeBudget = GetTraineeBudget(cursist, training);

                double nieuwAantalDagen = traineeBudget.RemainingDays + (duration.Hours / 8);
                Entity budget = new Entity("cref8_jaarlijkbudget");
                budget["cref8_jaarlijkbudgetid"] = traineeBudget.Id;
                budget["cref8_overigedagen"] = nieuwAantalDagen;

                _service.Update(budget);
            }
        }
        private static List<Cursist> GetCursists(string entityName, string linkToEntityName, string linkAttributeName, string attributeName, Guid id)
        {
            var query = new QueryExpression()
            {
                EntityName = entityName,
                ColumnSet = new ColumnSet("cref8_cursistid", "cref8_fullname")
            };
            var link = query.AddLink(linkToEntityName, linkAttributeName, linkAttributeName);
            link.LinkCriteria = new FilterExpression()
            {
                Conditions =
                                    {
                                        new ConditionExpression(attributeName, ConditionOperator.Equal, id)
                                    }
            };

            return _service.RetrieveMultiple(query).Entities.Select(e => EntityMapper.Map<Cursist>(e)).ToList();
        }
        private static TraineeBudget GetTraineeBudget(Cursist cursist, Training training)
        {
            ConditionExpression ceYearlyBudgetFromTrainee = new ConditionExpression("cref8_cursist", ConditionOperator.Equal, cursist.Id);
            ConditionExpression ceYearlyBudgetYear = new ConditionExpression("cref8_jaar", ConditionOperator.Equal, (int)training.Year);
            FilterExpression filter = new FilterExpression();
            filter.Conditions.Add(ceYearlyBudgetFromTrainee);
            filter.Conditions.Add(ceYearlyBudgetYear);
            QueryExpression qeYearlyBudget = new QueryExpression("cref8_jaarlijkbudget");
            qeYearlyBudget.ColumnSet = new ColumnSet("cref8_jaarlijkbudgetid", "cref8_overigedagen");
            qeYearlyBudget.Criteria.AddFilter(filter);
            EntityCollection yearlyBudgetResult = _service.RetrieveMultiple(qeYearlyBudget);

            return EntityMapper.Map<TraineeBudget>(yearlyBudgetResult.Entities.First());
        }

    }
}

 

 

As you can see both Plugins do the same thing. They get the TraineeBudget of all Trainees and refund the ExtraKost or the Duration.

 

  • ExtraKost Plugin is firing but no calculations are done (I think Cursists are empty when Plugin code is executing)
  • Duration Plugin is firing and calculations are done correctly.

How can one Plugin work, and basically an identical Plugin does not work?

 

EDIT:

  • If I put the ExtraKost Delete plugin on Update message for ExtraKostname field for example and I trigger it the plugin works fine.
  • I Tried changing the Plugin to Prevalidation but also the plugin does not do any calculations

 

Best Regards,

Anthony

1 ACCEPTED SOLUTION

Accepted Solutions
bipinshan
Solution Sage
Solution Sage

Hi @Anthony_Dob ,

 

Make sure you register your plugin step on Pre-validation stage instead of pre-operation.

 

Because primary entity record and related records will be already deleted from the system when plugin reaches pre-operation stage.

 

Thanks,

Bipin

Kudos and accept my solution if helpful!

View solution in original post

1 REPLY 1
bipinshan
Solution Sage
Solution Sage

Hi @Anthony_Dob ,

 

Make sure you register your plugin step on Pre-validation stage instead of pre-operation.

 

Because primary entity record and related records will be already deleted from the system when plugin reaches pre-operation stage.

 

Thanks,

Bipin

Kudos and accept my solution if helpful!

Helpful resources

Announcements
Microsoft 365 Conference – December 6-8, 2022

Microsoft 365 Conference – December 6-8, 2022

Join us in Las Vegas to experience community, incredible learning opportunities, and connections that will help grow skills, know-how, and more.

Difinity Conference 2022

Difinity Conference 2022

Register today for two amazing days of learning, featuring intensive learning sessions across multiple tracks, led by engaging and dynamic experts.

European SharePoint Conference

European SharePoint Conference

The European SharePoint Conference returns live and in-person November 28-December 1 with 4 Microsoft Keynotes, 9 Tutorials, and 120 Sessions.

Power Apps Ideas

Changes to Ideas Coming

We are excited to announce a new way to share your ideas for Power Apps!

Users online (2,065)