Skip to content

Commit

Permalink
MCR-4862: update-withdrawRate-api-to-drop-withdrawn-rates (#3045)
Browse files Browse the repository at this point in the history
* Drop withdrawn rates from draft and unlocked contracts

* Test to make sure unlocked contracts previously submitted with rate get emails.

* Clean up

* Fix pre-commit

* Fix rollback in withdrawRate transaction

* cypress re-run

* Add longer timeout
  • Loading branch information
JasonLin0991 authored Jan 2, 2025
1 parent 011f8a5 commit 7d5c5f5
Show file tree
Hide file tree
Showing 5 changed files with 325 additions and 165 deletions.
3 changes: 0 additions & 3 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#!/bin/bash
. "$(dirname "$0")/_/husky.sh"

# In a continuing effort to print errors when they are needed, we check for
# all pre-commit dependency requirements here.
requirements=("protolint" "shellcheck" "detect-secrets")
Expand Down
77 changes: 51 additions & 26 deletions services/app-api/src/emailer/emails/sendWithdrawnRateStateEmail.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
import { formatCalendarDate } from '@mc-review/dates';
import { ProgramType, RateType } from "../../domain-models";
import { EmailData } from "../emailer";
import { EmailConfiguration } from "../emailer";
import { findContractPrograms, renderTemplate, stripHTMLFromTemplate } from "../templateHelpers";
import { formatCalendarDate } from '@mc-review/dates'
import type { ProgramType, RateType } from '../../domain-models'
import type { EmailData } from '../emailer'
import type { EmailConfiguration } from '../emailer'
import {
findContractPrograms,
renderTemplate,
stripHTMLFromTemplate,
} from '../templateHelpers'
import { packageName as generatePackageName } from '@mc-review/hpp'
import { submissionSummaryURL } from '../generateURLs';
import { pruneDuplicateEmails } from '../formatters';
import { submissionSummaryURL } from '../generateURLs'
import { pruneDuplicateEmails } from '../formatters'

type WithdrawnFromContractData = {
contractName: string,
contractName: string
submissionURL: string
}

type WithdrawnRateEtaData = {
rateName: string,
withdrawnBy: string, //email
withdrawnDate: string, // mm/dd/yyyy format in PT timezone.
withdrawnReason: string,
rateName: string
withdrawnBy: string //email
withdrawnDate: string // mm/dd/yyyy format in PT timezone.
withdrawnReason: string
withdrawnFromContractData: WithdrawnFromContractData[]
}

export const sendWithdrawnRateStateEmail = async (
config: EmailConfiguration,
rate: RateType,
statePrograms: ProgramType[]
config: EmailConfiguration,
rate: RateType,
statePrograms: ProgramType[]
): Promise<EmailData | Error> => {
if (rate.consolidatedStatus !== 'WITHDRAWN') {
return new Error('Rate consolidated status is not WITHDRAWN')
Expand All @@ -37,7 +41,10 @@ export const sendWithdrawnRateStateEmail = async (
return new Error('Rate does not any have review actions')
}

const latestAction = reviewStatusActions.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())[0]
const latestAction = reviewStatusActions.sort(
(a, b) =>
new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
)[0]

if (latestAction.actionType !== 'WITHDRAW') {
return new Error('Rate latest review action was not a withdraw action')
Expand All @@ -47,19 +54,31 @@ export const sendWithdrawnRateStateEmail = async (
const withdrawnFromContracts = rate.withdrawnFromContracts

if (!withdrawnFromContracts || withdrawnFromContracts.length === 0) {
return new Error('Rate was withdrawn, but was not associated with any contracts')
return new Error(
'Rate was withdrawn, but was not associated with any contracts'
)
}

const stateContactEmails: string[] = []
const withdrawnFromContractData = []

// parse contract data and collect state contact emails
for (const contract of withdrawnFromContracts) {
const latestContractRev = contract.packageSubmissions[0].contractRevision
const pkgPrograms = findContractPrograms(latestContractRev, statePrograms)
// Get latest revision to generate package name. Use draft revision if contract is unlocked.
const latestContractRev =
contract.consolidatedStatus === 'UNLOCKED'
? contract.draftRevision!
: contract.packageSubmissions[0].contractRevision

const pkgPrograms = findContractPrograms(
latestContractRev,
statePrograms
)

if (pkgPrograms instanceof Error) {
return new Error(`Error parsing withdrawn from contract data for contract with ID: ${contract.id}. ${pkgPrograms.message}`)
return new Error(
`Error parsing withdrawn from contract data for contract with ID: ${contract.id}. ${pkgPrograms.message}`
)
}

const packageName = generatePackageName(
Expand All @@ -73,7 +92,7 @@ export const sendWithdrawnRateStateEmail = async (

withdrawnFromContractData.push({
contractName: packageName,
submissionURL
submissionURL,
})

latestContractRev.formData.stateContacts.forEach((contact) => {
Expand All @@ -83,18 +102,24 @@ export const sendWithdrawnRateStateEmail = async (

const toAddresses = pruneDuplicateEmails([
...stateContactEmails,
...config.devReviewTeamEmails
...config.devReviewTeamEmails,
])

const etaData: WithdrawnRateEtaData = {
rateName: latestRateRev.formData.rateCertificationName!,
withdrawnBy: latestAction.updatedBy.email,
withdrawnDate: formatCalendarDate(latestAction.updatedAt, 'America/Los_Angeles'),
withdrawnDate: formatCalendarDate(
latestAction.updatedAt,
'America/Los_Angeles'
),
withdrawnReason: latestAction.updatedReason,
withdrawnFromContractData,
}

const template = await renderTemplate<WithdrawnRateEtaData>('sendWithdrawnRateStateEmail', etaData)
const template = await renderTemplate<WithdrawnRateEtaData>(
'sendWithdrawnRateStateEmail',
etaData
)

if (template instanceof Error) {
return template
Expand All @@ -107,7 +132,7 @@ export const sendWithdrawnRateStateEmail = async (
config.stage !== 'prod' ? `[${config.stage}] ` : ''
}${etaData.rateName} was withdrawn`,
bodyText: stripHTMLFromTemplate(template),
bodyHTML: template
bodyHTML: template,
}
}
}
}
Loading

0 comments on commit 7d5c5f5

Please sign in to comment.