@kenyaemr/esm-billing-app 5.4.2-pre.2557 → 5.4.2-pre.2563
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +5 -5
- package/dist/{570.js → 440.js} +1 -1
- package/dist/440.js.map +1 -0
- package/dist/{297.js → 880.js} +2 -2
- package/dist/880.js.map +1 -0
- package/dist/kenyaemr-esm-billing-app.js +3 -3
- package/dist/kenyaemr-esm-billing-app.js.buildmanifest.json +620 -620
- package/dist/main.js +11 -11
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/billable-services/billiable-item/order-actions/components/medication-order-button.component.tsx +2 -1
- package/src/billable-services/billiable-item/order-actions/components/medication-order-button.scss +11 -0
- package/src/claims/dashboard/form/claims-form.component.tsx +9 -33
- package/src/claims/dashboard/form/claims-form.resource.ts +62 -0
- package/src/claims/dashboard/form/claims-form.scss +6 -0
- package/src/claims/dashboard/form/claims-supporting-documents-inputs.form.tsx +183 -0
- package/dist/297.js.map +0 -1
- package/dist/570.js.map +0 -1
package/dist/routes.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"kenyaemr":"^19.0.0"},"pages":[{"component":"billableServicesHome","route":"billable-services"},{"component":"requirePaymentModal","routeRegex":"^patient/.+/chart","online":true,"offline":false}],"extensions":[{"component":"accountingDashboardLink","name":"accounting-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"accounting","slot":"accounting-dashboard-slot","title":"Accounting"}},{"name":"billing-dashboard","component":"billingDashboard","slot":"accounting-dashboard-slot"},{"component":"benefitsPackageDashboardLink","name":"benefits-package-dashboard-link","meta":{"name":"benefits-package","slot":"patient-chart-benefits-dashboard-slot","path":"insurance-benefits","columns":1,"columnSpan":1},"featureFlag":"healthInformationExchange"},{"component":"benefitsPackage","name":"benefits-package","slot":"patient-chart-benefits-dashboard-slot"},{"component":"root","name":"billing-dashboard-root","slot":"billing-dashboard-slot"},{"component":"benefitsEligibilyRequestForm","name":"benefits-eligibility-request-form"},{"component":"benefitsPreAuthForm","name":"benefits-pre-auth-form"},{"name":"billing-patient-summary","component":"billingPatientSummary","slot":"patient-chart-billing-dashboard-slot","order":10,"meta":{"columnSpan":4}},{"name":"billing-summary-dashboard-link","component":"billingSummaryDashboardLink","order":11,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-billing-dashboard-slot","path":"Billing","layoutMode":"anchored"}},{"name":"billing-check-in-form","slot":"extra-visit-attribute-slot","component":"billingCheckInForm"},{"name":"patient-banner-billing-tags","component":"visitAttributeTags","slot":"patient-banner-tags-slot","order":2},{"name":"initiate-payment-modal","component":"initiatePaymentDialog"},{"name":"delete-billableservice-modal","component":"deleteBillableServiceModal"},{"name":"refund-bill-modal","component":"refundBillModal"},{"name":"delete-bill-modal","component":"deleteBillModal"},{"name":"lab-order-billable-item","component":"labOrder","slot":"top-of-lab-order-form-slot"},{"name":"procedure-order-billable-item","component":"procedureOrder","slot":"top-of-procedure-order-form-slot"},{"name":"imaging-order-billable-item","component":"imagingOrder","slot":"top-of-imaging-order-form-slot"},{"name":"price-info-order","component":"priceInfoOrder"},{"name":"drug-order-billable-item","component":"drugOrder","slot":"medication-info-slot"},{"name":"order-action-button","component":"orderActionButton","slots":["prescription-action-button-slot","imaging-orders-action","procedure-orders-action","tests-ordered-actions-slot"],"order":0},{"component":"claimsManagementOverviewDashboardLink","name":"claims-management-overview-link","slots":["claims-management-dashboard-link-slot"]},{"component":"preAuthRequestsDashboardLink","name":"preauthrequest-overview-link","slots":["claims-management-dashboard-link-slot"]},{"component":"claimsOverview","name":"claims-overview-dashboard-link","slot":"claims-management-overview-slot"},{"component":"waiveBillActionButton","name":"waive-bill-action-button","slot":"bill-actions-slot"},{"component":"deleteBillActionButton","name":"delete-bill-action-button","slot":"bill-actions-slot"},{"component":"refundLineItem","name":"refund-line-item","slot":"bill-actions-overflow-menu-slot"},{"name":"edit-line-item","component":"editLineItem","slot":"bill-actions-overflow-menu-slot"},{"name":"cancel-line-item","component":"cancelLineItem","slot":"bill-actions-overflow-menu-slot"},{"name":"patient-info-sha-status","component":"patientBannerShaStatus","slot":"patient-banner-tags-slot"}],"workspaces":[{"name":"create-bill-workspace","component":"createBillWorkspace","title":"Create Bill Workspace","type":"other-form"},{"name":"waive-bill-form","component":"waiveBillForm","title":"Waive Bill Form","type":"other-form"},{"name":"edit-bill-form","component":"editBillForm","title":"Edit Bill Form","type":"other-form"},{"name":"billable-service-form","component":"addServiceForm","title":"Create Charge Item Form","type":"other-form"},{"name":"commodity-form","component":"addCommodityForm","title":"Create Charge Item Form","type":"other-form"},{"name":"billing-form","component":"billingForm","title":"Billing Form","type":"other-form","width":"extra-wide"},{"name":"payment-mode-workspace","component":"paymentModeWorkspace","title":"Payment Mode Workspace","type":"other-form"},{"name":"cancel-bill-workspace","component":"cancelBillWorkspace","title":"Cancel Bill Workspace","type":"other-form"},{"name":"add-deposit-workspace","component":"addDepositWorkspace","title":"Add Deposit","type":"other-form"},{"name":"deposit-transaction-workspace","component":"depositTransactionWorkspace","title":"Deposit Transaction","type":"other-form"},{"name":"payment-workspace","component":"paymentWorkspace","title":"Payment Workspace","type":"other-form"}],"modals":[{"name":"create-payment-point","component":"createPaymentPoint"},{"name":"clock-out-modal","component":"clockOut"},{"name":"bulk-import-billable-services-modal","component":"bulkImportBillableServicesModal"},{"name":"delete-payment-mode-modal","component":"deletePaymentModeModal"},{"name":"manage-claim-request-modal","component":"manageClaimRequestModal"},{"name":"clock-in-modal","component":"clockIn"},{"name":"create-bill-item-modal","component":"createBillItemModal"},{"name":"delete-deposit-modal","component":"deleteDepositModal"},{"name":"reverse-transaction-modal","component":"reverseTransactionModal"},{"name":"print-preview-modal","component":"printPreviewModal"},{"name":"bill-action-modal","component":"billActionModal"},{"name":"require-billing-modal","component":"requirePaymentModal"}],"version":"5.4.2-pre.
|
|
1
|
+
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"kenyaemr":"^19.0.0"},"pages":[{"component":"billableServicesHome","route":"billable-services"},{"component":"requirePaymentModal","routeRegex":"^patient/.+/chart","online":true,"offline":false}],"extensions":[{"component":"accountingDashboardLink","name":"accounting-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"accounting","slot":"accounting-dashboard-slot","title":"Accounting"}},{"name":"billing-dashboard","component":"billingDashboard","slot":"accounting-dashboard-slot"},{"component":"benefitsPackageDashboardLink","name":"benefits-package-dashboard-link","meta":{"name":"benefits-package","slot":"patient-chart-benefits-dashboard-slot","path":"insurance-benefits","columns":1,"columnSpan":1},"featureFlag":"healthInformationExchange"},{"component":"benefitsPackage","name":"benefits-package","slot":"patient-chart-benefits-dashboard-slot"},{"component":"root","name":"billing-dashboard-root","slot":"billing-dashboard-slot"},{"component":"benefitsEligibilyRequestForm","name":"benefits-eligibility-request-form"},{"component":"benefitsPreAuthForm","name":"benefits-pre-auth-form"},{"name":"billing-patient-summary","component":"billingPatientSummary","slot":"patient-chart-billing-dashboard-slot","order":10,"meta":{"columnSpan":4}},{"name":"billing-summary-dashboard-link","component":"billingSummaryDashboardLink","order":11,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-billing-dashboard-slot","path":"Billing","layoutMode":"anchored"}},{"name":"billing-check-in-form","slot":"extra-visit-attribute-slot","component":"billingCheckInForm"},{"name":"patient-banner-billing-tags","component":"visitAttributeTags","slot":"patient-banner-tags-slot","order":2},{"name":"initiate-payment-modal","component":"initiatePaymentDialog"},{"name":"delete-billableservice-modal","component":"deleteBillableServiceModal"},{"name":"refund-bill-modal","component":"refundBillModal"},{"name":"delete-bill-modal","component":"deleteBillModal"},{"name":"lab-order-billable-item","component":"labOrder","slot":"top-of-lab-order-form-slot"},{"name":"procedure-order-billable-item","component":"procedureOrder","slot":"top-of-procedure-order-form-slot"},{"name":"imaging-order-billable-item","component":"imagingOrder","slot":"top-of-imaging-order-form-slot"},{"name":"price-info-order","component":"priceInfoOrder"},{"name":"drug-order-billable-item","component":"drugOrder","slot":"medication-info-slot"},{"name":"order-action-button","component":"orderActionButton","slots":["prescription-action-button-slot","imaging-orders-action","procedure-orders-action","tests-ordered-actions-slot"],"order":0},{"component":"claimsManagementOverviewDashboardLink","name":"claims-management-overview-link","slots":["claims-management-dashboard-link-slot"]},{"component":"preAuthRequestsDashboardLink","name":"preauthrequest-overview-link","slots":["claims-management-dashboard-link-slot"]},{"component":"claimsOverview","name":"claims-overview-dashboard-link","slot":"claims-management-overview-slot"},{"component":"waiveBillActionButton","name":"waive-bill-action-button","slot":"bill-actions-slot"},{"component":"deleteBillActionButton","name":"delete-bill-action-button","slot":"bill-actions-slot"},{"component":"refundLineItem","name":"refund-line-item","slot":"bill-actions-overflow-menu-slot"},{"name":"edit-line-item","component":"editLineItem","slot":"bill-actions-overflow-menu-slot"},{"name":"cancel-line-item","component":"cancelLineItem","slot":"bill-actions-overflow-menu-slot"},{"name":"patient-info-sha-status","component":"patientBannerShaStatus","slot":"patient-banner-tags-slot"}],"workspaces":[{"name":"create-bill-workspace","component":"createBillWorkspace","title":"Create Bill Workspace","type":"other-form"},{"name":"waive-bill-form","component":"waiveBillForm","title":"Waive Bill Form","type":"other-form"},{"name":"edit-bill-form","component":"editBillForm","title":"Edit Bill Form","type":"other-form"},{"name":"billable-service-form","component":"addServiceForm","title":"Create Charge Item Form","type":"other-form"},{"name":"commodity-form","component":"addCommodityForm","title":"Create Charge Item Form","type":"other-form"},{"name":"billing-form","component":"billingForm","title":"Billing Form","type":"other-form","width":"extra-wide"},{"name":"payment-mode-workspace","component":"paymentModeWorkspace","title":"Payment Mode Workspace","type":"other-form"},{"name":"cancel-bill-workspace","component":"cancelBillWorkspace","title":"Cancel Bill Workspace","type":"other-form"},{"name":"add-deposit-workspace","component":"addDepositWorkspace","title":"Add Deposit","type":"other-form"},{"name":"deposit-transaction-workspace","component":"depositTransactionWorkspace","title":"Deposit Transaction","type":"other-form"},{"name":"payment-workspace","component":"paymentWorkspace","title":"Payment Workspace","type":"other-form"}],"modals":[{"name":"create-payment-point","component":"createPaymentPoint"},{"name":"clock-out-modal","component":"clockOut"},{"name":"bulk-import-billable-services-modal","component":"bulkImportBillableServicesModal"},{"name":"delete-payment-mode-modal","component":"deletePaymentModeModal"},{"name":"manage-claim-request-modal","component":"manageClaimRequestModal"},{"name":"clock-in-modal","component":"clockIn"},{"name":"create-bill-item-modal","component":"createBillItemModal"},{"name":"delete-deposit-modal","component":"deleteDepositModal"},{"name":"reverse-transaction-modal","component":"reverseTransactionModal"},{"name":"print-preview-modal","component":"printPreviewModal"},{"name":"bill-action-modal","component":"billActionModal"},{"name":"require-billing-modal","component":"requirePaymentModal"}],"version":"5.4.2-pre.2563"}
|
package/package.json
CHANGED
|
@@ -7,6 +7,7 @@ import { launchPrescriptionEditWorkspace, navigateAndLaunchWorkspace } from '../
|
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
import { useVisitOrOfflineVisit } from '@openmrs/esm-patient-common-lib/src';
|
|
9
9
|
import { Button } from '@carbon/react';
|
|
10
|
+
import styles from './medication-order-button.scss';
|
|
10
11
|
|
|
11
12
|
export interface MedicationOrderButtonProps {
|
|
12
13
|
medicationRequestBundle?: {
|
|
@@ -99,7 +100,7 @@ export const MedicationOrderButton: React.FC<MedicationOrderButtonProps> = ({
|
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
return (
|
|
102
|
-
<div>
|
|
103
|
+
<div className={styles.buttonContainer}>
|
|
103
104
|
{shouldAllowModify && (
|
|
104
105
|
<ModifyButton currentVisit={!!currentVisit} isLoading={isLoading} order={order} patientUuid={patientUuid} />
|
|
105
106
|
)}
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
Button,
|
|
3
3
|
ButtonSet,
|
|
4
4
|
Column,
|
|
5
|
+
ComboBox,
|
|
5
6
|
Form,
|
|
6
7
|
InlineLoading,
|
|
7
8
|
InlineNotification,
|
|
@@ -11,11 +12,10 @@ import {
|
|
|
11
12
|
Stack,
|
|
12
13
|
TextInput,
|
|
13
14
|
TextInputSkeleton,
|
|
14
|
-
ComboBox,
|
|
15
15
|
} from '@carbon/react';
|
|
16
16
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
17
17
|
import { navigate, showModal, showSnackbar, toOmrsIsoString, useConfig, useSession } from '@openmrs/esm-framework';
|
|
18
|
-
import React, { useCallback, useEffect,
|
|
18
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
19
19
|
import { Controller, FormProvider, useForm } from 'react-hook-form';
|
|
20
20
|
import { useTranslation } from 'react-i18next';
|
|
21
21
|
import { useParams } from 'react-router-dom';
|
|
@@ -25,48 +25,23 @@ import { BillingConfig } from '../../../config-schema';
|
|
|
25
25
|
import { useSystemSetting } from '../../../hooks/getMflCode';
|
|
26
26
|
import usePatientDiagnosis from '../../../hooks/usePatientDiagnosis';
|
|
27
27
|
import useProvider from '../../../hooks/useProvider';
|
|
28
|
+
import useProviderList from '../../../hooks/useProviderList';
|
|
28
29
|
import { ClaimSummary, LineItem, MappedBill, OTPVerificationModalOptions } from '../../../types';
|
|
29
30
|
import ClaimExplanationAndJusificationInput from './claims-explanation-and-justification-form-input.component';
|
|
30
|
-
import {
|
|
31
|
-
import useProviderList from '../../../hooks/useProviderList';
|
|
31
|
+
import { ClaimsFormSchema, ClaimsFormSchemaBase, processClaims, useVisit } from './claims-form.resource';
|
|
32
32
|
|
|
33
|
-
import styles from './claims-form.scss';
|
|
34
33
|
import debounce from 'lodash-es/debounce';
|
|
35
|
-
import { formatDateTime } from '../../utils';
|
|
36
34
|
import { otpManager } from '../../../hooks/useOTP';
|
|
37
35
|
import { usePhoneNumberAttribute } from '../../../hooks/usePhoneNumber';
|
|
36
|
+
import { formatDateTime } from '../../utils';
|
|
37
|
+
import styles from './claims-form.scss';
|
|
38
|
+
import ClaimsSupportingDocumentsInput from './claims-supporting-documents-inputs.form';
|
|
38
39
|
|
|
39
40
|
type ClaimsFormProps = {
|
|
40
41
|
bill: MappedBill;
|
|
41
42
|
selectedLineItems: LineItem[];
|
|
42
43
|
};
|
|
43
44
|
|
|
44
|
-
const ClaimsFormSchemaBase = z.object({
|
|
45
|
-
claimExplanation: z.string(),
|
|
46
|
-
claimJustification: z.string(),
|
|
47
|
-
diagnoses: z.array(z.string()),
|
|
48
|
-
visitType: z.string(),
|
|
49
|
-
facility: z.string(),
|
|
50
|
-
treatmentStart: z.string(),
|
|
51
|
-
treatmentEnd: z.string(),
|
|
52
|
-
packages: z.array(z.string()),
|
|
53
|
-
interventions: z.array(z.string()),
|
|
54
|
-
provider: z.string(),
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
const ClaimsFormSchema = z.object({
|
|
58
|
-
claimExplanation: z.string().min(1, { message: 'Claim explanation is required' }),
|
|
59
|
-
claimJustification: z.string().min(1, { message: 'Claim justification is required' }),
|
|
60
|
-
diagnoses: z.array(z.string()).min(1, { message: 'At least one diagnosis is required' }),
|
|
61
|
-
visitType: z.string().min(1, { message: 'Visit type is required' }),
|
|
62
|
-
facility: z.string().min(1, { message: 'Facility is required' }),
|
|
63
|
-
treatmentStart: z.string().min(1, { message: 'Treatment start date is required' }),
|
|
64
|
-
treatmentEnd: z.string().min(1, { message: 'Treatment end date is required' }),
|
|
65
|
-
packages: z.array(z.string()).min(1, { message: 'At least one package is required' }),
|
|
66
|
-
interventions: z.array(z.string()).min(1, { message: 'At least one intervention is required' }),
|
|
67
|
-
provider: z.string().min(1, { message: 'Provider is required' }),
|
|
68
|
-
});
|
|
69
|
-
|
|
70
45
|
enum OTPState {
|
|
71
46
|
NOT_STARTED = 'not_started',
|
|
72
47
|
REQUESTED = 'requested',
|
|
@@ -302,6 +277,7 @@ const ClaimsForm: React.FC<ClaimsFormProps> = ({ bill, selectedLineItems }) => {
|
|
|
302
277
|
billNumber: billUuid,
|
|
303
278
|
packages: data.packages,
|
|
304
279
|
interventions: data.interventions,
|
|
280
|
+
supportingDocuments: data.supportingDocuments ?? [],
|
|
305
281
|
};
|
|
306
282
|
|
|
307
283
|
try {
|
|
@@ -640,7 +616,7 @@ const ClaimsForm: React.FC<ClaimsFormProps> = ({ bill, selectedLineItems }) => {
|
|
|
640
616
|
validationEnabled={validationEnabled}
|
|
641
617
|
onInteraction={() => setValidationEnabled(true)}
|
|
642
618
|
/>
|
|
643
|
-
|
|
619
|
+
<ClaimsSupportingDocumentsInput patientUuid={patientUuid} />
|
|
644
620
|
<ButtonSet className={styles.buttonSet}>
|
|
645
621
|
<Button className={styles.button} kind="secondary" onClick={handleDiscardClaim}>
|
|
646
622
|
{t('discardClaim', 'Discard Claim')}
|
|
@@ -3,6 +3,7 @@ import { useMemo } from 'react';
|
|
|
3
3
|
import useSWR from 'swr';
|
|
4
4
|
import useSWRImmutable from 'swr/immutable';
|
|
5
5
|
import { mockInterventions, mockPackages } from './claims-form.mocks';
|
|
6
|
+
import z from 'zod';
|
|
6
7
|
|
|
7
8
|
interface Provider {
|
|
8
9
|
uuid: string;
|
|
@@ -97,3 +98,64 @@ export const updateClaimStatus = (responseUUID: string) => {
|
|
|
97
98
|
method: 'GET',
|
|
98
99
|
});
|
|
99
100
|
};
|
|
101
|
+
|
|
102
|
+
export const ClaimsFormSchemaBase = z.object({
|
|
103
|
+
claimExplanation: z.string(),
|
|
104
|
+
claimJustification: z.string(),
|
|
105
|
+
diagnoses: z.array(z.string()),
|
|
106
|
+
visitType: z.string(),
|
|
107
|
+
facility: z.string(),
|
|
108
|
+
treatmentStart: z.string(),
|
|
109
|
+
treatmentEnd: z.string(),
|
|
110
|
+
packages: z.array(z.string()),
|
|
111
|
+
interventions: z.array(z.string()),
|
|
112
|
+
provider: z.string(),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
export const ClaimsFormSchema = z.object({
|
|
116
|
+
claimExplanation: z.string().min(1, { message: 'Claim explanation is required' }),
|
|
117
|
+
claimJustification: z.string().min(1, { message: 'Claim justification is required' }),
|
|
118
|
+
diagnoses: z.array(z.string()).min(1, { message: 'At least one diagnosis is required' }),
|
|
119
|
+
visitType: z.string().min(1, { message: 'Visit type is required' }),
|
|
120
|
+
facility: z.string().min(1, { message: 'Facility is required' }),
|
|
121
|
+
treatmentStart: z.string().min(1, { message: 'Treatment start date is required' }),
|
|
122
|
+
treatmentEnd: z.string().min(1, { message: 'Treatment end date is required' }),
|
|
123
|
+
packages: z.array(z.string()).min(1, { message: 'At least one package is required' }),
|
|
124
|
+
interventions: z.array(z.string()).min(1, { message: 'At least one intervention is required' }),
|
|
125
|
+
provider: z.string().min(1, { message: 'Provider is required' }),
|
|
126
|
+
supportingDocuments: z
|
|
127
|
+
.object({
|
|
128
|
+
name: z.string(),
|
|
129
|
+
type: z.string(),
|
|
130
|
+
size: z.number(),
|
|
131
|
+
base64: z.string(),
|
|
132
|
+
intervention: z.string(),
|
|
133
|
+
purpose: z.enum([
|
|
134
|
+
'CLAIM_FORM',
|
|
135
|
+
'PREAUTH_FORM',
|
|
136
|
+
'DISCHARGE_SUMMARY',
|
|
137
|
+
'PRESCRIPTION',
|
|
138
|
+
'LAB_ORDER',
|
|
139
|
+
'INVOICE',
|
|
140
|
+
'BIO_DETAILS',
|
|
141
|
+
'IMAGING_ORDER',
|
|
142
|
+
'OTHER',
|
|
143
|
+
'FINAL_BILL',
|
|
144
|
+
'LAB_RESULTS',
|
|
145
|
+
'DEATH_NOTICE',
|
|
146
|
+
'THEATRE_NOTES',
|
|
147
|
+
'BIRTH_NOTIFICATION',
|
|
148
|
+
]),
|
|
149
|
+
uploadedAt: z.date({ coerce: true }),
|
|
150
|
+
})
|
|
151
|
+
.array(),
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
export function fileToBase64(file: File) {
|
|
155
|
+
return new Promise((resolve, reject) => {
|
|
156
|
+
const reader = new FileReader();
|
|
157
|
+
reader.readAsDataURL(file);
|
|
158
|
+
reader.onload = () => resolve(reader.result);
|
|
159
|
+
reader.onerror = (error) => reject(error);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { Button, Dropdown, FileUploader, InlineLoading, InlineNotification, Tag } from '@carbon/react';
|
|
2
|
+
import { TrashCan } from '@carbon/react/icons';
|
|
3
|
+
import { showSnackbar, usePatient } from '@openmrs/esm-framework';
|
|
4
|
+
import React, { FC } from 'react';
|
|
5
|
+
import { Controller, useFormContext } from 'react-hook-form';
|
|
6
|
+
import { useTranslation } from 'react-i18next';
|
|
7
|
+
import z from 'zod';
|
|
8
|
+
import { ClaimsFormSchema, fileToBase64 } from './claims-form.resource';
|
|
9
|
+
import styles from './claims-form.scss';
|
|
10
|
+
import { InterventionsFilter, useInterventions } from '../../../hooks/useInterventions';
|
|
11
|
+
const ClaimsSupportingDocumentsInput: FC<{ patientUuid: string }> = ({ patientUuid }) => {
|
|
12
|
+
const { t } = useTranslation();
|
|
13
|
+
const form = useFormContext<z.infer<typeof ClaimsFormSchema>>();
|
|
14
|
+
const { error: patientError, isLoading: isPatientLoading, patient } = usePatient(patientUuid);
|
|
15
|
+
const categories = form.watch('packages') ?? [];
|
|
16
|
+
const filters: InterventionsFilter = {
|
|
17
|
+
package_code: categories.join(','),
|
|
18
|
+
applicable_gender: patient?.gender === 'male' ? 'MALE' : 'FEMALE',
|
|
19
|
+
};
|
|
20
|
+
const { error, interventions, isLoading } = useInterventions(filters);
|
|
21
|
+
|
|
22
|
+
const supportDocs = form.watch('supportingDocuments') ?? [];
|
|
23
|
+
const selectedInterventionsObservable = form.watch('interventions') ?? [];
|
|
24
|
+
|
|
25
|
+
if (isLoading || isPatientLoading) {
|
|
26
|
+
return (
|
|
27
|
+
<InlineLoading
|
|
28
|
+
status="active"
|
|
29
|
+
iconDescription="Loading"
|
|
30
|
+
description={t('loadingInterventions', 'Loading interventions') + '...'}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (error || patientError) {
|
|
36
|
+
return (
|
|
37
|
+
<InlineNotification
|
|
38
|
+
aria-label="closes notification"
|
|
39
|
+
kind="error"
|
|
40
|
+
lowContrast={true}
|
|
41
|
+
statusIconDescription="notification"
|
|
42
|
+
title={t('failure', 'Error loading interventions')}
|
|
43
|
+
subtitle={error?.message ?? patientError?.message}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div>
|
|
50
|
+
{supportDocs?.map((doc, i) => (
|
|
51
|
+
<div key={i} className={styles.doc}>
|
|
52
|
+
<Button
|
|
53
|
+
hasIconOnly
|
|
54
|
+
renderIcon={TrashCan}
|
|
55
|
+
kind="danger--ghost"
|
|
56
|
+
onClick={() =>
|
|
57
|
+
form.setValue(
|
|
58
|
+
'supportingDocuments',
|
|
59
|
+
supportDocs.filter((_, ind) => ind != i),
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
/>
|
|
63
|
+
<Controller
|
|
64
|
+
control={form.control}
|
|
65
|
+
name={`supportingDocuments.${i}.base64`}
|
|
66
|
+
render={({ field, fieldState }) => (
|
|
67
|
+
<div className="cds--file__container">
|
|
68
|
+
<FileUploader
|
|
69
|
+
accept={['.jpg', '.png']}
|
|
70
|
+
buttonKind="tertiary"
|
|
71
|
+
buttonLabel={t('select', 'Select')}
|
|
72
|
+
filenameStatus="edit"
|
|
73
|
+
labelDescription={t(
|
|
74
|
+
'supportDocsInstruction',
|
|
75
|
+
'Max file size is 1 MB. Only .jpg and .png files are supported.',
|
|
76
|
+
)}
|
|
77
|
+
labelTitle={t('uploadSupportFiles', 'Upload support files')}
|
|
78
|
+
name=""
|
|
79
|
+
onChange={async ({
|
|
80
|
+
target: {
|
|
81
|
+
files: [file],
|
|
82
|
+
},
|
|
83
|
+
}) => {
|
|
84
|
+
if (file instanceof File) {
|
|
85
|
+
const oneMBInBytes = 1024 * 1024; // 1MB = 1024 KB * 1024 B/KB
|
|
86
|
+
if (file.size > oneMBInBytes) {
|
|
87
|
+
showSnackbar({
|
|
88
|
+
title: t('error', 'Error'),
|
|
89
|
+
kind: 'error',
|
|
90
|
+
subtitle: t('fileToLargeError', 'File size to large exceeding 1MB'),
|
|
91
|
+
});
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const base64 = await fileToBase64(file);
|
|
95
|
+
field.onChange(base64);
|
|
96
|
+
form.setValue(`supportingDocuments.${i}.size`, file.size);
|
|
97
|
+
form.setValue(`supportingDocuments.${i}.name`, file.name);
|
|
98
|
+
form.setValue(`supportingDocuments.${i}.type`, file.type);
|
|
99
|
+
form.setValue(`supportingDocuments.${i}.uploadedAt`, new Date());
|
|
100
|
+
}
|
|
101
|
+
}}
|
|
102
|
+
onClick={() => {}}
|
|
103
|
+
onDelete={() => {
|
|
104
|
+
form.setValue(
|
|
105
|
+
'supportingDocuments',
|
|
106
|
+
supportDocs.filter((_, ind) => ind != i),
|
|
107
|
+
);
|
|
108
|
+
}}
|
|
109
|
+
size="md"
|
|
110
|
+
/>
|
|
111
|
+
{doc.size && <Tag>{(doc.size / 1024).toFixed(2)} KB</Tag>}
|
|
112
|
+
</div>
|
|
113
|
+
)}
|
|
114
|
+
/>
|
|
115
|
+
<Controller
|
|
116
|
+
control={form.control}
|
|
117
|
+
name={`supportingDocuments.${i}.intervention`}
|
|
118
|
+
render={({ field, fieldState }) => (
|
|
119
|
+
<Dropdown
|
|
120
|
+
{...field}
|
|
121
|
+
invalid={Boolean(fieldState?.error?.message)}
|
|
122
|
+
invalidText={fieldState?.error?.message}
|
|
123
|
+
id={'document-intervention'}
|
|
124
|
+
selectedItem={field.value}
|
|
125
|
+
onChange={({ selectedItem }) => field.onChange(selectedItem)}
|
|
126
|
+
items={selectedInterventionsObservable}
|
|
127
|
+
itemToString={(item) => interventions.find((i) => i.interventionCode === item)?.interventionName ?? ''}
|
|
128
|
+
label={t('intervention', 'Intervention')}
|
|
129
|
+
titleText={t('intervention', 'Intervention')}
|
|
130
|
+
/>
|
|
131
|
+
)}
|
|
132
|
+
/>
|
|
133
|
+
<Controller
|
|
134
|
+
control={form.control}
|
|
135
|
+
name={`supportingDocuments.${i}.purpose`}
|
|
136
|
+
render={({ field, fieldState }) => (
|
|
137
|
+
<Dropdown
|
|
138
|
+
invalid={Boolean(fieldState?.error?.message)}
|
|
139
|
+
invalidText={fieldState?.error?.message}
|
|
140
|
+
id={'document-purpose'}
|
|
141
|
+
{...field}
|
|
142
|
+
selectedItem={field.value}
|
|
143
|
+
onChange={({ selectedItem }) => field.onChange(selectedItem)}
|
|
144
|
+
items={[
|
|
145
|
+
'CLAIM_FORM',
|
|
146
|
+
'PREAUTH_FORM',
|
|
147
|
+
'DISCHARGE_SUMMARY',
|
|
148
|
+
'PRESCRIPTION',
|
|
149
|
+
'LAB_ORDER',
|
|
150
|
+
'INVOICE',
|
|
151
|
+
'BIO_DETAILS',
|
|
152
|
+
'IMAGING_ORDER',
|
|
153
|
+
'OTHER',
|
|
154
|
+
'FINAL_BILL',
|
|
155
|
+
'LAB_RESULTS',
|
|
156
|
+
'DEATH_NOTICE',
|
|
157
|
+
'THEATRE_NOTES',
|
|
158
|
+
'BIRTH_NOTIFICATION',
|
|
159
|
+
]}
|
|
160
|
+
label={t('purpose', 'Purpose')}
|
|
161
|
+
titleText={t('purpose', 'Purpose')}
|
|
162
|
+
itemToString={(item) => item.toLowerCase().replace('_', ' ')}
|
|
163
|
+
/>
|
|
164
|
+
)}
|
|
165
|
+
/>
|
|
166
|
+
</div>
|
|
167
|
+
))}
|
|
168
|
+
<Button
|
|
169
|
+
disabled={supportDocs.length >= 4}
|
|
170
|
+
kind="tertiary"
|
|
171
|
+
onClick={async () => {
|
|
172
|
+
const valid = await form.trigger(`supportingDocuments`);
|
|
173
|
+
if (!supportDocs?.length || valid) {
|
|
174
|
+
form.setValue('supportingDocuments', [...supportDocs, {}]);
|
|
175
|
+
}
|
|
176
|
+
}}>
|
|
177
|
+
{t('addSupportDocs', 'Add support docs')}
|
|
178
|
+
</Button>
|
|
179
|
+
</div>
|
|
180
|
+
);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export default ClaimsSupportingDocumentsInput;
|