/// <summary> /// Performs the Audit. /// </summary> /// <exception cref="System.ApplicationException">A problem occurred while generating database snapshot.</exception> public void PerformAudit() { //when complete present... //1-Items from upload not included in audit //2-items in upload but not in master //3-items in master but not in upload //4-items in both but with differences Dictionary<string, ExtractItemModel> extractExclude = new Dictionary<string, ExtractItemModel>(); List<ExtractItemModel> extractInclude = new List<ExtractItemModel>(); List<AuditException> auditExceptions = new List<AuditException>(); //Step 1: get extract contents, by default I'm not peristing it in the model var extractItems = ExtractViewModel.GetExtractItems(_unitOfWork, (int)this.ExtractId); //Step 2: determine which extract items can/should be used foreach(ExtractItemModel extractItem in extractItems) { if (!ExcludeFromAuditYN(extractItem)) { extractInclude.Add(extractItem); } else { string userNameUse = (extractItem.UserName ?? string.Empty).Trim().ToLower(); if (!extractExclude.ContainsKey(userNameUse)) { extractExclude.Add(userNameUse, extractItem); } } } //Note: use extractInclude list as source for audit henceforth //Step #3: generate database snapshot against which to perform the audit, and build lookup var genResult = _unitOfWork.OptUsers.GenerateMasterUsersForAudit(this.AuditId); if (genResult < 1) { throw new ApplicationException("A problem occurred while generating database snapshot."); } //Step #4: fetch that database snapshot var databaseMaster = _unitOfWork.AuditMasterItems.GetAll() .Where(i => i.AuditId == this.AuditId) .Select(i => new AuditMasterItemModel { AuditMasterItemId = i.AuditMasterItemId, FirstName = i.LastName, LastName = i.LastName, Login = i.Login, Facilities = i.Facilities, Templates = i.Templates, ProcessedYN = false //derived col to monitor audit status }) .ToDictionary(i => i.Login.ToLower(), i => i); //Step #5: get some helper info to use during audit, e.g. id's for exception types //ugly code but prevents need for lookups during the audit int idInUploadButNotInMaster = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InUploadButNotInMaster) .SingleOrDefault() .AuditExceptionTypeId; int idInMasterButNotInUpload = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InMasterButNotInUpload) .SingleOrDefault() .AuditExceptionTypeId; int idInBothWithFacilityDifferences = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InBothWithFacilityDifferences) .SingleOrDefault() .AuditExceptionTypeId; int idInBothWithTemplateDifferences = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InBothWithTemplateDifferences) .SingleOrDefault() .AuditExceptionTypeId; int idInUploadButInvalid = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InUploadButInvalid) .SingleOrDefault() .AuditExceptionTypeId; int idInUploadButHandleManually = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InUploadButHandleManually) .SingleOrDefault() .AuditExceptionTypeId; //Step #6: iterate over upload/extract and perform audit foreach (ExtractItemModel extractItem in extractInclude) { string optTemplates = CalculateOptimumTemplatesForComparison(extractItem.SecurityGroup, this.Name); string optFac = CalculateOptimumFacilitiesForComparison(extractItem.EmployeeID, this.Name); if (!databaseMaster.ContainsKey(extractItem.UserName.ToLower())) { AuditException ex = new AuditException(); ex.AuditId = this.AuditId; ex.AuditExceptionTypeId = idInUploadButNotInMaster; //ex.AuditExceptionType.Name = AuditExceptionTypeModel.InExtractButNotInMaster; ex.Message = string.Format("User '{0}' occurs in upload but not in master", extractItem.UserName); ex.UserNameFromOptimum = extractItem.UserName; ex.UserNameFromMaster = string.Empty; ex.FacilitiesFromMaster = string.Empty; ex.FacilitiesFromOptimum = optFac; ex.TemplatesFromOptimum = optTemplates; ex.TemplatesFromMaster = string.Empty; _unitOfWork.AuditExceptions.Add(ex); } else { //in both but check for facility differences AuditMasterItemModel dbItem = databaseMaster[extractItem.UserName.ToLower()]; dbItem.ProcessedYN = true; //indicate that db entry has been processed string dbFac = CalculateDatabaseFacilitiesForComparison(dbItem.Facilities, this.Name); string dbTemplates = CalculateDatabaseTemplatesForComparison(dbItem.Templates, this.Name); if (optFac != dbFac) { AuditException ex = new AuditException(); ex.AuditId = this.AuditId; ex.AuditExceptionTypeId = idInBothWithFacilityDifferences; ex.Message = string.Format("User '{0}' occurs in both but facilities differ", extractItem.UserName); ex.UserNameFromOptimum = extractItem.UserName; ex.UserNameFromMaster = extractItem.UserName; ex.FacilitiesFromMaster = dbFac; ex.FacilitiesFromOptimum = optFac; ex.TemplatesFromOptimum = optTemplates; ex.TemplatesFromMaster = dbTemplates; _unitOfWork.AuditExceptions.Add(ex); } //in both but check for template differences if (optTemplates != dbTemplates) { AuditException ex = new AuditException(); ex.AuditId = this.AuditId; ex.AuditExceptionTypeId = idInBothWithTemplateDifferences; ex.Message = string.Format("User '{0}' occurs in both but templates differ", extractItem.UserName); ex.UserNameFromOptimum = extractItem.UserName; ex.UserNameFromMaster = extractItem.UserName; ex.FacilitiesFromMaster = dbFac; ex.FacilitiesFromOptimum = optFac; ex.TemplatesFromOptimum = optTemplates; ex.TemplatesFromMaster = dbTemplates; _unitOfWork.AuditExceptions.Add(ex); } } } //Step #7: make note of master items that were not processed foreach(string key in databaseMaster.Keys) { if (!databaseMaster[key].ProcessedYN && !extractExclude.ContainsKey(key)) { string dbFac = CalculateDatabaseFacilitiesForComparison(databaseMaster[key].Facilities, this.Name); string dbTemplates = CalculateDatabaseTemplatesForComparison(databaseMaster[key].Templates, this.Name); AuditException ex = new AuditException(); ex.AuditId = this.AuditId; ex.AuditExceptionTypeId = idInMasterButNotInUpload; ex.Message = string.Format("User '{0}' occurs in master but not in upload", key); ex.UserNameFromMaster = key; ex.UserNameFromOptimum = string.Empty; ex.FacilitiesFromMaster = dbFac; ex.FacilitiesFromOptimum = string.Empty; ex.TemplatesFromOptimum = string.Empty; ex.TemplatesFromMaster = dbTemplates; _unitOfWork.AuditExceptions.Add(ex); } } //Step #8: make note of extract items that were excluded - add them as exceptions foreach (ExtractItemModel extractItem in extractExclude.Values) { AuditException ex = new AuditException(); string optTemplates = CalculateOptimumTemplatesForComparison(extractItem.SecurityGroup, this.Name); ex.AuditId = this.AuditId; ex.TemplatesFromMaster = string.Empty; ex.TemplatesFromOptimum = optTemplates; ex.UserNameFromMaster = string.Empty; ex.FacilitiesFromMaster = string.Empty; ex.UserNameFromOptimum = extractItem.UserName; if ((extractItem.EmployeeID ?? string.Empty).Trim().ToLower() == "multiple") { ex.AuditExceptionTypeId = idInUploadButHandleManually; ex.Message = string.Format("User '{0}' must be handled manually", extractItem.UserName); ex.FacilitiesFromOptimum = extractItem.EmployeeID; } else { string optFac = CalculateOptimumFacilitiesForComparison(extractItem.EmployeeID, this.Name); ex.AuditExceptionTypeId = idInUploadButInvalid; ex.Message = string.Format("User '{0}' from upload was excluded from audit", extractItem.UserName); ex.FacilitiesFromOptimum = optFac; } _unitOfWork.AuditExceptions.Add(ex); } //Step #9: set end date Audit audit = _unitOfWork.Audits.GetAll().Where(a => a.AuditId == this.AuditId).SingleOrDefault(); audit.AuditEndDate = DateTime.Now; //Step #9: commit everyting - may take a minute _unitOfWork.Save(); }
/// <summary> /// Performs the Audit. /// </summary> /// <exception cref="System.ApplicationException">A problem occurred while generating database snapshot.</exception> public void PerformAudit() { //when complete present... //1-Items from upload not included in audit //2-items in upload but not in master //3-items in master but not in upload //4-items in both but with differences Dictionary <string, ExtractItemModel> extractExclude = new Dictionary <string, ExtractItemModel>(); List <ExtractItemModel> extractInclude = new List <ExtractItemModel>(); List <AuditException> auditExceptions = new List <AuditException>(); //Step 1: get extract contents, by default I'm not peristing it in the model var extractItems = ExtractViewModel.GetExtractItems(_unitOfWork, (int)this.ExtractId); //Step 2: determine which extract items can/should be used foreach (ExtractItemModel extractItem in extractItems) { if (!ExcludeFromAuditYN(extractItem)) { extractInclude.Add(extractItem); } else { string userNameUse = (extractItem.UserName ?? string.Empty).Trim().ToLower(); if (!extractExclude.ContainsKey(userNameUse)) { extractExclude.Add(userNameUse, extractItem); } } } //Note: use extractInclude list as source for audit henceforth //Step #3: generate database snapshot against which to perform the audit, and build lookup var genResult = _unitOfWork.OptUsers.GenerateMasterUsersForAudit(this.AuditId); if (genResult < 1) { throw new ApplicationException("A problem occurred while generating database snapshot."); } //Step #4: fetch that database snapshot var databaseMaster = _unitOfWork.AuditMasterItems.GetAll() .Where(i => i.AuditId == this.AuditId) .Select(i => new AuditMasterItemModel { AuditMasterItemId = i.AuditMasterItemId, FirstName = i.LastName, LastName = i.LastName, Login = i.Login, Facilities = i.Facilities, Templates = i.Templates, ProcessedYN = false //derived col to monitor audit status }) .ToDictionary(i => i.Login.ToLower(), i => i); //Step #5: get some helper info to use during audit, e.g. id's for exception types //ugly code but prevents need for lookups during the audit int idInUploadButNotInMaster = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InUploadButNotInMaster) .SingleOrDefault() .AuditExceptionTypeId; int idInMasterButNotInUpload = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InMasterButNotInUpload) .SingleOrDefault() .AuditExceptionTypeId; int idInBothWithFacilityDifferences = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InBothWithFacilityDifferences) .SingleOrDefault() .AuditExceptionTypeId; int idInBothWithTemplateDifferences = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InBothWithTemplateDifferences) .SingleOrDefault() .AuditExceptionTypeId; int idInUploadButInvalid = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InUploadButInvalid) .SingleOrDefault() .AuditExceptionTypeId; int idInUploadButHandleManually = _unitOfWork.AuditExceptionTypes.GetAll() .Where(t => t.Name == AuditExceptionTypeModel.InUploadButHandleManually) .SingleOrDefault() .AuditExceptionTypeId; //Step #6: iterate over upload/extract and perform audit foreach (ExtractItemModel extractItem in extractInclude) { string optTemplates = CalculateOptimumTemplatesForComparison(extractItem.SecurityGroup, this.Name); string optFac = CalculateOptimumFacilitiesForComparison(extractItem.EmployeeID, this.Name); if (!databaseMaster.ContainsKey(extractItem.UserName.ToLower())) { AuditException ex = new AuditException(); ex.AuditId = this.AuditId; ex.AuditExceptionTypeId = idInUploadButNotInMaster; //ex.AuditExceptionType.Name = AuditExceptionTypeModel.InExtractButNotInMaster; ex.Message = string.Format("User '{0}' occurs in upload but not in master", extractItem.UserName); ex.UserNameFromOptimum = extractItem.UserName; ex.UserNameFromMaster = string.Empty; ex.FacilitiesFromMaster = string.Empty; ex.FacilitiesFromOptimum = optFac; ex.TemplatesFromOptimum = optTemplates; ex.TemplatesFromMaster = string.Empty; _unitOfWork.AuditExceptions.Add(ex); } else { //in both but check for facility differences AuditMasterItemModel dbItem = databaseMaster[extractItem.UserName.ToLower()]; dbItem.ProcessedYN = true; //indicate that db entry has been processed string dbFac = CalculateDatabaseFacilitiesForComparison(dbItem.Facilities, this.Name); string dbTemplates = CalculateDatabaseTemplatesForComparison(dbItem.Templates, this.Name); if (optFac != dbFac) { AuditException ex = new AuditException(); ex.AuditId = this.AuditId; ex.AuditExceptionTypeId = idInBothWithFacilityDifferences; ex.Message = string.Format("User '{0}' occurs in both but facilities differ", extractItem.UserName); ex.UserNameFromOptimum = extractItem.UserName; ex.UserNameFromMaster = extractItem.UserName; ex.FacilitiesFromMaster = dbFac; ex.FacilitiesFromOptimum = optFac; ex.TemplatesFromOptimum = optTemplates; ex.TemplatesFromMaster = dbTemplates; _unitOfWork.AuditExceptions.Add(ex); } //in both but check for template differences if (optTemplates != dbTemplates) { AuditException ex = new AuditException(); ex.AuditId = this.AuditId; ex.AuditExceptionTypeId = idInBothWithTemplateDifferences; ex.Message = string.Format("User '{0}' occurs in both but templates differ", extractItem.UserName); ex.UserNameFromOptimum = extractItem.UserName; ex.UserNameFromMaster = extractItem.UserName; ex.FacilitiesFromMaster = dbFac; ex.FacilitiesFromOptimum = optFac; ex.TemplatesFromOptimum = optTemplates; ex.TemplatesFromMaster = dbTemplates; _unitOfWork.AuditExceptions.Add(ex); } } } //Step #7: make note of master items that were not processed foreach (string key in databaseMaster.Keys) { if (!databaseMaster[key].ProcessedYN && !extractExclude.ContainsKey(key)) { string dbFac = CalculateDatabaseFacilitiesForComparison(databaseMaster[key].Facilities, this.Name); string dbTemplates = CalculateDatabaseTemplatesForComparison(databaseMaster[key].Templates, this.Name); AuditException ex = new AuditException(); ex.AuditId = this.AuditId; ex.AuditExceptionTypeId = idInMasterButNotInUpload; ex.Message = string.Format("User '{0}' occurs in master but not in upload", key); ex.UserNameFromMaster = key; ex.UserNameFromOptimum = string.Empty; ex.FacilitiesFromMaster = dbFac; ex.FacilitiesFromOptimum = string.Empty; ex.TemplatesFromOptimum = string.Empty; ex.TemplatesFromMaster = dbTemplates; _unitOfWork.AuditExceptions.Add(ex); } } //Step #8: make note of extract items that were excluded - add them as exceptions foreach (ExtractItemModel extractItem in extractExclude.Values) { AuditException ex = new AuditException(); string optTemplates = CalculateOptimumTemplatesForComparison(extractItem.SecurityGroup, this.Name); ex.AuditId = this.AuditId; ex.TemplatesFromMaster = string.Empty; ex.TemplatesFromOptimum = optTemplates; ex.UserNameFromMaster = string.Empty; ex.FacilitiesFromMaster = string.Empty; ex.UserNameFromOptimum = extractItem.UserName; if ((extractItem.EmployeeID ?? string.Empty).Trim().ToLower() == "multiple") { ex.AuditExceptionTypeId = idInUploadButHandleManually; ex.Message = string.Format("User '{0}' must be handled manually", extractItem.UserName); ex.FacilitiesFromOptimum = extractItem.EmployeeID; } else { string optFac = CalculateOptimumFacilitiesForComparison(extractItem.EmployeeID, this.Name); ex.AuditExceptionTypeId = idInUploadButInvalid; ex.Message = string.Format("User '{0}' from upload was excluded from audit", extractItem.UserName); ex.FacilitiesFromOptimum = optFac; } _unitOfWork.AuditExceptions.Add(ex); } //Step #9: set end date Audit audit = _unitOfWork.Audits.GetAll().Where(a => a.AuditId == this.AuditId).SingleOrDefault(); audit.AuditEndDate = DateTime.Now; //Step #9: commit everyting - may take a minute _unitOfWork.Save(); }