Beispiel #1
0
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var haveStarted         = GetArgumentKey("forEachHaveStarted");
            var foreachList         = GetArgumentKey("forEachResourceList");
            var resourceListKey     = GetArgumentKey("foreachList");
            var selectedResourceKey = GetArgumentKey("foreachSelectedResource");


            IEnumerable <IEntity> resourceList;


            if (!(context.GetArgValue <bool?>(ActivityInstance, haveStarted) ?? false))
            {
                context.SetArgValue(ActivityInstance, haveStarted, true);

                //
                // it's the first time into the loop
                //
                object listObj;
                if (inputs.TryGetValue(resourceListKey, out listObj))
                {
                    if (listObj == null)
                    {
                        throw new ApplicationException("The [List] argument is null. This should never happen.");
                    }

                    resourceList = (IEnumerable <IEntity>)listObj;
                }
                else
                {
                    throw new ApplicationException("The [List] is missing from the input arguments. This should never happen.");
                }
            }
            else
            {
                resourceList = context.GetArgValue <IEnumerable <IEntity> >(ActivityInstance, foreachList);
            }

            var selectedResourceRef = resourceList.FirstOrDefault();


            if (selectedResourceRef != null)
            {
                context.SetArgValue(ActivityInstance, selectedResourceKey, selectedResourceRef);
                resourceList = resourceList.Skip(1);
                context.SetArgValue(ActivityInstance, foreachList, resourceList);
                context.ExitPointId = Entity.GetId(LoopExitPointAlias);
            }
            else
            {
                // We have finished
                context.SetArgValue(ActivityInstance, haveStarted, false);
                context.SetArgValue(ActivityInstance, foreachList, null);
                context.ExitPointId = Entity.GetId("core", "foreachCompletedExitPoint");
            }
        }
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var ResourceTypeToCreateKey = GetArgumentKey("createActivityResourceArgument");
            var CreatedResourceKey      = GetArgumentKey("createActivityCreatedResource");

            IEntity newEntity = null;

            var resTypeRef = (IEntity)inputs[ResourceTypeToCreateKey];
            var resType    = resTypeRef?.As <EntityType>();

            if (resType == null)
            {
                throw new WorkflowRunException_Internal("Input resource argument must be a type.", null);
            }

            var activityAs = ActivityInstance.Cast <EntityWithArgsAndExits>();
            Action <IEntity> updateAction = (e) => UpdateArgsHelper.UpdateEntityFromArgs(activityAs, inputs, e);


            DatabaseContext.RunWithRetry(() =>
            {
                newEntity = PerformCreate(resType, updateAction);
            });

            context.SetArgValue(ActivityInstance, CreatedResourceKey, newEntity);
        }
        /// <summary>
        /// Handles the response that was received from a request this activity made.
        /// </summary>
        /// <param name="context">The workflow run context.</param>
        /// <param name="request">The original request object.</param>
        /// <param name="response">The object that was received in response to the request.</param>
        protected override void OnResponse(IRunState context, TenantOperationRequest request, TenantInfoResponse response)
        {
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            var databaseId = request.DatabaseId;

            if (string.IsNullOrEmpty(databaseId))
            {
                throw new WorkflowRunException("The platform context for this tenant was unknown.");
            }

            var tenantInfo = response.Tenants.FirstOrDefault();

            if (tenantInfo == null)
            {
                throw new WorkflowRunException("No information about the tenant was received.");
            }

            var tenant = PlatformService.CreateOrUpdateTenant(databaseId, tenantInfo);

            if (tenant == null)
            {
                throw new WorkflowRunException("Failed to create or update this tenant entity.");
            }

            var tenantKey = GetArgumentKey(TenantArgumentAlias);

            context.SetArgValue(ActivityInstance, tenantKey, tenant);
        }
        /// <summary>
        /// Continue a paused activity
        /// </summary>
        /// <returns>True if the activity has completed, false if it is paused.</returns>
        public override bool OnResume(IRunState context, IWorkflowEvent resumeEvent)
        {
            var userCompletesEvent = resumeEvent as PromptUserTaskCompletedEvent;

            if (userCompletesEvent != null)
            {
                context.ExitPointId = new EntityRef("promptUserCompleted");

                var userTaskId = userCompletesEvent.UserTaskId;

                var userTask = Entity.Get <PromptUserTask>(userTaskId, PromptUserTask.PromptForTaskStateInfo_Field);
                if (userTask != null)
                {
                    // load the state information in the task back into the workflow run context
                    foreach (var arg in userTask.PromptForTaskArguments)
                    {
                        var input = userTask.PromptForTaskStateInfo.FirstOrDefault(si => si.StateInfoArgument.Id == arg.ActivityPromptArgument.Id);
                        if (input == null)
                        {
                            continue;
                        }

                        context.SetArgValue(input.StateInfoArgument, ActivityArgumentHelper.GetArgParameterValue(input.StateInfoValue));
                    }

                    Entity.Delete(userTask);
                }
            }

            return(true);
        }
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var resource = GetArgumentEntity <Resource>(inputs, "core:createLinkResourceArgument");

            if (resource == null)
            {
                throw new WorkflowRunException("The 'Resource' argument is empty. It must have a value.");
            }

            string Url = NavigationHelper.GetResourceViewUrl(resource.Id).ToString();

            string anchor = string.Format("<a href='{0}'>{1}</a>", Url, XmlHelper.EscapeXmlText(resource.Name ?? "[Unnamed]"));

            context.SetArgValue(ActivityInstance, GetArgumentKey("core:createLinkUrlOutput"), Url);
            context.SetArgValue(ActivityInstance, GetArgumentKey("core:createLinkAnchorOutput"), anchor);
        }
Beispiel #6
0
        /// <summary>
        /// Handles the response that was received from a request this activity made.
        /// </summary>
        /// <param name="context">The workflow run context.</param>
        /// <param name="request">The original request object.</param>
        /// <param name="response">The object that was received in response to the request.</param>
        protected override void OnResponse(IRunState context, ApplicationOperationRequest request, ApplicationInfoResponse response)
        {
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            var databaseId = request.DatabaseId;

            if (string.IsNullOrEmpty(databaseId))
            {
                throw new WorkflowRunException("The platform context for this user was unknown.");
            }

            var tenant = PlatformService.UpdateInstalledApplications(databaseId, request.Tenant, response.Installed);

            if (tenant == null)
            {
                throw new WorkflowRunException("Cannot update the tenant with apps installed.");
            }

            var installedKey = GetArgumentKey(ApplicationsInstalledArgumentAlias);

            context.SetArgValue(ActivityInstance, installedKey, tenant.HasAppsInstalled.ToList());
        }
        void ProcessResult(IRunState context, WorkflowRun run)
        {
            if (run.WorkflowRunStatus_Enum != WorkflowRunState_Enumeration.WorkflowRunCompleted)
            {
                throw new InnerWorkflowFailedException(string.Format("Inner workflow '{0}' failed", run.WorkflowBeingRun.Name));
            }

            var proxyExitPoint    = run.GetExitPoint();
            var matchingExitPoint = context.Metadata.GetExitpointsForActivity(ActivityInstance.Id).SingleOrDefault(ep => ep.Name == proxyExitPoint.Name);

            if (matchingExitPoint == null)
            {
                throw new WorkflowRunException("Workflow proxy returned using an exit point that doesn't match anything in the parent");
            }

            context.ExitPointId = matchingExitPoint;

            var outputs = run.GetOutput();

            var outArgs = ActivityInstance.GetOutputArguments();

            // copy the values from the results into the arguments witht eh same name
            foreach (var arg in outArgs)
            {
                var    name  = arg.Name;
                object value = null;

                if (outputs.TryGetValue(name, out value))
                {
                    context.SetArgValue(ActivityInstance, arg, value);
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Runs when the activity is run by the workflow.
        /// </summary>
        /// <param name="context">The run state.</param>
        /// <param name="inputs">The inputs.</param>
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            using (Profiler.Measure("ExportToImplementation.OnRunNow"))
            {
                var name   = GetArgumentValue <string>(inputs, "inExportToName");
                var report = GetArgumentEntity <Report>(inputs, "inExportToReport");
                var format = GetArgumentEntity <ExportFileTypeEnum>(inputs, "inExportToFormat");

                if (String.IsNullOrWhiteSpace(name))
                {
                    name = GenerateName(report.Name);
                }

                var description = string.Format(DescriptionFormat, report.Name ?? "[Unnamed]", DateTime.Now.ToShortTimeString());

                Document generatedDoc;

                using (CustomContext.SetContext(context.EffectiveSecurityContext))
                {
                    var timeZone = RequestContext.GetContext().TimeZone ?? TimeZoneHelper.SydneyTimeZoneName;

                    generatedDoc = ExportTo(report, name, description, timeZone, ToExportFormat(format));
                }

                context.SetArgValue(ActivityInstance, GetArgumentKey("core:outExportToDoc"), generatedDoc);
            }
        }
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            _activityInputs = inputs;
            try
            {
                if (string.IsNullOrEmpty(TenantEmailSetting.SmtpServer))
                {
                    throw new Exception("smtpServer has not been specified.");
                }

                var sendEmailRecipientsType = GetArgumentValue <Resource>(inputs, "core:sendEmailRecipientsType");

                var sentEmailMessages = new List <SentEmailMessage>();
                if (string.IsNullOrEmpty(sendEmailRecipientsType?.Alias) || (sendEmailRecipientsType?.Alias == "core:sendEmailActivityRecipientsAddress"))
                {
                    sentEmailMessages.Add(GenerateEmailToRecipientsExpression());
                }
                else
                {
                    var sendEmailDistributionType = GetArgumentValue <Resource>(inputs, "core:sendEmailDistributionType");
                    if (string.IsNullOrEmpty(sendEmailDistributionType?.Alias) || (sendEmailDistributionType?.Alias == "core:sendEmailActivityGroupDistribution"))
                    {
                        sentEmailMessages.Add(GenerateGroupEmailsToRecipientsList());
                    }
                    else
                    {
                        sentEmailMessages.AddRange(GenerateIndividualEmailsToRecipientsList());
                    }
                }

                var mailMessages = new List <MailMessage>();
                sentEmailMessages.RemoveAll(msg => string.IsNullOrEmpty(msg.EmTo) && string.IsNullOrEmpty(msg.EmCC) && string.IsNullOrEmpty(msg.EmBCC));
                sentEmailMessages.RemoveAll(msg => string.IsNullOrEmpty(msg.EmSubject));
                sentEmailMessages.ForEach(msg =>
                {
                    msg.EmSentDate = DateTime.UtcNow;
                    msg.Save();
                    mailMessages.Add(msg.ToMailMessage());
                });

                RecordInfoToUserLog(context, $"Sending {sentEmailMessages.Count} emails");

                if (sentEmailMessages.Count == 0)
                {
                    context.ExitPointId = Entity.GetId("core:sendEmailSucceededSend");
                    return;
                }

                EmailSender.SendMessages(mailMessages);

                context.SetArgValue(ActivityInstance, GetArgumentKey("core:outSentEmailMessages"), sentEmailMessages);
                context.ExitPointId = Entity.GetId("core:sendEmailSucceededSend");
            }
            catch (Exception ex)
            {
                RecordErrorToUserLog(context, ex);
                context.ExitPointId = Entity.GetId("core:sendEmailFailedSend");
            }
        }
Beispiel #10
0
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var activityAs    = ActivityInstance.Cast <AssignToVariable>();
            var valueArgument = Entity.Get <ActivityArgument>("assignValueArgument", Resource.Name_Field);
            var targetVar     = activityAs.TargetVariable;

            context.SetArgValue(targetVar, inputs[valueArgument]);
        }
Beispiel #11
0
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var typeRefKey   = GetArgumentKey("getResourcesResourceType");
            var reportRefKey = GetArgumentKey("getResourcesReport");
            var listKey      = GetArgumentKey("getResourcesList");
            var firstKey     = GetArgumentKey("getResourcesFirst");
            var countKey     = GetArgumentKey("getResourcesCount");

            object     o;
            EntityType resourceType = null;
            IEntity    reportRef    = null;

            if (inputs.TryGetValue(typeRefKey, out o))
            {
                if (o != null)
                {
                    resourceType = ((IEntity)o).As <EntityType>();
                }
            }

            if (inputs.TryGetValue(reportRefKey, out o))
            {
                if (o != null)
                {
                    reportRef = (IEntity)o;
                }
            }

            if (resourceType == null && reportRef == null)
            {
                throw new WorkflowRunException("Get Resources must have one of either the Type or Report parameters specified.");
            }


            IEnumerable <IEntity> list = null;

            SecurityBypassContext.RunAsUser(() =>
            {
                list = reportRef != null ? GetListFromReport(context, reportRef) : GetListFromType(resourceType);
            });

            context.SetArgValue(ActivityInstance, listKey, list);
            context.SetArgValue(ActivityInstance, firstKey, list.FirstOrDefault());
            context.SetArgValue(ActivityInstance, countKey, list.Count());
        }
        public override bool OnResume(IRunState context, IWorkflowEvent resumeEvent)
        {
            var userTaskEntity = context.GetArgValue <IEntity>(ActivityInstance, GetArgumentKey("core:outDisplayFormUserTask"));
            var keepHistory    = context.GetArgValue <bool>(ActivityInstance, GetArgumentKey("core:dfaInternalKeepHistory"));

            var userTask = userTaskEntity != null?userTaskEntity.As <DisplayFormUserTask>() : null;         // We could have a combination of a deleted user task and a time-out


            if (!HandleTimeout(context, resumeEvent))       // handle timeout will set the exit point
            {
                HandleResumeTransition(context, (IWorkflowUserTransitionEvent)resumeEvent);

                if (!(userTask.HideComment ?? false))
                {
                    context.SetArgValue(ActivityInstance, GetArgumentKey("core:outTaskComment"), userTask.TaskComment);
                }

                if (keepHistory)
                {
                    var writableTask = userTask.AsWritable <DisplayFormUserTask>();
                    writableTask.TaskStatus_Enum = TaskStatusEnum_Enumeration.TaskStatusCompleted;
                    writableTask.Save();
                }
            }

            if (userTask != null)
            {
                if (keepHistory)
                {
                    if (userTask.LogEntryForUserAction != null)
                    {
                        UpdateLogEntry(userTask);
                    }
                }
                else
                {
                    context.SetArgValue(ActivityInstance, GetArgumentKey("core:outDisplayFormUserTask"), null);
                    Entity.Delete(userTask);
                }
            }

            return(true);
        }
        //private const string ClonedNameFormat = "{0} (clone)";

        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            using (Profiler.MeasureAndSuppress("CloneImplementation.OnRunNow"))
            {
                var resourceKey   = GetArgumentKey("resourceToCloneArgument");
                var definitionKey = GetArgumentKey("newDefinitionCloneArgument");
                var clonedKey     = GetArgumentKey("clonedResourceArgument");

                var resId    = (IEntity)inputs[resourceKey];
                var resource = resId.As <Resource>();

                IEntity clone = null;

                EntityType cloneType = null;


                object definitionObj;
                if (inputs.TryGetValue(definitionKey, out definitionObj))
                {
                    if (definitionObj != null)
                    {
                        cloneType = ((IEntity)definitionObj).As <EntityType>();
                    }
                }

                try
                {
                    using (CustomContext.SetContext(context.EffectiveSecurityContext))
                    {
                        using (var ctx = DatabaseContext.GetContext(true))
                        {
                            var activityAs = ActivityInstance.Cast <EntityWithArgsAndExits>();

                            Action <IEntity> updateAction = c => UpdateArgsHelper.UpdateEntityFromArgs(activityAs, inputs, c);

                            clone = CreateClone(resource, cloneType, updateAction);

                            clone.Save();

                            ctx.CommitTransaction();
                        }
                    };
                }
                catch (DuplicateKeyException ex)
                {
                    throw new WorkflowRunException("The Clone item failed during saving: " + ex.Message, ex);
                }
                catch (ValidationException ex)
                {
                    throw new WorkflowRunException("The Cloned item failed validation during saving: " + ex.Message, ex);
                }

                context.SetArgValue(ActivityInstance, clonedKey, clone);
            }
        }
Beispiel #14
0
        /// <summary>
        /// Update any arguments on the workflow with the resolved expressions
        /// </summary>
        private void UpdateWorkflowArguments(IRunState context, Dictionary <WfExpression, object> resolvedExpressions)
        {
            foreach (var kvp in resolvedExpressions)
            {
                var expression = kvp.Key;

                ActivityArgument arg = context.Metadata.GetArgumentPopulatedByExpression(expression);

                context.SetArgValue(arg, kvp.Value);
            }
        }
        /// <summary>
        /// Runs the activity.
        /// </summary>
        /// <param name="context">The run context.</param>
        /// <param name="inputs">The input parameters.</param>
        public void OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var campaign = GetArgumentEntity <SurveyCampaign>(inputs, "inStartSurveyCampaign");

            var tasks = campaign.Launch().ToList();

            Entity.Save(tasks);

            var responses = tasks.Select(t => t.UserSurveyTaskSurveyResponse);

            context.SetArgValue(ActivityInstance, GetArgumentKey("core:outStartSurveyResponses"), responses);
        }
        /// <summary>
        /// Start the activity running
        /// </summary>
        /// <returns>True if the activity has completed, false if it is paused. Along with a sequence number of if it is paused</returns>
        public override bool OnStart(IRunState context, ActivityInputs inputs)
        {
            var survey       = GetArgumentEntity <UserSurvey>(inputs, "inLaunchPersonSurvey");
            var recipients   = GetArgumentEntityList <Person>(inputs, "inLaunchPersonRecipients").ToList();
            var targetObject = GetArgumentEntity <UserResource>(inputs, "inLaunchPersonTarget");
            var taskName     = GetArgumentValue <string>(inputs, "inLaunchPersonTaskName");
            var dueInDays    = GetArgumentValue(inputs, "inLaunchPersonDueDays", 0m);
            var pause        = GetArgumentValue(inputs, "inLaunchPersonPause", false);

            // ensure that there is at least one recipient
            if (recipients.Count <= 0)
            {
                throw new WorkflowRunException("The recipients list for the Survey was empty.");
            }

            var campaign = Entity.Create <SurveyPersonCampaign>();

            campaign.Name = $"Person Campaign ({survey.Name})";
            campaign.SurveyForCampaign = survey;
            campaign.CampaignPersonRecipients.AddRange(recipients);
            if (dueInDays > 0)
            {
                campaign.SurveyClosesOn = DateTime.UtcNow.AddDays(decimal.ToDouble(dueInDays));
            }

            var tasks = campaign.Launch(campaign.SurveyClosesOn, targetObject, taskName).ToList();

            if (pause)
            {
                foreach (var task in tasks)
                {
                    // this will do the save for us.
                    context.SetUserTask(task.Cast <BaseUserTask>());
                }
            }
            else
            {
                Entity.Save(tasks);
            }

            var responses = tasks.Select(t => t.UserSurveyTaskSurveyResponse);

            context.SetArgValue(ActivityInstance, GetArgumentKey("core:outLaunchPersonResponses"), responses);

            // Deal with time-outs. Time-outs can only occur if there is due date and we are pausing.
            if (pause)
            {
                SetTimeoutIfNeeded(context, dueInDays);
            }

            // Note that there is no need to set an exit point if we are not pausing as the default exit point will be used.
            return(!pause);
        }
Beispiel #17
0
        /// <summary>
        /// Copy any input arguments
        /// </summary>
        public void MapInitialInput(IRunState context, IDictionary <ActivityArgument, object> inputArguments)
        {
            foreach (var kvp in inputArguments)
            {
                context.SetArgValue(kvp.Key, kvp.Value);
            }

            // Do the initial variable initialization
            var variableExpressions = _activityInstanceAsWf.Variables.Select(v => v.PopulatedByExpression.FirstOrDefault()).Where(e => e != null).ToList();
            var resolvedExpressions = ResolveExpressions(context, variableExpressions);

            UpdateWorkflowArguments(context, resolvedExpressions);
        }
        /// <summary>
        /// Handles the response that was received from a request this activity made.
        /// </summary>
        /// <param name="context">The workflow run context.</param>
        /// <param name="request">The original request object.</param>
        /// <param name="response">The object that was received in response to the request.</param>
        protected override void OnResponse(IRunState context, LogRequest request, LogResponse response)
        {
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            if (response.Time == DateTime.MinValue)
            {
                throw new ArgumentException("response.time value was not set.");
            }

            var logTimeKey = GetArgumentKey(LogTimeArgumentAlias);

            context.SetArgValue(ActivityInstance, logTimeKey, response.Time.ToLocalTime());
        }
        private const decimal DefaultTimeOutMins = 0;     // no time out


        public override bool OnStart(IRunState context, ActivityInputs inputs)
        {
            var users = GetArgumentEntityList(inputs, "inPeople");

            var message           = GetArgumentValue <String>(inputs, "inMessage");
            var waitForReplies    = GetArgumentValueStruct <bool>(inputs, "inWaitForReplies");
            var timeoutDays       = GetArgumentValue <decimal>(inputs, "inNotifyTimeOut", 0);
            var acceptRepliesDays = GetArgumentValue <decimal>(inputs, "inAcceptRepliesFor", 1);

            var linkToRecord = GetArgumentEntity <UserResource>(inputs, "inLinkToRecord");

            if (!Factory.Current.Resolve <INotifier>().IsConfigured)
            {
                throw new WorkflowRunException("No tenant notifier has been configured in tenant general settings.");
            }

            //
            // Notification needs to be created first to ensure that a fast response will not be processed before the notification is created
            //
            var effectiveUser = Entity.Get <UserAccount>(context.EffectiveSecurityContext.Identity.Id);

            var notification = Entity.Create <Notification>();

            notification.NMessage            = message;
            notification.SecurityOwner       = effectiveUser;           // The workflow runner can delete and update the notification and the send and replies.
            notification.NRelatedRecord      = linkToRecord;
            notification.NAcceptRepliesUntil = DateTime.UtcNow.AddDays(Convert.ToDouble(acceptRepliesDays));

            CopyReplyMap(context, notification);

            notification.Save();

            context.SetArgValue(ActivityInstance, GetArgumentKey("core:outNotificationRecord"), notification);

            if (waitForReplies)
            {
                SetTimeoutIfNeeded(context, timeoutDays);    // Note that there is no timeout exit.
            }

            SendMessagesInBackground(context, notification.Id, users.Select(u => u.Id).ToList(), waitForReplies);

            return(false);
        }
        /// <summary>
        /// Runs when the activity is run by the workflow.
        /// </summary>
        /// <param name="context">The run state.</param>
        /// <param name="inputs">The inputs.</param>
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            using (Profiler.Measure("GenerateDocImplementation.OnRunNow"))
            {
                var inGenerateDocTemplateKey = GetArgumentKey("inGenerateDocTemplate");
                var inGenerateDocNameKey     = GetArgumentKey("inGenerateDocName");
                var inGenerateDocSourceKey   = GetArgumentKey("inGenerateDocSource");

                var reportTemplate = ((IEntity)inputs[inGenerateDocTemplateKey]).As <ReportTemplate>();

                var name = inputs.ContainsKey(inGenerateDocNameKey) ? (string)inputs[inGenerateDocNameKey] : null;

                if (String.IsNullOrWhiteSpace(name))
                {
                    name = GenerateName(reportTemplate.Name);
                }

                var description = string.Format(DescriptionFormat, reportTemplate.Name ?? "[Unnamed]", DateTime.Now.ToShortTimeString());

                var sourceResource = inputs.ContainsKey(inGenerateDocSourceKey) ? ((IEntity)inputs[inGenerateDocSourceKey]) : null;

                Document generatedDoc;

                using (CustomContext.SetContext(context.EffectiveSecurityContext))
                {
                    var timeZone     = RequestContext.GetContext().TimeZone ?? TimeZoneHelper.SydneyTimeZoneName;
                    var templateFile = reportTemplate.ReportTemplateUsesDocument;

                    try
                    {
                        generatedDoc = GenerateDoc(templateFile, sourceResource, name, description, timeZone);
                    }
                    catch (DocGenException ex)
                    {
                        throw new WorkflowRunException(ex.Message);
                    }
                }

                context.SetArgValue(ActivityInstance, GetArgumentKey("core:outGenerateDocDoc"), generatedDoc);
            }
        }
        /// <summary>
        /// Start the activity running
        /// </summary>
        /// <returns>True if the activity has completed, false if it is paused. Along with a sequence number of if it is paused</returns>
        public override bool OnStart(IRunState context, ActivityInputs inputs)
        {
            var targets          = GetArgumentEntityList <UserResource>(inputs, "inLaunchTargetTargets").ToList();
            var survey           = GetArgumentEntity <UserSurvey>(inputs, "inLaunchTargetSurvey");
            var surveyTaker      = GetArgumentEntity <Relationship>(inputs, "inLaunchTargetSurveyTaker");
            var targetDefinition = GetArgumentEntity <Definition>(inputs, "inLaunchTargetTargetObject");
            var taskName         = GetArgumentValue <string>(inputs, "inLaunchTargetTaskName");
            var dueInDays        = GetArgumentValue(inputs, "inLaunchTargetDueDays", 0m);
            var pause            = GetArgumentValue(inputs, "inLaunchTargetPause", false);

            EntityType targetType;
            DirectionEnum_Enumeration targetDirection;

            // ensure that there is at least one target
            if (targets.Count <= 0)
            {
                throw new WorkflowRunException("The targets list for the Survey was empty.");
            }

            // ensure the relationship is valid (as there is no UI validation in workflow)
            var surveyTakerAttachesToPerson =
                surveyTaker.ToType.GetAncestorsAndSelf().Select(t => t.Id).Contains(Person.Person_Type.Id) ||
                surveyTaker.FromType.GetAncestorsAndSelf().Select(t => t.Id).Contains(Person.Person_Type.Id);

            if (!surveyTakerAttachesToPerson)
            {
                throw new WorkflowRunException("Invalid relationship used for Survey taker. Must connect to Person.");
            }

            // Derive the direction and (base-most) target type for this campaign, based on the relationship that has been input
            if (surveyTaker.ToType
                .GetAncestorsAndSelf().Select(t => t.Id)
                .Contains(Person.Person_Type.Id))
            {
                targetType      = surveyTaker.FromType;
                targetDirection = DirectionEnum_Enumeration.Forward;
            }
            else
            {
                targetType      = surveyTaker.ToType;
                targetDirection = DirectionEnum_Enumeration.Reverse;
            }

            // If a target object definition has been specified, then enforce it
            if (targetDefinition != null)
            {
                // override the target type derived above
                targetType = targetDefinition.As <EntityType>();

                // all the inputs we have should be of this type
                var targetsConform = targets.All(target =>
                {
                    return(target.GetAllTypes().Select(t => t.Id).Contains(targetType.Id));
                });

                if (!targetsConform)
                {
                    throw new WorkflowRunException("All targets must conform to the Target object if it has been specified.");
                }

                // validate that the relationship also connects to the target object type
                var relTypeToCheck = targetDirection == DirectionEnum_Enumeration.Forward
                    ? surveyTaker.FromType
                    : surveyTaker.ToType;

                var surveyTakerAttachesToTargetObject =
                    targetType.GetAncestorsAndSelf().Select(t => t.Id).Contains(relTypeToCheck.Id);

                if (!surveyTakerAttachesToTargetObject)
                {
                    throw new WorkflowRunException("Invalid relationship used for Survey taker. Must connect to the Target object if it has been specified.");
                }
            }

            var campaign = Entity.Create <SurveyTargetCampaign>();

            campaign.Name = $"Target Campaign ({survey.Name})";
            campaign.SurveyForCampaign          = survey;
            campaign.CampaignTarget             = targetType.As <Definition>();
            campaign.CampaignTargetRelationship = surveyTaker;
            campaign.CampaignTargetRelationshipDirection_Enum = targetDirection;
            campaign.CampaignTargetTargets.AddRange(targets);
            if (dueInDays > 0)
            {
                campaign.SurveyClosesOn = DateTime.UtcNow.AddDays(decimal.ToDouble(dueInDays));
            }

            var tasks = campaign.Launch(campaign.SurveyClosesOn, taskName).ToList();

            if (pause)
            {
                foreach (var task in tasks)
                {
                    context.SetUserTask(task.Cast <BaseUserTask>());     // this will do the save for us.
                }
            }
            else
            {
                Entity.Save(tasks);
            }

            var responses = tasks.Select(t => t.UserSurveyTaskSurveyResponse);

            context.SetArgValue(ActivityInstance, GetArgumentKey("core:outLaunchTargetResponses"), responses);

            // Deal with time-outs. Time-outs can only occur if there is due date and we are pausing.
            if (pause)
            {
                SetTimeoutIfNeeded(context, dueInDays);
            }

            // Note that there is no need to set an exit point if we are not pausing as the default exit point will be used.
            return(!pause);
        }
Beispiel #22
0
        /// <summary>
        /// Runs when the activity is run by the workflow.
        /// </summary>
        /// <param name="context">The run state.</param>
        /// <param name="inputs">The inputs.</param>
        public void OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var startedKey    = GetArgumentKey(StartedArgumentAlias);
            var listKey       = GetArgumentKey(ListArgumentAlias);
            var appIdKey      = GetArgumentKey(ApplicationIdArgumentAlias);
            var appVersionKey = GetArgumentKey(ApplicationVersionArgumentAlias);

            var ids     = new List <Guid>();
            var started = context.GetArgValue <bool?>(ActivityInstance, startedKey) ?? false;

            if (!started)
            {
                // set that the activity has started
                context.SetArgValue(ActivityInstance, startedKey, true);

                // retrieve the product
                var productSku = GetArgumentValue <string>(inputs, ProductSkuArgumentAlias);

                var product = MarketplaceService.GetProduct(productSku);
                if (product == null)
                {
                    throw new WorkflowRunException("Product {0} was not found.", productSku);
                }

                // process the included apps and app versions and sort their ids
                ids.AddRange(GetSortedApplicationIds(product));
            }
            else
            {
                // retrieve the current state of the ordered list from the context
                var list = context.GetArgValue <string>(ActivityInstance, listKey);
                if (!string.IsNullOrEmpty(list))
                {
                    ids.AddRange(list.Split(',').Select(Guid.Parse));
                }
            }

            // loop over the next id on the list
            var current = ids.FirstOrDefault();

            if (current != default(Guid))
            {
                // set the application id and any specific version info on the output
                var variables = GetAppVariables(context, current);
                if (variables.Item1 != Guid.Empty)
                {
                    context.SetArgValue(ActivityInstance, appIdKey, variables.Item1);
                    context.SetArgValue(ActivityInstance, appVersionKey, variables.Item2);
                }

                // remove this id from the list and store it again
                ids = ids.Skip(1).ToList();

                var list = string.Join(",", ids);

                context.SetArgValue(ActivityInstance, listKey, list);
                context.ExitPointId = new EntityRef(LoopExitPointAlias);
            }
            else
            {
                // we have finished
                context.SetArgValue(ActivityInstance, startedKey, false);
                context.SetArgValue(ActivityInstance, listKey, null);
                context.ExitPointId = new EntityRef(FinishedExitPointAlias);
            }
        }
        private const decimal DefaultTimeOutMins = 0;     // no time out

        public override bool OnStart(IRunState context, ActivityInputs inputs)
        {
            var assignedTo          = GetArgumentEntity <Person>(inputs, "inDisplayFormForUser");
            var recordToPresent     = GetArgumentEntity <UserResource>(inputs, "inDisplayFormResource");
            var form                = GetArgumentEntity <CustomEditForm>(inputs, "inDisplayFormForm");
            var timeoutDays         = GetArgumentValue <decimal>(inputs, "inDisplayFormTimeOut", DefaultTimeOutMins);
            var priority            = GetArgumentEntity <EventEmailPriorityEnum>(inputs, "inDisplayFormPriority");
            var activityInstanceAs  = ActivityInstance.Cast <DisplayFormActivity>();
            var percentageCompleted = GetArgumentValue <decimal?>(inputs, "inDisplayFormPercentageCompleted", null);
            var waitForNext         = GetArgumentValue <bool>(inputs, "inDisplayFormWaitForNext", false);
            var recordHistory       = GetArgumentValue <bool>(inputs, "inDisplayFormRecordHistory", false);
            var hideComment         = GetArgumentValue <bool>(inputs, "inHideComment", false);
            var openInEditMode      = GetArgumentValue <bool>(inputs, "inOpenInEditMode", false);

            priority = priority ?? Entity.Get <EventEmailPriorityEnum>(new EntityRef("core", "normalPriority"));

            var workflowRun = context.WorkflowRun;


            var dueDate = DateTime.UtcNow.AddDays((double)timeoutDays);

            var userTask = new DisplayFormUserTask
            {
                Name                 = ActivityInstance.Name ?? DefaultTitle,
                RecordToPresent      = recordToPresent,
                FormToUse            = form,
                AvailableTransitions = GetAvailableUserTransitions(),
                AssignedToUser       = assignedTo,
                TaskPriority         = priority,
                TaskStatus_Enum      = TaskStatusEnum_Enumeration.TaskStatusNotStarted,
                PercentageCompleted  = percentageCompleted,
                WaitForNextTask      = waitForNext,
                UserTaskDueOn        = dueDate,
                HideComment          = hideComment,
                OpenInEditMode       = openInEditMode,
                DfutLinkToken        = CryptoHelper.GetRandomPrintableString(8)
            };

            context.SetUserTask(userTask.Cast <BaseUserTask>());

            if (recordHistory)
            {
                CreateLogEntry(context, userTask);
            }

            SetTimeoutIfNeeded(context, timeoutDays);

            var tenantSetting = Entity.Get <TenantGeneralSettings>(WellKnownAliases.CurrentTenant.TenantGeneralSettingsInstance);

            if (Factory.FeatureSwitch.Get("enableWfUserActionNotify"))
            {
                //
                // IN PROGRESS - Please leave
                // This code is in development and switched off until email and SMS approvals are required by PM.
                //
                Notifier notifier = null; // tenantSetting.UserActionNotifier;
                if (notifier != null)
                {
                    // TODO: Format correctly for where it is being sent SMS email etc. Move the decision out of here and make the notfier decide on the type of message
                    var generator = new HtmlGenerator();

                    string message = null;
                    if (notifier.Is <EmailNotifier>())           // TODO: This is wrong, it should be somehow tied to the Router
                    {
                        var transitionOptions = userTask.AvailableTransitions.Select(t => t.FromExitPoint.Name).Where(n => !String.IsNullOrEmpty(n));

                        if (transitionOptions.Any())
                        {
                            message = generator.GenerateSelectionPage(userTask);
                        }
                    }
                    else if (notifier.Is <TwilioNotifier>())
                    {
                        message = generator.GenerateSelectionPageUrl(userTask.DfutLinkToken);
                    }

                    if (message != null)
                    {
                        var userList = userTask.AssignedToUser.ToEnumerable();

                        var notification = new Notification {
                            NMessage = message
                        };

                        //TOOD: Add alternative text in the email with a link to the SMS page
                        NotificationRouter.Instance.Send(notifier, notification, userList, false);
                    }
                }
            }

            context.SetArgValue(ActivityInstance, GetArgumentKey("core:outDisplayFormUserTask"), userTask);
            context.SetArgValue(ActivityInstance, GetArgumentKey("core:dfaInternalKeepHistory"), recordHistory);

            return(false);
        }