예제 #1
0
 public static Task <TResult> CreateAsync <TResult>(Guid processStageId, Guid actorId,
                                                    Guid processStageTypeId, string title,
                                                    Guid[] viewableActorIds, Guid[] editableActorIds, Guid [] completableActorIds,
                                                    KeyValuePair <Guid[], Guid>[] confirmableActorIdsNexts,
                                                    EastFive.Api.Security security,
                                                    Func <TResult> onCreated,
                                                    Func <TResult> onAlreadyExists,
                                                    Func <TResult> onTypeDoesNotExist,
                                                    Func <Guid, TResult> onConfirmationStageDoesNotExist,
                                                    Func <TResult> onActorDoesNotExist,
                                                    Func <string, TResult> onFailure)
 {
     // TODO: Security
     return(ProcessStages.CreateAsync(processStageId, actorId,
                                      processStageTypeId, title,
                                      viewableActorIds, editableActorIds, completableActorIds,
                                      confirmableActorIdsNexts,
                                      onCreated,
                                      onAlreadyExists,
                                      onTypeDoesNotExist,
                                      onConfirmationStageDoesNotExist,
                                      onActorDoesNotExist,
                                      onFailure));
 }
        public static Task <IHttpResponse> FindByIdAsync(
            [QueryParameter(CheckFileName = true)] Guid id,
            EastFive.Api.Security security,
            ContentResponse onFound,
            NotFoundResponse onNotFound,
            UnauthorizedResponse onUnauthorized)
        {
            return(stages.First(
                       async(stage, next) =>
            {
                if (stage.Id.UUID == id)
                {
                    return onFound(stage);
                }
                return await next();
            },
                       () => onNotFound().ToTask()));

            //return Connectors.FindByIdAsync(id,
            //        security.performingAsActorId, security.claims,
            //    (synchronization, destinationIntegrationId) => onFound(GetResource(synchronization, destinationIntegrationId, url)),
            //    () => onNotFound(),
            //    () => onUnauthorized());
        }
예제 #3
0
 public static Task <HttpResponseMessage> FindAllAsync(
     EastFive.Api.Security security, HttpRequestMessage request, UrlHelper url,
     MultipartAcceptArrayResponseAsync onMultipart)
 {
     return(onMultipart(stages));
 }
 public static IHttpResponse FindAll(
     EastFive.Api.Security security,
     MultipartAcceptArrayResponse onMultipart)
 {
     return(onMultipart(stages));
 }
예제 #5
0
        public static async Task <TResult> CreateAsync <TResult>(Guid processId,
                                                                 Guid processStageId, Guid resourceId, DateTime createdOn,
                                                                 KeyValuePair <string, Guid>[] resourceIds,
                                                                 Guid?previousStepId, DateTime?confirmedWhen, Guid?confirmedBy,
                                                                 EastFive.Api.Security security,
                                                                 Func <TResult> onCreated,
                                                                 Func <TResult> onAlreadyExists,
                                                                 Func <TResult> onStageDoesNotExist,
                                                                 Func <string, TResult> onFailure)
        {
            return(await await Persistence.ProcessStageDocument.FindByIdAsync(processStageId,
                                                                              async stage =>
            {
                return await await ProcessStageTypes.FindIdAsync(stage.processStageTypeId,
                                                                 async(stageType) =>
                {
                    var resourceType = stageType.resourceType;

                    return await stageType.resourceKeys
                    .FlatMap(resourceIds.ToDictionary(),
                             async(kvp, unusedResourceKvps, next, skip, tail) =>
                    {
                        if (!unusedResourceKvps.ContainsKey(kvp.Key))
                        {
                            if (confirmedWhen.HasValue)
                            {
                                return await tail(onFailure($"Missing resource for `{kvp.Key}`").ToTask());
                            }
                            return await skip(unusedResourceKvps);
                        }
                        return await next(
                            new Process.ProcessStageResource()
                        {
                            key = kvp.Key,
                            resourceId = unusedResourceKvps[kvp.Key],
                            type = kvp.Value,
                        },
                            unusedResourceKvps
                            .Where(kvpR => kvpR.Key != kvp.Key)
                            .ToDictionary());
                    },
                             async(Process.ProcessStageResource[] procStageResources, Dictionary <string, Guid> unusedResourceIds) =>
                    {
                        if (unusedResourceIds.Any())
                        {
                            return onFailure($"`{unusedResourceIds.First().Key}` is not valid resource key for a stage of type `{stageType.processStageTypeId}`");
                        }

                        var applicableActors = stage.completableIds
                                               .Concat(stage.confirmableIds.SelectKeys().SelectMany())
                                               .Concat(stage.editableIds).Concat(stage.viewableIds)
                                               .Distinct()
                                               .ToArray();

                        if (previousStepId.HasValue)
                        {
                            return await await Persistence.ProcessDocument.FindByIdAsync(previousStepId.Value,
                                                                                         async previousStep =>
                            {
                                if (!(previousStep.confirmedBy.HasValue && previousStep.confirmedWhen.HasValue))
                                {
                                    return onFailure("Previous step has not been confirmed.");
                                }

                                //TODO: if(previousStep.nextStep.HasValue)

                                return await Persistence.ProcessDocument.CreateAsync(processId,
                                                                                     processStageId, stage.ownerId,
                                                                                     resourceId, resourceType, createdOn,
                                                                                     procStageResources,
                                                                                     previousStepId, confirmedWhen, confirmedBy,
                                                                                     applicableActors,
                                                                                     onCreated,
                                                                                     onAlreadyExists);
                            },
                                                                                         () => onFailure("Previous step does not exist").ToTask());
                        }

                        // TODO: If confirmed is set, ensure that the security actor posesses a position that is authorized to move the process forward
                        return await Persistence.ProcessDocument.CreateAsync(processId,
                                                                             processStageId, stage.ownerId,
                                                                             resourceId, resourceType, createdOn,
                                                                             procStageResources,
                                                                             previousStepId, confirmedWhen, confirmedBy,
                                                                             applicableActors,
                                                                             onCreated,
                                                                             onAlreadyExists);
                    });
                },
                                                                 onStageDoesNotExist.AsAsyncFunc());
            },
                                                                              onStageDoesNotExist.AsAsyncFunc()));
        }
예제 #6
0
 internal static Task <TResult> UpdateAsync <TResult>(Guid processId,
                                                      Guid?confirmedById, DateTime?confirmedWhen,
                                                      KeyValuePair <string, Guid>[] resources, EastFive.Api.Security security,
                                                      Func <TResult> onUpdated,
                                                      Func <TResult> onNotFound,
                                                      Func <TResult> onUnauthorized,
                                                      Func <string, TResult> onFailure)
 {
     return(Persistence.ProcessDocument.UpdateAsync(processId,
                                                    async(process, saveAsync) =>
     {
         return await await Persistence.ProcessStageDocument.FindByIdAsync(process.processStageId,
                                                                           async processStage => await await Persistence.ProcessStageTypeDocument.FindByIdAsync(processStage.processStageTypeId,
                                                                                                                                                                processStageType =>
         {
             process.confirmedBy = confirmedById;
             process.confirmedWhen = confirmedWhen;
             return resources
             .FlatMap(
                 (resourceKvp, nextProcessStageResource, skip, tail) => processStageType.resourceKeys
                 .First(
                     (kvp, next) => kvp.Key == resourceKvp.Key ?
                     nextProcessStageResource(
                         new Process.ProcessStageResource()
             {
                 key = resourceKvp.Key,
                 resourceId = resourceKvp.Value,
                 type = kvp.Value,
             })
                                             :
                     next(),
                     () => tail(onFailure($"Resource key ${resourceKvp.Key} is not valid for this stage.").ToTask())),
                 async(IEnumerable <Process.ProcessStageResource> psrs) =>
             {
                 var procStageResources = psrs.ToArray();
                 if (procStageResources.Length != processStageType.resourceKeys.Length)
                 {
                     if (confirmedWhen.HasValue || process.confirmedWhen.HasValue)
                     {
                         return onFailure($"Cannot confirm resource without `{processStageType.resourceKeys.SelectKeys().Except(procStageResources.Select(psr => psr.key)).Join(",")}`");
                     }
                 }
                 process.resources = procStageResources;
                 await saveAsync(process);
                 return onUpdated();
             });
         },
                                                                                                                                                                () => onFailure($"Process stage is no longer valid `{process.processStageId}` => `{processStage.processStageTypeId}`").ToTask()),
                                                                           () => onFailure($"Process is no longer valid `{processId}` => `{process.processStageId}`").ToTask());
     },
                                                    onNotFound));
 }
 public static Task <TResult> FindAllAsync <TResult>(EastFive.Api.Security security,
                                                     Func <ProcessStageType[], TResult> onFound,
                                                     Func <TResult> onUnauthorized)
 {
     return(Persistence.ProcessStageTypeDocument.FindAllAsync(onFound));
 }
예제 #8
0
        public async static Task <TResult> FindByResourceAsync <TResult>(Guid actorId, Type resourceType,
                                                                         EastFive.Api.Security security,
                                                                         Func <ProcessResourceView[], TResult> onFound,
                                                                         Func <TResult> onResourceNotFound,
                                                                         Func <TResult> onUnauthorized)
        {
            return(await await Persistence.ProcessDocument.FindAllInFlowByActorAsync(actorId, resourceType,
                                                                                     (processSteps) =>
            {
                return processSteps
                .Select(ps => ps.processStageId)
                .Distinct()
                .FlatMap(
                    async(processStageId, next, skip) => await await Persistence.ProcessStageDocument.FindByIdAsync <Task <TResult> >(processStageId,
                                                                                                                                      processStage => next(processStageId.PairWithValue(processStage)),
                                                                                                                                      () => skip()),
                    (IEnumerable <KeyValuePair <Guid, ProcessStage> > processStages) =>
                {
                    var processStageLookup = processStages.ToDictionary();
                    return processStages
                    .SelectValues(stage => stage.processStageTypeId)
                    .Distinct()
                    .FlatMap <Guid, Guid[], KeyValuePair <Guid, ProcessStageType>, Task <TResult> >(
                        new Guid[] { },
                        async(processStageTypeId, kvpsAggr, next, skip) => await await ProcessStageTypes.FindIdAsync(processStageTypeId,
                                                                                                                     stageType => next(processStageTypeId.PairWithValue(stageType), kvpsAggr),
                                                                                                                     () => skip(kvpsAggr.Append(processStageTypeId).ToArray())),
                        async(KeyValuePair <Guid, ProcessStageType>[] stageTypes, Guid[] missingValues) =>
                    {
                        var processStageTypeLookup = stageTypes.ToDictionary();
                        return processSteps
                        .GroupBy(processStep => processStep.resourceId)
                        .FlatMap(
                            (stepsUnordered, next, skip) =>
                        {
                            var steps = stepsUnordered
                                        .OrderWith(default(Guid?),
                                                   (carry, step) => step.previousStep == carry,
                                                   step => step.processId)
                                        .ToArray();
                            if (!steps.Any())
                            {
                                return skip();
                            }
                            var viewableSteps = steps
                                                .Where(step => processStageLookup[step.processStageId].viewableIds.Contains(actorId))
                                                .ToArray();
                            var activeStep = viewableSteps.Last();
                            var stage = processStageLookup[activeStep.processStageId];

                            var possibleResourceKeys = viewableSteps
                                                       .SelectMany(step => processStageTypeLookup[processStageLookup[step.processStageId].processStageTypeId].resourceKeys.SelectKeys())
                                                       .Distinct()
                                                       .Select(
                                key => key.PairWithValue(new Process.ProcessStageResource
                            {
                                key = key,
                                type = processStageTypeLookup.SelectValues().First(
                                    (v, nextStageType) =>
                                {
                                    return v.resourceKeys.First(
                                        (v2, nextKey) =>
                                    {
                                        if (v2.Key == key)
                                        {
                                            return v2.Value;
                                        }
                                        return nextKey();
                                    },
                                        () => nextStageType());
                                },
                                    () => default(Type)),
                            }))
                                                       .ToDictionary();

                            try
                            {
                                var view = new ProcessResourceView()
                                {
                                    processViewId = activeStep.processId,
                                    resourceId = activeStep.resourceId,
                                    actorId = actorId,
                                    currentProcessStepId = activeStep.processId,
                                    titles = viewableSteps
                                             .Select(step => processStageLookup[step.processStageId].title)
                                             .ToArray(),
                                    completions = viewableSteps
                                                  .Select(step => step.confirmedWhen)
                                                  .ToArray(),
                                    invalidations = viewableSteps
                                                    .Select(step => step.invalidatedWhen)
                                                    .ToArray(),
                                    resourceType = resourceType,
                                    resourcesProvided = steps
                                                        .Where(step => step.confirmedWhen.HasValue)
                                                        .Aggregate(
                                        possibleResourceKeys,
                                        (aggr, step) =>
                                    {
                                        // TODO: This probably does not work
                                        foreach (var resource in step.resources)
                                        {
                                            // In case it is not a resource that is
                                            // referenced in a viewable step
                                            if (!aggr.ContainsKey(resource.key))
                                            {
                                                continue;
                                            }

                                            var aggrv = aggr[resource.key];
                                            if (resource.resourceId.HasValue)
                                            {
                                                aggrv.resourceId = resource.resourceId;
                                            }
                                            aggrv.type = resource.type;
                                        }
                                        return aggr;
                                    })
                                                        .SelectValues()
                                                        .ToArray(),
                                    nextStages = stage.confirmableIds
                                                 .Where(actorKvps => actorKvps.Key.Contains(actorId))
                                                 .Select(actorKvps => new ProcessStage()
                                    {
                                        // TODO: Rest of these values
                                        processStageId = actorKvps.Value,
                                    })
                                                 .ToArray(),
                                    displayResources = processStageLookup[activeStep.processStageId]
                                                       .resourcesDisplayed
                                                       .NullToEmpty()
                                                       .Intersect(possibleResourceKeys.SelectKeys())
                                                       .ToArray(),
                                    editable = processStageLookup[activeStep.processStageId].editableIds.Contains(actorId),
                                    completable = processStageLookup[activeStep.processStageId].completableIds.Contains(actorId),
                                };
                                return next(view);
                            } catch (Exception ex)
                            {
                                return skip();
                            }
                        },
                            (IEnumerable <ProcessResourceView> views) => onFound(views.ToArray()));
                    });
                });
            },
                                                                                     () => onFound(new ProcessResourceView[] { }).ToTask()));
        }
예제 #9
0
 public static async Task <TResult> FindStartByActorAndResourceTypeAsync <TResult>(Guid ownerId, Type resourceType, EastFive.Api.Security security,
                                                                                   Func <ProcessStage[], TResult> onFound,
                                                                                   Func <TResult> onResourceNotFound,
                                                                                   Func <TResult> onUnauthorized)
 {
     return(await await Persistence.ProcessStageDocument.FindByOwnerAsync(ownerId,
                                                                          async (processStages) =>
     {
         var typeIds = await processStages
                       .Select(processStage => processStage.processStageTypeId)
                       .Distinct()
                       .FlatMap(
             async(processStageTypeId, add, skip) => await await Persistence.ProcessStageTypeDocument.FindByIdAsync(processStageTypeId,
                                                                                                                    processStageTypeDoc => processStageTypeDoc.resourceType == resourceType ?
                                                                                                                    add(processStageTypeId)
                             :
                                                                                                                    skip(),
                                                                                                                    () => skip()),
             (IEnumerable <Guid> processStageTypeIds) => processStageTypeIds.ToLookup(v => v).ToTask());
         var listedAsNext = processStages.SelectMany(procStage => procStage.confirmableIds.SelectValues()).ToLookup(v => v);
         return onFound(
             processStages
             .Where(procStage => typeIds.Contains(procStage.processStageTypeId))
             .Where(procStage => !listedAsNext.Contains(procStage.processStageId))
             .ToArray());
     },
                                                                          onResourceNotFound.AsAsyncFunc()));
 }