From 1c686baf64f6490ddaa318a803f73a35c564beb7 Mon Sep 17 00:00:00 2001 From: Amos Machora Date: Wed, 15 Jan 2025 13:25:12 +0300 Subject: [PATCH 1/6] refactor: end visit and redirect to claim page --- .../src/invoice/invoice.component.tsx | 61 ++++++++++++-- .../src/invoice/invoice.resource.ts | 81 +++++++++++++++++++ 2 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 packages/esm-billing-app/src/invoice/invoice.resource.ts diff --git a/packages/esm-billing-app/src/invoice/invoice.component.tsx b/packages/esm-billing-app/src/invoice/invoice.component.tsx index 809ffd27..c87bec14 100644 --- a/packages/esm-billing-app/src/invoice/invoice.component.tsx +++ b/packages/esm-billing-app/src/invoice/invoice.component.tsx @@ -5,7 +5,10 @@ import { formatDatetime, navigate, parseDate, + setCurrentVisit, showModal, + showSnackbar, + updateVisit, useFeatureFlag, usePatient, useVisit, @@ -21,6 +24,7 @@ import { convertToCurrency } from '../helpers'; import { usePaymentsReconciler } from '../hooks/use-payments-reconciler'; import { LineItem } from '../types'; import InvoiceTable from './invoice-table.component'; +import { removeQueuedPatient, useVisitQueueEntry } from './invoice.resource'; import styles from './invoice.scss'; import Payments from './payments/payments.component'; import ReceiptPrintButton from './print-bill-receipt/receipt-print-button.component'; @@ -39,7 +43,14 @@ const Invoice: React.FC = () => { const { patient, isLoading: isLoadingPatient, error: patientError } = usePatient(patientUuid); const { bill, isLoading: isLoadingBill, error: billingError } = useBill(billUuid); usePaymentsReconciler(billUuid); - const { currentVisit, isLoading: isVisitLoading, error: visitError } = useVisit(patientUuid); + const { + currentVisit, + isLoading: isVisitLoading, + error: visitError, + currentVisitIsRetrospective, + mutate: mutateVisit, + } = useVisit(patientUuid); + const { queueEntry } = useVisitQueueEntry(patientUuid, currentVisit?.uuid); const [selectedLineItems, setSelectedLineItems] = useState([]); const componentRef = useRef(null); const isProcessClaimsFormEnabled = useFeatureFlag('healthInformationExchange'); @@ -108,12 +119,49 @@ const Invoice: React.FC = () => { ); } - const handleViewClaims = () => { + const handleEndVisit = async () => { + if (currentVisitIsRetrospective) { + setCurrentVisit(null, null); + } else { + const endVisitPayload = { + stopDatetime: new Date(), + }; + + const abortController = new AbortController(); + + updateVisit(currentVisit.uuid, endVisitPayload, abortController) + .then((response) => { + if (queueEntry) { + removeQueuedPatient( + queueEntry.queue.uuid, + queueEntry.queueEntryUuid, + abortController, + response?.data.stopDatetime, + ); + } + mutateVisit(); + showSnackbar({ + isLowContrast: true, + kind: 'success', + subtitle: t('visitEndSuccessfully', `${response?.data?.visitType?.display} ended successfully`), + title: t('visitEnded', 'Visit ended'), + }); + }) + .catch((error) => { + showSnackbar({ + title: t('errorEndingVisit', 'Error ending visit'), + kind: 'error', + isLowContrast: false, + subtitle: error?.message, + }); + }); + } + }; + + const handleViewClaims = async () => { if (currentVisit) { - const dispose = showModal('end-visit-dialog', { - closeModal: () => dispose(), - patientUuid, - }); + await handleEndVisit(); + navigate({ to: `${spaBasePath}/billing/patient/${patientUuid}/${billUuid}/claims` }); } else { navigate({ to: `${spaBasePath}/billing/patient/${patientUuid}/${billUuid}/claims` }); } @@ -153,6 +201,7 @@ const Invoice: React.FC = () => { {isProcessClaimsFormEnabled && ( - - )} - -
- - - {inforce ? t('active', 'Active') : t('inactive', 'Inactive')} - + if (isHIEEligible) { + return ( + + {data?.map(({ inforce, insurer, start, eligibility_response }, index) => { + return ( +
+
+ {t('insurer', 'Insurer:')}{' '} + SHA + {start && ( + + + + )} +
+
+ + + {inforce ? t('active', 'Active') : t('inactive', 'Inactive')} + +
-
- ); - })} - - ); + ); + })} + + ); + } }; export default SHANumberValidity; From 9b4492e64954fcfa82e2af6bb485742510300580 Mon Sep 17 00:00:00 2001 From: Amos Machora Date: Fri, 17 Jan 2025 09:45:22 +0300 Subject: [PATCH 4/6] applied CR changes and made more code refators --- .../src/billing-form/hie.resource.tsx | 12 +-- .../sha-number-validity.component.tsx | 75 ++++++++++--------- 2 files changed, 44 insertions(+), 43 deletions(-) diff --git a/packages/esm-billing-app/src/billing-form/hie.resource.tsx b/packages/esm-billing-app/src/billing-form/hie.resource.tsx index cfdc3889..b5e00651 100644 --- a/packages/esm-billing-app/src/billing-form/hie.resource.tsx +++ b/packages/esm-billing-app/src/billing-form/hie.resource.tsx @@ -45,7 +45,7 @@ type HIEEligibilityResponse = { eligibility_response: EligibilityResponse; }; -export const useHIEEligibility = (patientUuid: string, shaIdentificationNumber?: fhir.Identifier[]) => { +export const useSHAEligibility = (patientUuid: string, shaIdentificationNumber?: fhir.Identifier[]) => { const { patient } = usePatient(patientUuid); const { nationalIdUUID } = useConfig(); @@ -62,13 +62,9 @@ export const useHIEEligibility = (patientUuid: string, shaIdentificationNumber?: }); return { - data: - data?.data.map((d) => { - return { - ...d, - eligibility_response: JSON.parse(d.eligibility_response as unknown as string) as EligibilityResponse, - }; - }) ?? [], + data: data + ? { ...(JSON.parse(data?.data.at(0)?.eligibility_response as unknown as string) as EligibilityResponse) } + : undefined, isLoading, error, mutate, diff --git a/packages/esm-billing-app/src/billing-form/social-health-authority/sha-number-validity.component.tsx b/packages/esm-billing-app/src/billing-form/social-health-authority/sha-number-validity.component.tsx index 86ce9017..a7937db2 100644 --- a/packages/esm-billing-app/src/billing-form/social-health-authority/sha-number-validity.component.tsx +++ b/packages/esm-billing-app/src/billing-form/social-health-authority/sha-number-validity.component.tsx @@ -1,11 +1,12 @@ import { ActionableNotification, Form, InlineLoading, InlineNotification, Tooltip } from '@carbon/react'; import { CheckboxCheckedFilled, Information } from '@carbon/react/icons'; import { formatDate, navigate, useConfig, usePatient } from '@openmrs/esm-framework'; +import { isWithinInterval } from 'date-fns'; import React from 'react'; import { useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { BillingConfig } from '../../config-schema'; -import { useHIEEligibility } from '../hie.resource'; +import { useSHAEligibility } from '../hie.resource'; import styles from './sha-number-validity.scss'; type SHANumberValidityProps = { @@ -16,16 +17,24 @@ type SHANumberValidityProps = { const SHANumberValidity: React.FC = ({ paymentMethod, patientUuid }) => { const { t } = useTranslation(); const { shaIdentificationNumberUUID } = useConfig(); - const { patient, isLoading } = usePatient(patientUuid); + const { patient, isLoading: isLoadingPatientUuid } = usePatient(patientUuid); const { watch } = useFormContext(); const isSHA = watch('insuranceScheme')?.includes('SHA'); const shaIdentificationNumber = patient?.identifier ?.filter((identifier) => identifier) .filter((identifier) => identifier.type.coding.some((coding) => coding.code === shaIdentificationNumberUUID)); - const { data, isLoading: isLoadingHIEEligibility, error } = useHIEEligibility(patientUuid, shaIdentificationNumber); - const isHIEEligible = data.at(0)?.eligibility_response.status === 1; - const isNotHIEEligible = data.at(0)?.eligibility_response.active === false; + const { data, isLoading: isLoadingHIEEligibility, error } = useSHAEligibility(patientUuid, shaIdentificationNumber); + + const isRegisteredOnSHA = Boolean(data?.coverageEndDate) && Boolean(data?.coverageStartDate); + const isNotRegisteredOnSHA = data?.active === false; + + const isActive = isRegisteredOnSHA + ? isWithinInterval(new Date(), { + start: new Date(data?.coverageStartDate), + end: new Date(data?.coverageEndDate), + }) + : false; if (!isSHA) { return null; @@ -50,7 +59,7 @@ const SHANumberValidity: React.FC = ({ paymentMethod, pa ); } - if (isLoadingHIEEligibility || isLoading) { + if (isLoadingHIEEligibility || isLoadingPatientUuid) { return ; } @@ -67,45 +76,41 @@ const SHANumberValidity: React.FC = ({ paymentMethod, pa ); } - if (isNotHIEEligible) { + if (isNotRegisteredOnSHA) { return ( ); } - if (isHIEEligible) { + if (isRegisteredOnSHA) { return (
- {data?.map(({ inforce, insurer, start, eligibility_response }, index) => { - return ( -
-
- {t('insurer', 'Insurer:')}{' '} - SHA - {start && ( - - - - )} -
-
- - - {inforce ? t('active', 'Active') : t('inactive', 'Inactive')} - -
-
- ); - })} +
+
+ {t('insurer', 'Insurer:')}{' '} + SHA + {isActive && ( + + + + )} +
+
+ + + {isActive ? t('active', 'Active') : t('inactive', 'Inactive')} + +
+
); } From 69263d425d57babab5c60a62ab5cae216a55bc0e Mon Sep 17 00:00:00 2001 From: Amos Machora Date: Fri, 17 Jan 2025 09:51:55 +0300 Subject: [PATCH 5/6] fix: use array length instead of array presence to check for sha id during request prep --- packages/esm-billing-app/src/billing-form/hie.resource.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/esm-billing-app/src/billing-form/hie.resource.tsx b/packages/esm-billing-app/src/billing-form/hie.resource.tsx index b5e00651..6dffb9f1 100644 --- a/packages/esm-billing-app/src/billing-form/hie.resource.tsx +++ b/packages/esm-billing-app/src/billing-form/hie.resource.tsx @@ -54,9 +54,10 @@ export const useSHAEligibility = (patientUuid: string, shaIdentificationNumber?: .filter((identifier) => identifier.type.coding.some((coding) => coding.code === nationalIdUUID)) ?.at(0)?.value; - const url = shaIdentificationNumber - ? `${restBaseUrl}/insuranceclaims/CoverageEligibilityRequest?patientUuid=${patientUuid}&nationalId=${nationalId}` - : undefined; // this is to avoid making the request if the patient does not have a SHA Id. + const url = + shaIdentificationNumber?.length > 0 + ? `${restBaseUrl}/insuranceclaims/CoverageEligibilityRequest?patientUuid=${patientUuid}&nationalId=${nationalId}` + : undefined; // this is to avoid making the request if the patient does not have a SHA Id. const { data, error, isLoading, mutate } = useSWR<{ data: Array }>(url, openmrsFetch, { errorRetryCount: 0, }); From 2ee2a274602485ec24b1e5717ee6691856312e44 Mon Sep 17 00:00:00 2001 From: Amos Machora Date: Fri, 17 Jan 2025 09:55:46 +0300 Subject: [PATCH 6/6] code review suggestion from @donaldkibet Co-authored-by: Donald Kibet --- packages/esm-billing-app/src/billing-form/hie.resource.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/esm-billing-app/src/billing-form/hie.resource.tsx b/packages/esm-billing-app/src/billing-form/hie.resource.tsx index 6dffb9f1..df343c8b 100644 --- a/packages/esm-billing-app/src/billing-form/hie.resource.tsx +++ b/packages/esm-billing-app/src/billing-form/hie.resource.tsx @@ -17,7 +17,7 @@ export interface EligibilityResponse { coverageType: string; primaryContributor: null; employerDetails: EmployerDetails; - dependants: any[]; + dependants: Array; active: boolean; }