internal bool ValidateProviderNotSelfOverlap(Domain2.Hours.Hours entry) { if (_resolutionService.Provider.IsBCBA) { return(true); } var hoursAtDate = _resolutionService.AllProposedProviderHours.Where(x => x.Date == entry.Date).ToList(); // remove any of these that are SSG non-parents var ssgToRemove = hoursAtDate.Where(x => x.SSGParentID != null && x.SSGParentID != x.ID).ToList(); foreach (var removal in ssgToRemove) { hoursAtDate.Remove(removal); } var tuples = GetHoursRangeTuples(hoursAtDate); if (ValidationHelpers.AreAnyOverlapping(tuples)) { if (_resolutionService.EntryMode == HoursEntryMode.ManagementEntry) { _resolutionService.Issues.AddIssue("These hours cause an overlap by this provider.", ValidationIssueType.Warning); } else { _resolutionService.Issues.AddIssue("Unable to apply hours, this would cause a time overlap of other entries."); return(false); } } return(true); }
internal bool ValidateAideNotDROverlapOnCase(Domain2.Hours.Hours entry) { if (_resolutionService.Provider.IsBCBA || (_resolutionService.EntryMode == HoursEntryMode.ManagementEntry && entry.IsTrainingEntry)) { return(true); } var caseDRHours = _resolutionService.AllProposedCaseHours(entry.CaseID) .Where(x => x.Date == entry.Date && x.ServiceID == _resolutionService.DRServiceID) .ToList(); var tuples = GetHoursRangeTuples(caseDRHours); if (ValidationHelpers.AreAnyOverlapping(tuples)) { if (_resolutionService.EntryMode == HoursEntryMode.ManagementEntry) { _resolutionService.Issues.AddIssue("These hours will cause an overlap in Aide DR entries for this case.", ValidationIssueType.Warning); } else { _resolutionService.Issues.AddIssue("Unable to apply hours, this would cause an overlap of DR services for this case."); return(false); } } return(true); }
internal bool ValidateBCBAMaxAssessmentHoursPerCasePerDay(Domain2.Hours.Hours entry) { const int MAX_ASSESSMENT_HOURS = 6; if (!_resolutionService.Provider.IsBCBA || (_resolutionService.EntryMode == HoursEntryMode.ManagementEntry && entry.IsTrainingEntry) || (!_assessmentServiceIDs.ToList().Contains(entry.Service.ID))) { return(true); } var caseHoursToday = _resolutionService.AllProposedCaseHours(entry.CaseID) .Where(x => x.Date == entry.Date && x.Provider.ID == _resolutionService.Provider.ID && _assessmentServiceIDs.ToList().Contains(x.Service.ID)) .ToList(); if (caseHoursToday.Sum(x => x.TotalHours) > MAX_ASSESSMENT_HOURS) { if (_resolutionService.EntryMode == HoursEntryMode.ManagementEntry) { _resolutionService.Issues.AddIssue($"BCBA Assessment Hours over max {MAX_ASSESSMENT_HOURS} per case per day.", ValidationIssueType.Warning); } else { _resolutionService.Issues.AddIssue($"Assessment Hours over max {MAX_ASSESSMENT_HOURS} per case per day."); return(false); } } return(true); }
internal bool ValidateAideMaxHoursPerDayPerCase(Domain2.Hours.Hours entry) { const int MAX_HOURS = 4; if (!_resolutionService.Provider.IsAide || (_resolutionService.EntryMode == HoursEntryMode.ManagementEntry && entry.IsTrainingEntry)) { return(true); } var caseHoursPerDate = _resolutionService.AllProposedCaseHours(entry.CaseID).Where(x => x.Date == entry.Date && x.ProviderID == entry.ProviderID).ToList(); var sumOfHours = caseHoursPerDate.Sum(x => x.TotalHours); if (sumOfHours > MAX_HOURS) { if (_resolutionService.EntryMode == HoursEntryMode.ManagementEntry) { _resolutionService.Issues.AddIssue("This entry will submit more than the max hours per day per case for this provider", ValidationIssueType.Warning); } else { _resolutionService.Issues.AddIssue("Unable to submit, this will cause your max hours per day, per case to be over."); return(false); } } return(true); }
private List <AuthorizationBreakdown> getBreakdownsForRule(Domain2.Hours.Hours entry, AuthorizationMatchRule matchedRule) { var breakdowns = new List <AuthorizationBreakdown>(); var activeCaseAuths = ResolutionServiceRepository.GetCase(entry.CaseID).GetActiveAuthorizations(entry.Date); int totalMinutes = (int)Math.Round(entry.TotalHours * 60); if (!matchedRule.IsInitialAuthUsableForTimeEntry) { return(null); } if (totalMinutes < matchedRule.InitialMinimumMinutes) { return(null); } var initialAuth = activeCaseAuths.Where(x => x.AuthorizationCodeID == matchedRule.InitialAuthorizationID).FirstOrDefault(); if (initialAuth == null) { return(null); } var initialBreakdown = new AuthorizationBreakdown(); initialBreakdown.AuthorizationID = matchedRule.InitialAuthorization.ID; initialBreakdown.Authorization = initialAuth; initialBreakdown.HoursEntry = entry; //initialBreakdown.HoursID = _hours.ID; initialBreakdown.Minutes = matchedRule.GetApplicableInitialMinutes(totalMinutes); breakdowns.Add(initialBreakdown); if (!matchedRule.IsFinalAuthUsableForTimeEntry) { return(breakdowns); } var finalAuth = activeCaseAuths.Where(x => x.AuthorizationCodeID == matchedRule.FinalAuthorizationID).FirstOrDefault(); if (finalAuth == null) { return(breakdowns); } var finalBreakdown = new AuthorizationBreakdown(); finalBreakdown.AuthorizationID = matchedRule.FinalAuthorization.ID; finalBreakdown.Authorization = finalAuth; finalBreakdown.HoursEntry = entry; //finalBreakdown.HoursID = entry.ID; finalBreakdown.Minutes = matchedRule.GetApplicableFinalMinutes(totalMinutes); if (finalBreakdown.Minutes > 0) { breakdowns.Add(finalBreakdown); } return(breakdowns); }
internal bool ValidateSSG(Domain2.Hours.Hours entry) { if (entry.ServiceID != _resolutionService.SSGServiceID) { return(true); } // make sure we're applying to more than one case if (entry.SSGCaseIDs == null || entry.SSGCaseIDs.Length < 2) { _resolutionService.Issues.AddIssue("SSG Hours must be applied to more than one case."); return(false); } // ensure the cases we're applying to aren't finalized yet var finalizedTargetCases = GetFinalizedSSGTargetCases(entry); if (finalizedTargetCases.Count > 0) { if (_resolutionService.EntryMode == HoursEntryMode.ManagementEntry) { _resolutionService.Issues.AddIssue("Some target cases are already finalized.", ValidationIssueType.Warning); } else { _resolutionService.Issues.AddIssue("Some target cases are already finalized. Unable to add SSG Hours."); return(false); } } return(true); }
internal void LoadFromDomainHours(Domain2.Hours.Hours hours) { this.Status = hours.Status; this.BillableHours = hours.BillableHours; this.BillingRef = hours.BillingRef; this.CaseID = hours.Case.ID; this.Date = hours.Date; this.DateCreated = hours.DateCreated; this.HasCatalystData = hours.HasCatalystData; this.ID = hours.ID; this.Notes = hours.Memo; this.PatientName = hours.Case.Patient.CommonName; this.PayableHours = hours.PayableHours; this.ProviderID = hours.ProviderID; this.ProviderName = Helpers.CommonListItems.GetCommonName(hours.Provider.FirstName, hours.Provider.LastName); this.ServiceID = hours.Service.ID; this.ServiceLocationID = hours.ServiceLocationID; this.SSGParentID = hours.SSGParentID; this.TimeIn = hours.Date + hours.StartTime; this.TimeOut = hours.Date + hours.EndTime; this.TotalHours = hours.TotalHours; this.Authorizations = String.Join(", ", hours.AuthorizationBreakdowns.Select(x => x.Authorization.AuthorizationCode.Code)); if (hours.Provider.ProviderType.ID == 15) { this.ExtendedNotes = new AABC.DomainServices.Hours.HoursMultiNotes().GetExistingNotesWithTemplateMerge(15, hours.ID); } }
private List <Domain2.Hours.Hours> GetEntryList(Domain2.Hours.Hours entry) { return(new List <Domain2.Hours.Hours>() { entry }); }
public void ValidateBCBAMaxHoursPerEntryAddsWarningIssueOnManagementEntry() { var entry = new Domain2.Hours.Hours(); var serviceMock = new Mock <IResolutionService>(); entry.TotalHours = 3; entry.ServiceID = (int)Domain2.Services.ServiceIDs.DirectSupervision; entry.Service = new Domain2.Services.Service() { ID = entry.ServiceID.Value }; serviceMock .Setup(x => x.Provider) .Returns(() => new Domain2.Providers.Provider() { ProviderTypeID = (int)Domain2.Providers.ProviderTypeIDs.BoardCertifiedBehavioralAnalyst }); serviceMock.Setup(x => x.Issues).Returns(new ValidationIssueCollection()); serviceMock.Setup(x => x.EntryMode).Returns(Domain2.Cases.HoursEntryMode.ManagementEntry); var validator = new CaseAndProviderValidations(serviceMock.Object); var result = validator.ValidateBCBAMaxHoursPerEntry(entry); Assert.IsTrue(serviceMock.Object.Issues.Issues.Count == 1); Assert.IsTrue(serviceMock.Object.Issues.HasWarnings); }
public ValidationResults Validate(Domain2.Hours.Hours entry, EntryApp entryApp, bool isOnAideLegacyMode) { if (entry.Provider.IsAide && isOnAideLegacyMode) { if (string.IsNullOrWhiteSpace(entry.Memo)) { return(new ValidationResults { IsValid = false, Errors = new[] { "Notes are required for this entry." } }); } if (entryApp != EntryApp.ProviderApp && !ValidateMemo(entry.Memo)) { return(new ValidationResults { IsValid = false, Errors = new[] { "Note must be at least 3 sentences, with at least 18 characters per sentence." } }); } } else if (entry.Provider.IsBCBA && (entry.ExtendedNotes == null || entry.ExtendedNotes.Count < 3)) { return(new ValidationResults { IsValid = false, Errors = new[] { "A minimum of three notes are required for this entry." } }); } return(new ValidationResults { IsValid = true }); }
public void ValidateAideMaxHoursPerDayPerCaseTrueIfNotOver() { var entry = new Domain2.Hours.Hours { Date = new DateTime(2017, 1, 1), TotalHours = (decimal)0.25, ProviderID = 5 }; ResetService(); _serviceMock.Setup(x => x.EntryMode).Returns(Domain2.Cases.HoursEntryMode.ManagementEntry); _serviceMock.Setup(x => x.AllProposedCaseHours(It.IsAny <int>())).Returns(() => _aideMaxHoursPerDayPerCaseHours); _serviceMock.Setup(x => x.Provider).Returns(new Domain2.Providers.Provider() { ID = 5, ProviderTypeID = 17 }); _serviceMock.Setup(x => x.Issues).Returns(new ValidationIssueCollection()); _serviceMock.Object.AllProposedCaseHours(It.IsAny <int>()).Add(entry); var resolver = new CaseAndProviderValidations(_serviceMock.Object); var result = resolver.ValidateAideMaxHoursPerDayPerCase(entry); Assert.IsTrue(_serviceMock.Object.Issues.Issues.Count == 0); Assert.IsTrue(result); }
public void ValidateBCBAMaxHoursPerEntryTrueIfOk() { var entry = new Domain2.Hours.Hours(); var serviceMock = new Mock <IResolutionService>(); entry.TotalHours = 1; entry.ServiceID = (int)Domain2.Services.ServiceIDs.DirectSupervision; entry.Service = new Domain2.Services.Service() { ID = entry.ServiceID.Value }; serviceMock .Setup(x => x.Provider) .Returns(() => new Domain2.Providers.Provider() { ProviderTypeID = (int)Domain2.Providers.ProviderTypeIDs.BoardCertifiedBehavioralAnalyst }); serviceMock.Setup(x => x.Issues).Returns(new ValidationIssueCollection()); var validator = new CaseAndProviderValidations(serviceMock.Object); var result = validator.ValidateBCBAMaxHoursPerEntry(entry); Assert.IsTrue(result); }
public void ValidateAideNotDROverlapValidatesCorrectly() { var entry = new Domain2.Hours.Hours { Date = new DateTime(2017, 1, 1), StartTime = new TimeSpan(15, 30, 0), EndTime = new TimeSpan(16, 30, 0), ServiceID = 9 }; ResetService(); _serviceMock.Setup(x => x.EntryMode).Returns(Domain2.Cases.HoursEntryMode.ProviderEntry); _serviceMock.Setup(x => x.AllProposedCaseHours(It.IsAny <int>())).Returns(() => _aideDROverlapHours); _serviceMock.Setup(x => x.Provider).Returns(new Domain2.Providers.Provider() { ID = 5, ProviderTypeID = 17 }); _serviceMock.Setup(x => x.Issues).Returns(new ValidationIssueCollection()); _serviceMock.Object.AllProposedCaseHours(It.IsAny <int>()).Add(entry); var resolver = new CaseAndProviderValidations(_serviceMock.Object); var result = resolver.ValidateAideNotDROverlapOnCase(entry); Assert.IsTrue(result); }
public void ValidateProviderNotSelfOverlapTrueIfNoOverlaps() { var entry = new Domain2.Hours.Hours { Date = new DateTime(2017, 1, 1), StartTime = new TimeSpan(12, 30, 0), EndTime = new TimeSpan(13, 30, 0) }; ResetService(); _serviceMock.Setup(x => x.EntryMode).Returns(Domain2.Cases.HoursEntryMode.ProviderEntry); _serviceMock.Setup(x => x.AllProposedProviderHours).Returns(() => _selfOverlapHours); _serviceMock.Setup(x => x.Provider).Returns(new Domain2.Providers.Provider() { ID = 5, ProviderTypeID = 17 }); _serviceMock.Setup(x => x.Issues).Returns(new ValidationIssueCollection()); _serviceMock.Object.AllProposedProviderHours.Add(entry); var resolver = new CaseAndProviderValidations(_serviceMock.Object); var result = resolver.ValidateProviderNotSelfOverlap(entry); Assert.IsTrue(result); Assert.IsTrue(_serviceMock.Object.Issues.Issues.Count == 0); }
public void ValidateBCBAMaxAssessmentHoursPerCasePerDayFalseIfOver() { var entry = new Domain2.Hours.Hours(); var serviceMock = new Mock <IResolutionService>(); var provider = new Domain2.Providers.Provider(); entry.TotalHours = 5; entry.Date = new DateTime(2017, 1, 1); entry.ServiceID = (int)Domain2.Services.ServiceIDs.Assessment; entry.Service = new Domain2.Services.Service() { ID = entry.ServiceID.Value }; entry.Provider = provider; provider.ID = 5; provider.ProviderTypeID = (int)Domain2.Providers.ProviderTypeIDs.BoardCertifiedBehavioralAnalyst; serviceMock.Setup(x => x.Provider).Returns(provider); serviceMock.Setup(x => x.AllProposedCaseHours(It.IsAny <int>())).Returns(_bcbaMaxAssessmentCaseHours); serviceMock.Setup(x => x.Issues).Returns(new ValidationIssueCollection()); serviceMock.Setup(x => x.AssessmentServiceIDs).Returns(new int[] { 11, 17, 18 }); serviceMock.Object.AllProposedCaseHours(It.IsAny <int>()).Add(entry); var validator = new CaseAndProviderValidations(serviceMock.Object); var result = validator.ValidateBCBAMaxAssessmentHoursPerCasePerDay(entry); Assert.IsFalse(result); }
public bool Resolve() { var originallyProposedEntries = _resolutionService.ProposedEntries.ToList(); foreach (var entry in originallyProposedEntries) { _repository.RemoveOrphanedSSGRecords(entry.ID); if (!isSSG(entry)) { continue; } // add new records for SSG foreach (int caseID in entry.SSGCaseIDs) { if (entry.CaseID == caseID) { entry.SSGParentID = entry.ID; } else { var newEntry = new Domain2.Hours.Hours(); newEntry.BillableHours = entry.BillableHours; newEntry.Case = _repository.GetCase(caseID); newEntry.CaseID = caseID; newEntry.Date = entry.Date; newEntry.DateCreated = DateTime.Now; newEntry.EndTime = entry.EndTime; newEntry.ExtendedNotes = entry.ExtendedNotes; newEntry.InternalMemo = entry.InternalMemo; newEntry.IsAdjustment = entry.IsAdjustment; newEntry.Memo = entry.Memo; newEntry.PayableHours = 0; newEntry.Provider = entry.Provider; newEntry.ProviderID = entry.ProviderID; newEntry.Service = entry.Service; newEntry.ServiceID = entry.ServiceID; newEntry.ServiceLocationID = entry.ServiceLocationID; //newEntry.SSGParent = entry; newEntry.SSGParentID = entry.ID; newEntry.StartTime = entry.StartTime; newEntry.Status = entry.Status; newEntry.TotalHours = entry.TotalHours; newEntry.WatchEnabled = entry.WatchEnabled; newEntry.WatchNote = entry.WatchNote; _resolutionService.ProposedEntries.Add(newEntry); // for later-cross-validation processing _repository.AddSSGEntry(newEntry); // for repository level tracking } } } return(true); }
public int?GetPriorEntryServiceID(Domain2.Hours.Hours entry) { if (entry.ID == 0) { return(null); } var result = _context.Database.SqlQuery <int?>("SELECT HoursServiceID FROM dbo.CaseAuthHours WHERE ID = " + entry.ID); return(result.FirstOrDefault <int?>()); }
public List <Case> GetSSGCases(Domain2.Hours.Hours entry) { var results = new List <Case>(); foreach (int caseID in entry.SSGCaseIDs) { results.Add(_context.Cases.Find(caseID)); } return(results); }
private bool isSSG(Domain2.Hours.Hours entry) { if (entry.ServiceID == (int)Domain2.Services.ServiceIDs.SocialSkillsGroup) { return(true); } else { return(false); } }
public void ValidateCoreEntriesSSGFalseIfNoSSGIDs() { var entry = new Domain2.Hours.Hours { ServiceID = 1 }; var resolver = new CoreValidations(_resolutionServiceMock.Object, null); bool result = resolver.ValidateSSG(entry); Assert.IsFalse(result); }
public void NormalizeTimesStripsTimeFromHoursDate() { var entry = new Domain2.Hours.Hours { Case = new Domain2.Cases.Case(), Provider = new Domain2.Providers.Provider(), Date = new DateTime(2017, 1, 2, 3, 4, 5) }; var resolver = new ResolutionService(GetEntryList(entry), _repoMock.Object); resolver.NormalizeCoreData(EntryApp.Unknown); Assert.AreEqual(new DateTime(2017, 1, 2, 0, 0, 0), entry.Date); }
private Domain2.Hours.Hours getMockHours() { var hours = new Domain2.Hours.Hours(); hours.Case = new Domain2.Cases.Case(); hours.Service = new Domain2.Services.Service(); hours.Provider = new Domain2.Providers.Provider(); hours.Provider.ProviderType = new Domain2.Providers.ProviderType(); hours.Case.Patient = new Domain2.Patients.Patient(); hours.Case.Patient.Insurance = new Domain2.Insurances.Insurance(); return(hours); }
private bool TargetPeriodFinalized(Domain2.Hours.Hours entry) { var c = _repository.GetCase(entry.CaseID); var period = c.GetPeriod(entry.Date.Year, entry.Date.Month); if (period != null) { if (period.IsProviderFinalized(entry.ProviderID)) { return(true); } } return(false); }
private static bool IsOnAideLegacyMode(Provider p, Domain2.Hours.Hours h) { if (p.ProviderTypeID == (int)ProviderTypeIDs.BoardCertifiedBehavioralAnalyst) { return(true); } else if (h != null && h.Report == null) { return(true); } else { return(bool.Parse(ConfigurationManager.AppSettings["NotesLegacy"])); } }
private static Domain2.Hours.Hours GetMockHours() { var hours = new Domain2.Hours.Hours { Case = new Domain2.Cases.Case(), Service = new Domain2.Services.Service(), Provider = new Domain2.Providers.Provider() }; hours.Provider.ProviderType = new Domain2.Providers.ProviderType(); hours.Case.Patient = new Domain2.Patients.Patient { Insurance = new Domain2.Insurances.Insurance() }; return hours; }
public void ValidateBCBAMaxAssessmentHoursPerCasePerDayIgnoresNonBCBAs() { var entry = new Domain2.Hours.Hours(); var serviceMock = new Mock <IResolutionService>(); var provider = new Domain2.Providers.Provider(); entry.TotalHours = 8; provider.ProviderTypeID = (int)Domain2.Providers.ProviderTypeIDs.Aide; serviceMock.Setup(x => x.Provider).Returns(provider); var validator = new CaseAndProviderValidations(serviceMock.Object); var result = validator.ValidateBCBAMaxAssessmentHoursPerCasePerDay(entry); Assert.IsTrue(result); }
public ValidationIssueCollection AddSingleHourEntry(bool ignoreWarnings, int caseID, int providerID, DateTime date, DateTime timeIn, DateTime timeOut, int serviceID, string notes, bool isAdjustment) { using (var transaction = _context.Database.BeginTransaction()) { try { var hourEntry = new Domain2.Hours.Hours { CaseID = caseID, Provider = _context.Providers.Single(m => m.ID == providerID), Service = _context.Services.Single(m => m.ID == serviceID), Date = date, StartTime = timeIn.TimeOfDay, EndTime = timeOut.TimeOfDay, Memo = notes }; hourEntry.ProviderID = hourEntry.Provider.ID; hourEntry.ServiceID = hourEntry.Service.ID; var repository = new ResolutionServiceRepository(_context); var resolutionService = new ResolutionService(new List <Domain2.Hours.Hours> { hourEntry }, repository) { EntryMode = HoursEntryMode.ManagementEntry }; var issues = resolutionService.Resolve(); if (issues.HasErrors || (issues.HasWarnings && !ignoreWarnings)) { transaction.Rollback(); return(issues); } else { _context.SaveChanges(); transaction.Commit(); return(issues); } } catch (Exception e) { transaction.Rollback(); Exceptions.Handle(e, Global.GetWebInfo()); throw e; } } }
public void NormalizeTimesSetsPayableHours() { var entry = new Domain2.Hours.Hours { Case = new Domain2.Cases.Case(), Provider = new Domain2.Providers.Provider(), Date = DateTime.Now, StartTime = new TimeSpan(6, 15, 0), EndTime = new TimeSpan(9, 30, 0) }; var resolver = new ResolutionService(GetEntryList(entry), _repoMock.Object); resolver.NormalizeCoreData(EntryApp.Unknown); Assert.AreEqual((decimal)3.25, entry.PayableHours); }
public void AuthResolverGetsNoAuth() { var patient = _context.Patients.Find(1865); // aetna insurance var hours = new Domain2.Hours.Hours(); hours.Case = patient.ActiveCase; hours.Provider = patient.ActiveCase.GetProvidersAtDate(DateTime.Now).First().Provider; hours.Date = DateTime.Now; hours.Service = _context.Services.Where(x => x.Code == "TM").First(); hours.ServiceID = hours.Service.ID; hours.TotalHours = 1.5M; var resolver = new AuthResolver(hours); var sut = resolver.GetAuthorizationBreakdowns(); Assert.IsNull(sut); }
public void ValidateCoreEntriesSSGTrue() { var entry = new Domain2.Hours.Hours { ServiceID = 1, Date = new DateTime(2017, 1, 1), SSGCaseIDs = new int[] { 1, 2 } }; _resolutionServiceMock.Setup(x => x.EntryMode).Returns(Domain2.Cases.HoursEntryMode.ProviderEntry); var repoMock = GetRepositoryMock(false); var resolver = new CoreValidations(_resolutionServiceMock.Object, repoMock.Object); bool result = resolver.ValidateSSG(entry); Assert.IsTrue(result); }