MademoiselleLenore
MademoiselleLenore

Reputation: 569

Setting values to fields

I created a plugin counting the number of records of an entity related to another one, if there is more than one record, I retrieve the last record. If that record is inactive and a specific field's value >0, then I add the value of this field to the newly created one...But can't get it to work...

Any help would be great !

Edit: The plugin is registered to "new_lignecontrat" wich contains the attributes "new_unitesutilisees" and "new_unitesrestantes".

Edit 2:

Ok solved it ! All I needed was simply to get an EntityReference for the lookup field and rearrange a bit my code...

Thanks for your help !

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System.Web;
using System.Collections;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Messages;

namespace ClassLibrary1
{
    public class StatusContrat : IPlugin
    {         
        public void Execute(IServiceProvider serviceProvider)
        {
            // Instanciation des services
            IPluginExecutionContext context     = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service        = factory.CreateOrganizationService(null);

            Entity statusEntité = (Entity)context.InputParameters["Target"];

                    // Récupération des lignes de contrat liées au contrat courant
                FetchExpression fetch   = new FetchExpression("<fetch distinct='false' mapping='logical'>" +
               "<entity name='new_contrats'>" +
               "<link-entity name='new_lignecontrat' alias='nombreligne' from='new_contratsid' to='new_contratsid'>" +
               "</link-entity>" +
               "</entity>" +
               "</fetch>");

                EntityCollection lines = service.RetrieveMultiple(fetch);

                    // Vérification qu'il y a au moins une ligne de contrat associée
                    if (lines.Entities.Count > 0)
                    {   
                        if (lines.Entities.Last().GetAttributeValue<OptionSetValue>("statecode").Value == 1)
                        {
                           if (lines.Entities.Last().GetAttributeValue<float>("new_unitesrestantes")<0)
                           {
                              var unitesRestantes = (statusEntité.GetAttributeValue<float>("new_unitesrestantes")) + (lines.Entities.Last().GetAttributeValue<float>("new_unitesrestantes"));
                              var unitesUtilisee =  (statusEntité.GetAttributeValue<float>("new_unitesutilisees")) - (lines.Entities.Last().GetAttributeValue<float>("new_unitesutilisees"));

                                statusEntité ["new_unitesutilisees"] = unitesUtilisee;
                                statusEntité ["new_unitesrestantes"] = unitesRestantes;

                                service.Update(statusEntité);
                           }
                        }
                    }
                    else
                    {

                        statusEntité["new_unitesutilisees"] = "0";
                        statusEntité["new_unitesrestantes"] = statusEntité["new_unitestotales"];

                        service.Update(statusEntité);
}                        

         }
      }
   }

Upvotes: 2

Views: 5269

Answers (2)

Luke Baulch
Luke Baulch

Reputation: 3656

A couple of thoughts:

Q: Are you sure your plugin is being executed at all?
To check this, you could alter the code to throw an InvalidPluginExecutionException somewhere so you know its at least executing.

Q: Is your plugin registered correctly?
Check to see if your plugin is registered on the Create message and in either of the Pre-Validation or Pre-Operation steps.

Q: Is your plugin executing along the path you'd expect?
I'd suggest you perform some debugging on the server (assuming you're doing your dev on-premise)

Edit:

I just realized that you are trying to update your target entity using a service call. When a plugin needs to update the fields on the primary entity of that plugin, it only needs to modify the attributes on the Target during either Pre-Validation or Pre-Operation stages.

        Entity target = (Entity)context.InputParameters["Target"];

        // Récupération des lignes de contrat liées au contrat courant
        FetchExpression fetch = new FetchExpression(@"
            <fetch distinct='false' mapping='logical'>
              <entity name='new_contrats'>
                <link-entity name='new_lignecontrat' alias='nombreligne' from='new_contratsid' to='new_contratsid'>
                </link-entity>
              </entity>
            </fetch>");

        // Note: Do you need some attribute fields so that the entities are actually returning some relevant data
        // Note: Do you want to retrieve ALL the 'new_contrats' or should you be adding a condition in here to the primary entity?
        //  <filter type='and'>
        //    <condition attribute='MyIdFieldHere' operator='eq' value='" + context.PrimaryEntityId + "' /> 
        //  </filter>

        EntityCollection lines = service.RetrieveMultiple(fetch);

        // Vérification qu'il y a au moins une ligne de contrat associée
        if (lines.Entities.Any())
        {
            // store last entity in variable so that the collection is enumerabled 4 seperate times
            var last = lines.Entities.Last();
            if (last.GetAttributeValue<OptionSetValue>("statecode").Value == 1)
            {
                if (last.GetAttributeValue<float>("new_unitesrestantes") < 0)
                {
                    var unitesRestantes = (target.GetAttributeValue<float>("new_unitesrestantes")) + (last.GetAttributeValue<float>("new_unitesrestantes"));
                    var unitesUtilisee = (target.GetAttributeValue<float>("new_unitesutilisees")) - (last.GetAttributeValue<float>("new_unitesutilisees"));

                    target["new_unitesutilisees"] = unitesUtilisee;
                    target["new_unitesrestantes"] = unitesRestantes;
                }
            }
        }
        else
        {
            // if 'new_unitesutilisees' is a float, then the value must also be a float
            target["new_unitesutilisees"] = 0f; 
            target["new_unitesrestantes"] = target["new_unitestotales"];
        }     

Edit 2:

Also, I'm assuming there is a better fetch query to run instead of retrieving all entities, then only using the last one. Could you narrow down the retrieved list by adjusting the query to set a reverse order and retrieve only the first item? Depending on how many entities in the system, this little optimization will greatly reduce the execution time of this plugin.

Upvotes: 1

Peter Majeed
Peter Majeed

Reputation: 5352

If this is the code you're using, it could be because your FetchXML doesn't retrieve any attributes, particularly the attributes new_unitesrestantes and new_unitesutilisees, so any entities retrieved by the RetrieveMultiple request wouldn't have values for those attributes.

<fetch distinct='false' mapping='logical'>
  <entity name='new_contrats'>
    <!-- no attributes listed here -->
    <link-entity name='new_lignecontrat' alias='nombreligne' from='new_contratsid' to='new_contratsid'>
      <!-- no attributes listed here either -->
    </link-entity>
  </entity>
</fetch>

Upvotes: 0

Related Questions