public async Task <IActionResult> Get(string id) { return(await FunctionWrapper.ExecuteFunction(this, async() => { return await _workflowNodeRepository.Get(new ObjectId(id)); })); }
private async Task <WorkflowTransition> HydrateForGetAndSave(WorkflowTransition transition) { try { var fromNode = await _workflowNodeRepository.Get(transition.FromNodeId); var toNode = await _workflowNodeRepository.Get(transition.ToNodeId); if (fromNode == null || toNode == null) { throw new ApplicationException("Cannot find node."); } transition.FromNode = fromNode; transition.ToNode = toNode; return(transition); } catch (Exception ex) { throw ex; } }
public async Task <IActionResult> ExecuteTransition(string id, [FromBody] WorkflowTransitionExecutionRequest requestArgs) { return(await FunctionWrapper.ExecuteFunction(this, async() => { // This method assumes that a client has recognized the need to display screens // in order to populate all required fields or make any field updates to the item in transition if (string.IsNullOrEmpty(requestArgs.ItemId)) { throw new Exception("Required fields not supplied."); } Item item = null; string serializedObject = ""; item = await _itemRepository.Get(new ObjectId(requestArgs.ItemId), null); if (item == null) { throw new Exception("Cannot find item specified."); } //TODO: Verify that the transition is valid for the item's current state/node serializedObject = JsonConvert.SerializeObject(item); var transition = await _workflowTransitionRepository.Get(new ObjectId(id)); if (transition == null) { throw new Exception("Cannot find transition."); } FunctionRegistry functionRegistry = new FunctionRegistry( _itemRepository, _itemTypeRepository, _fieldRepository, _workflowNodeRepository); WorkflowTransitionExecutionResult result = new WorkflowTransitionExecutionResult(); if (transition.PreConditions != null) { // Execute all pre-conditions for the transition foreach (WorkflowTransitionFunction funcRef in transition.PreConditions) { var execResult = await functionRegistry.ExecuteFunction(funcRef, item); if (execResult.IsFailure) { result.ErrorMessages.Add(execResult.DisplayMessage); } } } // Stop now if any conditions fail if (result.ErrorMessages.Count > 0) { return result; } if (transition.Validations != null) { // Execute all validations for the transition foreach (WorkflowTransitionFunction funcRef in transition.Validations) { var execResult = await functionRegistry.ExecuteFunction(funcRef, item); if (execResult.IsFailure) { result.ErrorMessages.Add(execResult.DisplayMessage); } } } // Stop now if any validations fail if (result.ErrorMessages.Count > 0) { return result; } if (transition.PostFunctions != null) { foreach (WorkflowTransitionFunction funcRef in transition.PostFunctions) { var execResult = await functionRegistry.ExecuteFunction(funcRef, item); if (execResult.IsFailure) { throw new ApplicationException(execResult.DisplayMessage); } } } // Set Item Workflow Node / Status (should this be optional to avoid having // transitions that simply return to the same status just to execute functions?) WorkflowNode node = await _workflowNodeRepository.Get(transition.ToNodeId); if (node == null) { throw new Exception("Cannot find destination node."); } item.WorkflowNodeId = node.Id; await _itemRepository.Update(item); if (result.ErrorMessages.Count > 0) { return result; } return result; })); }
private async Task <Item> HydrateForGetAndSave(Item item) { try { // Clear linked items as they should not be saved item.LinkedItems = null; // Set Type from ID string typeId = item.TypeId.ToString(); if (!tempItemTypeCache.ContainsKey(typeId)) { var itemType = await _itemTypeRepository.Get(item.TypeId); if (itemType == null) { throw new ApplicationException("Invalid Type ID."); } tempItemTypeCache.Add(typeId, itemType); } item.Type = tempItemTypeCache[typeId]; if (item.LocationId != null && item.LocationId != ObjectId.Empty) { string locationId = item.LocationId.ToString(); if (!tempItemLocationCache.ContainsKey(locationId)) { var loc = await _itemLocationRepository.Get(item.LocationId); if (loc == null) { throw new ApplicationException("Invalid Location ID."); } tempItemLocationCache.Add(locationId, loc); } item.Location = tempItemLocationCache[locationId]; } // Populate item's workflow node ID from default node from assoc. item type workflow // if not already set (should only be for new items) if (item.WorkflowNodeId == null || item.WorkflowNodeId == ObjectId.Empty) { if (item.Type.WorkflowId == null || item.Type.WorkflowId == ObjectId.Empty) { throw new ApplicationException("Item does not have an associated workflow."); } var workflowNodes = await _workflowNodeRepository.Search(item.Type.WorkflowId); var workflowNode = workflowNodes.FirstOrDefault(); if (workflowNode == null) { throw new ApplicationException("Associated workflow does not have any nodes."); } item.WorkflowNodeId = workflowNode.Id; } // Set Workflow Node from ItemType's associated Workflow string workflowNodeId = item.WorkflowNodeId.ToString(); if (!tempWorkflorNodeCache.ContainsKey(workflowNodeId)) { var workflowNode = await _workflowNodeRepository.Get(item.WorkflowNodeId); if (workflowNode == null) { throw new ApplicationException("Cannot find workflow node."); } tempWorkflorNodeCache.Add(workflowNodeId, workflowNode); } item.WorkflowNode = tempWorkflorNodeCache[workflowNodeId]; return(item); } catch (Exception ex) { throw ex; } }
public Task <OperationResult <bool> > Execute(string argsObject) { return(Task.Run(async() => { if (_item == null) { return new OperationResult <bool>() { Value = false, ErrorMessage = "Item is required." }; } LinkedItemOfTypeInStatusArgs args = JsonConvert.DeserializeObject <LinkedItemOfTypeInStatusArgs>(argsObject); if (string.IsNullOrEmpty(args.SelectedItemTypeId) || string.IsNullOrEmpty(args.SelectedWorkflowNodeId)) { return new OperationResult <bool>() { Value = false, ErrorMessage = "Post-function is not configured correctly." }; } if (_item.LinkedItems == null || _item.LinkedItems.Count == 0) { return new OperationResult <bool>() { Value = false, ErrorMessage = $"No linked item was found." }; } // Check for linked item of appropriate type foreach (Item linkedItem in _item.LinkedItems) { if (linkedItem.Type.Id == new ObjectId(args.SelectedItemTypeId)) { // Check for appropriate status on linked item if (args.SelectedWorkflowNodeId == "000000000000000000000000" || (linkedItem.WorkflowNode.Id == new ObjectId(args.SelectedWorkflowNodeId))) { return new OperationResult <bool>() { Value = true }; } } } var itemType = await _itemTypeRepository.Get(new ObjectId(args.SelectedItemTypeId)); var workflowNode = await _workflowNodeRepository.Get(new ObjectId(args.SelectedWorkflowNodeId)); return new OperationResult <bool>() { Value = false, ErrorMessage = workflowNode != null ? $"No linked item of type {itemType.Name} with status {workflowNode.Name} was found." : $"No linked item of type {itemType.Name} was found." }; })); }