Skip to content

Commit

Permalink
Tests passing
Browse files Browse the repository at this point in the history
  • Loading branch information
haworku committed Sep 1, 2023
1 parent b70b14a commit 02f72bf
Show file tree
Hide file tree
Showing 9 changed files with 456 additions and 137 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import { contractRevisionWithRatesSchema } from './revisionTypes'
// submissions are kept intact here across time
const contractSchema = z.object({
id: z.string().uuid(),
status: z.union([z.literal('SUBMITTED'), z.literal('DRAFT')]),
status: z.union([
z.literal('SUBMITTED'),
z.literal('DRAFT'),
z.literal('UNLOCKED'),
z.literal('RESUBMITTED'),
]),
stateCode: z.string(),
stateNumber: z.number().min(1),
// If this contract is in a DRAFT or UNLOCKED status, there will be a draftRevision
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import type {
SubmissionDocument,
UnlockedHealthPlanFormDataType,
} from 'app-web/src/common-code/healthPlanFormDataType'
import type {
HealthPlanPackageType,
HealthPlanRevisionType,
} from '../HealthPlanPackageType'
import type { ContractType } from './contractTypes'
import {
toDomain,
toProtoBuffer,
} from 'app-web/src/common-code/proto/healthPlanFormDataProto'

function convertContractToUnlockedHealthPlanPackage(
contract: ContractType
): HealthPlanPackageType | Error {
console.info('Attempting to convert contract to health plan package')

// Since drafts come in separate on the Contract type, we push it onto the revisions before converting below
if (contract.draftRevision) {
contract.revisions.unshift(contract.draftRevision)
}

const healthPlanRevisions =
convertContractRevisionToHealthPlanRevision(contract)

if (healthPlanRevisions instanceof Error) {
return healthPlanRevisions
}

return {
id: contract.id,
stateCode: contract.stateCode,
revisions: healthPlanRevisions,
}
}

function convertContractRevisionToHealthPlanRevision(
contract: ContractType
): HealthPlanRevisionType[] | Error {
if (contract.status !== 'DRAFT') {
return new Error(
`Contract with ID: ${contract.id} status is not "DRAFT". Cannot convert to unlocked health plan package`
)
}

let healthPlanRevisions: HealthPlanRevisionType[] | Error = []
for (const contractRev of contract.revisions) {
const unlockedHealthPlanFormData: UnlockedHealthPlanFormDataType = {
id: contractRev.id,
createdAt: contractRev.createdAt,
updatedAt: contractRev.updatedAt,
status: contract.status,
stateCode: contract.stateCode,
stateNumber: contract.stateNumber,
programIDs: contractRev.formData.programIDs,
populationCovered: contractRev.formData.populationCovered,
submissionType: contractRev.formData.submissionType,
riskBasedContract: contractRev.formData.riskBasedContract,
submissionDescription: contractRev.formData.submissionDescription,
stateContacts: contractRev.formData.stateContacts,
addtlActuaryCommunicationPreference: undefined,
addtlActuaryContacts: [],
documents: contractRev.formData.supportingDocuments.map((doc) => ({
...doc,
documentCategories: ['CONTRACT_RELATED'],
})) as SubmissionDocument[],
contractType: contractRev.formData.contractType,
contractExecutionStatus:
contractRev.formData.contractExecutionStatus,
contractDocuments: contractRev.formData.contractDocuments.map(
(doc) => ({
...doc,
documentCategories: ['CONTRACT'],
})
) as SubmissionDocument[],
contractDateStart: contractRev.formData.contractDateStart,
contractDateEnd: contractRev.formData.contractDateEnd,
managedCareEntities: contractRev.formData.managedCareEntities,
federalAuthorities: contractRev.formData.federalAuthorities,
contractAmendmentInfo: {
modifiedProvisions: {
inLieuServicesAndSettings:
contractRev.formData.inLieuServicesAndSettings,
modifiedBenefitsProvided:
contractRev.formData.modifiedBenefitsProvided,
modifiedGeoAreaServed:
contractRev.formData.modifiedGeoAreaServed,
modifiedMedicaidBeneficiaries:
contractRev.formData.modifiedMedicaidBeneficiaries,
modifiedRiskSharingStrategy:
contractRev.formData.modifiedRiskSharingStrategy,
modifiedIncentiveArrangements:
contractRev.formData.modifiedIncentiveArrangements,
modifiedWitholdAgreements:
contractRev.formData.modifiedWitholdAgreements,
modifiedStateDirectedPayments:
contractRev.formData.modifiedStateDirectedPayments,
modifiedPassThroughPayments:
contractRev.formData.modifiedPassThroughPayments,
modifiedPaymentsForMentalDiseaseInstitutions:
contractRev.formData
.modifiedPaymentsForMentalDiseaseInstitutions,
modifiedMedicalLossRatioStandards:
contractRev.formData.modifiedMedicalLossRatioStandards,
modifiedOtherFinancialPaymentIncentive:
contractRev.formData
.modifiedOtherFinancialPaymentIncentive,
modifiedEnrollmentProcess:
contractRev.formData.modifiedEnrollmentProcess,
modifiedGrevienceAndAppeal:
contractRev.formData.modifiedGrevienceAndAppeal,
modifiedNetworkAdequacyStandards:
contractRev.formData.modifiedNetworkAdequacyStandards,
modifiedLengthOfContract:
contractRev.formData.modifiedLengthOfContract,
modifiedNonRiskPaymentArrangements:
contractRev.formData.modifiedNonRiskPaymentArrangements,
},
},
rateInfos: [],
}

const formDataProto = toProtoBuffer(unlockedHealthPlanFormData)

// check that we can encode then decode with no issues
const domainData = toDomain(formDataProto)

// If any revision has en error in decoding we break the loop and return an error
if (domainData instanceof Error) {
healthPlanRevisions = new Error(
`Could not convert contract revision with ID: ${contractRev.id} to health plan package revision: ${domainData}`
)
break
}

const healthPlanRevision: HealthPlanRevisionType = {
id: contractRev.id,
unlockInfo: contractRev.unlockInfo,
submitInfo: contractRev.submitInfo,
createdAt: contractRev.createdAt,
formDataProto,
}

healthPlanRevisions.push(healthPlanRevision)
}

return healthPlanRevisions
}

export {
convertContractRevisionToHealthPlanRevision,
convertContractToUnlockedHealthPlanPackage,
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import {

const rateSchema = z.object({
id: z.string().uuid(),
status: z.union([z.literal('SUBMITTED'), z.literal('DRAFT')]),
status: z.union([
z.literal('SUBMITTED'),
z.literal('DRAFT'),
z.literal('UNLOCKED'),
z.literal('RESUBMITTED'),
]),
stateCode: z.string(),
stateNumber: z.number().min(1),
// If this rate is in a DRAFT or UNLOCKED status, there will be a draftRevision
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
contractFormDataToDomainModel,
convertUpdateInfoToDomainModel,
ratesRevisionsToDomainModel,
getContractStatus,
getContractRateStatus,
} from './prismaSharedContractRateHelpers'
import type { ContractTableFullPayload } from './prismaSubmittedContractHelpers'

Expand Down Expand Up @@ -177,11 +177,11 @@ function contractWithHistoryToDomainModel(

return {
id: contract.id,
status: getContractStatus(contract.revisions),
status: getContractRateStatus(contract.revisions),
stateCode: contract.stateCode,
stateNumber: contract.stateNumber,
draftRevision,
revisions
revisions,
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {
RateRevisionWithContractsType,
RateType,
RateRevisionType
RateRevisionType,
} from '../../domain-models/contractAndRates'
import { rateSchema } from '../../domain-models/contractAndRates'
import { contractRevisionsToDomainModels } from './parseContractWithHistory'
Expand All @@ -13,7 +13,7 @@ import type {
} from './prismaSharedContractRateHelpers'
import {
convertUpdateInfoToDomainModel,
getContractStatus,
getContractRateStatus,
rateFormDataToDomainModel,
} from './prismaSharedContractRateHelpers'
import type { RateTableFullPayload } from './prismaSubmittedRateHelpers'
Expand Down Expand Up @@ -88,7 +88,7 @@ function rateRevisionsToDomainModels(
function rateWithHistoryToDomainModel(
rate: RateTableFullPayload
): RateType | Error {
// so you get all the rate revisions. each one has a bunch of contracts
// so you get all the rate revisions. each one has a bunch of contracts
// each set of contracts gets its own "revision" in the return list
// further rateRevs naturally are their own "revision"

Expand Down Expand Up @@ -168,11 +168,11 @@ function rateWithHistoryToDomainModel(

return {
id: rate.id,
status: getContractStatus(rate.revisions),
status: getContractRateStatus(rateRevisions),
stateCode: rate.stateCode,
stateNumber: rate.stateNumber,
draftRevision,
revisions
revisions,
}
}
export {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Prisma, UpdateInfoTable } from '@prisma/client'
import type { Prisma } from '@prisma/client'
import type { DocumentCategoryType } from 'app-web/src/common-code/healthPlanFormDataType'
import type {
ContractFormDataType,
Expand Down Expand Up @@ -35,19 +35,28 @@ function convertUpdateInfoToDomainModel(
}

// -----

function getContractStatus(
revision: {
createdAt: Date
submitInfo: UpdateInfoTable | null
}[]
function getContractRateStatus(
revisions:
| ContractRevisionTableWithFormData[]
| RateRevisionTableWithFormData[]
): ContractStatusType {
// need to order revisions from latest to earliest
const latestToEarliestRev = revision.sort(
const revs = revisions.sort(
(revA, revB) => revB.createdAt.getTime() - revA.createdAt.getTime()
)
const latestRevision = latestToEarliestRev[0]
return latestRevision?.submitInfo ? 'SUBMITTED' : 'DRAFT'
const latestRevision = revs[0]
// submitted - one revision with submission status
if (revs.length === 1 && latestRevision.submitInfo) {
return 'SUBMITTED'
} else if (revs.length > 1) {
// unlocked - multiple revs, latest revision has unlocked status and no submitted status
// resubmitted - multiple revs, latest revision has submitted status
if (latestRevision.submitInfo) {
return 'RESUBMITTED'
}
return 'UNLOCKED'
}
return 'DRAFT'
}

// ------
Expand Down Expand Up @@ -248,7 +257,7 @@ export {
includeUpdateInfo,
includeContractFormData,
includeRateFormData,
getContractStatus,
getContractRateStatus,
convertUpdateInfoToDomainModel,
contractFormDataToDomainModel,
rateFormDataToDomainModel,
Expand Down
Loading

0 comments on commit 02f72bf

Please sign in to comment.