Reputation: 3555
I have 2 custom entities and a list of Calendar rules which i'm trying to each parse to a separate list of a 3rd custom entity, 1 or 2 for each day. I then Union those lists together to make a final list which contains the right entities.
I'm now trying to debug the workflow before I finalize it by generating all the entities, but I have to fix several processing errors first.
Errors I get:
Unhandled Exception: System.Activities.InvalidWorkflowException: The following errors were encountered while processing the workflow tree:
'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "DirectCast(CustomActivityStep1: tijdindelingen maken_1_converted, System.String)".
Syntax error in cast operator; two arguments separated by comma are required.
'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "DirectCast(CustomActivityStep1_1_converted, Microsoft.Xrm.Sdk.EntityReference)".Invalid L-value expression.:Reference expressions cannot end with Conversion. The provided expression's type must exactly match the type T of VisualBasicReference<T> or LambdaReference<T>.
'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "CustomActivityStep1: tijdindelingen maken_1_converted".
End of expression expected.
'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "CustomActivityStep1: tijdindelingen maken_1".
End of expression expected.
'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "CustomActivityStep1: tijdindelingen maken_1".
End of expression expected.
at System.Activities.Hosting.WorkflowInstance.ValidateWorkflow(WorkflowInstanceExtensionManager extensionManager)
at System.Activities.WorkflowApplication.EnsureInitialized()
at System.Activities.WorkflowApplication.Enqueue(InstanceOperation operation, Boolean push)
at System.Activities.WorkflowApplication.WaitForTurn(InstanceOperation operation, TimeSpan timeout)
at System.Activities.WorkflowApplication.InternalRun(TimeSpan timeout, Boolean isUserRun)
at Microsoft.Crm.Workflow.SynchronousRuntime.ActivityHost.StartWorkflowExecution(Activity workflow, ICommonWorkflowContext context)
at Microsoft.Crm.Workflow.SynchronousRuntime.ActivityHost.StartWorkflow(ICommonWorkflowContext context)
Code which gives these errors:
// <copyright file="GenerateTijdIndelingen.cs" company="">
// Copyright (c) 2013 All Rights Reserved
// </copyright>
// <author></author>
// <date>11/22/2013 12:28:26 PM</date>
// <summary>Implements the GenerateTijdIndelingen Workflow Activity.</summary>
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
namespace acm.mscrm2011.hrpro.Workflow
{
using System;
using System.Activities;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
public sealed class GenerateTijdIndelingen : CodeActivity
{
[Input("Personeelsfiche")]
[ReferenceTarget(slfn_personeelsfiche.EntityLogicalName)]
public InArgument<EntityReference> Personeelsfichereference { get; set; }
/// <summary>
/// Executes the workflow activity.
/// </summary>
/// <param name="executionContext">The execution context.</param>
protected override void Execute(CodeActivityContext executionContext)
{
// Create the tracing service
ITracingService tracingService = executionContext.GetExtension<ITracingService>();
if (tracingService == null)
{
throw new InvalidPluginExecutionException("Failed to retrieve tracing service.");
}
tracingService.Trace("Entered GenerateTijdIndelingen.Execute(), Activity Instance Id: {0}, Workflow Instance Id: {1}",
executionContext.ActivityInstanceId,
executionContext.WorkflowInstanceId);
// Create the context
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
if (context == null)
{
throw new InvalidPluginExecutionException("Failed to retrieve workflow context.");
}
tracingService.Trace("GenerateTijdIndelingen.Execute(), Correlation Id: {0}, Initiating User: {1}",
context.CorrelationId,
context.InitiatingUserId);
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
// This is where the magic happens
Type type = Type.GetType("Microsoft.Crm.Workflow.SynchronousRuntime.WorkflowContext, Microsoft.Crm.Workflow, Version=5.0.0.0");
type.GetProperty("ProxyTypesAssembly").SetValue(serviceFactory, typeof(XrmServiceContext).Assembly, null);
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
XrmServiceContext serviceContext = new XrmServiceContext(service);
try
{
//gegevens ophalen
Guid personeelslidGuid = Personeelsfichereference.Get<slfn_personeelsfiche>(executionContext).Id;
IEnumerable<CalendarRule> applicableCalendarRules = GetCalendarRules(serviceContext).Where(cr => IsInNMonthsOrLess(cr.StartTime.GetValueOrDefault(), 2));
Guid feestDagGuid = GetAfwezigheidsRedenId(serviceContext, "Feestdag");
IEnumerable<acm_weekkalender> weekkalenders = GetWeekKalender(serviceContext, personeelslidGuid);
IEnumerable<acm_afwezigheden> applicableAfwezigheden = GetAfwezighedenForPersoneelslid(serviceContext, personeelslidGuid).Where(afw => IsInNMonthsOrLess(afw.acm_eerstedag.GetValueOrDefault(), 2) || IsInNMonthsOrLess(afw.acm_laatstedag.GetValueOrDefault(), 2));
List<acm_tijdindeling> feestdagTijdindelingen = new List<acm_tijdindeling>();
//calendarrules parsen
foreach (CalendarRule calendarRule in applicableCalendarRules)
{
acm_tijdindeling feestdagtijdindeling = new acm_tijdindeling { acm_personeelsfiche = new EntityReference(slfn_personeelsfiche.EntityLogicalName, personeelslidGuid), acm_starttijdstip = calendarRule.StartTime, acm_eindtijdstip = calendarRule.EndTime.GetValueOrDefault(), acm_iswerktijd = false, acm_redenvanafwezigheid = new EntityReference(acm_afwezigheidsreden.EntityLogicalName, feestDagGuid) };
feestdagtijdindeling.acm_name = String.Format(feestdagtijdindeling.acm_personeelsfiche.Name + " - " + feestdagtijdindeling.acm_redenvanafwezigheid.Name + " - " + feestdagtijdindeling.acm_starttijdstip.GetValueOrDefault().ToShortDateString());
feestdagTijdindelingen.Add(feestdagtijdindeling);
}
//afwezigheden parsen
List<acm_tijdindeling> afwezigheidTijdIndelingen = new List<acm_tijdindeling>();
foreach (acm_afwezigheden acmAfwezigheid in applicableAfwezigheden)
{
acm_tijdindeling afwezigheidtijdindeling = new acm_tijdindeling { acm_personeelsfiche = new EntityReference(slfn_personeelsfiche.EntityLogicalName, acmAfwezigheid.acm_personeelslid.Id), acm_starttijdstip = acmAfwezigheid.acm_eerstedag.GetValueOrDefault(), acm_eindtijdstip = acmAfwezigheid.acm_laatstedag.GetValueOrDefault(), acm_iswerktijd = false, acm_redenvanafwezigheid = new EntityReference(acm_afwezigheidsreden.EntityLogicalName, acmAfwezigheid.acm_afwezigheidsreden.Id) };
afwezigheidtijdindeling.acm_name = String.Format(afwezigheidtijdindeling.acm_personeelsfiche.Name + " - " + afwezigheidtijdindeling.acm_redenvanafwezigheid.Name + " - " + afwezigheidtijdindeling.acm_starttijdstip.GetValueOrDefault().ToShortDateString());
afwezigheidTijdIndelingen.Add(afwezigheidtijdindeling);
}
//weekkalenders parsen
List<acm_tijdindeling> werktijdIndelingen = new List<acm_tijdindeling>();
foreach (acm_weekkalender acmWeekkalender in weekkalenders)
{
DateTime contractstartDateTime = DateTime.Now;
DateTime contractendDateTime = contractstartDateTime.AddMonths(2);
List<DayOfWeek> dayOfWeeks = Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>().ToList();
CultureInfo dutchCultureInfo = new CultureInfo("nl-BE");
Array vmnmList = Enum.GetValues(typeof(DagDeel));
foreach (DayOfWeek dayOfWeek in dayOfWeeks)
{
// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysUntilNextDay = ((int)dayOfWeek - (int)contractstartDateTime.DayOfWeek + 7) % 7;
DateTime nextDateTime = contractstartDateTime.AddDays(daysUntilNextDay).AddDays((acmWeekkalender.acm_volgnummer.GetValueOrDefault(1) - 1) * 7);
string weekdag = dutchCultureInfo.DateTimeFormat.DayNames[(int)dayOfWeek].ToLower();
foreach (DagDeel dagDeel in vmnmList)
{
string lowerDagDeel = dagDeel.ToString().ToLower();
if (acmWeekkalender.GetAttributeValue<Boolean>("acm_" + weekdag + lowerDagDeel + "vrijaf")) continue;
int startuur = acmWeekkalender.GetAttributeValue<OptionSetValue>("acm_" + weekdag + lowerDagDeel + "startuur").Value;
int startminuut = acmWeekkalender.GetAttributeValue<OptionSetValue>("acm_" + weekdag + lowerDagDeel + "startminuut").Value;
int einduur = acmWeekkalender.GetAttributeValue<OptionSetValue>("acm_" + weekdag + lowerDagDeel + "einduur").Value;
int eindminuut = acmWeekkalender.GetAttributeValue<OptionSetValue>("acm_" + weekdag + lowerDagDeel + "eindminuut").Value;
DateTime startDateTime = new DateTime(nextDateTime.Year, nextDateTime.Month, nextDateTime.Day, Convert.ToInt16(GetOptionsetText("acm_uren", startuur, service)), Convert.ToInt16(GetOptionsetText("acm_minuten", startminuut, service)), 0, DateTimeKind.Local);
DateTime endDateTime = new DateTime(nextDateTime.Year, nextDateTime.Month, nextDateTime.Day, Convert.ToInt16(GetOptionsetText("acm_uren", einduur, service)), Convert.ToInt16(GetOptionsetText("acm_minuten", eindminuut, service)), 0, DateTimeKind.Local);
for (DateTime dateTime = nextDateTime; dateTime < contractendDateTime; dateTime.AddDays(7))
{
acm_tijdindeling werktijdindeling = new acm_tijdindeling { acm_personeelsfiche = new EntityReference(slfn_personeelsfiche.EntityLogicalName, acmWeekkalender.acm_werknemer.Id), acm_weekkalender = new EntityReference(acm_weekkalender.EntityLogicalName, acmWeekkalender.Id), acm_starttijdstip = startDateTime, acm_eindtijdstip = endDateTime, acm_iswerktijd = true };
werktijdindeling.acm_name = String.Format(werktijdindeling.acm_personeelsfiche.Name + " - " + werktijdindeling.acm_redenvanafwezigheid.Name + " - " + werktijdindeling.acm_starttijdstip.GetValueOrDefault().ToShortDateString());
werktijdIndelingen.Add(werktijdindeling);
}
}
}
}
//debug info.
List<acm_tijdindeling> unionTijdindelingen = feestdagTijdindelingen.Union(afwezigheidTijdIndelingen, new TijdIndelingComparer()).Union(werktijdIndelingen, new TijdIndelingComparer()).ToList();
int aantalFeestdagen = unionTijdindelingen.Count(uti => uti.acm_redenvanafwezigheid.Id.Equals(feestDagGuid));
int aantalwerkdagen = unionTijdindelingen.Count(uti => uti.acm_iswerktijd.GetValueOrDefault());
int aantalAfwezigheidsdagen = unionTijdindelingen.Count(uti => !uti.acm_iswerktijd.GetValueOrDefault(false) && !uti.acm_redenvanafwezigheid.Id.Equals(feestDagGuid));
}
catch (FaultException<OrganizationServiceFault> e)
{
tracingService.Trace("Exception: {0}", e.ToString());
// Handle the exception.
throw;
}
tracingService.Trace("Exiting GenerateTijdIndelingen.Execute(), Correlation Id: {0}", context.CorrelationId);
}
private static Guid GetAfwezigheidsRedenId(XrmServiceContext serviceContext, string type)
{
return (from afwr in serviceContext.acm_afwezigheidsredenSet
where afwr.acm_name.ToLower(CultureInfo.InvariantCulture).Equals(type.ToLower(CultureInfo.InvariantCulture))
select afwr.Id).First();
}
private static IEnumerable<acm_afwezigheden> GetAfwezighedenForPersoneelslid(XrmServiceContext serviceContext, Guid personeelslidGuid)
{
return (from afw in serviceContext.acm_afwezighedenSet
where afw.acm_personeelslid.Id.Equals(personeelslidGuid)
select afw);
}
private static IEnumerable<acm_weekkalender> GetWeekKalender(XrmServiceContext serviceContext, Guid personeelslidGuid)
{
return (from wk in serviceContext.acm_weekkalenderSet
where wk.acm_werknemer.Id.Equals(personeelslidGuid)
select wk);
}
private static bool IsInNMonthsOrLess(DateTime checkedDateTime, int n)
{
DateTime nowDateTime = DateTime.Now;
DateTime nMonthsDateTime = nowDateTime.AddMonths(n);
return (nowDateTime <= checkedDateTime && checkedDateTime <= nMonthsDateTime);
}
private static IEnumerable<CalendarRule> GetCalendarRules(XrmServiceContext serviceContext)
{
Organization org = (from o in serviceContext.OrganizationSet
select o).FirstOrDefault();
if (org != null && org.BusinessClosureCalendarId != null)
{
Guid businessClosureCalendarId = org.BusinessClosureCalendarId.Value;
Calendar businessClosureCalendar = (from c in serviceContext.CalendarSet
where c.CalendarId == businessClosureCalendarId
select c).FirstOrDefault();
if (businessClosureCalendar != null)
{
return businessClosureCalendar.CalendarRules;
}
} return null;
}
private enum DagDeel
{
Vm,
Nm
}
private static string GetOptionsetText(string optionsetName, int optionsetValue, IOrganizationService service)
{
string optionsetSelectedText = string.Empty;
RetrieveOptionSetRequest retrieveOptionSetRequest =
new RetrieveOptionSetRequest
{
Name = optionsetName
};
// Execute the request.
RetrieveOptionSetResponse retrieveOptionSetResponse =
(RetrieveOptionSetResponse)service.Execute(retrieveOptionSetRequest);
// Access the retrieved OptionSetMetadata.
OptionSetMetadata retrievedOptionSetMetadata = (OptionSetMetadata)retrieveOptionSetResponse.OptionSetMetadata;
// Get the current options list for the retrieved attribute.
OptionMetadata[] optionList = retrievedOptionSetMetadata.Options.ToArray();
foreach (OptionMetadata optionMetadata in optionList)
{
if (optionMetadata.Value == optionsetValue)
{
optionsetSelectedText = optionMetadata.Label.UserLocalizedLabel.Label;
break;
}
}
return optionsetSelectedText;
}
private class TijdIndelingComparer : IEqualityComparer<acm_tijdindeling>
{
public bool Equals(acm_tijdindeling ati1, acm_tijdindeling ati2)
{
return ati1.acm_starttijdstip.GetValueOrDefault().Date.Equals(ati2.acm_starttijdstip.GetValueOrDefault().Date);
}
public int GetHashCode(acm_tijdindeling ati)
{
return ati.acm_starttijdstip.GetHashCode();
}
}
}
}
the 3 lines at the end of the execute are just for eventual debugging, once I get it to work.
I've tried to google why it fails, but I can't seem to find any info on this.
edit: clarified what exactly causes the workflow errors.
Upvotes: 1
Views: 2297
Reputation: 106
This is now a rather old question but nevertheless I can answer it so that there is a record for others to find.
The problem is actually with how workflow process creation is carried out. To profile a custom workflow, a Step referencing that workflow is required. This reference is entered into the panel at the bottom of the process creation window. Once the Step has been added, a text box invites you to add a description. Do NOT under any circumstances enter anything. Any content in this text box will cause failure when trying to run the workflow manually.
Compare my description: ‘Exercises CreateQuoteApprovalMatrix’ - to the error message: 'CustomActivityStep1: Exercises CreateQuoteApprovalMatrix_1_converted'. As soon as the description was removed I was able to successfully debug.
Upvotes: 1
Reputation: 3555
I figured out that this problem had nothing to do with the code itself. I got the same errors with 90% of my code commented out. apparently it was a problem with how the workflow debugger handled early binding. Once I commented out early binding, it gave another error related to the plugin debugger itself which even fired with just 3 lines of code, namely the service registration.
because of this, I decided to use a different method of debugging, namely by judicious use of traceInfos. I also noticed from this that I should first test my app local, because the risk of an infinite loop is big when handling for loops with DateTimes.
Upvotes: 0