public static void Start(SchemaBuilder sb, Func <WorkflowConfigurationEmbedded> getConfiguration)
    {
        if (sb.NotDefined(MethodInfo.GetCurrentMethod()))
        {
            PermissionAuthLogic.RegisterPermissions(WorkflowPermission.ViewWorkflowPanel);
            PermissionAuthLogic.RegisterPermissions(WorkflowPermission.ViewCaseFlow);
            PermissionAuthLogic.RegisterPermissions(WorkflowPermission.WorkflowToolbarMenu);

            WorkflowLogic.getConfiguration = getConfiguration;

            UserAssetsImporter.Register <WorkflowEntity>("Workflow", WorkflowOperation.Save);
            UserAssetsImporter.Register <WorkflowScriptEntity>("WorkflowScript", WorkflowScriptOperation.Save);
            UserAssetsImporter.Register <WorkflowTimerConditionEntity>("WorkflowTimerCondition", WorkflowTimerConditionOperation.Save);
            UserAssetsImporter.Register <WorkflowConditionEntity>("WorkflowCondition", WorkflowConditionOperation.Save);
            UserAssetsImporter.Register <WorkflowActionEntity>("WorkflowAction", WorkflowActionOperation.Save);
            UserAssetsImporter.Register <WorkflowScriptRetryStrategyEntity>("WorkflowScriptRetryStrategy", WorkflowScriptRetryStrategyOperation.Save);

            sb.Include <WorkflowEntity>()
            .WithConstruct(WorkflowOperation.Create)
            .WithQuery(() => DynamicQueryCore.Auto(
                           from e in Database.Query <WorkflowEntity>()
                           select new
            {
                Entity = e,
                e.Id,
                e.Name,
                e.MainEntityType,
                HasExpired = e.HasExpired(),
                e.ExpirationDate,
            })
                       .ColumnDisplayName(a => a.HasExpired, () => WorkflowMessage.HasExpired.NiceToString()))
            .WithExpressionFrom((CaseActivityEntity ca) => ca.Workflow());

            WorkflowGraph.Register();
            QueryLogic.Expressions.Register((WorkflowEntity wf) => wf.WorkflowStartEvent());
            QueryLogic.Expressions.Register((WorkflowEntity wf) => wf.HasExpired(), WorkflowMessage.HasExpired);
            sb.AddIndex((WorkflowEntity wf) => wf.ExpirationDate);

            DynamicCode.GetCustomErrors += GetCustomErrors;

            Workflows = sb.GlobalLazy(() => Database.Query <WorkflowEntity>().ToDictionary(a => a.ToLite()),
                                      new InvalidateWith(typeof(WorkflowEntity)));


            sb.Include <WorkflowPoolEntity>()
            .WithUniqueIndex(wp => new { wp.Workflow, wp.Name })
            .WithSave(WorkflowPoolOperation.Save)
            .WithDelete(WorkflowPoolOperation.Delete)
            .WithExpressionFrom((WorkflowEntity p) => p.WorkflowPools())
            .WithQuery(() => e => new
            {
                Entity = e,
                e.Id,
                e.Name,
                e.BpmnElementId,
                e.Workflow,
            });

            sb.Include <WorkflowLaneEntity>()
            .WithUniqueIndex(wp => new { wp.Pool, wp.Name })
            .WithSave(WorkflowLaneOperation.Save)
            .WithDelete(WorkflowLaneOperation.Delete)
            .WithExpressionFrom((WorkflowPoolEntity p) => p.WorkflowLanes())
            .WithQuery(() => e => new
            {
                Entity = e,
                e.Id,
                e.Name,
                e.BpmnElementId,
                e.Pool,
                e.Pool.Workflow,
            });

            sb.Include <WorkflowActivityEntity>()
            .WithUniqueIndex(w => new { w.Lane, w.Name })
            .WithSave(WorkflowActivityOperation.Save)
            .WithDelete(WorkflowActivityOperation.Delete)
            .WithExpressionFrom((WorkflowEntity p) => p.WorkflowActivities())
            .WithExpressionFrom((WorkflowLaneEntity p) => p.WorkflowActivities())
            .WithVirtualMList(wa => wa.BoundaryTimers, e => e.BoundaryOf, WorkflowEventOperation.Save, WorkflowEventOperation.Delete)
            .WithQuery(() => e => new
            {
                Entity = e,
                e.Id,
                e.Name,
                e.BpmnElementId,
                e.Comments,
                e.Lane,
                e.Lane.Pool.Workflow,
            });

            sb.Include <WorkflowEventEntity>()
            .WithExpressionFrom((WorkflowEntity p) => p.WorkflowEvents())
            .WithExpressionFrom((WorkflowLaneEntity p) => p.WorkflowEvents())
            .WithQuery(() => e => new
            {
                Entity = e,
                e.Id,
                e.Type,
                e.Name,
                e.BpmnElementId,
                e.Lane,
                e.Lane.Pool.Workflow,
            });


            new Graph <WorkflowEventEntity> .Execute(WorkflowEventOperation.Save)
            {
                CanBeNew      = true,
                CanBeModified = true,
                Execute       = (e, _) =>
                {
                    if (e.Timer == null && e.Type.IsTimer())
                    {
                        throw new InvalidOperationException(ValidationMessage._0IsMandatoryWhen1IsSetTo2.NiceToString(e.NicePropertyName(a => a.Timer), e.NicePropertyName(a => a.Type), e.Type.NiceToString()));
                    }

                    if (e.Timer != null && !e.Type.IsTimer())
                    {
                        throw new InvalidOperationException(ValidationMessage._0ShouldBeNullWhen1IsSetTo2.NiceToString(e.NicePropertyName(a => a.Timer), e.NicePropertyName(a => a.Type), e.Type.NiceToString()));
                    }

                    if (e.BoundaryOf == null && e.Type.IsBoundaryTimer())
                    {
                        throw new InvalidOperationException(ValidationMessage._0IsMandatoryWhen1IsSetTo2.NiceToString(e.NicePropertyName(a => a.BoundaryOf), e.NicePropertyName(a => a.Type), e.Type.NiceToString()));
                    }

                    if (e.BoundaryOf != null && !e.Type.IsBoundaryTimer())
                    {
                        throw new InvalidOperationException(ValidationMessage._0ShouldBeNullWhen1IsSetTo2.NiceToString(e.NicePropertyName(a => a.BoundaryOf), e.NicePropertyName(a => a.Type), e.Type.NiceToString()));
                    }

                    e.Save();
                },
            }

            .Register();

            new Graph <WorkflowEventEntity> .Delete(WorkflowEventOperation.Delete)
            {
                Delete = (e, _) =>
                {
                    if (e.Type.IsScheduledStart())
                    {
                        var scheduled = e.ScheduledTask();
                        if (scheduled != null)
                        {
                            WorkflowEventTaskLogic.DeleteWorkflowEventScheduledTask(scheduled);
                        }
                    }

                    e.Delete();
                },
            }

            .Register();

            sb.Include <WorkflowGatewayEntity>()
            .WithSave(WorkflowGatewayOperation.Save)
            .WithDelete(WorkflowGatewayOperation.Delete)
            .WithExpressionFrom((WorkflowEntity p) => p.WorkflowGateways())
            .WithExpressionFrom((WorkflowLaneEntity p) => p.WorkflowGateways())
            .WithQuery(() => e => new
            {
                Entity = e,
                e.Id,
                e.Type,
                e.Name,
                e.BpmnElementId,
                e.Lane,
                e.Lane.Pool.Workflow,
            });

            sb.Include <WorkflowConnectionEntity>()
            .WithSave(WorkflowConnectionOperation.Save)
            .WithDelete(WorkflowConnectionOperation.Delete)
            .WithExpressionFrom((WorkflowEntity p) => p.WorkflowConnections())
            .WithExpressionFrom((WorkflowEntity p) => p.WorkflowMessageConnections(), null !)
            .WithExpressionFrom((WorkflowPoolEntity p) => p.WorkflowConnections())
            .WithExpressionFrom((IWorkflowNodeEntity p) => p.NextConnections(), null !)
            .WithExpressionFrom((IWorkflowNodeEntity p) => p.PreviousConnections(), null !)
            .WithQuery(() => e => new
            {
                Entity = e,
                e.Id,
                e.Name,
                e.BpmnElementId,
                e.From,
                e.To,
            });

            WorkflowEventTaskEntity.GetWorkflowEntity = lite => WorkflowGraphLazy.Value.GetOrThrow(lite).Workflow;

            WorkflowGraphLazy = sb.GlobalLazy(() =>
            {
                using (new EntityCache())
                {
                    var events      = Database.RetrieveAll <WorkflowEventEntity>().GroupToDictionary(a => a.Lane.Pool.Workflow.ToLite());
                    var gateways    = Database.RetrieveAll <WorkflowGatewayEntity>().GroupToDictionary(a => a.Lane.Pool.Workflow.ToLite());
                    var activities  = Database.RetrieveAll <WorkflowActivityEntity>().GroupToDictionary(a => a.Lane.Pool.Workflow.ToLite());
                    var connections = Database.RetrieveAll <WorkflowConnectionEntity>().GroupToDictionary(a => a.From.Lane.Pool.Workflow.ToLite());

                    var result = Database.RetrieveAll <WorkflowEntity>().ToDictionary(workflow => workflow.ToLite(), workflow =>
                    {
                        var w         = workflow.ToLite();
                        var nodeGraph = new WorkflowNodeGraph
                        {
                            Workflow    = workflow,
                            Events      = events.TryGetC(w).EmptyIfNull().ToDictionary(e => e.ToLite()),
                            Gateways    = gateways.TryGetC(w).EmptyIfNull().ToDictionary(g => g.ToLite()),
                            Activities  = activities.TryGetC(w).EmptyIfNull().ToDictionary(a => a.ToLite()),
                            Connections = connections.TryGetC(w).EmptyIfNull().ToDictionary(c => c.ToLite()),
                        };

                        nodeGraph.FillGraphs();
                        return(nodeGraph);
                    });

                    return(result);
                }
            }, new InvalidateWith(typeof(WorkflowConnectionEntity)));
            WorkflowGraphLazy.OnReset += (e, args) => DynamicCode.OnInvalidated?.Invoke();

            Validator.PropertyValidator((WorkflowConnectionEntity c) => c.Condition).StaticPropertyValidation = (e, pi) =>
            {
                if (e.Condition != null && e.From != null)
                {
                    var conditionType = (e.Condition.EntityOrNull ?? Conditions.Value.GetOrThrow(e.Condition)).MainEntityType;
                    var workflowType  = e.From.Lane.Pool.Workflow.MainEntityType;

                    if (!conditionType.Is(workflowType))
                    {
                        return(WorkflowMessage.Condition0IsDefinedFor1Not2.NiceToString(conditionType, workflowType));
                    }
                }

                return(null);
            };

            StartWorkflowConditions(sb);

            StartWorkflowTimerConditions(sb);

            StartWorkflowActions(sb);

            StartWorkflowScript(sb);
        }
    }
Exemple #2
0
 public static void Start(SchemaBuilder sb, Func <WorkflowConfigurationEmbedded> getConfiguration)
 {
     WorkflowLogic.Start(sb, getConfiguration);
     CaseActivityLogic.Start(sb);
     WorkflowEventTaskLogic.Start(sb);
 }