Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MCR-4663: Withdrawn rates shown on summary and review submit page #3065

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions services/app-web/src/components/InfoTag/InfoTag.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
color: custom.$mcr-foundation-ink;
}

.gray-medium {
@include uswds.u-bg('gray-60');
color: custom.$mcr-foundation-white;
}

.light-green {
@include uswds.u-bg('green-cool-20v');
color: custom.$mcr-foundation-ink;
Expand Down
10 changes: 9 additions & 1 deletion services/app-web/src/components/InfoTag/InfoTag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ Main application-wide tag to draw attention to key info.
This is a react-uswds Tag enhanced with CMS styles.
*/
export type TagProps = {
color: 'green' | 'gold' | 'cyan' | 'blue' | 'light green' | 'gray'
color:
| 'green'
| 'gold'
| 'cyan'
| 'blue'
| 'light green'
| 'gray'
| 'gray-medium'
emphasize?: boolean
} & ComponentProps<typeof USWDSTag>

Expand All @@ -28,6 +35,7 @@ export const InfoTag = ({
[styles['gold']]: color === 'gold',
[styles['blue']]: color === 'blue',
[styles['gray']]: color === 'gray',
[styles['gray-medium']]: color === 'gray-medium',
},
emphasize ? styles['emphasize'] : undefined,
className
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,6 @@ describe('RateDetailsSummarySection', () => {
// Is this the best way to check that the link is not present?
expect(screen.queryByText('Edit')).not.toBeInTheDocument()

//expects loading button on component load
expect(screen.getByText('Loading')).toBeInTheDocument()

// expects download all button after loading has completed
await waitFor(() => {
expect(
Expand Down Expand Up @@ -1253,6 +1250,7 @@ describe('RateDetailsSummarySection', () => {
).toBeInTheDocument()
})
})

it('displays deprecated fields on previous submissions viewed by state users', async () => {
vi.spyOn(
usePreviousSubmission,
Expand Down Expand Up @@ -1301,6 +1299,7 @@ describe('RateDetailsSummarySection', () => {
screen.findByText('Programs this rate certification covers')
).toBeTruthy()
})

it('does not display deprecated fields on unlocked submissions for state users', async () => {
const draftContract = mockContractPackageDraft()
if (
Expand Down Expand Up @@ -1333,4 +1332,135 @@ describe('RateDetailsSummarySection', () => {
screen.queryByText('Programs this rate certification covers')
).toBeNull()
})

it('displays withdrawn rates', async () => {
const contractWithWithdrawnRates = mockContractPackageSubmitted({
withdrawnRates: [
{
id: '1234',
webURL: 'https://testmcreview.example/rates/1234',
createdAt: new Date('01/01/2021'),
updatedAt: new Date('01/01/2021'),
status: 'SUBMITTED',
reviewStatus: 'WITHDRAWN',
consolidatedStatus: 'WITHDRAWN',
state: mockMNState(),
stateCode: 'MN',
stateNumber: 5,
parentContractID: 'test-abc-123',
revisions: [],
packageSubmissions: [
{
cause: 'CONTRACT_SUBMISSION',
submitInfo: {
updatedAt: new Date('01/01/2021'),
updatedBy: {
email: '[email protected]',
familyName: 'Hotman',
givenName: 'Zuko',
role: 'CMS_USER',
},
updatedReason: 'Test reason',
},
contractRevisions: [],
rateRevision: {
id: '1234',
rateID: '5678',
createdAt: new Date('01/01/2021'),
updatedAt: new Date('01/01/2021'),
formData: {
rateType: 'NEW',
rateCapitationType: 'RATE_CELL',
rateDocuments: [
{
s3URL: 's3://foo/bar/rate',
name: 'rate docs test 1',
sha256: 'fakesha',
dateAdded: new Date(),
},
],
supportingDocuments: [],
rateDateStart: new Date('01/01/2021'),
rateDateEnd: new Date('12/31/2021'),
rateDateCertified: new Date('12/31/2020'),
amendmentEffectiveDateStart: new Date(
'01/01/2021'
),
amendmentEffectiveDateEnd: new Date(
'12/31/2021'
),
rateCertificationName:
'WITHDRAWN-RATE-NAME',
rateProgramIDs: [
'abbdf9b0-c49e-4c4c-bb6f-040cb7b51cce',
],
deprecatedRateProgramIDs: [],
consolidatedRateProgramIDs: [
'abbdf9b0-c49e-4c4c-bb6f-040cb7b51cce',
],
certifyingActuaryContacts: [
{
actuarialFirm: 'DELOITTE',
name: 'Jimmy Jimerson',
titleRole: 'Certifying Actuary',
email: '[email protected]',
},
],
addtlActuaryContacts: [
{
actuarialFirm: 'DELOITTE',
name: 'Additional actuary',
titleRole: 'Test Actuary Contact 1',
email: '[email protected]',
},
],
actuaryCommunicationPreference:
'OACT_TO_ACTUARY',
packagesWithSharedRateCerts: [],
},
},
submittedRevisions: [],
},
],
},
],
})

renderWithProviders(
<RateDetailsSummarySection
contract={contractWithWithdrawnRates}
submissionName="MN-MSHO-0003"
statePrograms={statePrograms}
/>,
{
apolloProvider: apolloProviderCMSUser,
}
)

expect(
screen.getByRole('heading', {
level: 2,
name: 'Rate details',
})
).toBeInTheDocument()
// Is this the best way to check that the link is not present?
expect(screen.queryByText('Edit')).not.toBeInTheDocument()

// expects download all button after loading has completed
await waitFor(() => {
expect(
screen.getByRole('link', {
name: 'Download all rate documents',
})
).toBeInTheDocument()
})

// expect withdrawn rate to be on the screen
expect(
screen.getByRole('heading', {
level: 3,
name: /WITHDRAWN-RATE-NAME/,
})
).toBeInTheDocument()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { useParams } from 'react-router-dom'
import { LinkWithLogging } from '../../../components/TealiumLogging/Link'
import classnames from 'classnames'
import { hasCMSUserPermissions } from '@mc-review/helpers'
import { InfoTag } from '../../../components/InfoTag/InfoTag'

export type RateDetailsSummarySectionProps = {
contract: Contract | UnlockedContract
Expand Down Expand Up @@ -69,7 +70,7 @@ type PackageNamesLookupType = {
export function renderDownloadButton(
zippedFilesURL: string | undefined | Error
) {
if (zippedFilesURL instanceof Error) {
if (zippedFilesURL instanceof Error || !zippedFilesURL) {
return (
<InlineDocumentWarning message="Rate document download is unavailable" />
)
Expand Down Expand Up @@ -107,6 +108,15 @@ export const RateDetailsSummarySection = ({
? rateRevisions
: getVisibleLatestRateRevisions(contract, isEditing)

const withdrawnRateRevisions: RateRevision[] =
contract.withdrawnRates?.reduce((acc, rate) => {
const latestRevision = rate.packageSubmissions?.[0].rateRevision
if (rate.consolidatedStatus === 'WITHDRAWN' && latestRevision) {
acc.push(latestRevision)
}
return acc
}, [] as RateRevision[]) ?? []

// Calculate last submitted data for document upload tables
const lastSubmittedIndex = getIndexFromRevisionVersion(
contract,
Expand Down Expand Up @@ -227,8 +237,10 @@ export const RateDetailsSummarySection = ({
// get all the keys for the documents we want to zip
async function fetchZipUrl() {
const submittedRates =
getLastContractSubmission(contract)?.rateRevisions
if (submittedRates !== undefined) {
getLastContractSubmission(contract)?.rateRevisions ?? []

// skip if no rates
if (submittedRates.length > 0) {
const keysFromDocs = submittedRates
.flatMap((rateInfo) =>
rateInfo.formData.rateDocuments.concat(
Expand Down Expand Up @@ -279,6 +291,12 @@ export const RateDetailsSummarySection = ({
isAdminUser && !isLinkedRate && !isPreviousSubmission,
})

const showDownloadAllButton =
isSubmittedOrCMSUser &&
!isPreviousSubmission &&
rateRevs &&
rateRevs.length > 0

const noRatesMessage = () => {
if (isStateUser) {
return isSubmitted
Expand All @@ -299,9 +317,7 @@ export const RateDetailsSummarySection = ({
header="Rate details"
editNavigateTo={editNavigateTo}
>
{isSubmittedOrCMSUser &&
!isPreviousSubmission &&
renderDownloadButton(zippedFilesURL)}
{showDownloadAllButton && renderDownloadButton(zippedFilesURL)}
</SectionHeader>
{rateRevs && rateRevs.length > 0
? rateRevs.map((rateRev) => {
Expand Down Expand Up @@ -575,6 +591,21 @@ export const RateDetailsSummarySection = ({
: (isSubmitted || isStateUser) && (
<DataDetailMissingField requiredText={noRatesMessage()} />
)}
{withdrawnRateRevisions.length > 0 &&
withdrawnRateRevisions.map((rateRev) => (
<SectionCard
id={`withdrawn-rate-${rateRev.id}`}
key={rateRev.id}
>
<h3
aria-label={`Rate ID: ${rateRev.formData.rateCertificationName}`}
className={styles.rateName}
>
<InfoTag color="gray-medium">WITHDRAWN</InfoTag>{' '}
{rateRev.formData.rateCertificationName}
</h3>
</SectionCard>
))}
</SectionCard>
)
}
Loading