@kenyaemr/esm-billing-app 5.4.1-pre.1935 → 5.4.1-pre.1941
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 +70 -70
- package/dist/22.js +1 -0
- package/dist/22.js.map +1 -0
- package/dist/300.js +1 -1
- package/dist/423.js +1 -0
- package/dist/423.js.map +1 -0
- package/dist/917.js +2 -0
- package/dist/917.js.map +1 -0
- package/dist/kenyaemr-esm-billing-app.js +1 -1
- package/dist/kenyaemr-esm-billing-app.js.buildmanifest.json +84 -84
- package/dist/kenyaemr-esm-billing-app.js.map +1 -1
- package/dist/main.js +2 -2
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/benefits-package/benefits-package.resources.tsx +1 -1
- package/src/benefits-package/forms/benefit-pre-auth-form.workspace.tsx +8 -52
- package/src/benefits-package/forms/{package-interventions.component.tsx → interventions-form.component.tsx} +25 -13
- package/src/benefits-package/forms/packages-and-interventions-form.component.tsx +72 -0
- package/src/billable-services/billiable-item/order-actions/components/base-order-button.component.tsx +42 -0
- package/src/billable-services/billiable-item/order-actions/components/lab-order-button.component.tsx +51 -0
- package/src/billable-services/billiable-item/order-actions/components/medication-order-button.component.tsx +84 -0
- package/src/billable-services/billiable-item/order-actions/components/order-action-button.component.tsx +29 -0
- package/src/billable-services/billiable-item/order-actions/hooks/useBillStatus.ts +12 -0
- package/src/billable-services/billiable-item/order-actions/hooks/useLabOrderAction.ts +27 -0
- package/src/billable-services/billiable-item/order-actions/hooks/useMedicationOrderAction.ts +106 -0
- package/src/billable-services/billiable-item/order-actions/hooks/useModalHandler.ts +66 -0
- package/src/billable-services/billiable-item/order-actions/styles/order-action.scss +0 -0
- package/src/billing-form/billing-checkin-form.component.tsx +6 -1
- package/src/billing-form/check-in-form.utils.tsx +2 -0
- package/src/billing-form/visit-attributes/visit-attributes-form.component.tsx +13 -3
- package/src/claims/dashboard/form/claims-form.component.tsx +28 -59
- package/src/claims/dashboard/form/claims-form.resource.ts +18 -2
- package/src/config-schema.ts +6 -0
- package/src/constants.ts +1 -0
- package/src/hooks/useInterventions.ts +19 -21
- package/src/index.ts +2 -2
- package/src/routes.json +3 -3
- package/src/types/index.ts +1 -0
- package/translations/en.json +2 -5
- package/dist/138.js +0 -2
- package/dist/138.js.map +0 -1
- package/dist/202.js +0 -1
- package/dist/202.js.map +0 -1
- package/dist/614.js +0 -1
- package/dist/614.js.map +0 -1
- package/src/billable-services/billiable-item/test-order/test-order-action.component.tsx +0 -134
- package/src/billable-services/billiable-item/test-order/test-order-action.test.tsx +0 -178
- /package/dist/{138.js.LICENSE.txt → 917.js.LICENSE.txt} +0 -0
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":"billingDashboardLink","name":"billing-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"billing","title":"billing","slot":"billing-dashboard-slot"}},{"component":"benefitsPackageDashboardLink","name":"benefits-package-dashboard-link","slot":"patient-chart-dashboard-slot","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","slot":"patient-chart-dashboard-slot","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":"require-billing-modal","component":"requirePaymentModal"},{"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":"
|
|
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":"billingDashboardLink","name":"billing-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"billing","title":"billing","slot":"billing-dashboard-slot"}},{"component":"benefitsPackageDashboardLink","name":"benefits-package-dashboard-link","slot":"patient-chart-dashboard-slot","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","slot":"patient-chart-dashboard-slot","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":"require-billing-modal","component":"requirePaymentModal"},{"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","slot":"prescription-action-button-slot","order":0},{"component":"billingOverviewLink","name":"billing-overview-link","order":0,"slot":"billing-dashboard-link-slot"},{"component":"paymentHistoryLink","name":"payment-history-link","slot":"billing-dashboard-link-slot"},{"component":"paymentPointsLink","name":"payment-points-link","slot":"billing-dashboard-link-slot"},{"component":"paymentModesLink","name":"payment-modes-link","slot":"billing-dashboard-link-slot"},{"component":"billManagerLink","name":"bill-manager-link","slot":"billing-dashboard-link-slot"},{"component":"chargeableItemsLink","name":"chargeable-items-link","slot":"billing-dashboard-link-slot"},{"component":"billableExemptionsLink","name":"billable-exemptions-link","slot":"billing-dashboard-link-slot"},{"component":"claimsManagementSideNavGroup","name":"claims-management-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"claims-management","title":"Claims management Overview","slot":"case-management-slot"},"featureFlag":"healthInformationExchange"},{"component":"claimsManagementOverviewDashboardLink","name":"claims-management-overview-link","order":0,"slot":"claims-management-dashboard-link-slot"},{"component":"preAuthRequestsDashboardLink","name":"preauthrequest-overview-link","slot":"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"}],"workspaces":[{"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"}],"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":"retry-claim-request-modal","component":"retryClaimRequestModal"},{"name":"paid-bill-receipt-print-preview-modal","component":"paidBillReceiptPrintPreviewModal"},{"name":"clock-in-modal","component":"clockIn"},{"name":"create-bill-item-modal","component":"createBillItemModal"}],"version":"5.4.1-pre.1941"}
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@ export const preauthSchema = z.object({
|
|
|
16
16
|
providerUuid: z.string().uuid(),
|
|
17
17
|
facilityUuid: z.string().uuid(),
|
|
18
18
|
diagnosisUuids: z.array(z.string()),
|
|
19
|
-
|
|
19
|
+
packages: z.array(z.string()).nonempty('Require atleast 1 package'),
|
|
20
20
|
interventions: z.array(z.string()).nonempty('Require atleast 1 intervention'),
|
|
21
21
|
});
|
|
22
22
|
|
|
@@ -5,16 +5,15 @@ import {
|
|
|
5
5
|
DropdownSkeleton,
|
|
6
6
|
Form,
|
|
7
7
|
FormLabel,
|
|
8
|
-
InlineNotification,
|
|
9
8
|
Layer,
|
|
10
9
|
Loading,
|
|
11
10
|
MultiSelect,
|
|
12
11
|
Stack,
|
|
13
|
-
Tile,
|
|
14
12
|
} from '@carbon/react';
|
|
15
13
|
import { DocumentAttachment } from '@carbon/react/icons';
|
|
16
14
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
17
15
|
import { DefaultWorkspaceProps, showSnackbar, useSession } from '@openmrs/esm-framework';
|
|
16
|
+
import { ErrorState } from '@openmrs/esm-patient-common-lib';
|
|
18
17
|
import React, { useEffect, useRef, useState } from 'react';
|
|
19
18
|
import { Controller, FormProvider, useForm } from 'react-hook-form';
|
|
20
19
|
import { useTranslation } from 'react-i18next';
|
|
@@ -22,14 +21,12 @@ import { z } from 'zod';
|
|
|
22
21
|
import { useVisit } from '../../claims/dashboard/form/claims-form.resource';
|
|
23
22
|
import { MAX_ALLOWED_FILE_SIZE } from '../../constants';
|
|
24
23
|
import { useSystemSetting } from '../../hooks/getMflCode';
|
|
25
|
-
import usePackages from '../../hooks/usePackages';
|
|
26
24
|
import usePatientDiagnosis from '../../hooks/usePatientDiagnosis';
|
|
27
25
|
import useProvider from '../../hooks/useProvider';
|
|
28
26
|
import { PatientBenefit } from '../../types';
|
|
29
27
|
import { preAuthenticateBenefit, preauthSchema } from '../benefits-package.resources';
|
|
30
28
|
import styles from './benefits-pre-auth-form.scss';
|
|
31
|
-
import
|
|
32
|
-
import { ErrorState } from '@openmrs/esm-patient-common-lib';
|
|
29
|
+
import SHABenefitPackangesAndInterventions from './packages-and-interventions-form.component';
|
|
33
30
|
|
|
34
31
|
type BenefitsPreAuth = z.infer<typeof preauthSchema>;
|
|
35
32
|
|
|
@@ -41,7 +38,7 @@ interface BenefitPreAuthFormProps extends DefaultWorkspaceProps {
|
|
|
41
38
|
|
|
42
39
|
const BenefitPreAuthForm: React.FC<BenefitPreAuthFormProps> = ({ closeWorkspace, patientUuid }) => {
|
|
43
40
|
const { t } = useTranslation();
|
|
44
|
-
const { visits: recentVisit, isLoading } = useVisit(patientUuid);
|
|
41
|
+
const { visits: recentVisit, isLoading, error: visitError } = useVisit(patientUuid);
|
|
45
42
|
const { isLoading: diagnosesLoading, diagnoses } = usePatientDiagnosis(patientUuid);
|
|
46
43
|
const inputFileRef = useRef<HTMLInputElement>();
|
|
47
44
|
const [uploadedFile, setUploadedFile] = useState<File | null>(null);
|
|
@@ -53,7 +50,6 @@ const BenefitPreAuthForm: React.FC<BenefitPreAuthFormProps> = ({ closeWorkspace,
|
|
|
53
50
|
sessionLocation: { uuid: facilityUuid, display: facilityName },
|
|
54
51
|
} = useSession();
|
|
55
52
|
const { providerLoading: providerLoading, provider } = useProvider(providerUuid);
|
|
56
|
-
const { isLoading: packagesLoading, error: packageError, packages } = usePackages();
|
|
57
53
|
|
|
58
54
|
const form = useForm<BenefitsPreAuth>({
|
|
59
55
|
defaultValues: {
|
|
@@ -62,6 +58,7 @@ const BenefitPreAuthForm: React.FC<BenefitPreAuthFormProps> = ({ closeWorkspace,
|
|
|
62
58
|
facilityUuid,
|
|
63
59
|
diagnosisUuids: [],
|
|
64
60
|
interventions: [],
|
|
61
|
+
packages: [],
|
|
65
62
|
},
|
|
66
63
|
resolver: zodResolver(preauthSchema),
|
|
67
64
|
});
|
|
@@ -104,9 +101,7 @@ const BenefitPreAuthForm: React.FC<BenefitPreAuthFormProps> = ({ closeWorkspace,
|
|
|
104
101
|
}
|
|
105
102
|
};
|
|
106
103
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (packagesLoading || diagnosesLoading || isLoading || providerLoading) {
|
|
104
|
+
if (diagnosesLoading || isLoading || providerLoading) {
|
|
110
105
|
return (
|
|
111
106
|
<Layer className={styles.loading}>
|
|
112
107
|
<Loading withOverlay={false} small />
|
|
@@ -114,10 +109,10 @@ const BenefitPreAuthForm: React.FC<BenefitPreAuthFormProps> = ({ closeWorkspace,
|
|
|
114
109
|
);
|
|
115
110
|
}
|
|
116
111
|
|
|
117
|
-
if (
|
|
112
|
+
if (visitError) {
|
|
118
113
|
return (
|
|
119
114
|
<Layer className={styles.error}>
|
|
120
|
-
<ErrorState error={
|
|
115
|
+
<ErrorState error={visitError} headerTitle={t('errorMessage', 'Error')} />
|
|
121
116
|
</Layer>
|
|
122
117
|
);
|
|
123
118
|
}
|
|
@@ -206,46 +201,7 @@ const BenefitPreAuthForm: React.FC<BenefitPreAuthFormProps> = ({ closeWorkspace,
|
|
|
206
201
|
)}
|
|
207
202
|
/>
|
|
208
203
|
</Column>
|
|
209
|
-
<
|
|
210
|
-
<Controller
|
|
211
|
-
control={form.control}
|
|
212
|
-
name="packageUUid"
|
|
213
|
-
render={({ field }) => (
|
|
214
|
-
<>
|
|
215
|
-
{packageError ? (
|
|
216
|
-
<InlineNotification
|
|
217
|
-
kind="error"
|
|
218
|
-
subtitle={t('errorFetchingPackages', 'Error fetching packeges')}
|
|
219
|
-
lowContrast
|
|
220
|
-
/>
|
|
221
|
-
) : (
|
|
222
|
-
<Dropdown
|
|
223
|
-
ref={field.ref}
|
|
224
|
-
invalid={form.formState.errors[field.name]?.message}
|
|
225
|
-
invalidText={form.formState.errors[field.name]?.message}
|
|
226
|
-
id="package"
|
|
227
|
-
titleText={t('package', 'Package')}
|
|
228
|
-
onChange={(e) => {
|
|
229
|
-
field.onChange(e.selectedItem);
|
|
230
|
-
}}
|
|
231
|
-
initialSelectedItem={field.value}
|
|
232
|
-
label="Choose package"
|
|
233
|
-
items={packages.map((r) => r.uuid)}
|
|
234
|
-
itemToString={(item) => packages.find((r) => r.uuid === item)?.packageName ?? ''}
|
|
235
|
-
/>
|
|
236
|
-
)}
|
|
237
|
-
</>
|
|
238
|
-
)}
|
|
239
|
-
/>
|
|
240
|
-
</Column>
|
|
241
|
-
{selectedPackageObservable && (
|
|
242
|
-
<Column>
|
|
243
|
-
<PackageInterventions
|
|
244
|
-
category={packages.find((package_) => package_.uuid === selectedPackageObservable)?.packageCode ?? ''}
|
|
245
|
-
patientUuid={patientUuid}
|
|
246
|
-
/>
|
|
247
|
-
</Column>
|
|
248
|
-
)}
|
|
204
|
+
<SHABenefitPackangesAndInterventions patientUuid={patientUuid} />
|
|
249
205
|
<Column>
|
|
250
206
|
<Controller
|
|
251
207
|
control={form.control}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useMemo } from 'react';
|
|
2
2
|
import { InlineLoading, InlineNotification, MultiSelect } from '@carbon/react';
|
|
3
3
|
import { Controller, useFormContext } from 'react-hook-form';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
@@ -10,19 +10,35 @@ import { usePatient } from '@openmrs/esm-framework';
|
|
|
10
10
|
type EligibilityRequest = z.infer<typeof eligibilityRequestShema>;
|
|
11
11
|
|
|
12
12
|
type PackageInterventionsProps = {
|
|
13
|
-
|
|
13
|
+
categories: Array<string>;
|
|
14
14
|
patientUuid: string;
|
|
15
15
|
};
|
|
16
|
-
const PackageInterventions: React.FC<PackageInterventionsProps> = ({
|
|
16
|
+
const PackageInterventions: React.FC<PackageInterventionsProps> = ({ categories, patientUuid }) => {
|
|
17
17
|
const { error: patientError, isLoading: isPatientLoading, patient } = usePatient(patientUuid);
|
|
18
18
|
const filters: InterventionsFilter = {
|
|
19
|
-
package_code:
|
|
19
|
+
package_code: categories.join(','),
|
|
20
20
|
applicable_gender: patient?.gender === 'male' ? 'MALE' : 'FEMALE',
|
|
21
21
|
};
|
|
22
|
-
const { error, interventions, isLoading } = useInterventions(filters);
|
|
22
|
+
const { error, interventions, isLoading, allInterventions } = useInterventions(filters);
|
|
23
23
|
|
|
24
|
-
const form = useFormContext<
|
|
24
|
+
const form = useFormContext<{ packages: Array<string>; interventions: Array<string> }>();
|
|
25
25
|
const { t } = useTranslation();
|
|
26
|
+
const selectedInterventionsObservable = form.watch('interventions');
|
|
27
|
+
|
|
28
|
+
const interventions_ = useMemo(() => {
|
|
29
|
+
const additionalInterventions = selectedInterventionsObservable.reduce((prev, curr) => {
|
|
30
|
+
const interventionContainedInOptions = interventions.some((i) => i.interventionCode === curr);
|
|
31
|
+
if (!interventionContainedInOptions) {
|
|
32
|
+
const intervention = allInterventions.find((i) => i.interventionCode === curr);
|
|
33
|
+
if (intervention) {
|
|
34
|
+
prev.push(intervention);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return prev;
|
|
38
|
+
}, [] as typeof allInterventions);
|
|
39
|
+
|
|
40
|
+
return [...interventions, ...additionalInterventions];
|
|
41
|
+
}, [allInterventions, interventions, selectedInterventionsObservable]);
|
|
26
42
|
|
|
27
43
|
if (isLoading || isPatientLoading) {
|
|
28
44
|
return (
|
|
@@ -47,10 +63,6 @@ const PackageInterventions: React.FC<PackageInterventionsProps> = ({ category, p
|
|
|
47
63
|
);
|
|
48
64
|
}
|
|
49
65
|
|
|
50
|
-
if (interventions.length === 0) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
66
|
return (
|
|
55
67
|
<Controller
|
|
56
68
|
control={form.control}
|
|
@@ -65,10 +77,10 @@ const PackageInterventions: React.FC<PackageInterventionsProps> = ({ category, p
|
|
|
65
77
|
onChange={(e) => {
|
|
66
78
|
field.onChange(e.selectedItems);
|
|
67
79
|
}}
|
|
68
|
-
|
|
80
|
+
selectedItems={field.value}
|
|
69
81
|
label={t('chooseInterventions', 'Choose interventions')}
|
|
70
|
-
items={
|
|
71
|
-
itemToString={(item) =>
|
|
82
|
+
items={interventions_.map((r) => r.interventionCode)}
|
|
83
|
+
itemToString={(item) => interventions_.find((r) => r.interventionCode === item)?.interventionName ?? ''}
|
|
72
84
|
/>
|
|
73
85
|
)}
|
|
74
86
|
/>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Column, InlineLoading, InlineNotification, MultiSelect } from '@carbon/react';
|
|
2
|
+
import React, { useEffect } from 'react';
|
|
3
|
+
import { Controller, useFormContext } from 'react-hook-form';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import PackageInterventions from './interventions-form.component';
|
|
6
|
+
import usePackages from '../../hooks/usePackages';
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
patientUuid: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const SHABenefitPackangesAndInterventions: React.FC<Props> = ({ patientUuid }) => {
|
|
13
|
+
const form = useFormContext<{ packages: Array<string>; interventions: Array<string> }>();
|
|
14
|
+
const { isLoading: packagesLoading, error: packageError, packages } = usePackages();
|
|
15
|
+
const { t } = useTranslation();
|
|
16
|
+
const selectedPackageObservable = form.watch('packages');
|
|
17
|
+
|
|
18
|
+
if (packagesLoading) {
|
|
19
|
+
return (
|
|
20
|
+
<InlineLoading description={t('loading', 'Loading')} iconDescription={t('loading', 'Loading data') + '...'} />
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
<Column>
|
|
27
|
+
<Controller
|
|
28
|
+
control={form.control}
|
|
29
|
+
name="packages"
|
|
30
|
+
render={({ field }) => (
|
|
31
|
+
<>
|
|
32
|
+
{packageError ? (
|
|
33
|
+
<InlineNotification
|
|
34
|
+
kind="error"
|
|
35
|
+
subtitle={t('errorFetchingPackages', 'Error fetching packeges')}
|
|
36
|
+
lowContrast
|
|
37
|
+
/>
|
|
38
|
+
) : (
|
|
39
|
+
<MultiSelect
|
|
40
|
+
ref={field.ref}
|
|
41
|
+
invalid={form.formState.errors[field.name]?.message}
|
|
42
|
+
invalidText={form.formState.errors[field.name]?.message}
|
|
43
|
+
id="packages"
|
|
44
|
+
titleText={t('package', 'Packages')}
|
|
45
|
+
onChange={(e) => {
|
|
46
|
+
field.onChange(e.selectedItems);
|
|
47
|
+
}}
|
|
48
|
+
selectedItems={field.value}
|
|
49
|
+
label={t('choosePackage', 'Choose package')}
|
|
50
|
+
items={packages.map((r) => r.uuid)}
|
|
51
|
+
itemToString={(item) => packages.find((r) => r.uuid === item)?.packageName ?? ''}
|
|
52
|
+
/>
|
|
53
|
+
)}
|
|
54
|
+
</>
|
|
55
|
+
)}
|
|
56
|
+
/>
|
|
57
|
+
</Column>
|
|
58
|
+
<Column>
|
|
59
|
+
<PackageInterventions
|
|
60
|
+
categories={
|
|
61
|
+
packages
|
|
62
|
+
.filter((packages_) => selectedPackageObservable.includes(packages_.uuid))
|
|
63
|
+
?.map((p) => p.packageCode) ?? []
|
|
64
|
+
}
|
|
65
|
+
patientUuid={patientUuid}
|
|
66
|
+
/>
|
|
67
|
+
</Column>
|
|
68
|
+
</>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default SHABenefitPackangesAndInterventions;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { InlineLoading, Button } from '@carbon/react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
export type BaseOrderButtonProps = {
|
|
5
|
+
isDisabled: boolean;
|
|
6
|
+
isLoading: boolean;
|
|
7
|
+
buttonText: string;
|
|
8
|
+
onClick: () => void;
|
|
9
|
+
kind?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'tertiary';
|
|
10
|
+
size?: 'sm' | 'md' | 'lg';
|
|
11
|
+
className?: string;
|
|
12
|
+
Icon?;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const BaseOrderButton: React.FC<BaseOrderButtonProps> = ({
|
|
16
|
+
isDisabled,
|
|
17
|
+
isLoading,
|
|
18
|
+
buttonText,
|
|
19
|
+
onClick,
|
|
20
|
+
kind = 'primary',
|
|
21
|
+
size = 'md',
|
|
22
|
+
className = '',
|
|
23
|
+
Icon,
|
|
24
|
+
}) => {
|
|
25
|
+
const { t } = useTranslation();
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Button
|
|
29
|
+
kind={isLoading ? 'ghost' : kind}
|
|
30
|
+
renderIcon={!isLoading ? Icon : undefined}
|
|
31
|
+
className={className}
|
|
32
|
+
size={size}
|
|
33
|
+
disabled={isLoading || isDisabled}
|
|
34
|
+
onClick={onClick}>
|
|
35
|
+
{isLoading ? (
|
|
36
|
+
<InlineLoading description={t('verifyingBillStatus', 'Verifying bill status...')} status="active" />
|
|
37
|
+
) : (
|
|
38
|
+
buttonText
|
|
39
|
+
)}
|
|
40
|
+
</Button>
|
|
41
|
+
);
|
|
42
|
+
};
|
package/src/billable-services/billiable-item/order-actions/components/lab-order-button.component.tsx
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { showModal } from '@openmrs/esm-framework';
|
|
3
|
+
import { Order } from '@openmrs/esm-patient-common-lib';
|
|
4
|
+
import { BaseOrderButton } from './base-order-button.component';
|
|
5
|
+
import { useLabOrderAction } from '../hooks/useLabOrderAction';
|
|
6
|
+
import { useModalHandler } from '../hooks/useModalHandler';
|
|
7
|
+
import styles from '../styles/order-action.scss';
|
|
8
|
+
|
|
9
|
+
export interface LabOrderButtonProps {
|
|
10
|
+
order?: Order;
|
|
11
|
+
modalName?: string;
|
|
12
|
+
additionalProps?: Record<string, unknown>;
|
|
13
|
+
actionText?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const LabOrderButton: React.FC<LabOrderButtonProps> = ({
|
|
17
|
+
order,
|
|
18
|
+
modalName = 'pickup-lab-request-modal',
|
|
19
|
+
additionalProps,
|
|
20
|
+
actionText,
|
|
21
|
+
}) => {
|
|
22
|
+
const { isLoading, isDisabled, buttonText: defaultButtonText, isInProgress } = useLabOrderAction(order);
|
|
23
|
+
|
|
24
|
+
const { handleModalClose } = useModalHandler(additionalProps?.mutateUrl as string);
|
|
25
|
+
const buttonText = actionText ?? defaultButtonText;
|
|
26
|
+
|
|
27
|
+
const launchModal = useCallback(() => {
|
|
28
|
+
const dispose = showModal(modalName, {
|
|
29
|
+
closeModal: () => {
|
|
30
|
+
handleModalClose();
|
|
31
|
+
dispose();
|
|
32
|
+
},
|
|
33
|
+
order,
|
|
34
|
+
...(additionalProps && { additionalProps }),
|
|
35
|
+
});
|
|
36
|
+
}, [modalName, order, additionalProps, handleModalClose]);
|
|
37
|
+
|
|
38
|
+
if (isInProgress) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<BaseOrderButton
|
|
44
|
+
isLoading={isLoading}
|
|
45
|
+
isDisabled={isDisabled}
|
|
46
|
+
buttonText={buttonText}
|
|
47
|
+
onClick={launchModal}
|
|
48
|
+
className={styles.actionButton}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { Edit } from '@carbon/react/icons';
|
|
3
|
+
import { showModal, launchWorkspace } from '@openmrs/esm-framework';
|
|
4
|
+
import { BaseOrderButton } from './base-order-button.component';
|
|
5
|
+
import { useMedicationOrderAction, useOrderByUuid } from '../hooks/useMedicationOrderAction';
|
|
6
|
+
import { launchPrescriptionEditWorkspace, useModalHandler } from '../hooks/useModalHandler';
|
|
7
|
+
import { useTranslation } from 'react-i18next';
|
|
8
|
+
export interface MedicationOrderButtonProps {
|
|
9
|
+
medicationRequestBundle?: {
|
|
10
|
+
request: fhir.MedicationRequest;
|
|
11
|
+
};
|
|
12
|
+
modalName?: string;
|
|
13
|
+
additionalProps?: Record<string, unknown>;
|
|
14
|
+
actionText?: string;
|
|
15
|
+
closeable?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const MedicationOrderButton: React.FC<MedicationOrderButtonProps> = ({
|
|
19
|
+
medicationRequestBundle,
|
|
20
|
+
modalName,
|
|
21
|
+
additionalProps,
|
|
22
|
+
actionText,
|
|
23
|
+
closeable = true,
|
|
24
|
+
}) => {
|
|
25
|
+
const { t } = useTranslation();
|
|
26
|
+
const {
|
|
27
|
+
isLoading: isMedicationOrderLoading,
|
|
28
|
+
isDisabled,
|
|
29
|
+
buttonText: defaultButtonText,
|
|
30
|
+
shouldShowBillModal,
|
|
31
|
+
dispenseFormProps,
|
|
32
|
+
patientUuid,
|
|
33
|
+
shouldAllowModify,
|
|
34
|
+
} = useMedicationOrderAction(medicationRequestBundle);
|
|
35
|
+
const { data: order, isLoading: isOrderLoading } = useOrderByUuid(medicationRequestBundle?.request?.id);
|
|
36
|
+
const isLoading = isMedicationOrderLoading && isOrderLoading;
|
|
37
|
+
|
|
38
|
+
const { handleModalClose } = useModalHandler(additionalProps?.mutateUrl as string);
|
|
39
|
+
const buttonText = actionText ?? defaultButtonText;
|
|
40
|
+
|
|
41
|
+
const launchModal = useCallback(() => {
|
|
42
|
+
if (shouldShowBillModal) {
|
|
43
|
+
const disposeBill = showModal(modalName ?? 'create-bill-item-modal', {
|
|
44
|
+
closeModal: () => {
|
|
45
|
+
handleModalClose();
|
|
46
|
+
disposeBill();
|
|
47
|
+
},
|
|
48
|
+
medicationRequestBundle,
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (dispenseFormProps) {
|
|
54
|
+
launchWorkspace('dispense-workspace', dispenseFormProps);
|
|
55
|
+
}
|
|
56
|
+
}, [modalName, shouldShowBillModal, handleModalClose, medicationRequestBundle, dispenseFormProps]);
|
|
57
|
+
|
|
58
|
+
if (!closeable) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div>
|
|
64
|
+
{shouldAllowModify && (
|
|
65
|
+
<BaseOrderButton
|
|
66
|
+
size="lg"
|
|
67
|
+
kind="tertiary"
|
|
68
|
+
Icon={Edit}
|
|
69
|
+
isLoading={isLoading}
|
|
70
|
+
isDisabled={false}
|
|
71
|
+
buttonText={t('modify', 'Modify')}
|
|
72
|
+
onClick={() => launchPrescriptionEditWorkspace(order, patientUuid)}
|
|
73
|
+
/>
|
|
74
|
+
)}
|
|
75
|
+
<BaseOrderButton
|
|
76
|
+
size="lg"
|
|
77
|
+
isLoading={isLoading}
|
|
78
|
+
isDisabled={isDisabled}
|
|
79
|
+
buttonText={buttonText}
|
|
80
|
+
onClick={launchModal}
|
|
81
|
+
/>
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LabOrderButton } from './lab-order-button.component';
|
|
3
|
+
import { MedicationOrderButton } from './medication-order-button.component';
|
|
4
|
+
|
|
5
|
+
const OrderActionButton: React.FC<Record<string, any>> = (props) => {
|
|
6
|
+
if (Object.hasOwn(props, 'medicationRequestBundle')) {
|
|
7
|
+
const { medicationRequestBundle, modalName, additionalProps, actionText, closeable } = props;
|
|
8
|
+
return (
|
|
9
|
+
<MedicationOrderButton
|
|
10
|
+
medicationRequestBundle={medicationRequestBundle}
|
|
11
|
+
modalName={modalName}
|
|
12
|
+
additionalProps={additionalProps}
|
|
13
|
+
actionText={actionText}
|
|
14
|
+
closeable={closeable}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (props.orderType === 'lab') {
|
|
20
|
+
const { order, modalName, additionalProps, actionText } = props;
|
|
21
|
+
return (
|
|
22
|
+
<LabOrderButton order={order} modalName={modalName} additionalProps={additionalProps} actionText={actionText} />
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return null;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default OrderActionButton;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useOrderBill, useTestOrderBillStatus } from '../../test-order/test-order-action.resource';
|
|
2
|
+
|
|
3
|
+
export function useBillStatus(orderUuid?: string, patientUuid?: string) {
|
|
4
|
+
const { isLoading, hasPendingPayment } = useTestOrderBillStatus(orderUuid, patientUuid);
|
|
5
|
+
const { itemHasBill } = useOrderBill(patientUuid, orderUuid);
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
isLoading,
|
|
9
|
+
hasPendingPayment,
|
|
10
|
+
itemHasBill,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useTranslation } from 'react-i18next';
|
|
2
|
+
import { Order } from '@openmrs/esm-patient-common-lib';
|
|
3
|
+
import { useBillStatus } from './useBillStatus';
|
|
4
|
+
|
|
5
|
+
export enum FulfillerStatus {
|
|
6
|
+
IN_PROGRESS = 'IN_PROGRESS',
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function useLabOrderAction(order?: Order) {
|
|
10
|
+
const { t } = useTranslation();
|
|
11
|
+
const orderUuid = order?.uuid;
|
|
12
|
+
const patientUuid = order?.patient?.uuid;
|
|
13
|
+
|
|
14
|
+
const { isLoading, hasPendingPayment } = useBillStatus(orderUuid, patientUuid);
|
|
15
|
+
|
|
16
|
+
const isInProgress = order?.fulfillerStatus === FulfillerStatus.IN_PROGRESS;
|
|
17
|
+
const buttonText = hasPendingPayment ? t('unsettledBill', 'Unsettled bill') : t('pickLabRequest', 'Pick Lab Request');
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
isLoading,
|
|
21
|
+
isDisabled: hasPendingPayment,
|
|
22
|
+
buttonText,
|
|
23
|
+
isInProgress,
|
|
24
|
+
orderUuid,
|
|
25
|
+
patientUuid,
|
|
26
|
+
};
|
|
27
|
+
}
|