/// <summary> /// This method will add a Suggestion with a RefreshEntity FieldName and State to the Suggestions /// for this ServerEntity. By convention, this will tell the UI to refresh the Entity. This method /// is called when an Activity changes the Item (e.g. a DueDate is parsed out of the Name, a Contacts /// FieldName is created, etc). /// </summary> /// <param name="workflowInstance"></param> /// <param name="entity"></param> protected void SignalEntityRefresh(WorkflowInstance workflowInstance, ServerEntity entity) { var sugg = new Suggestion() { ID = Guid.NewGuid(), EntityID = entity.ID, EntityType = entity.GetType().Name, WorkflowType = workflowInstance.WorkflowType, WorkflowInstanceID = workflowInstance.ID, State = SuggestionTypes.RefreshEntity, SuggestionType = SuggestionTypes.RefreshEntity, DisplayName = SuggestionTypes.RefreshEntity, GroupDisplayName = SuggestionTypes.RefreshEntity, Value = null, TimeSelected = null }; SuggestionsContext.Suggestions.Add(sugg); SuggestionsContext.SaveChanges(); }
// get or create an reference to the given entity in the UserFolder EntityRefs list public Item GetEntityRef(User user, ServerEntity entity) { Item entityRefsList = GetEntityRefsList(user); if (entityRefsList == null) return null; var entityID = entity.ID.ToString(); try { // get existing reference to given entity if (storage.Items.Include("FieldValues").Any(i => i.UserID == user.ID && i.FolderID == entityRefsList.FolderID && i.ParentID == entityRefsList.ID && i.FieldValues.Any(fv => fv.FieldName == FieldNames.EntityRef && fv.Value == entityID))) { return storage.Items.Include("FieldValues").Single(i => i.UserID == user.ID && i.FolderID == entityRefsList.FolderID && i.ParentID == entityRefsList.ID && i.FieldValues.Any(fv => fv.FieldName == FieldNames.EntityRef && fv.Value == entityID)); } else { // create new reference to given entity DateTime now = DateTime.UtcNow; var entityRefItemID = Guid.NewGuid(); var entityRefItem = new Item() { ID = entityRefItemID, Name = entity.Name, FolderID = entityRefsList.FolderID, UserID = user.ID, ItemTypeID = SystemItemTypes.Reference, ParentID = entityRefsList.ID, Created = now, LastModified = now, FieldValues = new List<FieldValue>() { new FieldValue() { ItemID = entityRefItemID, FieldName = FieldNames.EntityRef, Value = entityID }, new FieldValue() { ItemID = entityRefItemID, FieldName = FieldNames.EntityType, Value = entity.GetType().Name }, } }; storage.Items.Add(entityRefItem); storage.SaveChanges(); TraceLog.TraceInfo(String.Format("Created entity ref item {0} for user {1}", entity.Name, user.Name)); return entityRefItem; } } catch (Exception ex) { TraceLog.TraceException(String.Format("Created entity ref item {0} for user {1}", entity.Name, user.Name), ex); return null; } }
/// <summary> /// Create a set of suggestions from the results of calling the suggestion function /// </summary> /// <param name="workflowInstance">Workflow instance to operate over</param> /// <param name="item">Item to process</param> /// <param name="suggestionFunction">Suggestion generation function</param> /// <returns>Complete if an exact match was found, Pending if multiple suggestions created</returns> protected Status CreateSuggestions( WorkflowInstance workflowInstance, ServerEntity entity, Func<WorkflowInstance, ServerEntity, Dictionary<string,string>, Status> suggestionFunction) { // analyze the item for possible suggestions var suggestions = new Dictionary<string, string>(); Status status = suggestionFunction.Invoke(workflowInstance, entity, suggestions); TraceLog.TraceDetail(String.Format("Retrieved {0} suggestions from activity {1}", suggestions.Count, Name)); // if the function completed with an error, or without generating any data, return (this is typically a fail-fast state) if (status == Status.Error || suggestions.Count == 0) return status; // if an "exact match" was discovered without user input, store it now and return if (status == Status.Complete && suggestions.Count == 1) { string s = null; foreach (var value in suggestions.Values) s = value; StoreInstanceData(workflowInstance, ActivityVariables.LastStateData, s); StoreInstanceData(workflowInstance, OutputParameterName, s); TraceLog.TraceDetail(String.Format("Exact match {0} was found for activity {1}", s, Name)); return status; } // construct the group display name string groupDisplayName = GroupDisplayName; if (groupDisplayName == null) groupDisplayName = workflowInstance.State; else groupDisplayName = FormatStringTemplate(workflowInstance, groupDisplayName); // get the suggestion parent ID if available var parentID = GetInstanceData(workflowInstance, ActivityVariables.ParentID); // add suggestions received from the suggestion function try { int num = 0; foreach (var s in suggestions.Keys) { // limit to four suggestions if (num++ == 4) break; var sugg = new Suggestion() { ID = Guid.NewGuid(), ParentID = parentID == null ? (Guid?) null : new Guid(parentID), EntityID = entity.ID, EntityType = entity.GetType().Name, WorkflowType = workflowInstance.WorkflowType, WorkflowInstanceID = workflowInstance.ID, State = workflowInstance.State, SuggestionType = SuggestionType, DisplayName = s, GroupDisplayName = groupDisplayName, SortOrder = num, Value = suggestions[s], TimeSelected = null }; SuggestionsContext.Suggestions.Add(sugg); TraceLog.TraceDetail(String.Format("Created suggestion {0} in group {1} for activity {2}", s, groupDisplayName, Name)); } SuggestionsContext.SaveChanges(); return status; } catch (Exception ex) { TraceLog.TraceException("Activity execution failed", ex); return Status.Error; } }