cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Anthony_Dob
Responsive Resident
Responsive Resident

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
Super User
Super User

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
Super User
Super User

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
PA Virtual Workshop Carousel 768x460.png

Register for a Free Workshop

This training provides practical hands-on experience in creating Power Apps solutions in a full-day of instructor-led App creation workshop.

Microsoft Build 768x460.png

Microsoft Build is May 24-26. Have you registered yet?

Come together to explore latest innovations in code and application development—and gain insights from experts from around the world.

May UG Leader Call Carousel 768x460.png

What difference can a User Group make for you?

At the monthly call, connect with other leaders and find out how community makes your experience even better.

Users online (2,835)