@kenyaemr/esm-billing-app 5.3.10-pre.1650 → 5.3.10-pre.1652
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 +50 -50
- package/dist/300.js +1 -1
- package/dist/{571.js → 999.js} +1 -1
- package/dist/999.js.map +1 -0
- package/dist/kenyaemr-esm-billing-app.js +1 -1
- package/dist/kenyaemr-esm-billing-app.js.buildmanifest.json +31 -31
- package/dist/kenyaemr-esm-billing-app.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/billable-services/payment-history/payment-history-table.component.tsx +5 -1
- package/src/hooks/usePaymentSchema.tsx +42 -0
- package/src/invoice/payments/payment-form/payment-form.component.tsx +27 -17
- package/src/invoice/payments/payments.component.tsx +7 -15
- package/src/invoice/payments/payments.test.tsx +1 -1
- package/src/invoice/payments/utils.ts +18 -5
- package/src/payment-modes/payment-mode.workspace.test.tsx +2 -3
- package/src/payment-modes/payment-mode.workspace.tsx +1 -1
- package/src/types/index.ts +1 -1
- package/translations/en.json +3 -2
- package/dist/571.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":"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":"billing-test-order-action","component":"testOrderAction","slot":"tests-ordered-actions-slot","order":0},{"component":"billingOverviewLink","name":"billing-overview-link","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","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-in-modal","component":"clockIn"},{"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"}],"version":"5.3.10-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":"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":"billing-test-order-action","component":"testOrderAction","slot":"tests-ordered-actions-slot","order":0},{"component":"billingOverviewLink","name":"billing-overview-link","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","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-in-modal","component":"clockIn"},{"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"}],"version":"5.3.10-pre.1652"}
|
package/package.json
CHANGED
|
@@ -59,7 +59,10 @@ export const PaymentHistoryTable = ({
|
|
|
59
59
|
return {
|
|
60
60
|
...row,
|
|
61
61
|
totalAmount: convertToCurrency(row.payments.reduce((acc, payment) => acc + payment.amountTendered, 0)),
|
|
62
|
-
referenceCodes: row.payments
|
|
62
|
+
referenceCodes: row.payments
|
|
63
|
+
.map(({ attributes }) => attributes.map(({ value }) => value).join(', '))
|
|
64
|
+
.filter((code) => code !== '')
|
|
65
|
+
.join(', '),
|
|
63
66
|
};
|
|
64
67
|
});
|
|
65
68
|
|
|
@@ -83,6 +86,7 @@ export const PaymentHistoryTable = ({
|
|
|
83
86
|
'Total Amount Paid': row.payments.reduce((acc, payment) => acc + payment.amountTendered, 0),
|
|
84
87
|
'Reason/Reference': row.payments
|
|
85
88
|
.map(({ attributes }) => attributes.map(({ value }) => value).join(' '))
|
|
89
|
+
.filter((code) => code !== '')
|
|
86
90
|
.join(', '),
|
|
87
91
|
};
|
|
88
92
|
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type MappedBill } from '../types';
|
|
3
|
+
|
|
4
|
+
export function usePaymentSchema(bill: MappedBill) {
|
|
5
|
+
const paymentSchema = z
|
|
6
|
+
.object({
|
|
7
|
+
method: z
|
|
8
|
+
.object({
|
|
9
|
+
uuid: z.string(),
|
|
10
|
+
name: z.string(),
|
|
11
|
+
attributeTypes: z.array(
|
|
12
|
+
z.object({
|
|
13
|
+
uuid: z.string(),
|
|
14
|
+
description: z.string(),
|
|
15
|
+
required: z.boolean(),
|
|
16
|
+
}),
|
|
17
|
+
),
|
|
18
|
+
})
|
|
19
|
+
.nullable()
|
|
20
|
+
.refine((val) => val !== null, { message: 'Payment method is required' }),
|
|
21
|
+
amount: z.number().refine((value) => {
|
|
22
|
+
const amountDue = Number(bill.totalAmount) - (Number(bill.tenderedAmount) + Number(value));
|
|
23
|
+
return amountDue >= 0 && value > 0;
|
|
24
|
+
}, 'Amount paid should not be greater than amount due'),
|
|
25
|
+
referenceCode: z.string(),
|
|
26
|
+
})
|
|
27
|
+
.refine(
|
|
28
|
+
(data) => {
|
|
29
|
+
const hasRequiredAttribute = data.method?.attributeTypes.some((attr) => attr.required === true);
|
|
30
|
+
if (hasRequiredAttribute) {
|
|
31
|
+
return data.referenceCode.trim().length > 0;
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
message: 'Reference code is required for this payment method',
|
|
37
|
+
path: ['referenceCode'],
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
return paymentSchema;
|
|
42
|
+
}
|
|
@@ -6,12 +6,12 @@ import { Button, Dropdown, NumberInputSkeleton, TextInput, NumberInput } from '@
|
|
|
6
6
|
import { ErrorState } from '@openmrs/esm-patient-common-lib';
|
|
7
7
|
import styles from './payment-form.scss';
|
|
8
8
|
import { usePaymentModes } from '../../../billing.resource';
|
|
9
|
-
import { PaymentFormValue } from '../../../types';
|
|
9
|
+
import { PaymentFormValue, PaymentMethod } from '../../../types';
|
|
10
10
|
|
|
11
11
|
type PaymentFormProps = {
|
|
12
12
|
disablePayment: boolean;
|
|
13
13
|
amountDue: number;
|
|
14
|
-
append: (obj: { method:
|
|
14
|
+
append: (obj: { method: PaymentMethod; amount: number; referenceCode: string }) => void;
|
|
15
15
|
fields: FieldArrayWithId<PaymentFormValue, 'payment', 'id'>[];
|
|
16
16
|
remove: UseFieldArrayRemove;
|
|
17
17
|
};
|
|
@@ -22,12 +22,18 @@ const PaymentForm: React.FC<PaymentFormProps> = ({ disablePayment, amountDue, ap
|
|
|
22
22
|
control,
|
|
23
23
|
formState: { errors },
|
|
24
24
|
setFocus,
|
|
25
|
+
getValues,
|
|
25
26
|
} = useFormContext<PaymentFormValue>();
|
|
26
27
|
const { paymentModes, isLoading, error } = usePaymentModes();
|
|
27
28
|
|
|
29
|
+
const shouldShowReferenceCode = (index: number) => {
|
|
30
|
+
const formValues = getValues();
|
|
31
|
+
return formValues?.payment?.[index]?.method?.attributeTypes?.some((attribute) => attribute.required);
|
|
32
|
+
};
|
|
33
|
+
|
|
28
34
|
const handleAppendPaymentMode = useCallback(() => {
|
|
29
35
|
{
|
|
30
|
-
append({ method:
|
|
36
|
+
append({ method: null, amount: 0, referenceCode: '' });
|
|
31
37
|
setFocus(`payment.${fields.length}.method`);
|
|
32
38
|
}
|
|
33
39
|
}, [append]);
|
|
@@ -59,7 +65,7 @@ const PaymentForm: React.FC<PaymentFormProps> = ({ disablePayment, amountDue, ap
|
|
|
59
65
|
id="paymentMethod"
|
|
60
66
|
onChange={({ selectedItem }) => {
|
|
61
67
|
setFocus(`payment.${index}.amount`);
|
|
62
|
-
field.onChange(selectedItem
|
|
68
|
+
field.onChange(selectedItem);
|
|
63
69
|
}}
|
|
64
70
|
titleText={t('paymentMethod', 'Payment method')}
|
|
65
71
|
label={t('selectPaymentMethod', 'Select payment method')}
|
|
@@ -85,19 +91,23 @@ const PaymentForm: React.FC<PaymentFormProps> = ({ disablePayment, amountDue, ap
|
|
|
85
91
|
/>
|
|
86
92
|
)}
|
|
87
93
|
/>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
94
|
+
{shouldShowReferenceCode(index) && (
|
|
95
|
+
<Controller
|
|
96
|
+
name={`payment.${index}.referenceCode`}
|
|
97
|
+
control={control}
|
|
98
|
+
render={({ field }) => (
|
|
99
|
+
<TextInput
|
|
100
|
+
{...field}
|
|
101
|
+
id="paymentReferenceCode"
|
|
102
|
+
labelText={t('referenceNumber', 'Reference number')}
|
|
103
|
+
placeholder={t('enterReferenceNumber', 'Enter ref. number')}
|
|
104
|
+
type="text"
|
|
105
|
+
invalid={!!errors?.payment?.[index]?.referenceCode}
|
|
106
|
+
invalidText={errors?.payment?.[index]?.referenceCode?.message}
|
|
107
|
+
/>
|
|
108
|
+
)}
|
|
109
|
+
/>
|
|
110
|
+
)}
|
|
101
111
|
<div className={styles.removeButtonContainer}>
|
|
102
112
|
<TrashCan onClick={() => handleRemovePaymentMode(index)} className={styles.removeButton} size={20} />
|
|
103
113
|
</div>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { Button, InlineNotification } from '@carbon/react';
|
|
2
3
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
3
4
|
import { navigate, showSnackbar } from '@openmrs/esm-framework';
|
|
4
5
|
import { CardHeader } from '@openmrs/esm-patient-common-lib';
|
|
5
|
-
import React, { useState } from 'react';
|
|
6
6
|
import { FormProvider, useFieldArray, useForm, useWatch } from 'react-hook-form';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
import { mutate } from 'swr';
|
|
@@ -17,6 +17,7 @@ import PaymentForm from './payment-form/payment-form.component';
|
|
|
17
17
|
import PaymentHistory from './payment-history/payment-history.component';
|
|
18
18
|
import styles from './payments.scss';
|
|
19
19
|
import { createPaymentPayload } from './utils';
|
|
20
|
+
import { usePaymentSchema } from '../../hooks/usePaymentSchema';
|
|
20
21
|
|
|
21
22
|
type PaymentProps = {
|
|
22
23
|
bill: MappedBill;
|
|
@@ -25,18 +26,11 @@ type PaymentProps = {
|
|
|
25
26
|
|
|
26
27
|
const Payments: React.FC<PaymentProps> = ({ bill, selectedLineItems }) => {
|
|
27
28
|
const { t } = useTranslation();
|
|
28
|
-
const paymentSchema =
|
|
29
|
-
method: z.string().refine((value) => !!value, 'Payment method is required'),
|
|
30
|
-
amount: z.number().refine((value) => {
|
|
31
|
-
const amountDue = Number(bill.totalAmount) - (Number(bill.tenderedAmount) + Number(value));
|
|
32
|
-
return amountDue >= 0;
|
|
33
|
-
}, 'Amount paid should not be greater than amount due'),
|
|
34
|
-
referenceCode: z.union([z.number(), z.string()]).optional(),
|
|
35
|
-
});
|
|
29
|
+
const paymentSchema = usePaymentSchema(bill);
|
|
36
30
|
const { globalActiveSheet } = useClockInStatus();
|
|
37
31
|
|
|
38
32
|
const methods = useForm<PaymentFormValue>({
|
|
39
|
-
mode: '
|
|
33
|
+
mode: 'onSubmit',
|
|
40
34
|
defaultValues: { payment: [] },
|
|
41
35
|
resolver: zodResolver(z.object({ payment: z.array(paymentSchema) })),
|
|
42
36
|
});
|
|
@@ -46,7 +40,6 @@ const Payments: React.FC<PaymentProps> = ({ bill, selectedLineItems }) => {
|
|
|
46
40
|
name: 'payment',
|
|
47
41
|
control: methods.control,
|
|
48
42
|
});
|
|
49
|
-
const [paymentSuccessful, setPaymentSuccessful] = useState(false);
|
|
50
43
|
|
|
51
44
|
const totalWaivedAmount = computeWaivedAmount(bill);
|
|
52
45
|
const totalAmountTendered = formValues?.reduce((curr: number, prev) => curr + Number(prev.amount), 0) ?? 0;
|
|
@@ -85,7 +78,6 @@ const Payments: React.FC<PaymentProps> = ({ bill, selectedLineItems }) => {
|
|
|
85
78
|
});
|
|
86
79
|
const url = `/ws/rest/v1/cashier/bill/${bill.uuid}`;
|
|
87
80
|
mutate((key) => typeof key === 'string' && key.startsWith(url), undefined, { revalidate: true });
|
|
88
|
-
setPaymentSuccessful(true);
|
|
89
81
|
},
|
|
90
82
|
(error) => {
|
|
91
83
|
showSnackbar({
|
|
@@ -123,7 +115,7 @@ const Payments: React.FC<PaymentProps> = ({ bill, selectedLineItems }) => {
|
|
|
123
115
|
<InlineNotification
|
|
124
116
|
title={t('incompletePayment', 'Incomplete payment')}
|
|
125
117
|
subtitle={t(
|
|
126
|
-
'
|
|
118
|
+
'incompletePaymentSubtitle',
|
|
127
119
|
'Please ensure all selected line items are fully paid, Total amount expected is {{selectedLineItemsAmountDue}}',
|
|
128
120
|
{
|
|
129
121
|
selectedLineItemsAmountDue: convertToCurrency(selectedLineItemsAmountDue),
|
|
@@ -136,9 +128,9 @@ const Payments: React.FC<PaymentProps> = ({ bill, selectedLineItems }) => {
|
|
|
136
128
|
)}
|
|
137
129
|
{hasAmountPaidExceeded && (
|
|
138
130
|
<InlineNotification
|
|
139
|
-
title={t('
|
|
131
|
+
title={t('overPayment', 'Over payment')}
|
|
140
132
|
subtitle={t(
|
|
141
|
-
'
|
|
133
|
+
'overPaymentSubtitle',
|
|
142
134
|
'Amount paid {{totalAmountTendered}} should not be greater than amount due {{selectedLineItemsAmountDue}} for selected line items',
|
|
143
135
|
{
|
|
144
136
|
totalAmountTendered: convertToCurrency(totalAmountTendered),
|
|
@@ -121,7 +121,10 @@ export const createPaymentPayload = (
|
|
|
121
121
|
const existingPayments = payments.map((payment) => ({
|
|
122
122
|
amount: payment.amount,
|
|
123
123
|
amountTendered: payment.amountTendered,
|
|
124
|
-
attributes:
|
|
124
|
+
attributes: payment.attributes.map((attribute) => ({
|
|
125
|
+
attributeType: attribute.attributeType?.uuid,
|
|
126
|
+
value: attribute.value,
|
|
127
|
+
})),
|
|
125
128
|
instanceType: payment.instanceType.uuid,
|
|
126
129
|
}));
|
|
127
130
|
|
|
@@ -129,8 +132,11 @@ export const createPaymentPayload = (
|
|
|
129
132
|
const currentPayments = paymentFormValues.map((formValue) => ({
|
|
130
133
|
amount: parseFloat(totalAmount.toFixed(2)),
|
|
131
134
|
amountTendered: parseFloat(Number(formValue.amount).toFixed(2)),
|
|
132
|
-
attributes:
|
|
133
|
-
|
|
135
|
+
attributes: formValue.method?.attributeTypes?.map((attribute) => ({
|
|
136
|
+
attributeType: attribute.uuid,
|
|
137
|
+
value: formValue.referenceCode,
|
|
138
|
+
})),
|
|
139
|
+
instanceType: formValue.method?.uuid,
|
|
134
140
|
}));
|
|
135
141
|
|
|
136
142
|
// Combine and calculate payments
|
|
@@ -163,13 +169,20 @@ export const createPaymentPayload = (
|
|
|
163
169
|
: // If no items were selected, update payment status for all line items
|
|
164
170
|
lineItems.map((lineItem) => ({
|
|
165
171
|
...lineItem,
|
|
166
|
-
billableService: extractServiceIdentifier(lineItem),
|
|
167
172
|
item: extractServiceIdentifier(lineItem),
|
|
173
|
+
billableService: extractServiceIdentifier(lineItem),
|
|
168
174
|
paymentStatus: isBillableItemFullyPaid(totalPaidAmount, lineItem),
|
|
169
175
|
}));
|
|
170
176
|
|
|
171
177
|
// Combine selected and remaining items into final processed list
|
|
172
|
-
const processedLineItems = [
|
|
178
|
+
const processedLineItems = [
|
|
179
|
+
...processedSelectedBillableItems,
|
|
180
|
+
...remainingLineItems.map((item) => ({
|
|
181
|
+
...item,
|
|
182
|
+
item: extractServiceIdentifier(item),
|
|
183
|
+
billableService: extractServiceIdentifier(item),
|
|
184
|
+
})),
|
|
185
|
+
];
|
|
173
186
|
|
|
174
187
|
// Determine final bill status
|
|
175
188
|
const hasUnpaidItems = processedLineItems.some((item) => item.paymentStatus === PaymentStatus.PENDING);
|
|
@@ -86,11 +86,11 @@ describe('PaymentModeWorkspace', () => {
|
|
|
86
86
|
// key in name, description and retired
|
|
87
87
|
const nameInput = screen.getByRole('textbox', { name: /Payment mode name/i });
|
|
88
88
|
const descriptionInput = screen.getByRole('textbox', { name: /Payment mode description/i });
|
|
89
|
-
const
|
|
89
|
+
const enablePaymentToggle = screen.getByRole('switch', { name: /Enable payment mode/i });
|
|
90
90
|
|
|
91
91
|
await user.type(nameInput, 'Test Name');
|
|
92
92
|
await user.type(descriptionInput, 'Test Description');
|
|
93
|
-
await user.click(
|
|
93
|
+
await user.click(enablePaymentToggle);
|
|
94
94
|
|
|
95
95
|
// Click to add attribute type
|
|
96
96
|
const addAttributeTypeButton = screen.getByRole('button', { name: /Add attribute type/i });
|
|
@@ -102,7 +102,6 @@ describe('PaymentModeWorkspace', () => {
|
|
|
102
102
|
const attributeRegExpInput = screen.getByRole('textbox', { name: /Enter regular expression/i });
|
|
103
103
|
const attributeRetiredToggle = screen.getByRole('switch', { name: /Attribute retired/i });
|
|
104
104
|
const attributeRequiredToggle = screen.getByRole('switch', { name: /Attribute required/i });
|
|
105
|
-
const attributeFormatDropdown = screen.getByRole('combobox', { name: /Attribute format/i });
|
|
106
105
|
|
|
107
106
|
// Key in attribute type details
|
|
108
107
|
await user.type(attributeTypeNameInput, 'Test Attribute Name');
|
|
@@ -167,7 +167,7 @@ const PaymentModeWorkspace: React.FC<PaymentModeWorkspaceProps> = ({
|
|
|
167
167
|
render={({ field }) => (
|
|
168
168
|
<Toggle
|
|
169
169
|
{...field}
|
|
170
|
-
labelText={t('
|
|
170
|
+
labelText={t('enablePaymentMode', 'Enable payment mode')}
|
|
171
171
|
labelA="Off"
|
|
172
172
|
labelB="On"
|
|
173
173
|
toggled={field.value}
|
package/src/types/index.ts
CHANGED
|
@@ -290,7 +290,7 @@ export interface Payment {
|
|
|
290
290
|
resourceVersion: string;
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
-
export type FormPayment = { method:
|
|
293
|
+
export type FormPayment = { method: PaymentMethod; amount: string | number; referenceCode?: number | string };
|
|
294
294
|
|
|
295
295
|
export type PaymentFormValue = {
|
|
296
296
|
payment: Array<FormPayment>;
|
package/translations/en.json
CHANGED
|
@@ -139,6 +139,7 @@
|
|
|
139
139
|
"identifier": "Identifier",
|
|
140
140
|
"inactive": "Inactive",
|
|
141
141
|
"incompletePayment": "Incomplete payment",
|
|
142
|
+
"incompletePaymentSubtitle": "Please ensure all selected line items are fully paid, Total amount expected is {{selectedLineItemsAmountDue}}",
|
|
142
143
|
"initiatePay": "Initiate Payment",
|
|
143
144
|
"inputSampleSchema": "Input sample schema",
|
|
144
145
|
"insuranceScheme": "Insurance scheme",
|
|
@@ -186,6 +187,8 @@
|
|
|
186
187
|
"noTransactionHistorySubtitle": "No transaction history loaded for the selected filters",
|
|
187
188
|
"notSearchedState": "Please search for a patient in the input above",
|
|
188
189
|
"overflowMenu": "Overflow menu",
|
|
190
|
+
"overPayment": "Over payment",
|
|
191
|
+
"overPaymentSubtitle": "Amount paid {{totalAmountTendered}} should not be greater than amount due {{selectedLineItemsAmountDue}} for selected line items",
|
|
189
192
|
"package": "Package",
|
|
190
193
|
"packages": "Packages",
|
|
191
194
|
"packagesOptions": "Choose packages",
|
|
@@ -199,8 +202,6 @@
|
|
|
199
202
|
"patientMissingSHAId": "Patient missing SHA identification number",
|
|
200
203
|
"patientMissingSHANumber": "Patient is missing SHA number, SHA validation cannot be done, Advise patient to visit registration desk",
|
|
201
204
|
"patientName": "Patient Name",
|
|
202
|
-
"paymentError": "Payment error",
|
|
203
|
-
"paymentErrorSubtitle": "Amount paid {{totalAmountTendered}} should not be greater than amount due {{selectedLineItemsAmountDue}} for selected line items",
|
|
204
205
|
"paymentHistory": "Payment History",
|
|
205
206
|
"paymentMethod": "Payment method",
|
|
206
207
|
"paymentMethodDescription": "Payment method {{methodName}}",
|