Files
continuousimprovement/tests/Strata.ContinuousImprovement.Biz.Test.Integration/SnowflakeIntegrationTests/StrategicOpportunityServiceTests.cs
T

654 lines
30 KiB
C#

using FluentAssertions;
using Hangfire;
using Microsoft.EntityFrameworkCore;
using Moq;
using Strata.ContinuousImprovement.Biz.Generics;
using Strata.ContinuousImprovement.Biz.InitiativeRollupColumns;
using Strata.ContinuousImprovement.Biz.OpportunityRoleAssignment;
using Strata.ContinuousImprovement.Biz.OpportunityWorkbooks;
using Strata.ContinuousImprovement.Biz.Security;
using Strata.ContinuousImprovement.Biz.StrategicOpportunities;
using Strata.ContinuousImprovement.Biz.StrategicOpportunities.DistributionProcess;
using Strata.ContinuousImprovement.Biz.StrategicOpportunities.Dtos;
using Strata.ContinuousImprovement.Biz.StrategicOpportunities.Enums;
using Strata.ContinuousImprovement.Biz.Test.Unit.Utilities;
using Strata.CoreLib.Claims.Extensions;
using Strata.DataSchema.Client;
using Strata.DataSchema.Models.Query;
using Strata.DataSchema.Models.Schema;
using Strata.Id.Client;
using Strata.Schema.Client;
using Strata.Schema.Client.Dtos;
using System.Diagnostics.CodeAnalysis;
namespace Strata.ContinuousImprovement.Biz.Test.Integration.SnowflakeIntegrationTests
{
[ExcludeFromCodeCoverage]
[Ignore("temporarily ignoring because schema is out of sync")]
[TestFixture, Category("Integration"), Category("CCI")]
public class StrategicOpportunityServiceTests : IntegrationTestBase
{
private const string POPULATION_NAME = "Mocked Population Name";
private IStrategicOpportunityService _strategicOpportunityService;
private IOpportunityRoleAssignmentService _opportunityRoleAssignmentService;
[OneTimeSetUp]
public void Setup()
{
// Arrange mocks
var mockSchemaServiceClient = new Mock<ISchemaServiceClient>();
var mockDataSchemaService = new Mock<IDataSchemaService>();
var mockIdServiceClient = new Mock<IIdServiceClient>();
var mockIdRollupColumn = new Mock<IInitiativeRollupColumnService>();
var mockOpportunityWorkbookService = new Mock<IOpportunityWorkbookService>();
var mockStrategicOpportunityDetailService = new Mock<IStrategicChargeCodeOpportunityDetailService>();
var mockStrategicGLOpportunityDetailService = new Mock<IStrategicGLOpportunityDetailService>();
var mockSimpleSecurityServiceClient = new Mock<ISimpleSecurityService>();
var mockOpportunityRoleAssignmentServiceClient = new Mock<IOpportunityRoleAssignmentService>();
var mockBackgroundJobClient = new Mock<IBackgroundJobClient>();
var mockDistributionProcessFactory = new Mock<IDistributionProcessFactory>();
// Add mock responses
mockDataSchemaService.Setup(x =>
x.GetDataTableBySqlFullNameAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new DataTable());
mockDataSchemaService.Setup(x =>
x.GetDataColumnsBySqlColumnNameAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync([]);
mockDataSchemaService.Setup(x =>
x.BuildSqlQuery(It.IsAny<QueryConfig>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new SqlResponse
{
SqlQuery = DataSchemaServiceSelectSql,
Parameters = new List<KeyValuePair<string, object>>
{
new(":dischargedatetime_Start_0", new DateTime(2024, 1, 1)),
new(":dischargedatetime_End_1", new DateTime(2024, 12, 31)),
new(":chargecodeid_2", 3541)
}
});
mockSchemaServiceClient.Setup(x =>
x.GetDimensionByGlobalIdAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new Schema.Client.Dtos.Info.ScoreDimensionInfoDto());
var list = new List<HierarchyNodeDto>();
list.Add(new HierarchyNodeDto
{
Path = "CLINICALINDICATOR|CLINICALINDI|188",
Name = POPULATION_NAME
});
mockSchemaServiceClient.Setup(x =>
x.GetHierarchyNodesFromHierarchyPathsAsync(It.IsAny<Guid>(), It.IsAny<IEnumerable<string>>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(list);
mockSchemaServiceClient.Setup(x =>
x.GetDimensionMembersFromHierarchyPathsAsync(It.IsAny<Guid>(), It.IsAny<IEnumerable<string>>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new List<MemberDto> {
new MemberDto
{
Id = "188",
Name = "All Readmissions"
}});
var claimsPrincipalAccessor = TestUtilities.GetClaimsPrincipalAccessor();
_opportunityRoleAssignmentService = new OpportunityRoleAssignmentService(
(DbContexts.CentralDbContext)CentralDbContext,
mockIdServiceClient.Object,
mockSimpleSecurityServiceClient.Object,
claimsPrincipalAccessor
);
_strategicOpportunityService = new StrategicOpportunityService(
JazzConnBuilderFactory,
(DbContexts.CentralDbContext)CentralDbContext,
claimsPrincipalAccessor,
mockSchemaServiceClient.Object,
SnowflakeDatabaseContext,
mockIdServiceClient.Object,
_opportunityRoleAssignmentService,
mockIdRollupColumn.Object,
mockOpportunityWorkbookService.Object,
mockBackgroundJobClient.Object,
mockStrategicOpportunityDetailService.Object,
new StrategicItemDimensionSyncService(JazzConnBuilderFactory, (DbContexts.CentralDbContext)CentralDbContext, SnowflakeDatabaseContext),
mockStrategicGLOpportunityDetailService.Object,
(Microsoft.Extensions.Logging.ILogger<StrategicOpportunityService>)logger);
}
[Test, Ignore("temporarily ignoring because schema is out of sync")]
public async Task CreatingOpportunityShouldAlsoCreateDetails()
{
//arrange
var opportunity = CreateOpportunityDto();
//act
var result = await _strategicOpportunityService.CreateOpportunityChargeCodeAsync(opportunity, CancellationToken.None);
//assert
result.Should().Be(1, "On success should return opportunity id.");
}
private static StrategicOpportunityChargeCodeDto CreateOpportunityDto()
{
var opportunity = new StrategicOpportunityChargeCodeDto()
{
Name = "Integration-StrategicOpportunityChargeCode",
OpportunityType = StrategicOpportunityTypes.ChargeCode,
OpportunityFiltersJSON = "[]",
Rollup1Id = 0,
Rollup2Id = 0,
Rollup3Id = 0,
BaselineType = BaselineType.MonthRange,
BaselineDistribution = DistributionMethod.Average,
BaselineStartDate = new DateOnly(2024, 1, 1),
BaselineEndDate = new DateOnly(2024, 12, 31),
EstimatedTrackingDuration = 12,
// Assume empty or test collections for these
Measures = Enumerable.Empty<StrategicOpportunityMeasureDto>(),
WorkbookIds = Enumerable.Empty<int>(),
// ChargeCode-specific properties
PatientPopulationHPath = "CLINICALINDICATOR|CLINICALINDI|188",
ExplorationPopulationId = 0,
ChargeCodeHPath = "CC|CCRU|Blood"
};
return opportunity;
}
[Test]
public async Task UpdateStrategicOpportunityRampUpsAsync_ShouldUpdateRampUps()
{
// Arrange
var opportunity = CreateOpportunityDto();
var opportunityId = await _strategicOpportunityService.CreateOpportunityChargeCodeAsync(opportunity, CancellationToken.None);
var rampUps = new List<StrategicOpportunityRampUpDto>
{
new() { OpportunityId = opportunityId, MonthNumber = 1, Percentage = 0.1 },
new() { OpportunityId = opportunityId, MonthNumber = 2, Percentage = 0.2 }
};
// Act
var updateResult = await _strategicOpportunityService.UpdateStrategicOpportunityRampUpsAsync(opportunityId, rampUps, CancellationToken.None);
// Assert
updateResult.Should().BeTrue();
// Verify persisted values
var retrieved = await _strategicOpportunityService.GetStrategicOpportunityRampUpsAsync(opportunityId, CancellationToken.None);
retrieved.Should().HaveCount(rampUps.Count);
retrieved[0].MonthNumber.Should().Be(rampUps[0].MonthNumber);
retrieved[0].Percentage.Should().Be(rampUps[0].Percentage);
retrieved[1].MonthNumber.Should().Be(rampUps[1].MonthNumber);
retrieved[1].Percentage.Should().Be(rampUps[1].Percentage);
}
[Test]
public async Task ResetStrategicOpportunityRampUps_ShouldResetRampUps()
{
// Arrange
var opportunity = CreateOpportunityDto();
var opportunityId = await _strategicOpportunityService.CreateOpportunityChargeCodeAsync(opportunity, CancellationToken.None);
var rampUps = new List<StrategicOpportunityRampUpDto>
{
new() { OpportunityId = opportunityId, MonthNumber = 1, Percentage = 0.1 },
new() { OpportunityId = opportunityId, MonthNumber = 2, Percentage = 0.2 }
};
await _strategicOpportunityService.UpdateStrategicOpportunityRampUpsAsync(opportunityId, rampUps, CancellationToken.None);
// Act
var resetResult = await _strategicOpportunityService.ResetStrategicOpportunityRampUps(opportunityId, CancellationToken.None);
// Assert
resetResult.Should().BeTrue();
var retrieved = await _strategicOpportunityService.GetStrategicOpportunityRampUpsAsync(opportunityId, CancellationToken.None);
// Verify persisted values
retrieved.Should().HaveCount(rampUps.Count);
retrieved[0].Percentage.Should().Be(1);
retrieved[1].Percentage.Should().Be(1);
}
[Test]
public async Task ResetStrategicOpportunityRampUps_ShouldNotResetRampUps()
{
// Arrange
var opportunity = CreateOpportunityDto();
var opportunityId = await _strategicOpportunityService.CreateOpportunityChargeCodeAsync(opportunity, CancellationToken.None);
// Act
var resetResult = await _strategicOpportunityService.ResetStrategicOpportunityRampUps(opportunityId, CancellationToken.None);
// Assert
resetResult.Should().BeFalse();
}
[Test]
public async Task UpdateStrategicOpportunityRoleAssignment_ShouldUpdateRoleAssignments()
{
// Arrange
var opportunity = CreateOpportunityDto();
var opportunityId = await _strategicOpportunityService.CreateOpportunityChargeCodeAsync(opportunity, CancellationToken.None);
var roleAssignments = new List<OpportunityRoleAssignmentView>()
{
new OpportunityRoleAssignmentView() { LootId = opportunityId, IdentityGuid = Guid.NewGuid(), IdentityName = "Test", CanRead = true, CanWrite = true, CanSecure = false }
};
// Act
var saveResult = await _opportunityRoleAssignmentService.SaveRoleAssignmentsAsync(opportunityId, roleAssignments, CancellationToken.None);
// Assert
saveResult.Should().BeTrue();
// Verify persisted values
var retrieved = await _opportunityRoleAssignmentService.GetRoleAssignmentsAsync(opportunityId, CancellationToken.None);
var userPermission = await _opportunityRoleAssignmentService.GetUserRoleAssignmentsAsync(opportunityId, CancellationToken.None);
retrieved.Should().HaveCount(roleAssignments.Count);
var item = retrieved.FirstOrDefault();
item.LootId.Should().Be(opportunityId);
item.IdentityGuid.Should().Be(roleAssignments[0].IdentityGuid);
item.IdentityName.Should().Be(roleAssignments[0].IdentityName);
item.CanRead.Should().Be(roleAssignments[0].CanRead);
item.CanWrite.Should().Be(roleAssignments[0].CanWrite);
item.CanSecure.Should().Be(roleAssignments[0].CanSecure);
}
[Test]
public async Task GetStrategicOpportunityRampUpsAsync_ShouldReturnEmptyListIfNoneExist()
{
// Arrange
var nonExistentOpportunityId = long.MaxValue;
// Act
var rampUps = await _strategicOpportunityService.GetStrategicOpportunityRampUpsAsync(nonExistentOpportunityId, CancellationToken.None);
// Assert
rampUps.Should().NotBeNull();
rampUps.Should().BeEmpty();
}
[Test]
public async Task GetStrategicOpportunitiesAsync_ShouldReturnOpportunitiesWithRollupsAndPopulation()
{
// Arrange
var opportunity = CreateOpportunityDto();
var opportunityId = await _strategicOpportunityService.CreateOpportunityChargeCodeAsync(opportunity, CancellationToken.None);
// Act
var results = await _strategicOpportunityService.GetStrategicOpportunitiesAsync(CancellationToken.None);
// Assert
results.Should().NotBeEmpty("At least one opportunity should be returned");
var createdOpportunity = results.FirstOrDefault(o => o.OpportunityId == opportunityId);
createdOpportunity.Should().NotBeNull("Created opportunity should be found in results");
createdOpportunity.OpportunityId.Should().Be(opportunityId);
createdOpportunity.Name.Should().Be(opportunity.Name);
createdOpportunity.OpportunityTypeName.Should().Be("Charge Code");
createdOpportunity.EncounterGroupName.Should().Be("Patient Population", "When PatientPopulationHPath is set, it should be Patient Population");
createdOpportunity.AdditionalFilters.Should().Be("No");
createdOpportunity.BaselinePeriod.Should()
.Be($"{opportunity.BaselineStartDate:MMM d, yyyy} - {opportunity.BaselineEndDate:MMM d, yyyy}");
createdOpportunity.EstimatedTrackDurationMonths.Should().Be(opportunity.EstimatedTrackingDuration);
createdOpportunity.Rollup1.Should().BeEmpty("When rollup1Id is 0, rollup should be empty");
createdOpportunity.Rollup2.Should().BeEmpty("When rollup2Id is 0, rollup should be empty");
createdOpportunity.Rollup3.Should().BeEmpty("When rollup3Id is 0, rollup should be empty");
createdOpportunity.PatientPopulationHPath.Should().Be(opportunity.PatientPopulationHPath);
createdOpportunity.ExplorationPopulationId.Should().Be(opportunity.ExplorationPopulationId);
createdOpportunity.Population.Should().Be(POPULATION_NAME);
}
[Test]
public async Task UpdateStrategicOpportunityStatus_WhenNewInitiative_ShouldUpdateStatusAndDates()
{
// Arrange
var opportunity = CreateOpportunityDto();
var opportunityId = await _strategicOpportunityService.CreateOpportunityChargeCodeAsync(opportunity, CancellationToken.None);
var updateStatusDto = new StrategicOpportunityUpdateStatusDto
{
Status = (byte)StrategicOpportunityStatus.NewInitiative,
TrackingStartDate = new DateOnly(2024, 1, 1),
TrackingEndDate = new DateOnly(2024, 12, 31)
};
// Act
var updateResult = await _strategicOpportunityService.UpdateStrategicOpportunityStatus(opportunityId, updateStatusDto, CancellationToken.None);
// Assert
updateResult.Should().BeTrue("Update should be successful");
var strataId = TestUtilities.GetClaimsPrincipalAccessor()?.GetCurrentClaimsPrincipal().GetStrataId();
var opportunityAfterUpdate = await CentralDbContext.StrategicOpportunities
.FirstOrDefaultAsync(x => x.OpportunityId == opportunityId && x.StrataId == strataId, CancellationToken.None);
opportunityAfterUpdate.Should().NotBeNull("Updated opportunity should exist");
opportunityAfterUpdate.Status.Should().Be(updateStatusDto.Status, "Status should be updated to NewInitiative");
opportunityAfterUpdate.TrackingStartDate.Should().Be(updateStatusDto.TrackingStartDate, "TrackingStartDate should be updated");
opportunityAfterUpdate.TrackingEndDate.Should().Be(updateStatusDto.TrackingEndDate, "TrackingEndDate should be updated");
}
[Test]
public async Task UpdateStrategicOpportunityStatus_WhenNewOpportunity_ShouldResetTrackingData()
{
// Arrange
var opportunity = CreateOpportunityDto();
var opportunityId = await _strategicOpportunityService.CreateOpportunityChargeCodeAsync(opportunity, CancellationToken.None);
var toInitiativeDto = new StrategicOpportunityUpdateStatusDto
{
Status = (byte)StrategicOpportunityStatus.NewInitiative,
TrackingStartDate = new DateOnly(2024, 1, 1),
TrackingEndDate = new DateOnly(2024, 12, 31)
};
await _strategicOpportunityService.UpdateStrategicOpportunityStatus(opportunityId, toInitiativeDto, CancellationToken.None);
var toOpportunityDto = new StrategicOpportunityUpdateStatusDto
{
Status = (byte)StrategicOpportunityStatus.NewOpportunity
};
// Act
var updateResult = await _strategicOpportunityService.UpdateStrategicOpportunityStatus(opportunityId, toOpportunityDto, CancellationToken.None);
// Assert
updateResult.Should().BeTrue("Update should be successful");
var strataId = TestUtilities.GetClaimsPrincipalAccessor()?.GetCurrentClaimsPrincipal().GetStrataId();
var opportunityAfterUpdate = await CentralDbContext.StrategicOpportunityChargeCodes
.FirstOrDefaultAsync(x => x.OpportunityId == opportunityId && x.StrataId == strataId, CancellationToken.None);
opportunityAfterUpdate.Should().NotBeNull("Updated opportunity should exist");
opportunityAfterUpdate.Status.Should().Be((byte)StrategicOpportunityStatus.NewOpportunity, "Status should be reset to NewOpportunity");
opportunityAfterUpdate.TrackingStartDate.Should().Be(default(DateOnly), "TrackingStartDate should be reset to default");
opportunityAfterUpdate.TrackingEndDate.Should().Be(default(DateOnly), "TrackingEndDate should be reset to default");
opportunityAfterUpdate.LastRunTrackingDate.Should().BeNull("LastRunTrackingDate should be cleared");
opportunityAfterUpdate.LastRunTrackingStatus.Should().Be(RunTrackingStatus.None, "LastRunTrackingStatus should be reset to None");
opportunityAfterUpdate.ProgressToDateActual.Should().Be(0, "ProgressToDateActual should be reset to 0");
opportunityAfterUpdate.ProgressToDateCommitted.Should().Be(0, "ProgressToDateCommitted should be reset to 0");
}
[Test]
public async Task UpdateStrategicOpportunityStatus_WhenOtherStatus_ShouldOnlyUpdateStatus()
{
// Arrange
var opportunity = CreateOpportunityDto();
var opportunityId = await _strategicOpportunityService.CreateOpportunityChargeCodeAsync(opportunity, CancellationToken.None);
var toInitiativeDto = new StrategicOpportunityUpdateStatusDto
{
Status = (byte)StrategicOpportunityStatus.NewInitiative,
TrackingStartDate = new DateOnly(2024, 1, 1),
TrackingEndDate = new DateOnly(2024, 12, 31)
};
await _strategicOpportunityService.UpdateStrategicOpportunityStatus(opportunityId, toInitiativeDto, CancellationToken.None);
var toInValidationDto = new StrategicOpportunityUpdateStatusDto
{
Status = (byte)StrategicOpportunityStatus.InValidation
};
// Act
var updateResult = await _strategicOpportunityService.UpdateStrategicOpportunityStatus(opportunityId, toInValidationDto, CancellationToken.None);
// Assert
updateResult.Should().BeTrue("Update should be successful");
var strataId = TestUtilities.GetClaimsPrincipalAccessor()?.GetCurrentClaimsPrincipal().GetStrataId();
var opportunityAfterUpdate = await CentralDbContext.StrategicOpportunityChargeCodes
.FirstOrDefaultAsync(x => x.OpportunityId == opportunityId && x.StrataId == strataId, CancellationToken.None);
opportunityAfterUpdate.Should().NotBeNull("Updated opportunity should exist");
opportunityAfterUpdate.Status.Should().Be((byte)StrategicOpportunityStatus.InValidation, "Status should be updated to InValidation");
opportunityAfterUpdate.TrackingStartDate.Should().Be(toInitiativeDto.TrackingStartDate, "TrackingStartDate should be unchanged");
opportunityAfterUpdate.TrackingEndDate.Should().Be(toInitiativeDto.TrackingEndDate, "TrackingEndDate should be unchanged");
}
[Test]
public async Task UpdateStrategicOpportunityStatus_WhenOpportunityNotFound_ShouldReturnFalse()
{
// Arrange
var nonExistentOpportunityId = long.MaxValue;
var updateStatusDto = new StrategicOpportunityUpdateStatusDto
{
Status = (byte)StrategicOpportunityStatus.NewOpportunity
};
// Act
var result = await _strategicOpportunityService.UpdateStrategicOpportunityStatus(nonExistentOpportunityId, updateStatusDto, CancellationToken.None);
// Assert
result.Should().BeFalse("Update should return false when the opportunity does not exist");
}
[Test]
public async Task CopyStrategicOpportunityRoleAssignments_ShouldReturnEmptyList()
{
// Arrange
var opportunity = CreateOpportunityDto();
var opportunityId = await _strategicOpportunityService.CreateOpportunityChargeCodeAsync(opportunity, CancellationToken.None);
// Act
var newOpportunityId = opportunityId + 1;
await _opportunityRoleAssignmentService.CopyTo(opportunityId, newOpportunityId, CancellationToken.None);
// Assert
var newRoles = await _opportunityRoleAssignmentService.GetRoleAssignmentsAsync(newOpportunityId, CancellationToken.None);
newRoles.Should().BeEmpty();
}
[Test]
public async Task CopyStrategicOpportunityRoleAssignments_ShouldReturnRoleAssignments()
{
// Arrange
var opportunity = CreateOpportunityDto();
var opportunityId = await _strategicOpportunityService.CreateOpportunityChargeCodeAsync(opportunity, CancellationToken.None);
var roleAssignments = new List<OpportunityRoleAssignmentView>()
{
new() { LootId = opportunityId, IdentityGuid = Guid.NewGuid(), IdentityName = "Test1", CanRead = true, CanWrite = false, CanSecure = true },
new() { LootId = opportunityId, IdentityGuid = Guid.NewGuid(), IdentityName = "Test2", CanRead = false, CanWrite = true, CanSecure = false },
};
await _opportunityRoleAssignmentService.SaveRoleAssignmentsAsync(opportunityId, roleAssignments, CancellationToken.None);
// Act
var newOpportunityId = opportunityId + 1;
await _opportunityRoleAssignmentService.CopyTo(opportunityId, newOpportunityId, CancellationToken.None);
// Assert
var newRoles = await _opportunityRoleAssignmentService.GetRoleAssignmentsAsync(newOpportunityId, CancellationToken.None);
// Verify persisted values
var retrieved = newRoles.ToList();
retrieved.Should().HaveCount(roleAssignments.Count);
CompareRoleAssignments(retrieved[0], roleAssignments[0]);
CompareRoleAssignments(retrieved[1], roleAssignments[1]);
}
private static void CompareRoleAssignments(OpportunityRoleAssignmentView item1, OpportunityRoleAssignmentView item2)
{
item1.IdentityGuid.Should().Be(item2.IdentityGuid);
item1.IdentityName.Should().Be(item2.IdentityName);
item1.CanRead.Should().Be(item2.CanRead);
item1.CanWrite.Should().Be(item2.CanWrite);
item1.CanSecure.Should().Be(item2.CanSecure);
}
public string DataSchemaServiceSelectSql = @"SELECT
""EncounterId"",
""DischargeDateTime"",
""EntityID"",
""PhysicianId"",
""PrimaryServiceLineId"",
""CPTCodeCaseTypeFamilyId"",
""MSDRGCaseTypeFamilyId"",
""APRDRGCaseTypeFamilyId"",
""DepartmentId"",
""PhysicianSpecialtyId"",
""ChargeCodeID"",
""CostDriver"",
""PatientTypeRollup"",
ZEROIFNULL(""Units"") AS ""Units"",
ZEROIFNULL(""Cost"") AS ""Cost""
FROM (
SELECT
""EncounterId"",
""DischargeDateTime"",
""EntityID"",
""PhysicianId"",
""PrimaryServiceLineId"",
""CPTCodeCaseTypeFamilyId"",
""MSDRGCaseTypeFamilyId"",
""APRDRGCaseTypeFamilyId"",
""DepartmentId"",
""PhysicianSpecialtyId"",
""ChargeCodeID"",
""CostDriver"",
""PatientTypeRollup"",
SUM(""Units"") AS ""Units"",
SUM(""Cost"") AS ""Cost""
FROM (
SELECT
DSSPES.encounterid AS ""EncounterId"",
DSSPES.dischargedatetime AS ""DischargeDateTime"",
DSSPES.entityid AS ""EntityID"",
DSSPES.primaryphysicianid AS ""PhysicianId"",
DSSPES.servicelineid AS ""PrimaryServiceLineId"",
DSSPES.cptcodecasetypefamilyid AS ""CPTCodeCaseTypeFamilyId"",
DSSPES.msdrgcasetypefamilyid AS ""MSDRGCaseTypeFamilyId"",
DSSPES.aprdrgcasetypefamilyid AS ""APRDRGCaseTypeFamilyId"",
PBLID.departmentid AS ""DepartmentId"",
PHYSPRIMARY.physicianspecialtyid AS ""PhysicianSpecialtyId"",
CC.chargecodeid AS ""ChargeCodeID"",
IFNULL(CC.costdriver::TEXT, '') AS ""CostDriver"",
IFNULL(EncounterPatientTypeRollup.patienttyperollup::TEXT, '') AS ""PatientTypeRollup"",
NULL AS ""Cost"",
SUM(PBLID.unitsofservice) AS ""Units""
FROM dss.FactPatientBillingLineItemDetail AS PBLID
INNER JOIN clientdss.FactPatientEncounterSummary AS DSSPES ON DSSPES.encounterrecordnumber = PBLID.encounterrecordnumber
LEFT JOIN dss.FactPatientEncounterClinicalIndicator AS DSSPECI ON DSSPECI.encounterid = PBLID.encounterid
LEFT JOIN CCI.VIEWENCOUNTERPATIENTTYPEROLLUP AS EncounterPatientTypeRollup ON EncounterPatientTypeRollup.encounterid = PBLID.encounterid
INNER JOIN FW.DIMCHARGECODE AS CC ON CC.chargecodeid = PBLID.chargecodeid
INNER JOIN DSS.DIMPHYSICIAN AS PHYSPRIMARY ON PHYSPRIMARY.physicianid = DSSPES.primaryphysicianid
WHERE
((DSSPES.dischargedatetime >= :dischargedatetime_Start_0 AND DSSPES.dischargedatetime <= :dischargedatetime_End_1) AND CC.chargecodeid IN (:chargecodeid_2))
GROUP BY
""EncounterId"",
""DischargeDateTime"",
""EntityID"",
""PhysicianId"",
""PrimaryServiceLineId"",
""CPTCodeCaseTypeFamilyId"",
""MSDRGCaseTypeFamilyId"",
""APRDRGCaseTypeFamilyId"",
""DepartmentId"",
""PhysicianSpecialtyId"",
""ChargeCodeID"",
""CostDriver"",
""PatientTypeRollup""
UNION ALL
SELECT
DSSPES.encounterid AS ""EncounterId"",
DSSPES.dischargedatetime AS ""DischargeDateTime"",
DSSPES.entityid AS ""EntityID"",
DSSPES.primaryphysicianid AS ""PhysicianId"",
DSSPES.servicelineid AS ""PrimaryServiceLineId"",
DSSPES.cptcodecasetypefamilyid AS ""CPTCodeCaseTypeFamilyId"",
DSSPES.msdrgcasetypefamilyid AS ""MSDRGCaseTypeFamilyId"",
DSSPES.aprdrgcasetypefamilyid AS ""APRDRGCaseTypeFamilyId"",
PBLID.departmentid AS ""DepartmentId"",
PHYSPRIMARY.physicianspecialtyid AS ""PhysicianSpecialtyId"",
CC.chargecodeid AS ""ChargeCodeID"",
IFNULL(CC.costdriver::TEXT, '') AS ""CostDriver"",
IFNULL(EncounterPatientTypeRollup.patienttyperollup::TEXT, '') AS ""PatientTypeRollup"",
SUM(COSTDETAIL.variabledirectcost) AS ""Cost"",
NULL AS ""Units""
FROM dss.FactPatientCostDetail AS COSTDETAIL
RIGHT JOIN dss.FactPatientBillingLineItemDetail AS PBLID ON PBLID.rowid = COSTDETAIL.pblidrowid
INNER JOIN clientdss.FactPatientEncounterSummary AS DSSPES ON DSSPES.encounterrecordnumber = PBLID.encounterrecordnumber
LEFT JOIN dss.FactPatientEncounterClinicalIndicator AS DSSPECI ON DSSPECI.encounterid = PBLID.encounterid
LEFT JOIN CCI.VIEWENCOUNTERPATIENTTYPEROLLUP AS EncounterPatientTypeRollup ON EncounterPatientTypeRollup.encounterid = PBLID.encounterid
INNER JOIN FW.DIMCHARGECODE AS CC ON CC.chargecodeid = PBLID.chargecodeid
INNER JOIN DSS.DIMPHYSICIAN AS PHYSPRIMARY ON PHYSPRIMARY.physicianid = DSSPES.primaryphysicianid
WHERE
((DSSPES.dischargedatetime >= :dischargedatetime_Start_0 AND DSSPES.dischargedatetime <= :dischargedatetime_End_1) AND CC.chargecodeid IN (:chargecodeid_2))
GROUP BY
""EncounterId"",
""DischargeDateTime"",
""EntityID"",
""PhysicianId"",
""PrimaryServiceLineId"",
""CPTCodeCaseTypeFamilyId"",
""MSDRGCaseTypeFamilyId"",
""APRDRGCaseTypeFamilyId"",
""DepartmentId"",
""PhysicianSpecialtyId"",
""ChargeCodeID"",
""CostDriver"",
""PatientTypeRollup""
)
GROUP BY
""EncounterId"",
""DischargeDateTime"",
""EntityID"",
""PhysicianId"",
""PrimaryServiceLineId"",
""CPTCodeCaseTypeFamilyId"",
""MSDRGCaseTypeFamilyId"",
""APRDRGCaseTypeFamilyId"",
""DepartmentId"",
""PhysicianSpecialtyId"",
""ChargeCodeID"",
""CostDriver"",
""PatientTypeRollup""
)
ORDER BY
""EncounterId"" ASC NULLS FIRST,
""DischargeDateTime"" ASC NULLS FIRST,
""EntityID"" ASC NULLS FIRST,
""PhysicianId"" ASC NULLS FIRST,
""PrimaryServiceLineId"" ASC NULLS FIRST,
""CPTCodeCaseTypeFamilyId"" ASC NULLS FIRST,
""MSDRGCaseTypeFamilyId"" ASC NULLS FIRST,
""APRDRGCaseTypeFamilyId"" ASC NULLS FIRST,
""DepartmentId"" ASC NULLS FIRST,
""PhysicianSpecialtyId"" ASC NULLS FIRST,
""ChargeCodeID"" ASC NULLS FIRST,
""CostDriver"" ASC NULLS FIRST,
""PatientTypeRollup"" ASC NULLS FIRST
";
}
}