Untitled
unknown
plain_text
a year ago
19 kB
6
Indexable
/* eslint-disable @typescript-eslint/ban-ts-comment */
import React, { useState } from 'react'
import { Card } from '@abyss/web/ui/Card'
import { Layout } from '@abyss/web/ui/Layout'
import { Grid } from '@abyss/web/ui/Grid'
import { DateInputRange } from '@abyss/web/ui/DateInputRange'
import { SelectInput } from '@abyss/web/ui/SelectInput'
import { Button } from '@abyss/web/ui/Button'
import { dayjs } from '@abyss/web/tools/dayjs'
import { useForm } from '@abyss/web/hooks/useForm'
import { FormProvider } from '@abyss/web/ui/FormProvider'
import { CollapseProvider } from '@abyss/web/ui/CollapseProvider'
import SubmittedFilesTiles from './SubmittedFilesTiles/SubmittedFilesTiles'
import { LoadingOverlay } from '@abyss/web/ui/LoadingOverlay'
import { RadioGroup } from '@abyss/web/ui/RadioGroup'
import { SubmittedTileDataType } from './SubmittedFilesDataModel'
import { useToast } from '@abyss/web/hooks/useToast'
import { HeaderWrapper, HeaderWrapperDiv1, HeaderWrapperDiv2, ClearCriteriaBtn } from './SubmittedFiles.styled'
import { getTenantOrPartnerData, fetchCountForTiles } from './SubmittedFilesTiles/submittedFilesService'
import { getHeaderName, apiResponseMapperObj, apisFor835Partner, apisForAllOtherTrn, apisFor275Partner, apisFor275Tenant } from './SubmittedFilesTiles/TileAPIMappings'
const initialTileState = {
'Submitted Files': '-',
'Processed Checks': '-',
'Invalid Files': '-',
'Duplicate Files': '-',
'ENR Checks': '-',
'Inbound Failed Files': '-',
'Outbound Failed Files': '-',
'Resubmissions Audit Tile': '-',
'Outbound Processed Files': '-',
"Missing 275's 999 Files": '-',
"Rejected 275's 999 Files": '-',
'Rejected Attachments': '-',
'Total Individual Attachments': '-'
}
interface SubmittedFilesFormDataType {
submissionDate: { from: string; to: string }
selectedTransactionTypes837: []
idType: string
selectedTenant: string
selectedPartner: string
}
export const buildReqBodyForEDI = (submittedData) => {
const reqBody = {
tenantId: submittedData.idType === 'TenantId' ? submittedData.selectedTenant : submittedData.selectedPartner,
startDate: submittedData.submissionDate.from.replaceAll('/', '-'),
endDate: submittedData.submissionDate.to.replaceAll('/', '-'),
transactionType: submittedData.selectedTransactionTypes837,
submissionTimeRange: 'DR',
submitterType: submittedData.idType
}
return reqBody
}
const SubmittedFiles = () => {
const minStartDate = new Date()
const CurDate = new Date()
minStartDate.setMonth(CurDate.getMonth() - 13, 0)
const defaultEndDate = dayjs(CurDate).format('MM/DD/YYYY')
const yesterdayDate = new Date()
yesterdayDate.setDate(yesterdayDate.getDate() - 1)
const defaultStartDate = dayjs(yesterdayDate).format('MM/DD/YYYY')
const form = useForm({
defaultValues: {
submissionDate: { from: defaultStartDate, to: defaultEndDate },
selectedTransactionTypes837: [],
idType: '',
selectedTenant: '',
selectedPartner: ''
}
})
const { toast } = useToast()
const idTypeLength = form.getValues('idType').length
const submissionDatefromfilled = form.getValues('submissionDate.from') != ''
const submissionDatetofilled = form.getValues('submissionDate.to') != ''
const selectTranslength = form.getValues('selectedTransactionTypes837').length
const selectTenantLength = form.getValues('selectedTenant').length
const selectPartnerLength = form.getValues('selectedPartner').length
const formidType = form.getValues('idType')
const valididType = (formidType) => {
if ((formidType === 'TenantId' && selectTenantLength > 0) || (formidType === 'PartnerId' && selectPartnerLength > 0)) {
return true
} else {
return false
}
}
const formvalid = idTypeLength > 0 && submissionDatefromfilled && submissionDatetofilled && selectTranslength > 0 && valididType(formidType)
const [value, setValue] = useState({ from: '', to: '' })
const [showTiles, setShowTiles] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const [tilesData, setTilesData] = useState<SubmittedTileDataType>(initialTileState)
const [transactiontype, setTransactiontype] = useState('')
const [data, setData] = useState<SubmittedFilesFormDataType>({
submissionDate: { from: '', to: '' },
selectedTransactionTypes837: [],
idType: '',
selectedTenant: '',
selectedPartner: ''
})
const [idType, setIdType] = useState('')
const [submit, setSubmit] = useState(false)
const [tenantsOrPartners, setTenantsOrPartners] = useState([])
const [tenantId, setTenantId] = useState('')
const [startDate, setStartDate] = useState('')
const [endDate, setEndDate] = useState('')
const [submitterIdType, setSubmitterIdType] = useState('')
const [filtercollapsed, setFiltercollapsed] = useState(false)
const trancString = JSON.stringify(data?.selectedTransactionTypes837)
const filterCollapseBtn: HTMLElement = document.getElementsByClassName('abyss-card-collapse-button')[0] as HTMLElement
filterCollapseBtn && filterCollapseBtn.addEventListener('click', () => setFiltercollapsed(!filtercollapsed))
const onReset = () => {
form.reset()
setData({ submissionDate: { from: '', to: '' }, selectedTransactionTypes837: [], idType: '', selectedTenant: '', selectedPartner: '' })
setIdType('')
setSubmitterIdType('')
setSubmit(false)
setShowTiles(false)
if (filtercollapsed) {
filterCollapseBtn.click()
}
}
const HeaderEDI = (
<HeaderWrapper>
<HeaderWrapperDiv1>Filters</HeaderWrapperDiv1>
{submit && (
<>
<HeaderWrapperDiv2>
{data.submissionDate && (
<span>
Submission Date Range: {data.submissionDate.from} - {data.submissionDate.to}
</span>
)}
<span>Transaction Type: {trancString}</span>
{data.idType === 'TenantId' && <span>Tenant ID: {data.selectedTenant}</span>}
{data.idType === 'PartnerId' && <span>Partner ID: {data.selectedPartner}</span>}
</HeaderWrapperDiv2>
<ClearCriteriaBtn id="clear-criteria" onClick={onReset}>
Clear Criteria
</ClearCriteriaBtn>
</>
)}
</HeaderWrapper>
)
// Further additions can be made here to include other transaction types
const transactionEDIOpts = [
{ value: 'All', label: 'All' },
{ value: '835', label: '835' },
{ value: '275', label: '275' }
]
const onSubmit = (data) => {
setData(data)
setSubmit(true)
setSubmitterIdType(idType)
showTiles && setIsLoading(true)
setTransactiontype(data.selectedTransactionTypes837)
setTenantId('TenantId' === idType ? data.selectedTenant : data.selectedPartner)
setStartDate(data.submissionDate.from.replaceAll('/', '-'))
setEndDate(data.submissionDate.to.replaceAll('/', '-'))
fetchDataForEDI(data)
filterCollapseBtn.click()
setFiltercollapsed(true)
}
const handleIDChange = (e) => {
e.stopPropagation()
setIdType(e.target.value)
setIsLoading(true)
getTenantOrPartnerList(e.target.value)
}
const getTenantOrPartnerList = (submitter) => {
return getTenantOrPartnerData(submitter)
.then((response) => {
const res = response.data.map((d) => ({
label: d,
value: d
}))
setIsLoading(false)
setTenantsOrPartners(res)
})
.catch(() => {
setIsLoading(false)
setTenantsOrPartners([])
return toast.show({
title: 'Internal Server Error',
message: 'This request could not be completed currently due to some internal server error. Please try again later.',
autoClose: false
})
})
}
const fetchDataForEDI = (submittedData) => {
prepareTilesToShow(submittedData.selectedTransactionTypes837, buildReqBodyForEDI(submittedData))
}
// For introducing APIs for new tiles, go to TileAPIMappings.ts and add the respective APIs that need to be called
// add additional condition in below method to include that transaction type
const getAPIListForTrnType = (transactionType) => {
let apiList
if (transactionType === '835' && idType === 'PartnerId') {
apiList = apisFor835Partner
} else if (transactionType === '275' && idType === 'PartnerId') {
apiList = apisFor275Partner
} else if (transactionType === '275' && idType === 'TenantId') {
apiList = apisFor275Tenant
} else {
apiList = apisForAllOtherTrn
}
return apiList
}
const buildTilesData = (transactionType, apiName, data, tileData, idType) => {
const header = getHeaderName(transactionType, apiName, idType)
if ('100' === data['statusCode']) {
tileData[header] = data[apiResponseMapperObj[apiName]]
} else if ('400' === data['statusCode']) {
tileData[header] = 'Failed to fetch data due to internal server error'
}
return { ...tileData }
}
const prepareTilesToShow = (transactionType, reqBody) => {
let apiListForTrnType: string[] = []
let tileData = initialTileState
apiListForTrnType = getAPIListForTrnType(transactionType)
apiListForTrnType.forEach((apiName) => {
setIsLoading(true)
fetchCountForTiles(apiName, reqBody)
.then((response) => {
tileData = buildTilesData(transactionType, apiName, response.data, tileData, idType)
setTilesData(tileData)
setIsLoading(false)
})
.catch(() => {
setIsLoading(false)
tileData = buildTilesData(transactionType, apiName, { statusCode: '400' }, tileData, idType)
setTilesData(tileData)
})
})
setShowTiles(true)
}
return (
<LoadingOverlay
loadingTitle="Please Wait"
loadingMessage="Retrieving Information."
isDismissable
ariaLoadingLabel="Loading"
isLoading={isLoading}
width="20%"
>
<CollapseProvider defaultIsOpen={true}>
<Card>
<div className="filters">
<Card header={HeaderEDI} size="small" collapse>
<Card.Section>
<FormProvider state={form} onSubmit={onSubmit}>
<Layout.Stack alignItems="left" grow>
<Grid>
<Grid.Col span={3}>
<DateInputRange
label="Submission Start Date"
model="submissionDate"
values={value}
// @ts-expect-error
onChange={setValue}
startDateLabel="Start Date"
endDateLabel="End Date"
minimumDate={minStartDate}
maximumDate={CurDate}
validators={{
required: true,
validate: {
isBefore: (v) => {
return (
dayjs(v.from, 'MM/DD/YYYY').isBefore(dayjs(new Date(), 'MM/DD/YYYY')) ||
toast.show({
title: 'Date input validation error',
message: 'Start Date should not be a future date'
}),
dayjs(v.from, 'MM/DD/YYYY').isBefore(dayjs(new Date(), 'MM/DD/YYYY')) || 'Start Date should not be a future date',
dayjs(v.to, 'MM/DD/YYYY').isBefore(dayjs(new Date(), 'MM/DD/YYYY')) ||
toast.show({
title: 'Date input validation error',
message: 'End date should not be a future date'
}),
dayjs(v.to, 'MM/DD/YYYY').isBefore(dayjs(new Date(), 'MM/DD/YYYY')) || 'End date should not be a future date'
)
},
isAfter: (v) => {
const beforestartDate = new Date(v.from)
beforestartDate.setDate(beforestartDate.getDate() - 1)
return (
dayjs(v.to, 'MM/DD/YYYY').isAfter(dayjs(beforestartDate, 'MM/DD/YYYY')) ||
toast.show({
title: 'Date input validation error',
message: 'End date should be after Start Date'
}),
dayjs(v.to, 'MM/DD/YYYY').isAfter(dayjs(beforestartDate, 'MM/DD/YYYY')) || 'End date should be after start date'
)
},
isBetween: (v) => {
const validatedefaultStartDate = new Date()
const validatedefaultMessageStartDate = new Date()
validatedefaultStartDate.setMonth(validatedefaultStartDate.getMonth() - 13, 0)
validatedefaultMessageStartDate.setMonth(validatedefaultMessageStartDate.getMonth() - 13, 1)
const validateToday = new Date()
return (
dayjs(v.from, 'MM/DD/YYYY').isBetween(dayjs(validatedefaultStartDate, 'MM/DD/YYYY', validateToday, 'MM/DD/YYYY')) ||
toast.show({
title: 'Date range validation error',
message:
'Date range should be between ' +
validatedefaultMessageStartDate.toLocaleDateString() +
'--' +
validateToday.toLocaleDateString()
}),
dayjs(v.from, 'MM/DD/YYYY').isBetween(
dayjs(validatedefaultStartDate.toLocaleDateString(), 'MM/DD/YYYY', validateToday, 'MM/DD/YYYY')
) ||
'Date range should be between ' +
validatedefaultMessageStartDate.toLocaleDateString() +
'--' +
validateToday.toLocaleDateString()
)
}
}
}}
/>
</Grid.Col>
<Grid.Col span={3}>
<SelectInput
label="Transaction Type"
model="selectedTransactionTypes837"
options={transactionEDIOpts}
placeholder={'Please select transaction type'}
validators={{ required: true }}
css={{ 'abyss-select-input-root': { padding: '0.35em' } }}
/>
</Grid.Col>
<Grid.Col span={2}>
<RadioGroup
label="Select ID Type"
model="idType"
onChange={(e) => handleIDChange(e)}
value={idType}
display="column"
validators={{ required: true }}
>
<RadioGroup.Radio label="Tenant ID" value="TenantId" />
<RadioGroup.Radio label="Partner ID" value="PartnerId" />
</RadioGroup>
</Grid.Col>
{idType === 'TenantId' && (
<Grid.Col span={3}>
<SelectInput
label="Tenant ID"
model="selectedTenant"
options={tenantsOrPartners}
placeholder={'Please select Tenant ID'}
isSearchable
virtual
validators={{ required: true }}
/>
</Grid.Col>
)}
{idType === 'PartnerId' && (
<Grid.Col span={3}>
<SelectInput
label="Partner ID"
model="selectedPartner"
options={tenantsOrPartners}
placeholder={'Please select Partner ID'}
isSearchable
virtual
validators={{ required: true }}
/>
</Grid.Col>
)}
</Grid>
<Grid>
<Grid.Col span={2}>
<Button type="submit" disabled={!formvalid}>
Apply Filters
</Button>
</Grid.Col>
</Grid>
</Layout.Stack>
</FormProvider>
</Card.Section>
</Card>
</div>
{showTiles && (
<Card.Section id="submittedFilesTiles">
<SubmittedFilesTiles
tilesData={tilesData}
transactionType={transactiontype}
submitterType={submitterIdType}
tenantId={tenantId}
startDate={startDate}
endDate={endDate}
fetchDataForEDI={() => fetchDataForEDI(data)}
/>
</Card.Section>
)}
</Card>
</CollapseProvider>
</LoadingOverlay>
)
}
export default SubmittedFiles
Editor is loading...
Leave a Comment