@openmrs/esm-billing-app 1.0.2-pre.112 → 1.0.2-pre.1124
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/.eslintrc +16 -2
- package/README.md +54 -9
- package/__mocks__/bills.mock.ts +12 -0
- package/__mocks__/react-i18next.js +6 -5
- package/dist/1119.js +1 -1
- package/dist/1146.js +1 -2
- package/dist/1146.js.map +1 -1
- package/dist/1197.js +1 -1
- package/dist/1537.js +1 -0
- package/dist/1537.js.map +1 -0
- package/dist/1856.js +1 -0
- package/dist/1856.js.map +1 -0
- package/dist/2146.js +1 -1
- package/dist/2177.js +1 -1
- package/dist/2177.js.map +1 -1
- package/dist/2524.js +1 -0
- package/dist/2524.js.map +1 -0
- package/dist/2690.js +1 -1
- package/dist/3099.js +1 -1
- package/dist/3584.js +1 -1
- package/dist/3717.js +2 -0
- package/dist/3717.js.map +1 -0
- package/dist/4055.js +1 -1
- package/dist/4132.js +1 -1
- package/dist/4300.js +1 -1
- package/dist/4335.js +1 -1
- package/dist/439.js +1 -0
- package/dist/4618.js +1 -1
- package/dist/4652.js +1 -1
- package/dist/4724.js +1 -0
- package/dist/4724.js.map +1 -0
- package/dist/4739.js +1 -1
- package/dist/4739.js.map +1 -1
- package/dist/4944.js +1 -1
- package/dist/5173.js +1 -1
- package/dist/5241.js +1 -1
- package/dist/5442.js +1 -1
- package/dist/5661.js +1 -1
- package/dist/6022.js +1 -1
- package/dist/6468.js +1 -1
- package/dist/6540.js +1 -1
- package/dist/6540.js.map +1 -1
- package/dist/6589.js +1 -0
- package/dist/6679.js +1 -1
- package/dist/6840.js +1 -1
- package/dist/6859.js +1 -1
- package/dist/7097.js +1 -1
- package/dist/7159.js +1 -1
- package/dist/723.js +1 -1
- package/dist/7255.js +1 -1
- package/dist/7255.js.map +1 -1
- package/dist/7617.js +1 -1
- package/dist/795.js +1 -1
- package/dist/8163.js +1 -1
- package/dist/8349.js +1 -1
- package/dist/8371.js +1 -0
- package/dist/8572.js +1 -0
- package/dist/8572.js.map +1 -0
- package/dist/8618.js +1 -1
- package/dist/8708.js +2 -0
- package/dist/{6557.js.LICENSE.txt → 8708.js.LICENSE.txt} +22 -0
- package/dist/8708.js.map +1 -0
- package/dist/890.js +1 -1
- package/dist/9214.js +1 -1
- package/dist/9538.js +1 -1
- package/dist/9569.js +1 -1
- package/dist/961.js +1 -1
- package/dist/961.js.map +1 -1
- package/dist/986.js +1 -1
- package/dist/9879.js +1 -1
- package/dist/9895.js +1 -1
- package/dist/9900.js +1 -1
- package/dist/9913.js +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-billing-app.js +1 -1
- package/dist/openmrs-esm-billing-app.js.buildmanifest.json +321 -249
- package/dist/openmrs-esm-billing-app.js.map +1 -1
- package/dist/routes.json +1 -1
- package/e2e/README.md +19 -18
- package/e2e/commands/billing-operations.ts +96 -0
- package/e2e/commands/index.ts +3 -0
- package/e2e/commands/patient-operations.ts +82 -0
- package/e2e/commands/types.ts +73 -0
- package/e2e/core/test.ts +12 -1
- package/e2e/fixtures/api.ts +2 -3
- package/e2e/pages/billing-dashboard-page.ts +84 -0
- package/e2e/pages/billing-form-page.ts +114 -0
- package/e2e/pages/index.ts +4 -1
- package/e2e/pages/invoice-page.ts +113 -0
- package/e2e/pages/payment-page.ts +104 -0
- package/e2e/specs/billing-dashboard.spec.ts +203 -0
- package/e2e/specs/billing-patient-chart.spec.ts +738 -0
- package/e2e/support/github/Dockerfile +1 -1
- package/e2e/support/github/run-e2e-docker-env.sh +29 -32
- package/example.env +15 -1
- package/package.json +19 -16
- package/playwright.config.ts +4 -2
- package/src/bill-history/bill-history.component.tsx +15 -17
- package/src/bill-history/bill-history.scss +4 -94
- package/src/bill-history/bill-history.test.tsx +37 -77
- package/src/bill-item-actions/bill-item-actions.scss +21 -5
- package/src/bill-item-actions/edit-bill-item.modal.tsx +227 -0
- package/src/bill-item-actions/edit-bill-item.test.tsx +233 -40
- package/src/billable-services/bill-waiver/bill-selection.component.tsx +5 -5
- package/src/billable-services/bill-waiver/bill-waiver-form.component.tsx +37 -39
- package/src/billable-services/bill-waiver/patient-bills.component.tsx +7 -7
- package/src/billable-services/bill-waiver/utils.ts +13 -3
- package/src/billable-services/{create-edit/add-billable-service.scss → billable-service-form/billable-service-form.scss} +32 -64
- package/src/billable-services/billable-service-form/billable-service-form.test.tsx +1099 -0
- package/src/billable-services/billable-service-form/billable-service-form.workspace.tsx +516 -0
- package/src/billable-services/billable-service.resource.ts +71 -27
- package/src/billable-services/billable-services-home.component.tsx +13 -42
- package/src/billable-services/billable-services-left-panel-link.component.tsx +50 -0
- package/src/billable-services/billable-services-left-panel-menu.component.tsx +48 -0
- package/src/billable-services/billable-services-menu-item/item.component.tsx +5 -4
- package/src/billable-services/billable-services.component.tsx +156 -152
- package/src/billable-services/billable-services.scss +29 -0
- package/src/billable-services/billable-services.test.tsx +6 -49
- package/src/billable-services/cash-point/add-cash-point.modal.tsx +170 -0
- package/src/billable-services/cash-point/cash-point-configuration.component.tsx +19 -193
- package/src/billable-services/cash-point/cash-point-configuration.scss +1 -5
- package/src/billable-services/dashboard/dashboard.component.tsx +0 -2
- package/src/billable-services/payment-modes/delete-payment-mode.modal.tsx +77 -0
- package/src/billable-services/payment-modes/payment-mode-form.modal.tsx +131 -0
- package/src/billable-services/payment-modes/payment-modes-config.component.tsx +139 -0
- package/src/billable-services/{payyment-modes → payment-modes}/payment-modes-config.scss +5 -4
- package/src/billable-services-admin-card-link.component.test.tsx +2 -2
- package/src/billable-services-admin-card-link.component.tsx +1 -1
- package/src/billing-dashboard/billing-dashboard.scss +1 -1
- package/src/billing-form/billing-checkin-form.component.tsx +29 -29
- package/src/billing-form/billing-checkin-form.scss +0 -7
- package/src/billing-form/billing-checkin-form.test.tsx +100 -27
- package/src/billing-form/billing-form.component.tsx +226 -284
- package/src/billing-form/billing-form.scss +143 -0
- package/src/billing-form/visit-attributes/visit-attributes-form.component.tsx +47 -41
- package/src/billing-form/visit-attributes/visit-attributes-form.scss +16 -3
- package/src/billing.resource.test.ts +503 -0
- package/src/billing.resource.ts +68 -76
- package/src/bills-table/bills-table.component.tsx +17 -24
- package/src/bills-table/bills-table.test.tsx +98 -54
- package/src/config-schema.ts +84 -31
- package/src/dashboard.meta.ts +5 -3
- package/src/helpers/functions.ts +5 -4
- package/src/index.ts +75 -13
- package/src/invoice/invoice-table.component.tsx +36 -70
- package/src/invoice/invoice-table.scss +8 -5
- package/src/invoice/invoice-table.test.tsx +273 -62
- package/src/invoice/invoice.component.tsx +44 -38
- package/src/invoice/invoice.scss +11 -4
- package/src/invoice/invoice.test.tsx +324 -120
- package/src/invoice/payments/invoice-breakdown/invoice-breakdown.scss +9 -9
- package/src/invoice/payments/payment-form/payment-form.component.tsx +45 -36
- package/src/invoice/payments/payment-form/payment-form.scss +5 -6
- package/src/invoice/payments/payment-form/payment-form.test.tsx +217 -67
- package/src/invoice/payments/payment-history/payment-history.component.tsx +6 -4
- package/src/invoice/payments/payment-history/payment-history.test.tsx +9 -14
- package/src/invoice/payments/payments.component.tsx +56 -68
- package/src/invoice/payments/payments.scss +4 -3
- package/src/invoice/payments/payments.test.tsx +282 -0
- package/src/invoice/payments/utils.ts +15 -27
- package/src/invoice/printable-invoice/print-receipt.component.tsx +3 -3
- package/src/invoice/printable-invoice/print-receipt.test.tsx +14 -25
- package/src/invoice/printable-invoice/printable-footer.component.tsx +2 -2
- package/src/invoice/printable-invoice/printable-footer.test.tsx +4 -13
- package/src/invoice/printable-invoice/printable-invoice-header.component.tsx +20 -11
- package/src/invoice/printable-invoice/printable-invoice-header.test.tsx +95 -16
- package/src/invoice/printable-invoice/printable-invoice.component.tsx +21 -35
- package/src/left-panel-link.component.tsx +9 -8
- package/src/left-panel-link.test.tsx +1 -4
- package/src/metrics-cards/metrics-cards.component.tsx +16 -6
- package/src/metrics-cards/metrics-cards.scss +4 -0
- package/src/metrics-cards/metrics-cards.test.tsx +18 -5
- package/src/modal/require-payment-modal.test.tsx +27 -22
- package/src/modal/{require-payment-modal.component.tsx → require-payment.modal.tsx} +18 -19
- package/src/routes.json +44 -20
- package/src/types/index.ts +87 -24
- package/translations/am.json +140 -80
- package/translations/ar.json +141 -81
- package/translations/ar_SY.json +141 -81
- package/translations/bn.json +143 -83
- package/translations/cs.json +230 -0
- package/translations/de.json +141 -81
- package/translations/en.json +142 -81
- package/translations/en_US.json +141 -81
- package/translations/es.json +140 -80
- package/translations/es_MX.json +141 -81
- package/translations/fr.json +224 -164
- package/translations/he.json +140 -80
- package/translations/hi.json +141 -81
- package/translations/hi_IN.json +141 -81
- package/translations/id.json +141 -81
- package/translations/it.json +166 -106
- package/translations/ka.json +141 -81
- package/translations/km.json +140 -80
- package/translations/ku.json +141 -81
- package/translations/ky.json +141 -81
- package/translations/lg.json +141 -81
- package/translations/ne.json +141 -81
- package/translations/pl.json +141 -81
- package/translations/pt.json +141 -81
- package/translations/pt_BR.json +141 -81
- package/translations/qu.json +141 -81
- package/translations/ro_RO.json +225 -165
- package/translations/ru_RU.json +141 -81
- package/translations/si.json +141 -81
- package/translations/sq.json +230 -0
- package/translations/sw.json +141 -81
- package/translations/sw_KE.json +141 -81
- package/translations/tr.json +141 -81
- package/translations/tr_TR.json +141 -81
- package/translations/uk.json +141 -81
- package/translations/uz.json +141 -81
- package/translations/uz@Latn.json +141 -81
- package/translations/uz_UZ.json +141 -81
- package/translations/vi.json +141 -81
- package/translations/zh.json +141 -81
- package/translations/zh_CN.json +171 -111
- package/translations/zh_TW.json +230 -0
- package/dist/1146.js.LICENSE.txt +0 -21
- package/dist/2352.js +0 -1
- package/dist/2352.js.map +0 -1
- package/dist/246.js +0 -1
- package/dist/246.js.map +0 -1
- package/dist/4689.js +0 -2
- package/dist/4689.js.map +0 -1
- package/dist/6557.js +0 -2
- package/dist/6557.js.map +0 -1
- package/dist/8638.js +0 -1
- package/dist/8638.js.map +0 -1
- package/dist/9968.js +0 -1
- package/dist/9968.js.map +0 -1
- package/e2e/pages/home-page.ts +0 -9
- package/e2e/specs/sample-test.spec.ts +0 -11
- package/src/bill-item-actions/edit-bill-item.component.tsx +0 -221
- package/src/billable-services/create-edit/add-billable-service.component.tsx +0 -401
- package/src/billable-services/create-edit/add-billable-service.test.tsx +0 -154
- package/src/billable-services/dashboard/service-metrics.component.tsx +0 -41
- package/src/billable-services/payyment-modes/payment-modes-config.component.tsx +0 -280
- package/src/invoice/payments/payments.component.test.tsx +0 -121
- /package/dist/{4689.js.LICENSE.txt → 3717.js.LICENSE.txt} +0 -0
|
@@ -64,25 +64,18 @@ const BillsTable = () => {
|
|
|
64
64
|
const searchResults = useMemo(() => {
|
|
65
65
|
if (!bills?.length) return bills;
|
|
66
66
|
|
|
67
|
-
return bills
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
})
|
|
77
|
-
.filter((bill) => {
|
|
78
|
-
const statusMatch = billPaymentStatus === '' ? true : bill.status === billPaymentStatus;
|
|
79
|
-
const searchMatch = !searchString
|
|
80
|
-
? true
|
|
81
|
-
: bill.patientName.toLowerCase().includes(searchString.toLowerCase()) ||
|
|
82
|
-
bill.identifier.toLowerCase().includes(searchString.toLowerCase());
|
|
67
|
+
return bills.filter((bill) => {
|
|
68
|
+
const statusMatch =
|
|
69
|
+
billPaymentStatus === '' ||
|
|
70
|
+
billPaymentStatus === bill.status ||
|
|
71
|
+
(billPaymentStatus === 'PENDING' && bill.status === 'POSTED');
|
|
72
|
+
const searchMatch = !searchString
|
|
73
|
+
? true
|
|
74
|
+
: bill.patientName.toLowerCase().includes(searchString.toLowerCase()) ||
|
|
75
|
+
bill.identifier.toLowerCase().includes(searchString.toLowerCase());
|
|
83
76
|
|
|
84
|
-
|
|
85
|
-
|
|
77
|
+
return statusMatch && searchMatch;
|
|
78
|
+
});
|
|
86
79
|
}, [bills, searchString, billPaymentStatus]);
|
|
87
80
|
|
|
88
81
|
const { paginated, goTo, results, currentPage } = usePagination(searchResults, pageSize);
|
|
@@ -121,9 +114,9 @@ const BillsTable = () => {
|
|
|
121
114
|
);
|
|
122
115
|
|
|
123
116
|
const filterItems = [
|
|
124
|
-
{ id: '', text: 'All bills' },
|
|
125
|
-
{ id: 'PENDING', text: 'Pending bills' },
|
|
126
|
-
{ id: 'PAID', text: 'Paid bills' },
|
|
117
|
+
{ id: '', text: t('allBills', 'All bills') },
|
|
118
|
+
{ id: 'PENDING', text: t('pendingBills', 'Pending bills') },
|
|
119
|
+
{ id: 'PAID', text: t('paidBills', 'Paid bills') },
|
|
127
120
|
];
|
|
128
121
|
|
|
129
122
|
const handleFilterChange = ({ selectedItem }) => {
|
|
@@ -149,7 +142,7 @@ const BillsTable = () => {
|
|
|
149
142
|
return (
|
|
150
143
|
<div className={styles.errorContainer}>
|
|
151
144
|
<Layer>
|
|
152
|
-
<ErrorState error={error} headerTitle={t('
|
|
145
|
+
<ErrorState error={error} headerTitle={t('billList', 'Bill list')} />
|
|
153
146
|
</Layer>
|
|
154
147
|
</div>
|
|
155
148
|
);
|
|
@@ -168,7 +161,7 @@ const BillsTable = () => {
|
|
|
168
161
|
label=""
|
|
169
162
|
onChange={handleFilterChange}
|
|
170
163
|
size={responsiveSize}
|
|
171
|
-
titleText={t('filterBy', 'Filter by')
|
|
164
|
+
titleText={t('filterBy', 'Filter by:')}
|
|
172
165
|
type="inline"
|
|
173
166
|
/>
|
|
174
167
|
</div>
|
|
@@ -190,7 +183,7 @@ const BillsTable = () => {
|
|
|
190
183
|
useZebraStyles={rowData?.length > 1 ? true : false}>
|
|
191
184
|
{({ rows, headers, getRowProps, getTableProps }) => (
|
|
192
185
|
<TableContainer>
|
|
193
|
-
<Table {...getTableProps()} aria-label=
|
|
186
|
+
<Table {...getTableProps()} aria-label={t('billList', 'Bill list')}>
|
|
194
187
|
<TableHead>
|
|
195
188
|
<TableRow>
|
|
196
189
|
{headers.map((header) => (
|
|
@@ -4,91 +4,126 @@ import { render, screen, waitFor } from '@testing-library/react';
|
|
|
4
4
|
import { useBills } from '../billing.resource';
|
|
5
5
|
import BillsTable from './bills-table.component';
|
|
6
6
|
|
|
7
|
-
jest.mock('
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
jest.mock('@openmrs/esm-framework', () => {
|
|
8
|
+
const actual = jest.requireActual('@openmrs/esm-framework');
|
|
9
|
+
return {
|
|
10
|
+
...actual,
|
|
11
|
+
ConfigurableLink: ({ children, to, templateParams }: any) => {
|
|
12
|
+
let resolvedTo = to as string;
|
|
13
|
+
if (templateParams) {
|
|
14
|
+
resolvedTo = resolvedTo
|
|
15
|
+
.replace('${patientUuid}', templateParams.patientUuid)
|
|
16
|
+
.replace('${uuid}', templateParams.uuid)
|
|
17
|
+
.replace('${openmrsSpaBase}', '/openmrs/spa');
|
|
18
|
+
}
|
|
19
|
+
resolvedTo = resolvedTo.replace(/^\/openmrs\/spa/, '');
|
|
20
|
+
return <a href={resolvedTo}>{children}</a>;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
jest.mock('../billing.resource', () => ({
|
|
26
|
+
useBills: jest.fn(() => ({
|
|
27
|
+
bills: mockBillsData,
|
|
28
|
+
isLoading: false,
|
|
29
|
+
isValidating: false,
|
|
30
|
+
error: null,
|
|
31
|
+
})),
|
|
11
32
|
}));
|
|
12
33
|
|
|
34
|
+
const mockBills = jest.mocked(useBills);
|
|
35
|
+
|
|
13
36
|
const mockBillsData = [
|
|
14
37
|
{
|
|
15
38
|
uuid: '1',
|
|
39
|
+
id: 1,
|
|
16
40
|
patientName: 'John Doe',
|
|
17
41
|
identifier: '12345678',
|
|
18
42
|
visitType: 'Checkup',
|
|
19
43
|
patientUuid: 'uuid1',
|
|
20
44
|
dateCreated: '2024-01-01',
|
|
21
|
-
lineItems: [
|
|
45
|
+
lineItems: [
|
|
46
|
+
{
|
|
47
|
+
uuid: 'line-item-1',
|
|
48
|
+
display: 'Service 1 Line Item',
|
|
49
|
+
voided: false,
|
|
50
|
+
voidReason: null,
|
|
51
|
+
item: 'Service 1',
|
|
52
|
+
billableService: 'Service 1',
|
|
53
|
+
quantity: 1,
|
|
54
|
+
price: 100,
|
|
55
|
+
priceName: 'Standard Price',
|
|
56
|
+
priceUuid: 'price-1',
|
|
57
|
+
lineItemOrder: 1,
|
|
58
|
+
resourceVersion: '1.0',
|
|
59
|
+
paymentStatus: 'PENDING',
|
|
60
|
+
},
|
|
61
|
+
],
|
|
22
62
|
status: 'PENDING',
|
|
63
|
+
cashPointUuid: 'cash-point-1',
|
|
64
|
+
cashPointName: 'Main Cash Point',
|
|
65
|
+
cashPointLocation: 'Main Hospital',
|
|
66
|
+
cashier: { uuid: 'cashier-1', display: 'Jane Cashier', links: [] },
|
|
67
|
+
receiptNumber: 'RCP-001',
|
|
68
|
+
billingService: 'Service 1',
|
|
69
|
+
payments: [],
|
|
70
|
+
totalAmount: 100,
|
|
71
|
+
tenderedAmount: 0,
|
|
23
72
|
},
|
|
24
73
|
{
|
|
25
74
|
uuid: '2',
|
|
75
|
+
id: 2,
|
|
26
76
|
patientName: 'Mary Smith',
|
|
27
77
|
identifier: '98765432',
|
|
28
78
|
visitType: 'Wake up',
|
|
29
79
|
patientUuid: 'uuid2',
|
|
30
80
|
dateCreated: '2024-01-02',
|
|
31
|
-
lineItems: [
|
|
81
|
+
lineItems: [
|
|
82
|
+
{
|
|
83
|
+
uuid: 'line-item-2',
|
|
84
|
+
display: 'Service 2 Line Item',
|
|
85
|
+
voided: false,
|
|
86
|
+
voidReason: null,
|
|
87
|
+
item: 'Service 2',
|
|
88
|
+
billableService: 'Service 2',
|
|
89
|
+
quantity: 1,
|
|
90
|
+
price: 200,
|
|
91
|
+
priceName: 'Standard Price',
|
|
92
|
+
priceUuid: 'price-1',
|
|
93
|
+
lineItemOrder: 1,
|
|
94
|
+
resourceVersion: '1.0',
|
|
95
|
+
paymentStatus: 'PENDING',
|
|
96
|
+
},
|
|
97
|
+
],
|
|
32
98
|
status: 'PENDING',
|
|
99
|
+
cashPointUuid: 'cash-point-1',
|
|
100
|
+
cashPointName: 'Main Cash Point',
|
|
101
|
+
cashPointLocation: 'Main Hospital',
|
|
102
|
+
cashier: { uuid: 'cashier-1', display: 'Jane Cashier', links: [] },
|
|
103
|
+
receiptNumber: 'RCP-002',
|
|
104
|
+
billingService: 'Service 2',
|
|
105
|
+
payments: [],
|
|
106
|
+
totalAmount: 200,
|
|
107
|
+
tenderedAmount: 200,
|
|
33
108
|
},
|
|
34
109
|
];
|
|
35
110
|
|
|
36
|
-
jest.mock('../billing.resource', () => ({
|
|
37
|
-
useBills: jest.fn(() => ({
|
|
38
|
-
bills: mockBillsData,
|
|
39
|
-
isLoading: false,
|
|
40
|
-
isValidating: false,
|
|
41
|
-
error: null,
|
|
42
|
-
})),
|
|
43
|
-
}));
|
|
44
|
-
|
|
45
|
-
jest.mock('@openmrs/esm-patient-common-lib', () => ({
|
|
46
|
-
EmptyDataIllustration: jest.fn(() => <div>Empty state illustration</div>),
|
|
47
|
-
}));
|
|
48
|
-
|
|
49
|
-
jest.mock('@openmrs/esm-framework', () => ({
|
|
50
|
-
useLayoutType: jest.fn(() => 'desktop'),
|
|
51
|
-
isDesktop: jest.fn(() => true),
|
|
52
|
-
ErrorState: jest.fn(({ error }) => <div data-testid="error-state">{error?.message || error}</div>),
|
|
53
|
-
useConfig: jest.fn(() => ({
|
|
54
|
-
bills: {
|
|
55
|
-
pageSizes: [10, 20, 30, 40, 50],
|
|
56
|
-
pageSize: 10,
|
|
57
|
-
},
|
|
58
|
-
})),
|
|
59
|
-
usePagination: jest.fn().mockImplementation((data) => ({
|
|
60
|
-
currentPage: 1,
|
|
61
|
-
goTo: jest.fn(),
|
|
62
|
-
results: data,
|
|
63
|
-
paginated: true,
|
|
64
|
-
})),
|
|
65
|
-
ConfigurableLink: jest.fn(({ children, to, templateParams }) => {
|
|
66
|
-
const resolvedTo = '/home/billing/patient/' + templateParams.patientUuid + '/' + templateParams.uuid;
|
|
67
|
-
return <a href={resolvedTo}>{children}</a>;
|
|
68
|
-
}),
|
|
69
|
-
openmrsSpaBase: '',
|
|
70
|
-
}));
|
|
71
|
-
|
|
72
111
|
describe('BillsTable', () => {
|
|
73
|
-
const mockBills = useBills as jest.Mock;
|
|
74
|
-
let user;
|
|
75
|
-
|
|
76
112
|
beforeEach(() => {
|
|
77
|
-
user = userEvent.setup();
|
|
78
113
|
mockBills.mockImplementation(() => ({
|
|
79
114
|
bills: mockBillsData,
|
|
80
115
|
isLoading: false,
|
|
81
116
|
isValidating: false,
|
|
82
117
|
error: null,
|
|
118
|
+
mutate: jest.fn(),
|
|
83
119
|
}));
|
|
84
120
|
});
|
|
85
121
|
|
|
86
122
|
test('renders data table with pending bills', () => {
|
|
87
123
|
render(<BillsTable />);
|
|
88
124
|
|
|
89
|
-
expect(screen.getByText('
|
|
90
|
-
expect(screen.getByText('
|
|
91
|
-
|
|
125
|
+
expect(screen.getByText('Visit time')).toBeInTheDocument();
|
|
126
|
+
expect(screen.getByText('Identifier')).toBeInTheDocument();
|
|
92
127
|
expect(screen.getByText(/John Doe/)).toBeInTheDocument();
|
|
93
128
|
expect(screen.getByText('12345678')).toBeInTheDocument();
|
|
94
129
|
});
|
|
@@ -99,6 +134,7 @@ describe('BillsTable', () => {
|
|
|
99
134
|
isLoading: false,
|
|
100
135
|
isValidating: false,
|
|
101
136
|
error: null,
|
|
137
|
+
mutate: jest.fn(),
|
|
102
138
|
}));
|
|
103
139
|
|
|
104
140
|
render(<BillsTable />);
|
|
@@ -111,28 +147,33 @@ describe('BillsTable', () => {
|
|
|
111
147
|
isLoading: true,
|
|
112
148
|
isValidating: false,
|
|
113
149
|
error: null,
|
|
150
|
+
mutate: jest.fn(),
|
|
114
151
|
}));
|
|
115
152
|
|
|
116
153
|
render(<BillsTable />);
|
|
154
|
+
|
|
117
155
|
const dataTableSkeleton = screen.getByRole('table');
|
|
118
156
|
expect(dataTableSkeleton).toBeInTheDocument();
|
|
119
157
|
expect(dataTableSkeleton).toHaveClass('cds--skeleton cds--data-table cds--data-table--zebra');
|
|
120
158
|
});
|
|
121
159
|
|
|
122
|
-
test('should display
|
|
160
|
+
test('should display an error state if there is a problem loading bill data', () => {
|
|
123
161
|
mockBills.mockImplementationOnce(() => ({
|
|
124
162
|
bills: undefined,
|
|
125
163
|
isLoading: false,
|
|
126
164
|
isValidating: false,
|
|
127
165
|
error: new Error('Error in fetching data'),
|
|
166
|
+
mutate: jest.fn(),
|
|
128
167
|
}));
|
|
129
168
|
|
|
130
169
|
render(<BillsTable />);
|
|
131
|
-
|
|
170
|
+
|
|
171
|
+
expect(screen.getByText(/error state/i)).toBeInTheDocument();
|
|
132
172
|
expect(screen.queryByRole('table')).not.toBeInTheDocument();
|
|
133
173
|
});
|
|
134
174
|
|
|
135
175
|
test('should filter bills by search term', async () => {
|
|
176
|
+
const user = userEvent.setup();
|
|
136
177
|
render(<BillsTable />);
|
|
137
178
|
|
|
138
179
|
const searchInput = screen.getByRole('searchbox');
|
|
@@ -142,7 +183,6 @@ describe('BillsTable', () => {
|
|
|
142
183
|
expect(screen.getByText('Mary Smith')).toBeInTheDocument();
|
|
143
184
|
|
|
144
185
|
await user.type(searchInput, 'John Doe');
|
|
145
|
-
|
|
146
186
|
await waitFor(() => {
|
|
147
187
|
expect(screen.queryByText('Mary Smith')).not.toBeInTheDocument();
|
|
148
188
|
});
|
|
@@ -156,15 +196,18 @@ describe('BillsTable', () => {
|
|
|
156
196
|
const patientNameLink = screen.getByRole('link', { name: 'John Doe' });
|
|
157
197
|
expect(patientNameLink).toBeInTheDocument();
|
|
158
198
|
|
|
159
|
-
expect(patientNameLink.
|
|
199
|
+
expect(patientNameLink).toHaveAttribute('href', '/home/billing/patient/uuid1/1');
|
|
160
200
|
});
|
|
161
201
|
|
|
162
202
|
test('should filter bills by payment status', async () => {
|
|
203
|
+
const user = userEvent.setup();
|
|
204
|
+
|
|
163
205
|
mockBills.mockImplementationOnce(() => ({
|
|
164
206
|
bills: mockBillsData.map((bill) => ({ ...bill, status: 'PENDING' })),
|
|
165
207
|
isLoading: false,
|
|
166
208
|
isValidating: false,
|
|
167
209
|
error: null,
|
|
210
|
+
mutate: jest.fn(),
|
|
168
211
|
}));
|
|
169
212
|
|
|
170
213
|
render(<BillsTable />);
|
|
@@ -175,7 +218,7 @@ describe('BillsTable', () => {
|
|
|
175
218
|
const paidBillsOption = screen.getAllByText('Paid bills')[0];
|
|
176
219
|
await user.click(paidBillsOption);
|
|
177
220
|
|
|
178
|
-
expect(screen.getByText('
|
|
221
|
+
expect(screen.getByText('No matching bills to display')).toBeInTheDocument();
|
|
179
222
|
});
|
|
180
223
|
|
|
181
224
|
test('should show loading state during background updates', () => {
|
|
@@ -184,6 +227,7 @@ describe('BillsTable', () => {
|
|
|
184
227
|
isLoading: false,
|
|
185
228
|
isValidating: true,
|
|
186
229
|
error: null,
|
|
230
|
+
mutate: jest.fn(),
|
|
187
231
|
}));
|
|
188
232
|
|
|
189
233
|
render(<BillsTable />);
|
package/src/config-schema.ts
CHANGED
|
@@ -1,85 +1,138 @@
|
|
|
1
|
-
import { Type } from '@openmrs/esm-framework';
|
|
2
|
-
|
|
3
|
-
export interface BillingConfig {}
|
|
1
|
+
import { Type, validators } from '@openmrs/esm-framework';
|
|
4
2
|
|
|
5
3
|
export const configSchema = {
|
|
6
|
-
|
|
4
|
+
logo: {
|
|
5
|
+
src: {
|
|
6
|
+
_type: Type.String,
|
|
7
|
+
_default: '',
|
|
8
|
+
_description: 'The path or URL to the logo image. If set to an empty string, the alt text will be used.',
|
|
9
|
+
_validators: [validators.isUrl],
|
|
10
|
+
},
|
|
11
|
+
alt: {
|
|
12
|
+
_type: Type.String,
|
|
13
|
+
_default: '',
|
|
14
|
+
_description:
|
|
15
|
+
'The alternative text for the logo image, displayed when the image cannot be loaded or on hover. If not provided and src is empty, the default OpenMRS SVG sprite will be used.',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
country: {
|
|
19
|
+
_type: Type.String,
|
|
20
|
+
_description: 'The text that gets printed on the top right of the invoice, typically the name of the country',
|
|
21
|
+
_default: 'Kenya',
|
|
22
|
+
},
|
|
23
|
+
patientCategory: {
|
|
7
24
|
_type: Type.Object,
|
|
8
|
-
_description:
|
|
25
|
+
_description:
|
|
26
|
+
'Visit Attribute Type UUIDs - These are custom attribute types that can be attached to patient visits. Each UUID represents a Visit Attribute Type in OpenMRS that stores payment-related information for the visit.',
|
|
9
27
|
_default: {
|
|
28
|
+
// Payment details attribute type (e.g., "Paying" or "Non-paying")
|
|
10
29
|
paymentDetails: 'fbc0702d-b4c9-4968-be63-af8ad3ad6239',
|
|
30
|
+
// Payment method attribute type (e.g., cash, insurance, mobile money)
|
|
11
31
|
paymentMethods: '8553afa0-bdb9-4d3c-8a98-05fa9350aa85',
|
|
32
|
+
// Insurance policy number attribute type
|
|
12
33
|
policyNumber: '3a988e33-a6c0-4b76-b924-01abb998944b',
|
|
34
|
+
// Insurance scheme name attribute type
|
|
13
35
|
insuranceScheme: 'aac48226-d143-4274-80e0-264db4e368ee',
|
|
36
|
+
// Patient category classification attribute type
|
|
14
37
|
patientCategory: '3b9dfac8-9e4d-11ee-8c90-0242ac120002',
|
|
38
|
+
// Form payload pending status attribute type
|
|
15
39
|
formPayloadPending: '919b51c9-8e2e-468f-8354-181bf3e55786',
|
|
16
40
|
},
|
|
17
41
|
},
|
|
18
|
-
|
|
19
|
-
catergoryConcepts: {
|
|
42
|
+
categoryConcepts: {
|
|
20
43
|
_type: Type.Object,
|
|
21
|
-
_description:
|
|
44
|
+
_description:
|
|
45
|
+
'Concept UUIDs - These are OpenMRS Concept UUIDs that represent the actual values/options for payment categories. These concepts are stored as values in the visit attributes defined in patientCategory.',
|
|
22
46
|
_default: {
|
|
47
|
+
// Concept UUID representing "Paying" payment category
|
|
23
48
|
payingDetails: '44b34972-6630-4e5a-a9f6-a6eb0f109650',
|
|
49
|
+
// Concept UUID representing "Non-paying" payment category
|
|
24
50
|
nonPayingDetails: 'f3fb2d88-cccd-422c-8766-be101ba7bd2e',
|
|
51
|
+
// Concept UUID representing "Insurance" as a payment method
|
|
25
52
|
insuranceDetails: 'beac329b-f1dc-4a33-9e7c-d95821a137a6',
|
|
26
53
|
},
|
|
27
54
|
},
|
|
28
|
-
|
|
29
55
|
nonPayingPatientCategories: {
|
|
30
56
|
_type: Type.Object,
|
|
31
|
-
_description:
|
|
57
|
+
_description:
|
|
58
|
+
'Concept UUIDs for non-paying patient categories - These are OpenMRS Concept UUIDs that identify specific patient categories eligible for non-paying status (e.g., children under 5, students). These are used as values when a patient is categorized as non-paying.',
|
|
32
59
|
_default: {
|
|
60
|
+
// Concept UUID for "Child Under 5" category
|
|
33
61
|
childUnder5: '1528AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
62
|
+
// Concept UUID for "Student" category
|
|
34
63
|
student: '159465AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
35
64
|
},
|
|
36
65
|
},
|
|
37
|
-
|
|
38
66
|
postBilledItems: {
|
|
39
67
|
_type: Type.Object,
|
|
40
|
-
_description:
|
|
68
|
+
_description:
|
|
69
|
+
'Default UUIDs used when creating bills - These UUIDs identify default resources (cash points, cashier providers) that are used when submitting a bill if not explicitly provided.',
|
|
41
70
|
_default: {
|
|
71
|
+
// Default Cash Point UUID - The cashier station/location where bills are processed
|
|
42
72
|
cashPoint: '54065383-b4d4-42d2-af4d-d250a1fd2590',
|
|
73
|
+
// Default Cashier Provider UUID - The provider/user UUID that identifies the cashier processing the bill
|
|
43
74
|
cashier: 'f9badd80-ab76-11e2-9e96-0800200c9a66',
|
|
75
|
+
// Default Price UUID - The service price UUID used when creating bills (currently unused in code)
|
|
44
76
|
priceUuid: '7b9171ac-d3c1-49b4-beff-c9902aee5245',
|
|
45
77
|
},
|
|
46
78
|
},
|
|
47
|
-
|
|
48
79
|
serviceTypes: {
|
|
49
80
|
_type: Type.Object,
|
|
50
|
-
_description:
|
|
81
|
+
_description:
|
|
82
|
+
'Service Type Concept Set UUID - This is an OpenMRS Concept Set UUID. The set members of this concept represent the different types of services that can be billed (e.g., Consultation, Lab Test, Procedure).',
|
|
51
83
|
_default: {
|
|
84
|
+
// Concept Set UUID - The concept set whose members represent the different service types that can be billed
|
|
52
85
|
billableService: '21b8cf43-9f9f-4d02-9f4a-d710ece54261',
|
|
53
86
|
},
|
|
54
87
|
},
|
|
55
|
-
|
|
56
88
|
defaultCurrency: {
|
|
57
89
|
_type: Type.String,
|
|
58
90
|
_description: 'The default currency for the application. Specify the currency code (e.g., KES, UGX, GBP).',
|
|
59
91
|
_default: 'KES',
|
|
60
92
|
},
|
|
61
|
-
|
|
62
93
|
pageSize: {
|
|
63
94
|
_type: Type.Number,
|
|
64
95
|
_description: 'The default page size',
|
|
65
96
|
_default: 10,
|
|
66
97
|
},
|
|
67
|
-
|
|
68
|
-
showEditBillButton: {
|
|
69
|
-
_type: Type.Boolean,
|
|
70
|
-
_description: 'Whether to show the edit bill button or not.',
|
|
71
|
-
_default: false,
|
|
72
|
-
},
|
|
73
98
|
};
|
|
74
99
|
|
|
75
|
-
|
|
76
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Configuration interface for the Billing module.
|
|
102
|
+
* All UUIDs represent OpenMRS resources that must exist in the system.
|
|
103
|
+
* See the configSchema above for detailed descriptions of each property.
|
|
104
|
+
*/
|
|
105
|
+
export interface BillingConfig {
|
|
106
|
+
logo: {
|
|
107
|
+
src: string;
|
|
108
|
+
alt: string;
|
|
109
|
+
};
|
|
110
|
+
country: string;
|
|
111
|
+
patientCategory: {
|
|
112
|
+
paymentDetails: string;
|
|
113
|
+
paymentMethods: string;
|
|
114
|
+
policyNumber: string;
|
|
115
|
+
insuranceScheme: string;
|
|
116
|
+
patientCategory: string;
|
|
117
|
+
formPayloadPending: string;
|
|
118
|
+
};
|
|
119
|
+
categoryConcepts: {
|
|
120
|
+
payingDetails: string;
|
|
121
|
+
nonPayingDetails: string;
|
|
122
|
+
insuranceDetails: string;
|
|
123
|
+
};
|
|
124
|
+
nonPayingPatientCategories: {
|
|
125
|
+
childUnder5: string;
|
|
126
|
+
student: string;
|
|
127
|
+
};
|
|
128
|
+
postBilledItems: {
|
|
129
|
+
cashPoint: string;
|
|
130
|
+
cashier: string;
|
|
131
|
+
priceUuid: string;
|
|
132
|
+
};
|
|
133
|
+
serviceTypes: {
|
|
134
|
+
billableService: string;
|
|
135
|
+
};
|
|
77
136
|
defaultCurrency: string;
|
|
78
|
-
|
|
79
|
-
pageSize;
|
|
80
|
-
object;
|
|
81
|
-
showEditBillButton: boolean;
|
|
82
|
-
postBilledItems: Object;
|
|
83
|
-
serviceTypes: Object;
|
|
84
|
-
nonPayingPatientCategories: Object;
|
|
137
|
+
pageSize: number;
|
|
85
138
|
}
|
package/src/dashboard.meta.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { type DashboardLinkConfig } from '@openmrs/esm-patient-common-lib';
|
|
2
|
+
|
|
3
|
+
export const dashboardMeta: DashboardLinkConfig & { slot: string; columns: number; hideDashboardTitle: boolean } = {
|
|
2
4
|
slot: 'patient-chart-billing-dashboard-slot',
|
|
3
5
|
columns: 1,
|
|
4
|
-
title: '
|
|
6
|
+
title: 'billingHistory',
|
|
5
7
|
hideDashboardTitle: true,
|
|
6
|
-
icon: '',
|
|
8
|
+
icon: 'omrs-icon-money',
|
|
7
9
|
path: 'Billing history',
|
|
8
10
|
};
|
package/src/helpers/functions.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getCoreTranslation } from '@openmrs/esm-framework';
|
|
1
2
|
import { type Payment, type LineItem } from '../types';
|
|
2
3
|
|
|
3
4
|
// amount already paid
|
|
@@ -51,13 +52,13 @@ export const convertToCurrency = (amountToConvert: number, currencyType?: string
|
|
|
51
52
|
export const getGender = (gender: string, t) => {
|
|
52
53
|
switch (gender) {
|
|
53
54
|
case 'male':
|
|
54
|
-
return
|
|
55
|
+
return getCoreTranslation('male');
|
|
55
56
|
case 'female':
|
|
56
|
-
return
|
|
57
|
+
return getCoreTranslation('female');
|
|
57
58
|
case 'other':
|
|
58
|
-
return
|
|
59
|
+
return getCoreTranslation('other');
|
|
59
60
|
case 'unknown':
|
|
60
|
-
return
|
|
61
|
+
return getCoreTranslation('unknown');
|
|
61
62
|
default:
|
|
62
63
|
return gender;
|
|
63
64
|
}
|
package/src/index.ts
CHANGED
|
@@ -3,14 +3,20 @@ import { createDashboardLink } from '@openmrs/esm-patient-common-lib';
|
|
|
3
3
|
import { createLeftPanelLink } from './left-panel-link.component';
|
|
4
4
|
import { dashboardMeta } from './dashboard.meta';
|
|
5
5
|
import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle } from '@openmrs/esm-framework';
|
|
6
|
+
import { Wallet, Money, Settings } from '@carbon/react/icons';
|
|
7
|
+
import { createBillableServicesLeftPanelLink } from './billable-services/billable-services-left-panel-link.component';
|
|
8
|
+
import { createBillableServicesLeftPanelMenu } from './billable-services/billable-services-left-panel-menu.component';
|
|
9
|
+
import AddCashPointModal from './billable-services/cash-point/add-cash-point.modal';
|
|
6
10
|
import appMenu from './billable-services/billable-services-menu-item/item.component';
|
|
7
11
|
import BillableServiceHome from './billable-services/billable-services-home.component';
|
|
8
12
|
import BillableServicesCardLink from './billable-services-admin-card-link.component';
|
|
9
13
|
import BillHistory from './bill-history/bill-history.component';
|
|
10
14
|
import BillingCheckInForm from './billing-form/billing-checkin-form.component';
|
|
11
|
-
import
|
|
15
|
+
import DeletePaymentModeModal from './billable-services/payment-modes/delete-payment-mode.modal';
|
|
16
|
+
import EditBillLineItemModal from './bill-item-actions/edit-bill-item.modal';
|
|
17
|
+
import PaymentModeFormModal from './billable-services/payment-modes/payment-mode-form.modal';
|
|
18
|
+
import RequirePaymentModal from './modal/require-payment.modal';
|
|
12
19
|
import RootComponent from './root.component';
|
|
13
|
-
import ServiceMetrics from './billable-services/dashboard/service-metrics.component';
|
|
14
20
|
import VisitAttributeTags from './invoice/payments/visit-tags/visit-attribute.component';
|
|
15
21
|
|
|
16
22
|
const moduleName = '@openmrs/esm-billing-app';
|
|
@@ -20,26 +26,28 @@ const options = {
|
|
|
20
26
|
moduleName,
|
|
21
27
|
};
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
export const importTranslation = require.context('../translations', false, /.json$/, 'lazy');
|
|
30
|
+
|
|
24
31
|
export const billingDashboardLink = getSyncLifecycle(
|
|
32
|
+
// t('billing', 'Billing')
|
|
25
33
|
createLeftPanelLink({
|
|
26
34
|
name: 'billing',
|
|
27
|
-
title: '
|
|
35
|
+
title: 'billing',
|
|
28
36
|
}),
|
|
29
37
|
options,
|
|
30
38
|
);
|
|
31
39
|
|
|
32
|
-
export const importTranslation = require.context('../translations', false, /.json$/, 'lazy');
|
|
33
|
-
|
|
34
40
|
export function startupApp() {
|
|
35
41
|
defineConfigSchema(moduleName, configSchema);
|
|
36
42
|
}
|
|
37
43
|
|
|
44
|
+
// t('billingHistory', 'Billing History')
|
|
38
45
|
export const billingSummaryDashboardLink = getSyncLifecycle(
|
|
39
46
|
createDashboardLink({ ...dashboardMeta, moduleName }),
|
|
40
47
|
options,
|
|
41
48
|
);
|
|
42
49
|
|
|
50
|
+
// t('billableServices', 'Billable services')
|
|
43
51
|
export const billableServicesAppMenuItem = getSyncLifecycle(appMenu, options);
|
|
44
52
|
|
|
45
53
|
export const billableServicesCardLink = getSyncLifecycle(BillableServicesCardLink, options);
|
|
@@ -52,16 +60,70 @@ export const billingPatientSummary = getSyncLifecycle(BillHistory, options);
|
|
|
52
60
|
|
|
53
61
|
export const requirePaymentModal = getSyncLifecycle(RequirePaymentModal, options);
|
|
54
62
|
|
|
55
|
-
export const
|
|
63
|
+
export const paymentModeFormModal = getSyncLifecycle(PaymentModeFormModal, options);
|
|
56
64
|
|
|
57
|
-
export const
|
|
65
|
+
export const deletePaymentModeModal = getSyncLifecycle(DeletePaymentModeModal, options);
|
|
58
66
|
|
|
59
|
-
export const
|
|
67
|
+
export const addCashPointModal = getSyncLifecycle(AddCashPointModal, options);
|
|
60
68
|
|
|
61
|
-
export const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
export const editBillLineItemModal = getSyncLifecycle(EditBillLineItemModal, options);
|
|
70
|
+
|
|
71
|
+
export const root = getSyncLifecycle(RootComponent, options);
|
|
72
|
+
|
|
73
|
+
export const visitAttributeTags = getSyncLifecycle(VisitAttributeTags, options);
|
|
65
74
|
|
|
66
75
|
// t('billingForm', 'Billing form')
|
|
67
76
|
export const billingFormWorkspace = getAsyncLifecycle(() => import('./billing-form/billing-form.component'), options);
|
|
77
|
+
|
|
78
|
+
// t('billableServiceForm', 'Billable service form')
|
|
79
|
+
export const billableServiceFormWorkspace = getAsyncLifecycle(
|
|
80
|
+
() => import('./billable-services/billable-service-form/billable-service-form.workspace'),
|
|
81
|
+
options,
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// t('billableServices', 'Billable services')
|
|
85
|
+
export const billableServicesLeftPanelLink = getSyncLifecycle(
|
|
86
|
+
createBillableServicesLeftPanelLink({
|
|
87
|
+
name: 'billable-services',
|
|
88
|
+
title: 'billableServices',
|
|
89
|
+
path: '',
|
|
90
|
+
icon: Wallet,
|
|
91
|
+
}),
|
|
92
|
+
options,
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// t('billWaiver', 'Bill waiver')
|
|
96
|
+
export const billWaiverLeftPanelLink = getSyncLifecycle(
|
|
97
|
+
createBillableServicesLeftPanelLink({
|
|
98
|
+
name: 'bill-waiver',
|
|
99
|
+
title: 'billWaiver',
|
|
100
|
+
path: 'waive-bill',
|
|
101
|
+
icon: Money,
|
|
102
|
+
privilege: 'coreapps.systemAdministration',
|
|
103
|
+
}),
|
|
104
|
+
options,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// t('billingSettings', 'Billing settings')
|
|
108
|
+
// t('cashPointConfig', 'Cash point configuration')
|
|
109
|
+
// t('paymentModesConfig', 'Payment modes configuration')
|
|
110
|
+
export const billingSettingsLeftPanelMenu = getSyncLifecycle(
|
|
111
|
+
createBillableServicesLeftPanelMenu({
|
|
112
|
+
title: 'billingSettings',
|
|
113
|
+
icon: Settings,
|
|
114
|
+
privilege: 'coreapps.systemAdministration',
|
|
115
|
+
items: [
|
|
116
|
+
{
|
|
117
|
+
name: 'cash-point-config',
|
|
118
|
+
title: 'cashPointConfig',
|
|
119
|
+
path: 'cash-point-config',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'payment-modes-config',
|
|
123
|
+
title: 'paymentModesConfig',
|
|
124
|
+
path: 'payment-modes-config',
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
}),
|
|
128
|
+
options,
|
|
129
|
+
);
|