Template
334 lines
15 KiB
C#
334 lines
15 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Strata.ContinuousImprovement.Biz.DbContexts;
|
|
using Strata.ContinuousImprovement.Biz.Generics;
|
|
using Strata.ContinuousImprovement.Biz.OpportunityWorkbooks;
|
|
using Strata.ContinuousImprovement.Client.Test.Integration.Models;
|
|
using Strata.ContinuousImprovement.Client.Test.Integration.Setup;
|
|
using Strata.DecisionSupport.Biz.Utilities;
|
|
using Strata.DecisionSupport.Models.Jazz;
|
|
using Strata.DecisionSupport.Models.Queries;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
namespace Strata.ContinuousImprovement.Client.Test.Integration.Tests
|
|
{
|
|
[ExcludeFromCodeCoverage]
|
|
[TestFixture(Category = "Integration")]
|
|
public class TestContinuousImprovementClient : ClientServiceBase
|
|
{
|
|
private const string MSDRGCaseTypeFamilyIdQuery = @"select ctf.casetypefamilyid Value
|
|
FROM dss.CaseTypeFamily ctf
|
|
WHERE ctf.Name = 'Acute Kidney Failure'
|
|
AND EXISTS (SELECT TOP (1) 1 FROM dss.CaseTypeFamilyMappingICD10 msdrg WHERE msdrg.CaseTypeFamilyID = ctf.CaseTypeFamilyID)";
|
|
private const string APRDRGCaseTypeFamilyIdQuery = @"SELECT ctf.CaseTypeFamilyID Value
|
|
FROM dss.CaseTypeFamily ctf
|
|
WHERE ctf.Name = 'Acute Kidney Injury'
|
|
AND EXISTS(SELECT TOP (1) 1 FROM dss.CaseTypeFamilyMappingAPRDRG aprdrg WHERE aprdrg.CaseTypeFamilyID = ctf.CaseTypeFamilyID)";
|
|
private const string CptCodeCaseTypeFamilyIdQuery = @"SELECT ctf.CaseTypeFamilyID Value
|
|
FROM dss.CaseTypeFamily ctf
|
|
WHERE ctf.Name = 'Acupuncture Procedures'
|
|
AND EXISTS(SELECT TOP (1) 1 FROM dss.CaseTypeFamilyMappingCPT cpt WHERE cpt.CaseTypeFamilyID = ctf.CaseTypeFamilyID)";
|
|
private const string PatientPopClinicalIndicatorIdQuery = @"SELECT ci.ClinicalIndicatorID Value
|
|
FROM dss.CaseTypeFamily ctf
|
|
INNER JOIN dss.DimCaseType ct ON ct.CaseTypeFamilyID = ctf.CaseTypeFamilyID
|
|
INNER JOIN dss.DimClinicalIndicator ci ON ci.ClinicalIndicatorID = ct.ClinicalIndicatorID
|
|
WHERE ct.CaseTypeCategory = 2
|
|
AND ci.Name = 'BPCI Major Joint Replacement - Knee'";
|
|
|
|
[Test, Order(1)]
|
|
public async Task TestGetConfigurations()
|
|
{
|
|
// arrange
|
|
|
|
// act
|
|
var configurations = await GetConfigurationsAsync(CancellationToken.None);
|
|
|
|
// assert
|
|
Assert.That(configurations, Is.Not.Empty);
|
|
}
|
|
|
|
[Test, Order(1)]
|
|
[Ignore("Test database needs to be rolled over to the new year")]
|
|
public async Task TestGetDfltConfiguration()
|
|
{
|
|
// arrange
|
|
|
|
// act
|
|
var configurations = await GetConfigurationsAsync(CancellationToken.None);
|
|
var dftlConfiguration = configurations.OrderBy(c => c.DisplayOrder).FirstOrDefault();
|
|
|
|
// assert
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(configurations, Is.Not.Empty);
|
|
Assert.That(dftlConfiguration, Is.Not.Null);
|
|
var expectedFiscalYearId = DateTime.Now.Year;
|
|
Assert.That(dftlConfiguration.FiscalYearId, Is.InRange(expectedFiscalYearId - 1, expectedFiscalYearId), "Fiscal year configuration needs to be updated for the current year.");
|
|
Assert.That(dftlConfiguration.OrgDefinedEndDate, Is.EqualTo(new DateTime(dftlConfiguration.FiscalYearId, 1, 1).AddDays(-1)));
|
|
});
|
|
}
|
|
|
|
[Test, Order(1)]
|
|
public async Task TestGetEntityConfiguration()
|
|
{
|
|
// arrange
|
|
|
|
// act
|
|
var configurations = await GetConfigurationsAsync(CancellationToken.None);
|
|
var configuration = configurations.OrderBy(c => c.DisplayOrder).FirstOrDefault(c => c.EntityIdsCsv != "" && !c.IsUsingCustomEntityDimension);
|
|
|
|
// assert
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(configurations, Is.Not.Empty);
|
|
Assert.That(configuration, Is.Not.Null);
|
|
Assert.That(configuration.IsUsingCustomEntityDimension, Is.False);
|
|
Assert.That(configuration.EntityIdsCsv, Is.Not.Empty);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public async Task TestDecisionSupportMsdrgEncounterInfo()
|
|
{
|
|
// arrange
|
|
var configurations = await GetConfigurationsAsync(CancellationToken.None);
|
|
var configuration = configurations.OrderBy(c => c.DisplayOrder).First(c => c.EntityIdsCsv != "" && !c.IsUsingCustomEntityDimension);
|
|
var entityIdValues = configuration.EntityIdsCsv?.Split(',') ?? [];
|
|
if (entityIdValues.IsEmpty())
|
|
{
|
|
entityIdValues = configuration.CustomEntityIdsCsv?.Split(',') ?? ["2"];
|
|
}
|
|
var entityIds = entityIdValues.Select(entityId => int.TryParse(entityId, out var r) ? r : 0).Distinct();
|
|
var caseTypeFamilyId = await GetCaseTypeFamilyId(MSDRGCaseTypeFamilyIdQuery, CancellationToken.None);
|
|
var encounterInfo = EncounterInfo(CaseTypeCategory.MSDRG, caseTypeFamilyId, configuration, entityIds);
|
|
|
|
// act
|
|
var result = Enumerable.Empty<MSDRGEncounterInfo>();
|
|
Assert.DoesNotThrowAsync(async () =>
|
|
result = await ContinuousImprovementService.DecisionSupportMsdrgEncounterInfo(encounterInfo, CancellationToken.None));
|
|
|
|
// assert
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(result, Is.AssignableTo<IEnumerable<MSDRGEncounterInfo>>());
|
|
Assert.That(result, Is.Not.Null.And.Not.Empty);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public async Task TestDecisionSupportAprdrgEncounterInfo()
|
|
{
|
|
// arrange
|
|
var configurations = await GetConfigurationsAsync(CancellationToken.None);
|
|
var configuration = configurations.OrderBy(c => c.DisplayOrder).First(c => c.EntityIdsCsv != "" && !c.IsUsingCustomEntityDimension);
|
|
var entityIdValues = configuration.EntityIdsCsv?.Split(',') ?? [];
|
|
if (entityIdValues.IsEmpty())
|
|
{
|
|
entityIdValues = configuration.CustomEntityIdsCsv?.Split(',') ?? ["2"];
|
|
}
|
|
var entityIds = entityIdValues.Select(entityId => int.TryParse(entityId, out var r) ? r : 0).Distinct();
|
|
var caseTypeFamilyId = await GetCaseTypeFamilyId(APRDRGCaseTypeFamilyIdQuery, CancellationToken.None);
|
|
var encounterInfo = EncounterInfo(CaseTypeCategory.APRDRG, caseTypeFamilyId, configuration, entityIds);
|
|
|
|
// act
|
|
var result = Enumerable.Empty<APRDRGEncounterInfo>();
|
|
Assert.DoesNotThrowAsync(async () =>
|
|
result = await ContinuousImprovementService.DecisionSupportAprdrgEncounterInfo(encounterInfo, CancellationToken.None));
|
|
|
|
// assert
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(result, Is.AssignableTo<IEnumerable<APRDRGEncounterInfo>>());
|
|
Assert.That(result, Is.Not.Null.And.Not.Empty);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public async Task TestDecisionSupportCptCodeDrgEncounterInfo()
|
|
{
|
|
// arrange
|
|
var configurations = await GetConfigurationsAsync(CancellationToken.None);
|
|
var configuration = configurations.OrderBy(c => c.DisplayOrder).First(c => c.EntityIdsCsv != "" && !c.IsUsingCustomEntityDimension);
|
|
var entityIdValues = configuration.EntityIdsCsv?.Split(',') ?? [];
|
|
if (entityIdValues.IsEmpty())
|
|
{
|
|
entityIdValues = configuration.CustomEntityIdsCsv?.Split(',') ?? ["2"];
|
|
}
|
|
var entityIds = entityIdValues.Select(entityId => int.TryParse(entityId, out var r) ? r : 0).Distinct();
|
|
var caseTypeFamilyId = await GetCaseTypeFamilyId(CptCodeCaseTypeFamilyIdQuery, CancellationToken.None);
|
|
var encounterInfo = EncounterInfo(CaseTypeCategory.CPTCode, caseTypeFamilyId, configuration, entityIds);
|
|
|
|
// act
|
|
var result = Enumerable.Empty<CPTCodeEncounterInfo>();
|
|
Assert.DoesNotThrowAsync(async () =>
|
|
result = await ContinuousImprovementService.DecisionSupportCptCodeEncounterInfo(encounterInfo, CancellationToken.None));
|
|
|
|
// assert
|
|
Assert.That(result, Is.AssignableTo<IEnumerable<CPTCodeEncounterInfo>>());
|
|
}
|
|
|
|
[Test]
|
|
public async Task TestDecisionSupportPatientPopulationEncounterInfo()
|
|
{
|
|
// arrange
|
|
var configurations = await GetConfigurationsAsync(CancellationToken.None);
|
|
var configuration = configurations.OrderBy(c => c.DisplayOrder).First(c => c.EntityIdsCsv != "" && !c.IsUsingCustomEntityDimension);
|
|
var entityIdValues = configuration.EntityIdsCsv?.Split(',') ?? [];
|
|
if (entityIdValues.IsEmpty())
|
|
{
|
|
entityIdValues = configuration.CustomEntityIdsCsv?.Split(',') ?? ["2"];
|
|
}
|
|
var entityIds = entityIdValues.Select(entityId => int.TryParse(entityId, out var r) ? r : 0).Distinct();
|
|
var clinicalIndicatorId = await GetCaseTypeFamilyId(PatientPopClinicalIndicatorIdQuery, CancellationToken.None);
|
|
var encounterInfo = EncounterInfo(CaseTypeCategory.PatientPopulation, clinicalIndicatorId, configuration, entityIds);
|
|
|
|
// act
|
|
var result = Enumerable.Empty<PatientPopulationEncounterInfo>();
|
|
Assert.DoesNotThrowAsync(async () =>
|
|
result = await ContinuousImprovementService.DecisionSupportPatientPopulationEncounterInfo(encounterInfo, CancellationToken.None));
|
|
|
|
// assert
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(result, Is.AssignableTo<IEnumerable<PatientPopulationEncounterInfo>>());
|
|
Assert.That(result, Is.Not.Null.And.Not.Empty);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public async Task TestGetAllWorkbooks()
|
|
{
|
|
// arrange
|
|
|
|
// act
|
|
var workbooks = await ContinuousImprovementService.GetAllWorkbooks(CancellationToken.None);
|
|
|
|
// assert
|
|
Assert.Multiple(() =>
|
|
{
|
|
|
|
Assert.That(workbooks, Is.AssignableTo<IEnumerable<WorkbookClientInfo>>());
|
|
Assert.That(workbooks.Count, Is.GreaterThanOrEqualTo(1));
|
|
var workbook = workbooks.FirstOrDefault();
|
|
if (workbook == null) { return; }
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(OpportunityWorkbook.WorkbookId, Is.GreaterThan(0));
|
|
Assert.That(OpportunityWorkbook.StrataId, Is.EqualTo(workbook.StrataId));
|
|
});
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public async Task TestGetOpportunityWorkbooks()
|
|
{
|
|
// arrange
|
|
|
|
// act
|
|
var workbooks = await ContinuousImprovementService.GetOpportunityWorkbooks(Guid.NewGuid(), CancellationToken.None);
|
|
|
|
// assert
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(workbooks, Is.AssignableTo<IEnumerable<OpportunityWorkbookClientInfo>>());
|
|
Assert.That(workbooks.Count, Is.GreaterThanOrEqualTo(0));
|
|
var workbook = workbooks.FirstOrDefault();
|
|
if (workbook == null) { return; }
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(OpportunityWorkbook.WorkbookId, Is.GreaterThan(0));
|
|
Assert.That(OpportunityWorkbook.StrataId, Is.EqualTo(workbook.StrataId));
|
|
});
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public async Task TestGetOpportunityTypeWorkbooks()
|
|
{
|
|
// arrange
|
|
|
|
// act
|
|
var workbooks = await ContinuousImprovementService.GetOpportunityTypeWorkbooks((int)OpportunityTypes.Encounter, CancellationToken.None);
|
|
|
|
// assert
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(workbooks, Is.AssignableTo<IEnumerable<OpportunityTypeWorkbookClientInfo>>());
|
|
Assert.That(workbooks.Count, Is.GreaterThanOrEqualTo(0));
|
|
var workbook = workbooks.FirstOrDefault();
|
|
if (workbook == null) { return; }
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(OpportunityWorkbook.WorkbookId, Is.GreaterThan(0));
|
|
Assert.That(OpportunityWorkbook.StrataId, Is.EqualTo(workbook.StrataId));
|
|
});
|
|
});
|
|
}
|
|
|
|
[Test, Ignore("WIP")]
|
|
public async Task TestCreateAndDeleteOpportunityWorkbooks()
|
|
{
|
|
// arrange
|
|
var jazzDbContext = (JazzDbContext)ServiceProperties.JazzDbContext;
|
|
var uvOpps = jazzDbContext.VariationOpportunities.Take(10).ToList();
|
|
var opportunityWorkbooks = uvOpps.Select(uv => new OpportunityWorkbookClientInfo
|
|
{
|
|
Name = uv.OpportunityKey,
|
|
OpportunityGuid = uv.OpportunityGuid,
|
|
StrataId = StrataId,
|
|
});
|
|
|
|
// act
|
|
var workbooks = await ContinuousImprovementService.CreateOpportunityWorkbooks(opportunityWorkbooks, CancellationToken.None);
|
|
|
|
// assert
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(workbooks, Is.AssignableTo<IEnumerable<OpportunityWorkbookClientInfo>>());
|
|
Assert.That(workbooks.Count, Is.GreaterThanOrEqualTo(0));
|
|
var workbook = workbooks.FirstOrDefault();
|
|
if (workbook == null) { return; }
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(OpportunityWorkbook.WorkbookId, Is.GreaterThan(0));
|
|
Assert.That(OpportunityWorkbook.StrataId, Is.EqualTo(workbook.StrataId));
|
|
});
|
|
});
|
|
|
|
foreach (var workbook in workbooks)
|
|
{
|
|
// act
|
|
var response = await ContinuousImprovementService.DeleteOpportunityWorkbook(workbook.OpportunityGuid, workbook.WorkbookId, CancellationToken.None);
|
|
|
|
//assert
|
|
response.EnsureSuccessStatusCode();
|
|
}
|
|
}
|
|
|
|
|
|
#region Helper Methods
|
|
|
|
private async Task<int> GetCaseTypeFamilyId(string query, CancellationToken cancellationToken)
|
|
=> await ((JazzDbContext)ServiceProperties.JazzDbContext).Database
|
|
.SqlQueryRaw<int>(query)
|
|
.SingleOrDefaultAsync(CancellationToken.None);
|
|
|
|
private EncounterQueryInfo EncounterInfo(CaseTypeCategory caseTypeCategory, int caseTypeFamilyId,
|
|
ConfigurationInfo configuration,
|
|
IEnumerable<int> entityIds)
|
|
=> new EncounterQueryInfo
|
|
{
|
|
CaseTypeCategory = caseTypeCategory,
|
|
CaseTypeFamilyId = caseTypeFamilyId,
|
|
StartDate = configuration.OrgDefinedEndDate.AddDays(1).AddYears(-1),
|
|
EndDate = configuration.OrgDefinedEndDate,
|
|
DepartmentRollupGlobalId = "",
|
|
ServiceLineGuid = configuration.ServiceLineDimensionGuid,
|
|
EntityIDs = entityIds,
|
|
ObservationUnitsDivisor = 0.5
|
|
};
|
|
|
|
|
|
#endregion
|
|
|
|
}
|
|
} |