1
votes

In our Dynamics 365, for each Project - we're showing the Created On date field. This field essentially represents the date on which the Project was created.

Created On

However, we're supposed to show the duration of Project.

Like at many places, we have these on Stackoverflow:

  • Asked n minute ago
  • Asked n day ago
  • Asked n week ago
  • Asked n month ago
  • and so on...

We wanted to show:

  • Created n minute ago
  • Created n day ago
  • Created n week ago
  • Created n month ago
  • and so on...

How do we calculate duration of project in Dynamics CRM 365?

Running jobs is not an option for us

2

2 Answers

1
votes

If you just need the fields calculated for display purposes you could do something like this

  1. Create your new fields
  2. Register a new plugin on Post Retrieve and RetrieveMultiple of Project entity
  3. Copy the logic from the code below, swapping entity/field names where needed.

What my code is doing is intercepting Contact records whenever they're to be displayed in CRM. This means in grids, forms, dashboards etc. It'll then calculate the time difference on the spot and populate the fields with the result. By then populating the entity object in the OutputParameters, the front end receives those values and can display them where appropriate.

The only downside here is that because those fields are calculated directly in CRM you won't be able to write any SSRS reports as the data isn't persisted to the database. If you were to implement this and then go do a SQL query against those fields you'll find them all null. Those fields merely act as placeholders. (see screenshots)

protected void ExecutePreValidateContactRetrieve(LocalPluginContext localContext)
    {
        if (localContext == null)
        {
            throw new ArgumentNullException("localContext");
        }

        IPluginExecutionContext pluginContext = localContext.PluginExecutionContext;

        if (pluginContext.OutputParameters.Contains("BusinessEntity"))
        {
            Entity target = (Entity)pluginContext.OutputParameters["BusinessEntity"];
            PopulateKPIs(localContext.OrganizationService, target);
        }
        else if (pluginContext.OutputParameters.Contains("BusinessEntityCollection"))
        {
            EntityCollection contacts = (EntityCollection)localContext.PluginExecutionContext.OutputParameters["BusinessEntityCollection"];

            foreach (Entity c in contacts.Entities)
                PopulateKPIs(localContext.OrganizationService, c);
        }
    }

    public void PopulateKPIs(IOrganizationService orgService, Entity contact)
    {
        DateTime createdOn;

        if (!contact.Contains("createdon"))
            createdOn = orgService.Retrieve(contact.LogicalName, contact.Id, new ColumnSet("createdon")).GetAttributeValue<DateTime>("createdon");
        else
            createdOn = contact.GetAttributeValue<DateTime>("createdon");

        TimeSpan diff = DateTime.Now - createdOn;

        contact["mst_secondssincecreation"] = Math.Floor(diff.TotalSeconds).ToString();
        contact["mst_minutessincecreation"] = Math.Floor(diff.TotalMinutes).ToString();
        contact["mst_hourssincecreation"] = Math.Floor(diff.TotalHours).ToString();
    }

Evidence:

enter image description here enter image description here

0
votes

I'm assuming you only need this on a form. In the DB you obviously store the actual created on date.

How this is normally done on web sites is being calculated in JS, based on a given date time. Using a library like this one http://timeago.yarp.com/

How you do this in CRM is exactly the same. * Create a simple web resource, which takes the createdon from it's parent and displays the "timeago" using the script above. * Put the createdon on the form (can be hidden, doesn't matter). * Put the web resource on the form. Add a label and make it 1 row if you want it to look like a form field.