public override CMCUDResult Update(CMFeatureVarStringDto updatingObject)
        {
            var opResult = new CMCUDResult();

            opResult.Errors.Add("Feature vars are immutable and cannot be updated after they are created.");
            return(opResult);
        }
        public override CMCUDResult Insert(CMFeatureVarStringDto insertingObject)
        {
            var opResult = new CMCUDResult();

            if (insertingObject.CMFeatureId == 0)
            {
                opResult.Errors.Add($"An item in {CollectionName} must be assigned to a feature.");
                return(opResult);
            }

            if (string.IsNullOrWhiteSpace(insertingObject.Name))
            {
                opResult.Errors.Add($"An item in {CollectionName} must have a name.");
                return(opResult);
            }

            // Check for another feature var with the same name in this same feature
            var existingFeatureVar = Find(v =>
                                          v.CMFeatureId == insertingObject.CMFeatureId &&
                                          v.Name.Equals(insertingObject.Name, StringComparison.OrdinalIgnoreCase) // Names are immutable and replacements of feature vars is also done in a case-insensitive manner
                                          );

            if (existingFeatureVar.Any())
            {
                opResult.Errors.Add($"There is already an item in {CollectionName} with the name {insertingObject.Name}. Duplicate entries are not allowed.");
                return(opResult);
            }

            return(base.Insert(insertingObject));
        }
        public override CMCUDResult Update(CMFeatureStateTransitionRuleDto updatingObject)
        {
            var opResult = new CMCUDResult();

            var cmRule = Get(updatingObject.Id);

            // Is the state that it's referring to changing ?
            if (cmRule.CMSystemStateId != updatingObject.CMSystemStateId)
            {
                // How many other transition rule states in this feature refer to the state ?
                var matchingRules = Find(r =>
                                         r.CMSystemStateId == cmRule.CMSystemStateId &&
                                         r.CMFeatureId == cmRule.CMFeatureId &&
                                         r.Id != updatingObject.Id
                                         );

                // If the one being updated was the last rule that referred to the state then check to see if any task templates are under this state
                if (!matchingRules.Any())
                {
                    var taskTemplates = CMDataProvider.DataStore.Value.CMTasks.Value.GetAll_ForFeature(cmRule.CMFeatureId);
                    if (taskTemplates.Any(t => t.CMSystemStateId == cmRule.CMSystemStateId))
                    {
                        opResult.Errors.Add($"Cannot update item in {CollectionName} with id {updatingObject.Id} because there are currently task templates in the state it referrs to.");
                        return(opResult);
                    }
                }
            }

            return(base.Update(updatingObject));
        }
        public override CMCUDResult Delete(int deletingId)
        {
            var opResult = new CMCUDResult();

            opResult.Errors.Add("Feature vars are immutable and cannot be deleted after they are created.");
            return(opResult);
        }
예제 #5
0
        public override CMCUDResult Update(CMSystemStateDto updatingObject)
        {
            var opResult = new CMCUDResult();

            opResult = UpsertChecks(opResult, updatingObject);
            if (opResult.Errors.Any())
            {
                return(opResult);
            }

            // Look for other items in the same system with the same name, that are not this item.
            var dupeNameResults = Find(s =>
                                       s.CMSystemId == updatingObject.CMSystemId &&
                                       s.Id != updatingObject.Id &&
                                       s.Name.Equals(updatingObject.Name, System.StringComparison.Ordinal) // Note: case 'sensitive' compare so we allow renames to upper/lower case
                                       );

            if (dupeNameResults.Any())
            {
                opResult.Errors.Add($"Cannot update item in {CollectionName} because an item with the same name already exists within this system.");
                return(opResult);
            }

            // Note: If a state's name is being updated this is okay to do without checking other refs. The refs should all refer to the state by the id
            // and will show the new name next time they are viewed.

            return(base.Update(updatingObject));
        }
        public override CMCUDResult Delete(int deletingId)
        {
            var opResult = new CMCUDResult();

            var cmRule = Get(deletingId);

            // How many other transition rules in this feature refer to the state ?
            var matchingRules = Find(r =>
                                     r.CMSystemStateId == cmRule.CMSystemStateId &&
                                     r.CMFeatureId == cmRule.CMFeatureId &&
                                     r.Id != deletingId
                                     );

            // If the one being deleted is the last one then check to see if any task templates are under this state
            if (!matchingRules.Any())
            {
                var taskTemplates = CMDataProvider.DataStore.Value.CMTasks.Value.GetAll_ForFeature(cmRule.CMFeatureId);
                if (taskTemplates.Any(t => t.CMSystemStateId == cmRule.CMSystemStateId))
                {
                    var targetSystemState = CMDataProvider.DataStore.Value.CMSystemStates.Value.Get(cmRule.CMSystemStateId);

                    opResult.Errors.Add($"Cannot delete item from {CollectionName} with id {deletingId} that has a target state of {targetSystemState.Name} because there are currently task templates in the state it referrs to.");
                    return(opResult);
                }
            }

            return(base.Delete(deletingId));
        }
예제 #7
0
        private CMCUDResult UpsertChecks(CMCUDResult opResult, CMSystemDto dto)
        {
            // If we are checking an insert operation
            if (dto.Id == 0)
            {
                if (Get_ForSystemName(dto.Name) != null)
                {
                    opResult.Errors.Add($"A system with the name '{dto.Name}' already exists. Rename that one first.");
                }
            }
            // If we are checking an update operation
            {
                // Look for systems with this name that are not this record
                var dupeResults = Find(s =>
                                       s.Id != dto.Id &&
                                       s.Name.Equals(dto.Name, System.StringComparison.Ordinal) // Note: case 'sensitive' compare so we allow renames to upper/lower case
                                       );

                if (dupeResults.Any())
                {
                    opResult.Errors.Add($"A system with the name '{dto.Name}' already exists.");
                    return(opResult);
                }
            }

            return(opResult);
        }
예제 #8
0
        public override CMCUDResult Delete(int deletingId)
        {
            var opResult = new CMCUDResult();

            var deletingItem = CMDataProvider.DataStore.Value.CMFeatures.Value.Get(deletingId);

            // Do not allow deleting of features if there are still tasks assigned to it.
            var featureTasks = CMDataProvider.DataStore.Value.CMTasks.Value.GetAll_ForFeature(deletingId);

            if (featureTasks.Any())
            {
                opResult.Errors.Add($"Cannot delete item in {CollectionName} because tasks are still assigned.");
                return(opResult);
            }

            // Also require any state transition rules to be removed
            var stateTransitionRules = CMDataProvider.DataStore.Value.CMFeatureStateTransitionRules.Value.GetAll_ForFeatureTemplate(deletingId);

            if (stateTransitionRules.Any())
            {
                opResult.Errors.Add($"Cannot delete item in {CollectionName} because there are feature state transition rules still associated with it.");
                return(opResult);
            }

            return(base.Delete(deletingId));
        }
        /// <summary>
        /// Checks that apply to both insert and update operations
        /// </summary>
        /// <param name="opResult"></param>
        /// <returns></returns>
        private CMCUDResult UpsertChecks(CMCUDResult opResult, CMDimensionInfoDto dto)
        {
            if (string.IsNullOrWhiteSpace(dto.Name))
            {
                opResult.Errors.Add($"Name cannot be empty for an item in {CollectionName}");
            }

            // If we are checking an insert operation
            if (dto.Id == 0)
            {
                if (Get_ForName(dto.Name) != null)
                {
                    opResult.Errors.Add($"A dimension with the name '{dto.Name}' already exists.");
                }
            }
            // If we are checking an update operation
            else
            {
                // Find a record with the same name that is not this one
                var dupeResults = Find(f =>
                                       f.Id != dto.Id &&
                                       f.Name.Equals(dto.Name, System.StringComparison.Ordinal));

                if (dupeResults.Any())
                {
                    opResult.Errors.Add($"A dimension with the name '{dto.Name}' already exists.");
                }
            }

            return(opResult);
        }
예제 #10
0
        /// <summary>
        /// Checks that apply to both insert and update operations
        /// </summary>
        /// <param name="opResult"></param>
        /// <returns></returns>
        private CMCUDResult UpsertChecks(CMCUDResult opResult, CMTaskFactoryDto dto)
        {
            if (string.IsNullOrWhiteSpace(dto.Name))
            {
                opResult.Errors.Add($"Name cannot be empty for an item in {CollectionName}");
            }

            return(opResult);
        }
예제 #11
0
        private CMCUDResult UpsertChecks(CMCUDResult opResult, T dto)
        {
            if (dto.TaskId == 0)
            {
                opResult.Errors.Add($"Item in collection {CollectionName} must have the {nameof(dto.TaskId)} set before insert or update.");
            }

            return(opResult);
        }
예제 #12
0
        /// <summary>
        /// Checks that apply to both insert and update operations
        /// </summary>
        /// <param name="opResult"></param>
        /// <returns></returns>
        private CMCUDResult UpsertChecks(CMCUDResult opResult, CMFeatureDto dto)
        {
            if (string.IsNullOrWhiteSpace(dto.Name))
            {
                opResult.Errors.Add($"Name cannot be empty for an item in {CollectionName}");
            }

            if (dto.CMSystemId == 0)
            {
                opResult.Errors.Add($"An item in {CollectionName} must have a valid {nameof(CMFeatureDto.CMSystemId)}");
            }

            // Only instances are required to have a valid system state
            if (dto.CMParentFeatureTemplateId != 0)
            {
                if (dto.CMSystemStateId == 0)
                {
                    opResult.Errors.Add($"An item in {CollectionName} must have a valid {nameof(CMFeatureDto.CMSystemStateId)}");
                }
            }

            // If we are checking an insert operation
            if (dto.Id == 0)
            {
                // Require that template names are distinct. Instances can have duplicate names.
                if (dto.IsTemplate)
                {
                    if (Get_ForName(dto.Name, dto.CMSystemId, dto.IsTemplate) != null)
                    {
                        opResult.Errors.Add($"A feature with the name '{dto.Name}' already exists within the system. Rename that one first.");
                    }
                }
            }
            // If we are checking an update operation
            else
            {
                // Require that template names are distinct. Instances can have duplicate names.
                if (dto.IsTemplate)
                {
                    // Find a record with the same name that is not this one
                    var dupeResults = Find(f =>
                                           f.Id != dto.Id &&
                                           (dto.IsTemplate ? f.CMParentFeatureTemplateId == 0 : f.CMParentFeatureTemplateId != 0) && // Don't use IsTemplate Dto property here b/c this queries BSON data directly
                                           f.CMSystemId == dto.CMSystemId &&
                                           f.Name.Equals(dto.Name, System.StringComparison.Ordinal)); // Note: case 'sensitive' compare so we allow renames to upper/lower case

                    if (dupeResults.Any())
                    {
                        opResult.Errors.Add($"A feature with the name '{dto.Name}' already exists within the system.");
                    }
                }
            }

            return(opResult);
        }
예제 #13
0
        public virtual CMCUDResult Delete(int deletingId)
        {
            var opResult = new CMCUDResult();

            if (CUDDepthTracking.ExceedsMaxOperationDepth(opResult))
            {
                return(opResult);
            }

            var dtoBefore = Get(deletingId);

            try
            {
                CUDDepthTracking.OperationDepth++;
                OnBeforeRecordDeleted?.Invoke(
                    new CMDataProviderRecordDeletedEventArgs()
                {
                    DtoBefore = dtoBefore,
                });
            }
            catch (Exception ex)
            {
                opResult.Errors.Add(ex.ToString());
            }
            finally
            {
                CUDDepthTracking.OperationDepth--;
            }

            if (!cmCollection.Delete(deletingId))
            {
                opResult.Errors.Add($"{CollectionName} with id {deletingId} was not found to delete.");
            }

            try
            {
                CUDDepthTracking.OperationDepth++;
                OnAfterRecordDeleted?.Invoke(
                    new CMDataProviderRecordDeletedEventArgs()
                {
                    DtoBefore = dtoBefore,
                });
            }
            catch (Exception ex)
            {
                opResult.Errors.Add(ex.ToString());
            }
            finally
            {
                CUDDepthTracking.OperationDepth--;
            }

            return(opResult);
        }
예제 #14
0
        public CMCUDResult Delete_ForTaskId(int taskId)
        {
            var opResult = new CMCUDResult();
            var result   = Get_ForTaskId(taskId);

            if (result == null)
            {
                return(opResult);
            }
            return(base.Delete(result.Id));
        }
예제 #15
0
        public override CMCUDResult Insert(CMTaskFactoryDto insertingObject)
        {
            var opResult = new CMCUDResult();

            opResult = UpsertChecks(opResult, insertingObject);
            if (opResult.Errors.Any())
            {
                return(opResult);
            }

            return(base.Insert(insertingObject));
        }
예제 #16
0
        public override CMCUDResult Update(CMTaskDto updatingObject)
        {
            var opResult = new CMCUDResult();

            opResult = UpsertChecks(opResult, updatingObject);
            if (opResult.Errors.Any())
            {
                return(opResult);
            }

            return(base.Update(updatingObject));
        }
예제 #17
0
        /// <summary>
        /// Checks that apply to both insert and update operations
        /// </summary>
        /// <param name="opResult"></param>
        /// <returns></returns>
        private CMCUDResult UpsertChecks(CMCUDResult opResult, CMTaskStateDto dto)
        {
            if (string.IsNullOrWhiteSpace(dto.InternalName) || string.IsNullOrWhiteSpace(dto.DisplayName))
            {
                opResult.Errors.Add($"Name cannot be empty for an item in {CollectionName}");
            }
            if (dto.TaskTypeId == 0)
            {
                opResult.Errors.Add($"An item in {CollectionName} must have the task type specified.");
            }

            return(opResult);
        }
예제 #18
0
        public override CMCUDResult Delete(int deletingId)
        {
            var opResult = new CMCUDResult();

            var refFeaturesCount = CMDataProvider.DataStore.Value.CMFeatures.Value.GetCount_InSystem(deletingId);

            if (refFeaturesCount > 0)
            {
                opResult.Errors.Add($"Cannot delete the item in {CollectionName} because there are features or feature templates that are still present.");
                return(opResult);
            }

            return(base.Delete(deletingId));
        }
예제 #19
0
        public override CMCUDResult Delete(int deletingId)
        {
            var opResult = new CMCUDResult();

            var dbTaskState = Get(deletingId);

            if (dbTaskState.Reserved)
            {
                opResult.Errors.Add($"Unable to delete task state {dbTaskState.DisplayName} because it is marked as reserved.");
                return(opResult);
            }

            return(base.Delete(deletingId));
        }
예제 #20
0
        /// <summary>
        /// Checks that apply to both insert and update operations
        /// </summary>
        /// <param name="opResult"></param>
        /// <returns></returns>
        private CMCUDResult UpsertChecks(CMCUDResult opResult, CMTaskDto dto)
        {
            if (string.IsNullOrWhiteSpace(dto.Title))
            {
                opResult.Errors.Add($"Name cannot be empty for an item in {CollectionName}");
            }

            if (dto.CMFeatureId == 0)
            {
                opResult.Errors.Add($"A task must be assigned to a feature in {CollectionName}");
            }

            if (dto.CMSystemStateId == 0)
            {
                opResult.Errors.Add($"A task must be assigned to a system state in {CollectionName}");
            }

            if (dto.CMTaskStateId == 0)
            {
                opResult.Errors.Add($"A task must have a task state set in {CollectionName}");
            }

            if (dto.CMTaskTypeId == 0)
            {
                opResult.Errors.Add($"A task must have a task type set in {CollectionName}");
            }

            // Must pass the previous checks before going on to this next phase of checks
            if (opResult.Errors.Any())
            {
                return(opResult);
            }

            var taskStateTemplate = CMDataProvider.DataStore.Value.CMTaskStates.Value.Get_ForInternalName(ReservedTaskStates.Template, dto.CMTaskTypeId);

            // The only state option for a template is "Template"
            if (dto.IsTemplate && (dto.CMTaskStateId != taskStateTemplate.Id))
            {
                opResult.Errors.Add($"A task template task state must be set to the 'Template' state.");
            }

            // A task instance cannot be set to the "Template" state.
            if (!dto.IsTemplate && (dto.CMTaskStateId == taskStateTemplate.Id))
            {
                opResult.Errors.Add($"A task instance cannot be set to the 'Template' state.");
            }

            return(opResult);
        }
예제 #21
0
        public CMCUDResult UpdateIfNeeded_Description(int cmFeatureId, string description)
        {
            var opResult = new CMCUDResult();
            var dbEntry  = Get(cmFeatureId);

            if (dbEntry.Description == description)
            {
                // Nothing changed, no update to the description is needed
                return(opResult);
            }

            // Update just the name
            dbEntry.Description = description;
            return(Update(dbEntry));
        }
예제 #22
0
        /// <summary>
        /// Updates only the name if it has changed from the database.
        /// </summary>
        /// <param name="updatingObject"></param>
        /// <returns></returns>
        public CMCUDResult UpdateIfNeeded_Name(int cmFeatureId, string name)
        {
            var opResult = new CMCUDResult();
            var dbEntry  = Get(cmFeatureId);

            if (dbEntry.Name == name)
            {
                // Nothing changed, no update to the name is needed
                return(opResult);
            }

            // Update just the name
            dbEntry.Name = name;
            return(Update(dbEntry));
        }
예제 #23
0
        /// <summary>
        /// Updates only the name if it has changed from the database.
        /// </summary>
        /// <param name="updatingObject"></param>
        /// <returns></returns>
        public CMCUDResult UpdateIfNeeded_Name(int cmSystemId, string name)
        {
            var opResult = new CMCUDResult();
            var dbEntry  = Get(cmSystemId);

            if (dbEntry.Name.Equals(name, System.StringComparison.Ordinal))
            {
                // Nothing changed, no update to the name is needed
                return(opResult);
            }

            // Update just the name
            dbEntry.Name = name;
            return(Update(dbEntry));
        }
예제 #24
0
        public override CMCUDResult Insert(T insertingObject)
        {
            var opResult = new CMCUDResult();

            opResult = UpsertChecks(opResult, insertingObject);
            if (opResult.Errors.Any())
            {
                return(opResult);
            }

            if (Get_ForTaskId(insertingObject.TaskId) != null)
            {
                opResult.Errors.Add($"A pre-existing task data record exists for task id {insertingObject.TaskId} in collection {CollectionName}. Update that record instead of adding a new one.");
                return(opResult);
            }

            return(base.Insert(insertingObject));
        }
예제 #25
0
        public override CMCUDResult Delete(int deletingId)
        {
            var opResult = new CMCUDResult();

            var originalState = Get(deletingId);

            // See if there are any features that referenced this state before deleting it
            var refStateTransitionRulesA = CMDataProvider.DataStore.Value.CMFeatureStateTransitionRules.Value.GetAll_ThatRef_SystemStateId(originalState.Id);
            var refStateTransitionRulesB = CMDataProvider.DataStore.Value.CMFeatureStateTransitionRules.Value.GetAll_ThatRef_ToCMSystemStateId(originalState.Id);

            if (refStateTransitionRulesA.Any() || refStateTransitionRulesB.Any())
            {
                opResult.Errors.Add($"Cannot delete item from {CollectionName} with id {deletingId} because there are feature state transition rules that still refer to it.");
                return(opResult);
            }

            return(base.Delete(deletingId));
        }
예제 #26
0
        public override CMCUDResult Insert(CMSystemStateDto insertingObject)
        {
            var opResult = new CMCUDResult();

            opResult = UpsertChecks(opResult, insertingObject);
            if (opResult.Errors.Any())
            {
                return(opResult);
            }

            if (Get_ForStateName(insertingObject.Name, insertingObject.CMSystemId) != null)
            {
                opResult.Errors.Add($"Cannot insert an item into {CollectionName} because an item with the same name already exists within this system.");
                return(opResult);
            }

            return(base.Insert(insertingObject));
        }
예제 #27
0
        /// <summary>
        /// Deletes the options from the database
        /// </summary>
        /// <returns></returns>
        public CMCUDResult DeleteOptions()
        {
            var opResult = new CMCUDResult();

            var options = GetOptions();

            OnRecordDeleted?.Invoke(
                new CMDataProviderRecordDeletedEventArgs()
            {
                DtoBefore = options,
            });

            if (!optionsCollection.Delete(options.Id))
            {
                opResult.Errors.Add($"Option with id {options.Id} was not found to delete.");
            }

            return(opResult);
        }
예제 #28
0
        public CMCUDResult UpdateOptions(CMOptionsDto options)
        {
            var opResult = new CMCUDResult();

            var updateEvent = new CMDataProviderRecordUpdatedEventArgs()
            {
                DtoBefore = GetOptions(),
                DtoAfter  = options,
            };

            if (!optionsCollection.Update(options))
            {
                opResult.Errors.Add("Options were not found in master db.");
                return(opResult);
            }

            OnRecordUpdated?.Invoke(updateEvent);

            return(opResult);
        }
예제 #29
0
        public virtual CMCUDResult Update(T updatingObject)
        {
            var opResult = new CMCUDResult();

            if (CUDDepthTracking.ExceedsMaxOperationDepth(opResult))
            {
                return(opResult);
            }

            var updateEvent = new CMDataProviderRecordUpdatedEventArgs()
            {
                DtoBefore = Get(updatingObject.Id),
                DtoAfter  = updatingObject,
            };

            if (cmCollection.Update(updatingObject) == false)
            {
                opResult.Errors.Add($"An item in {CollectionName} with id {updatingObject.Id} was not found to update.");
                return(opResult);
            }

            try
            {
                CUDDepthTracking.OperationDepth++;
                OnRecordUpdated?.Invoke(updateEvent);
            }
            catch (Exception ex)
            {
                opResult.Errors.Add(ex.ToString());
            }
            finally
            {
                CUDDepthTracking.OperationDepth--;
            }

            return(opResult);
        }
예제 #30
0
        public override CMCUDResult Update(T updatingObject)
        {
            var opResult = new CMCUDResult();

            opResult = UpsertChecks(opResult, updatingObject);
            if (opResult.Errors.Any())
            {
                return(opResult);
            }

            var dbTaskData = Get(updatingObject.Id);

            if (dbTaskData.TaskId != updatingObject.TaskId)
            {
                // Allow changing the task that the data is attached to, but it must be done in a way where there is never 1 task with 2 task data records
                if (Get_ForTaskId(updatingObject.TaskId) != null)
                {
                    opResult.Errors.Add($"A pre-existing task data record exists for task id {updatingObject.TaskId} in collection {CollectionName} therefore the updating task data cannot be re-assigned to that task. First make sure the destination task has no task data.");
                    return(opResult);
                }
            }

            return(base.Update(updatingObject));
        }