@digihmis/esm-administration-app 1.0.0

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.
Files changed (206) hide show
  1. package/README.md +4 -0
  2. package/dist/101.js +1 -0
  3. package/dist/101.js.map +1 -0
  4. package/dist/117.js +1 -0
  5. package/dist/117.js.map +1 -0
  6. package/dist/132.js +1 -0
  7. package/dist/132.js.map +1 -0
  8. package/dist/15.js +1 -0
  9. package/dist/15.js.map +1 -0
  10. package/dist/152.js +1 -0
  11. package/dist/152.js.map +1 -0
  12. package/dist/153.js +1 -0
  13. package/dist/153.js.map +1 -0
  14. package/dist/190.js +1 -0
  15. package/dist/190.js.map +1 -0
  16. package/dist/209.js +1 -0
  17. package/dist/209.js.map +1 -0
  18. package/dist/266.js +1 -0
  19. package/dist/266.js.map +1 -0
  20. package/dist/317.js +1 -0
  21. package/dist/317.js.map +1 -0
  22. package/dist/349.js +1 -0
  23. package/dist/349.js.map +1 -0
  24. package/dist/371.js +1 -0
  25. package/dist/371.js.map +1 -0
  26. package/dist/378.js +1 -0
  27. package/dist/378.js.map +1 -0
  28. package/dist/394.js +1 -0
  29. package/dist/394.js.map +1 -0
  30. package/dist/442.js +1 -0
  31. package/dist/442.js.map +1 -0
  32. package/dist/45.js +1 -0
  33. package/dist/45.js.map +1 -0
  34. package/dist/454.js +1 -0
  35. package/dist/454.js.map +1 -0
  36. package/dist/466.js +1 -0
  37. package/dist/466.js.map +1 -0
  38. package/dist/482.js +1 -0
  39. package/dist/482.js.map +1 -0
  40. package/dist/501.js +1 -0
  41. package/dist/501.js.map +1 -0
  42. package/dist/508.js +1 -0
  43. package/dist/508.js.map +1 -0
  44. package/dist/578.js +1 -0
  45. package/dist/578.js.map +1 -0
  46. package/dist/598.js +1 -0
  47. package/dist/598.js.map +1 -0
  48. package/dist/606.js +1 -0
  49. package/dist/606.js.map +1 -0
  50. package/dist/61.js +1 -0
  51. package/dist/61.js.map +1 -0
  52. package/dist/640.js +1 -0
  53. package/dist/640.js.map +1 -0
  54. package/dist/685.js +1 -0
  55. package/dist/685.js.map +1 -0
  56. package/dist/689.js +1 -0
  57. package/dist/689.js.map +1 -0
  58. package/dist/709.js +1 -0
  59. package/dist/709.js.map +1 -0
  60. package/dist/712.js +1 -0
  61. package/dist/712.js.map +1 -0
  62. package/dist/720.js +1 -0
  63. package/dist/720.js.map +1 -0
  64. package/dist/737.js +12 -0
  65. package/dist/737.js.map +1 -0
  66. package/dist/742.js +1 -0
  67. package/dist/742.js.map +1 -0
  68. package/dist/747.js +1 -0
  69. package/dist/747.js.map +1 -0
  70. package/dist/771.js +1 -0
  71. package/dist/771.js.map +1 -0
  72. package/dist/806.js +1 -0
  73. package/dist/806.js.map +1 -0
  74. package/dist/912.js +1 -0
  75. package/dist/912.js.map +1 -0
  76. package/dist/913.js +1 -0
  77. package/dist/913.js.map +1 -0
  78. package/dist/916.js +15 -0
  79. package/dist/916.js.map +1 -0
  80. package/dist/940.js +1 -0
  81. package/dist/940.js.map +1 -0
  82. package/dist/digihmis-esm-administration-app.js +6 -0
  83. package/dist/digihmis-esm-administration-app.js.buildmanifest.json +1100 -0
  84. package/dist/digihmis-esm-administration-app.js.map +1 -0
  85. package/dist/main.js +17 -0
  86. package/dist/main.js.map +1 -0
  87. package/dist/routes.json +1 -0
  88. package/increment-version.js +17 -0
  89. package/jest.config.js +26 -0
  90. package/package.json +51 -0
  91. package/release-version.js +16 -0
  92. package/rspack.config.js +1 -0
  93. package/src/bed-management/bed-management.component.tsx +19 -0
  94. package/src/bed-management/bed-management.scss +0 -0
  95. package/src/billing-management/billing-charge-items/billing-charge-items-modal/billing-charge-items.modal.tsx +79 -0
  96. package/src/billing-management/billing-charge-items/billing-charge-items-modal/billing-charge-items.resource.ts +11 -0
  97. package/src/billing-management/billing-charge-items/billing-charge-items-workspace/billing-charge-item.workspace.tsx +212 -0
  98. package/src/billing-management/billing-charge-items/billing-charge-items-workspace/billing-charge-items.resource.ts +51 -0
  99. package/src/billing-management/billing-charge-items/billing-charge-items-workspace/billing-charge-service.workspace.tsx +296 -0
  100. package/src/billing-management/billing-charge-items/billing-charge-items-workspace/components/concept-search.component.tsx +67 -0
  101. package/src/billing-management/billing-charge-items/billing-charge-items-workspace/components/price.component.tsx +81 -0
  102. package/src/billing-management/billing-charge-items/billing-charge-items-workspace/components/stock-search.component.tsx +107 -0
  103. package/src/billing-management/billing-charge-items/billing-charge-items-workspace/global/billing-charge-commodity.scss +61 -0
  104. package/src/billing-management/billing-charge-items/billing-charge-items-workspace/global/billing-charge-items.scss +59 -0
  105. package/src/billing-management/billing-charge-items/billing-charge-items-workspace/schemas/form-schemas.ts +33 -0
  106. package/src/billing-management/billing-charge-items/billing-charge-items.component.tsx +222 -0
  107. package/src/billing-management/billing-charge-items/billing-charge-items.resource.ts +20 -0
  108. package/src/billing-management/billing-charge-items/billing-charge-items.scss +84 -0
  109. package/src/billing-management/billing-charge-items/type/index.ts +88 -0
  110. package/src/billing-management/billing-charge-items/utils/index.ts +96 -0
  111. package/src/billing-management/billing-management.component.tsx +21 -0
  112. package/src/billing-management/billing-management.scss +0 -0
  113. package/src/billing-management/billing-payment-modes/billing-payment-modes-modal/billing-delete-payment-modes.modal.scss +28 -0
  114. package/src/billing-management/billing-payment-modes/billing-payment-modes-modal/billing-delete-payment-modes.modal.tsx +67 -0
  115. package/src/billing-management/billing-payment-modes/billing-payment-modes-modal/delete-payment-mode.test.tsx +56 -0
  116. package/src/billing-management/billing-payment-modes/billing-payment-modes-workspace/billing-payment-modes-form-schema.ts +52 -0
  117. package/src/billing-management/billing-payment-modes/billing-payment-modes-workspace/billing-payment-modes.resource.ts +35 -0
  118. package/src/billing-management/billing-payment-modes/billing-payment-modes-workspace/billing-payment-modes.workspace.scss +33 -0
  119. package/src/billing-management/billing-payment-modes/billing-payment-modes-workspace/billing-payment-modes.workspace.test.tsx +239 -0
  120. package/src/billing-management/billing-payment-modes/billing-payment-modes-workspace/billing-payment-modes.workspace.tsx +218 -0
  121. package/src/billing-management/billing-payment-modes/billing-payment-modes-workspace/payment-attributes/payment-mode-attributes.component.tsx +156 -0
  122. package/src/billing-management/billing-payment-modes/billing-payment-modes-workspace/payment-attributes/payment-mode-attributes.scss +10 -0
  123. package/src/billing-management/billing-payment-modes/billing-payment-modes.component.tsx +243 -0
  124. package/src/billing-management/billing-payment-modes/billing-payment-modes.resource.ts +23 -0
  125. package/src/billing-management/billing-payment-modes/billing-payment-modes.scss +140 -0
  126. package/src/billing-management/billing-payment-modes/type/index.ts +42 -0
  127. package/src/billing-management/billing-payment-points/billing-payment-point-modal/billing-delete-payment-modes.modal.scss +28 -0
  128. package/src/billing-management/billing-payment-points/billing-payment-point-modal/billing-delete-payment-point.modal.tsx +72 -0
  129. package/src/billing-management/billing-payment-points/billing-payment-point-modal/delete-payment-point.test.tsx +56 -0
  130. package/src/billing-management/billing-payment-points/billing-payment-point.component.tsx +202 -0
  131. package/src/billing-management/billing-payment-points/billing-payment-point.resource.ts +16 -0
  132. package/src/billing-management/billing-payment-points/billing-payment-point.scss +0 -0
  133. package/src/billing-management/billing-payment-points/billing-payment-points-workspace/billing-payment-point.resource.ts +39 -0
  134. package/src/billing-management/billing-payment-points/billing-payment-points-workspace/billing-payment-point.workspace.scss +33 -0
  135. package/src/billing-management/billing-payment-points/billing-payment-points-workspace/billing-payment-points.workspace.tsx +194 -0
  136. package/src/billing-management/billing-payment-points/type/index.ts +35 -0
  137. package/src/billing-management/billing-tabs/billing-tabs.component.scss +15 -0
  138. package/src/billing-management/billing-tabs/billing-tabs.component.tsx +36 -0
  139. package/src/components/custom-icon-wrapper/custom-icon-wrapper.component.tsx +17 -0
  140. package/src/components/custom-page-header/custom-page-header.component.tsx +38 -0
  141. package/src/components/custom-page-header/custom-page-header.scss +76 -0
  142. package/src/config-schema.ts +142 -0
  143. package/src/constant/index.ts +1 -0
  144. package/src/dashboard.meta.ts +47 -0
  145. package/src/declarations.d.ts +6 -0
  146. package/src/form-builder/form-builder.component.tsx +19 -0
  147. package/src/form-builder/form-builder.scss +0 -0
  148. package/src/hooks/useConcept.ts +13 -0
  149. package/src/hooks/useQueues.ts +22 -0
  150. package/src/hooks/useSystemSetting.ts +18 -0
  151. package/src/index.ts +133 -0
  152. package/src/left-panel/left-panel.component.tsx +49 -0
  153. package/src/left-panel/left-panel.scss +13 -0
  154. package/src/location-management/components/auto-suggest/autosuggest.component.tsx +149 -0
  155. package/src/location-management/components/auto-suggest/autosuggest.scss +61 -0
  156. package/src/location-management/components/auto-suggest/location-autosuggest.component.tsx +97 -0
  157. package/src/location-management/components/auto-suggest/location-autosuggest.scss +48 -0
  158. package/src/location-management/components/custom-results-tile/results-tile.component.tsx +43 -0
  159. package/src/location-management/components/custom-results-tile/results-tile.scss +86 -0
  160. package/src/location-management/forms/add-location/add-location.workspace.scss +71 -0
  161. package/src/location-management/forms/add-location/add-location.workspace.tsx +199 -0
  162. package/src/location-management/forms/search-location/search-location.workspace.scss +71 -0
  163. package/src/location-management/forms/search-location/search-location.workspace.tsx +214 -0
  164. package/src/location-management/helpers/index.ts +33 -0
  165. package/src/location-management/hooks/UseFacilityLocations.ts +12 -0
  166. package/src/location-management/hooks/useLocation.ts +18 -0
  167. package/src/location-management/hooks/useLocationTags.ts +15 -0
  168. package/src/location-management/location-management-dashboard.component.tsx +21 -0
  169. package/src/location-management/location-management-dashboard.scss +3 -0
  170. package/src/location-management/tables/locations-table.component.tsx +242 -0
  171. package/src/location-management/tables/locations-table.resource.ts +26 -0
  172. package/src/location-management/tables/locations-table.scss +114 -0
  173. package/src/location-management/types/index.ts +120 -0
  174. package/src/queue-management/queue-management-dashboard.component.tsx +23 -0
  175. package/src/queue-management/queue-management-dashboard.scss +8 -0
  176. package/src/queue-management/queue-management-table/queue-management-table.component.tsx +296 -0
  177. package/src/queue-management/queue-management-table/queue-management-table.scss +78 -0
  178. package/src/queue-management/queue-management-table/queue-management.resource.ts +39 -0
  179. package/src/queue-management/queue-management-workspace/queue-room/queue-room-form.scss +56 -0
  180. package/src/queue-management/queue-management-workspace/queue-room/queue-room-form.test.tsx +82 -0
  181. package/src/queue-management/queue-management-workspace/queue-room/queue-room-form.workspace.tsx +169 -0
  182. package/src/queue-management/queue-management-workspace/queue-room/queue-room.resource.ts +20 -0
  183. package/src/queue-management/queue-management-workspace/queue-service/queue-service-form.scss +61 -0
  184. package/src/queue-management/queue-management-workspace/queue-service/queue-service-form.test.tsx +127 -0
  185. package/src/queue-management/queue-management-workspace/queue-service/queue-service-form.workspace.tsx +178 -0
  186. package/src/queue-management/queue-management-workspace/queue-service/queue-service.resource.ts +55 -0
  187. package/src/queue-management/queue-types/index.ts +33 -0
  188. package/src/routes.json +157 -0
  189. package/src/setup-tests.ts +1 -0
  190. package/src/system-info/system-info.component.tsx +338 -0
  191. package/src/system-info/system-info.resource.ts +40 -0
  192. package/src/system-info/system-info.scss +622 -0
  193. package/src/type/index.ts +6 -0
  194. package/translations/am.json +111 -0
  195. package/translations/ar.json +115 -0
  196. package/translations/en.json +111 -0
  197. package/translations/es.json +112 -0
  198. package/translations/fr.json +112 -0
  199. package/translations/he.json +112 -0
  200. package/translations/km.json +110 -0
  201. package/translations/pt.json +112 -0
  202. package/translations/sw.json +111 -0
  203. package/translations/vi.json +110 -0
  204. package/translations/zh.json +110 -0
  205. package/tsconfig.json +5 -0
  206. package/version.js +27 -0
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod';
2
+
3
+ const ServiceConceptSchema = z.object({
4
+ concept: z.object({
5
+ uuid: z.string(),
6
+ display: z.string(),
7
+ }),
8
+ conceptName: z.object({
9
+ uuid: z.string(),
10
+ display: z.string(),
11
+ }),
12
+ display: z.string(),
13
+ });
14
+
15
+ export const servicePriceSchema = z.object({
16
+ price: z.number().gt(0.01, 'Price must be greater than 0').min(0.01, 'Price must be at least 0.01'),
17
+ paymentMode: z.object({ uuid: z.string(), name: z.string() }),
18
+ });
19
+
20
+ export const billableFormSchema = z.object({
21
+ name: z.string().min(1, 'Service name is required'),
22
+ shortName: z
23
+ .string()
24
+ .refine((value) => value.length !== 1, { message: 'Short name must be at least 1 character long' }),
25
+ serviceType: z.object({ uuid: z.string(), display: z.string() }),
26
+ servicePrices: z.array(servicePriceSchema).min(1, 'At least one price is required'),
27
+ serviceStatus: z.enum(['ENABLED', 'DISABLED']),
28
+ concept: ServiceConceptSchema,
29
+ stockItem: z.string().nullable().optional(),
30
+ });
31
+
32
+ export type BillableFormSchema = z.infer<typeof billableFormSchema>;
33
+ export type ServicePriceSchema = z.infer<typeof servicePriceSchema>;
@@ -0,0 +1,222 @@
1
+ import React, { useMemo, useState } from 'react';
2
+ import {
3
+ Button,
4
+ DataTable,
5
+ DataTableSkeleton,
6
+ Table,
7
+ TableBody,
8
+ TableCell,
9
+ TableContainer,
10
+ TableHead,
11
+ TableHeader,
12
+ TableRow,
13
+ Layer,
14
+ Pagination,
15
+ Tile,
16
+ IconButton,
17
+ } from '@carbon/react';
18
+ import { Add, Edit, TrashCan } from '@carbon/react/icons';
19
+ import { launchWorkspace, useLayoutType, ErrorState, showModal } from '@openmrs/esm-framework';
20
+ import { useTranslation } from 'react-i18next';
21
+ import styles from './billing-charge-items.scss';
22
+ import { CardHeader } from '@openmrs/esm-patient-common-lib';
23
+ import { useChargeItems } from './billing-charge-items.resource';
24
+
25
+ const ChargeItemsTable = () => {
26
+ const { t } = useTranslation();
27
+ const layout = useLayoutType();
28
+ const isTablet = layout === 'tablet';
29
+ const responsiveSize = isTablet ? 'lg' : 'sm';
30
+
31
+ const { chargeSummaryItems, isLoading, error } = useChargeItems();
32
+
33
+ const [currentPage, setCurrentPage] = useState(1);
34
+ const [currentPageSize, setCurrentPageSize] = useState(10);
35
+ const pageSizes = [10, 20, 30, 40, 50];
36
+
37
+ const headers = [
38
+ {
39
+ key: 'name',
40
+ header: t('name', 'Name'),
41
+ },
42
+ {
43
+ key: 'status',
44
+ header: t('status', 'Status'),
45
+ },
46
+ {
47
+ key: 'type',
48
+ header: t('type', 'Type'),
49
+ },
50
+ {
51
+ key: 'price',
52
+ header: t('price', 'Price'),
53
+ },
54
+ ];
55
+
56
+ const tableRows = useMemo(() => {
57
+ if (!chargeSummaryItems || !Array.isArray(chargeSummaryItems)) {
58
+ return [];
59
+ }
60
+
61
+ return chargeSummaryItems.map((item) => ({
62
+ id: item.uuid,
63
+ name: item.name || '-',
64
+ status: item.serviceStatus === 'ENABLED' ? t('enabled', 'Enabled') : t('disabled', 'Disabled'),
65
+ type: item.serviceType?.display || t('stockItem', 'Stock Item'),
66
+ price:
67
+ item.servicePrices && item.servicePrices.length > 0
68
+ ? item.servicePrices.map((p) => `${p.name}: ${p.price}`).join(', ')
69
+ : '-',
70
+ chargeItem: item,
71
+ }));
72
+ }, [chargeSummaryItems, t]);
73
+
74
+ const paginatedRows = useMemo(() => {
75
+ const startIndex = (currentPage - 1) * currentPageSize;
76
+ const endIndex = startIndex + currentPageSize;
77
+ return tableRows.slice(startIndex, endIndex);
78
+ }, [tableRows, currentPage, currentPageSize]);
79
+
80
+ const handleAddChargeService = () => {
81
+ launchWorkspace('billing-charge-service-workspace', {
82
+ workspaceTitle: t('addChargeService', 'Add Charge Service'),
83
+ });
84
+ };
85
+
86
+ const handleAddChargeItem = () => {
87
+ launchWorkspace('billing-charge-item-workspace', {
88
+ workspaceTitle: t('addChargeItem', 'Add Charge Item'),
89
+ });
90
+ };
91
+
92
+ const handleEdit = (service) => {
93
+ Boolean(service?.serviceType?.display)
94
+ ? launchWorkspace('billing-charge-service-workspace', {
95
+ initialValues: service,
96
+ workspaceTitle: t('editServiceChargeItem', 'Edit Service Charge Item'),
97
+ })
98
+ : launchWorkspace('billing-charge-item-workspace', {
99
+ initialValues: service,
100
+ workspaceTitle: t('editChargeItem', 'Edit Charge Item'),
101
+ });
102
+ };
103
+
104
+ const showDeleteChargeItemModal = (chargeItem) => {
105
+ const dispose = showModal('delete-billable-service-modal', {
106
+ closeModal: () => dispose(),
107
+ chargeableItem: chargeItem,
108
+ });
109
+ };
110
+
111
+ if (isLoading) {
112
+ return (
113
+ <div className={styles.section}>
114
+ <h3>{t('chargeItems', 'Charge Items')}</h3>
115
+ <DataTableSkeleton role="progressbar" compact={!isTablet} zebra />
116
+ </div>
117
+ );
118
+ }
119
+
120
+ if (error) {
121
+ return <ErrorState error={error} headerTitle={t('chargeItems', 'Charge Items')} />;
122
+ }
123
+
124
+ return (
125
+ <div className={styles.section}>
126
+ <CardHeader title={t('chargeItems', 'Charge Items')}>
127
+ <div className={styles.headerActions}>
128
+ <Button kind="ghost" renderIcon={(props) => <Add size={16} {...props} />} onClick={handleAddChargeService}>
129
+ {t('addChargeService', 'Add Charge Service')}
130
+ </Button>
131
+ <Button kind="ghost" renderIcon={(props) => <Add size={16} {...props} />} onClick={handleAddChargeItem}>
132
+ {t('addChargeItem', 'Add Charge Item')}
133
+ </Button>
134
+ </div>
135
+ </CardHeader>
136
+ <Layer>
137
+ <DataTable rows={paginatedRows} headers={headers} isSortable size={responsiveSize} useZebraStyles>
138
+ {({ rows, headers, getHeaderProps, getRowProps, getTableProps }) => (
139
+ <TableContainer>
140
+ <Table {...getTableProps()} aria-label={t('chargeItemsTable', 'Charge items table')}>
141
+ <TableHead>
142
+ <TableRow>
143
+ {headers.map((header) => (
144
+ <TableHeader key={header.key} {...getHeaderProps({ header })}>
145
+ {header.header}
146
+ </TableHeader>
147
+ ))}
148
+ <TableHeader>{t('actions', 'Actions')}</TableHeader>
149
+ </TableRow>
150
+ </TableHead>
151
+ <TableBody>
152
+ {rows.map((row, index) => {
153
+ const chargeItem = paginatedRows[index]?.chargeItem;
154
+ return (
155
+ <TableRow key={row.id} {...getRowProps({ row })}>
156
+ {row.cells.map((cell) => (
157
+ <TableCell key={cell.id}>{cell.value}</TableCell>
158
+ ))}
159
+ <TableCell>
160
+ <div style={{ display: 'flex', gap: '0.5rem' }}>
161
+ <IconButton
162
+ kind="ghost"
163
+ size={responsiveSize}
164
+ label={t('edit', 'Edit')}
165
+ onClick={() => handleEdit(chargeItem)}>
166
+ <Edit />
167
+ </IconButton>
168
+ <IconButton
169
+ kind="danger--ghost"
170
+ size={responsiveSize}
171
+ label={t('delete', 'Delete')}
172
+ onClick={() => showDeleteChargeItemModal(chargeItem)}>
173
+ <TrashCan />
174
+ </IconButton>
175
+ </div>
176
+ </TableCell>
177
+ </TableRow>
178
+ );
179
+ })}
180
+ </TableBody>
181
+ </Table>
182
+ {tableRows.length === 0 ? (
183
+ <div className={styles.tileContainer}>
184
+ <Tile className={styles.tile}>
185
+ <div className={styles.tileContent}>
186
+ <p className={styles.content}>{t('noChargeItemsFound', 'No charge items found')}</p>
187
+ <p className={styles.emptyStateHelperText}>
188
+ {t('checkFilters', 'Please check the filters above and try again')}
189
+ </p>
190
+ </div>
191
+ </Tile>
192
+ </div>
193
+ ) : null}
194
+ {tableRows.length > 0 && (
195
+ <Pagination
196
+ forwardText={t('nextPage', 'Next page')}
197
+ backwardText={t('previousPage', 'Previous page')}
198
+ page={currentPage}
199
+ pageSize={currentPageSize}
200
+ pageSizes={pageSizes}
201
+ totalItems={tableRows.length}
202
+ className={styles.pagination}
203
+ onChange={({ pageSize, page }) => {
204
+ if (pageSize !== currentPageSize) {
205
+ setCurrentPageSize(pageSize);
206
+ setCurrentPage(1);
207
+ }
208
+ if (page !== currentPage) {
209
+ setCurrentPage(page);
210
+ }
211
+ }}
212
+ />
213
+ )}
214
+ </TableContainer>
215
+ )}
216
+ </DataTable>
217
+ </Layer>
218
+ </div>
219
+ );
220
+ };
221
+
222
+ export default ChargeItemsTable;
@@ -0,0 +1,20 @@
1
+ import { FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
+ import useSWR from 'swr';
3
+ import { type ChargeItemsResponse } from './type';
4
+
5
+ export const useChargeItems = () => {
6
+ const url = `${restBaseUrl}/cashier/billableService?v=custom:(uuid,name,shortName,serviceStatus,serviceType:(uuid,display),servicePrices:(uuid,name,paymentMode,price),concept:(uuid,display),stockItem:(uuid,display))`;
7
+
8
+ const { data, isLoading, isValidating, error, mutate } = useSWR<FetchResponse<ChargeItemsResponse>>(
9
+ url,
10
+ openmrsFetch,
11
+ );
12
+
13
+ return {
14
+ chargeSummaryItems: data?.data?.results ?? [],
15
+ isLoading,
16
+ isValidating,
17
+ error,
18
+ mutate,
19
+ };
20
+ };
@@ -0,0 +1,84 @@
1
+ @use '@carbon/layout';
2
+ @use '@carbon/type';
3
+ @use '@carbon/colors';
4
+
5
+ :global(.cds--tab-content) {
6
+ padding: 0 !important;
7
+ padding-top: var(--cds-layout-density-padding-inline-local) !important;
8
+ }
9
+
10
+ .adminPage {
11
+ // padding: layout.$spacing-05;
12
+ background: var(--cds-field);
13
+ }
14
+
15
+ .section {
16
+ margin-bottom: layout.$spacing-07;
17
+
18
+ &:last-child {
19
+ margin-bottom: 0;
20
+ }
21
+ }
22
+
23
+ .sectionHeader {
24
+ display: flex;
25
+ justify-content: space-between;
26
+ align-items: center;
27
+ margin-bottom: layout.$spacing-05;
28
+ padding-bottom: layout.$spacing-03;
29
+ border-bottom: 1px solid var(--cds-border-subtle);
30
+
31
+ h3 {
32
+ margin: 0;
33
+ color: var(--cds-text-primary);
34
+ font-size: 1.25rem;
35
+ font-weight: 600;
36
+ }
37
+ }
38
+
39
+ @media (max-width: 768px) {
40
+ .adminPage {
41
+ padding: layout.$spacing-03;
42
+ }
43
+
44
+ .sectionHeader {
45
+ flex-direction: column;
46
+ align-items: flex-start;
47
+ gap: layout.$spacing-03;
48
+
49
+ h3 {
50
+ font-size: 1.125rem;
51
+ }
52
+ }
53
+ }
54
+
55
+ .tileContainer {
56
+ border-top: 1px solid colors.$gray-20;
57
+ padding: 3rem 0;
58
+ }
59
+
60
+ .tile {
61
+ margin: auto;
62
+ width: fit-content;
63
+ background: colors.$gray-20;
64
+ }
65
+
66
+ .tileContent {
67
+ display: flex;
68
+ flex-direction: column;
69
+ align-items: center;
70
+ }
71
+
72
+ .content {
73
+ @include type.type-style('heading-compact-02');
74
+ color: colors.$gray-70;
75
+ margin-bottom: layout.$spacing-03;
76
+ }
77
+
78
+ .singleLineDisplay {
79
+ white-space: nowrap;
80
+ }
81
+
82
+ .emptyStateHelperText {
83
+ @include type.type-style('helper-text-02');
84
+ }
@@ -0,0 +1,88 @@
1
+ import { OpenmrsResource } from '@openmrs/esm-framework';
2
+
3
+ export interface ChargeItems {
4
+ uuid: string;
5
+ name: string;
6
+ shortName: string;
7
+ serviceStatus: 'ENABLED' | 'DISABLED';
8
+ stockItem: OpenmrsResource;
9
+ serviceType: {
10
+ uuid: string;
11
+ display: string;
12
+ };
13
+ servicePrices: Array<{
14
+ uuid: string;
15
+ name: string;
16
+ price: number;
17
+ }>;
18
+ concept: {
19
+ uuid: string;
20
+ display: string;
21
+ };
22
+ }
23
+
24
+ export interface ChargeItemsResponse {
25
+ results: Array<ChargeItems>;
26
+ }
27
+
28
+ export type ServiceConcept = {
29
+ concept: {
30
+ uuid: string;
31
+ display: string;
32
+ };
33
+ conceptName: {
34
+ uuid: string;
35
+ display: string;
36
+ };
37
+ display: string;
38
+ };
39
+
40
+ export type ServiceType = { uuid: string; display: string; id: number };
41
+
42
+ export type ServiceTypesResponse = {
43
+ setMembers: Array<ServiceType>;
44
+ };
45
+
46
+ export type StockItemResponse = {
47
+ results: Array<{
48
+ uuid: string;
49
+ drugUuid: string;
50
+ drugName: string;
51
+ conceptUuid: string;
52
+ conceptName: string;
53
+ hasExpiration: boolean;
54
+ preferredVendorUuid: string;
55
+ preferredVendorName: string;
56
+ purchasePrice: number | null;
57
+ purchasePriceUoMUuid: string | null;
58
+ purchasePriceUoMName: string | null;
59
+ purchasePriceUoMFactor: number | null;
60
+ dispensingUnitName: string;
61
+ dispensingUnitUuid: string;
62
+ dispensingUnitPackagingUoMUuid: string;
63
+ dispensingUnitPackagingUoMName: string;
64
+ dispensingUnitPackagingUoMFactor: number;
65
+ defaultStockOperationsUoMUuid: string | null;
66
+ defaultStockOperationsUoMName: string | null;
67
+ defaultStockOperationsUoMFactor: number | null;
68
+ categoryUuid: string;
69
+ categoryName: string;
70
+ commonName: string;
71
+ acronym: string | null;
72
+ reorderLevel: number | null;
73
+ reorderLevelUoMUuid: string | null;
74
+ reorderLevelUoMName: string | null;
75
+ reorderLevelUoMFactor: number | null;
76
+ dateCreated: string;
77
+ creatorGivenName: string;
78
+ creatorFamilyName: string;
79
+ voided: boolean;
80
+ expiryNotice: number;
81
+ links: {
82
+ rel: string;
83
+ uri: string;
84
+ resourceAlias: string;
85
+ }[];
86
+ resourceVersion: string;
87
+ }>;
88
+ };
@@ -0,0 +1,96 @@
1
+ import { BillableFormSchema, ServicePriceSchema } from '../billing-charge-items-workspace/schemas/form-schemas';
2
+
3
+ export type BillableServicePayload = {
4
+ name: string;
5
+ shortName: string;
6
+ serviceType: number | string;
7
+ servicePrices: Array<{
8
+ paymentMode: string;
9
+ price: string | number;
10
+ name: string;
11
+ }>;
12
+ serviceStatus: string;
13
+ concept: string | number;
14
+ stockItem: string;
15
+ uuid?: string;
16
+ };
17
+
18
+ export const formatBillableServicePayloadForSubmission = (
19
+ formData: BillableFormSchema,
20
+ uuid?: string,
21
+ ): BillableServicePayload => {
22
+ const formPayload = {
23
+ name: formData.name,
24
+ shortName: formData.shortName,
25
+ serviceType: formData.serviceType.uuid,
26
+ servicePrices: formData.servicePrices.map((servicePrice) => ({
27
+ paymentMode: servicePrice.paymentMode.uuid,
28
+ price: servicePrice.price,
29
+ name: servicePrice.paymentMode.name,
30
+ })),
31
+ serviceStatus: formData.serviceStatus,
32
+ concept: formData.concept.concept.uuid,
33
+ stockItem: formData.stockItem || null,
34
+ };
35
+
36
+ return uuid ? Object.assign(formPayload, { uuid: uuid }) : formPayload;
37
+ };
38
+
39
+ export function mapInputToPayloadSchema(service): BillableFormSchema {
40
+ const servicePrices: Array<ServicePriceSchema> = service.servicePrices.map((price: any) => ({
41
+ price: price.price,
42
+ paymentMode: {
43
+ uuid: price.paymentMode?.uuid,
44
+ name: price.paymentMode?.name,
45
+ },
46
+ }));
47
+
48
+ const payload: BillableFormSchema = {
49
+ name: service.name,
50
+ shortName: service.shortName,
51
+ serviceType: {
52
+ uuid: service?.serviceType?.uuid,
53
+ display: service?.serviceType?.display,
54
+ },
55
+ servicePrices: servicePrices,
56
+ serviceStatus: service.serviceStatus,
57
+ concept: {
58
+ concept: {
59
+ uuid: service?.concept?.uuid,
60
+ display: service.concept?.display,
61
+ },
62
+ conceptName: {
63
+ uuid: service?.concept?.uuid,
64
+ display: service?.concept?.display,
65
+ },
66
+ display: service?.concept?.display,
67
+ },
68
+ stockItem: service?.stockItem?.uuid ?? null,
69
+ };
70
+
71
+ return payload;
72
+ }
73
+
74
+ export const formatStockItemToPayload = (stockItem: any): BillableFormSchema => {
75
+ return {
76
+ name: stockItem.commonName,
77
+ shortName: stockItem.commonName.length > 1 ? stockItem.commonName : `${stockItem.commonName} `,
78
+ serviceType: {
79
+ uuid: stockItem.serviceType?.uuid || '',
80
+ display: stockItem.serviceType?.display || '',
81
+ },
82
+ servicePrices: [],
83
+ concept: {
84
+ concept: {
85
+ uuid: stockItem.conceptUuid,
86
+ display: stockItem.conceptName,
87
+ },
88
+ conceptName: {
89
+ uuid: stockItem.conceptUuid,
90
+ display: stockItem.conceptName,
91
+ },
92
+ display: stockItem.conceptName,
93
+ },
94
+ stockItem: stockItem.uuid,
95
+ };
96
+ };
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { useConfig } from '@openmrs/esm-framework';
3
+ import styles from './billing-management.scss';
4
+ import { ConfigObject } from '../config-schema';
5
+ import { CustomPageHeader } from '../components/custom-page-header/custom-page-header.component';
6
+ import { useTranslation } from 'react-i18next';
7
+ import BillManagement from './billing-tabs/billing-tabs.component';
8
+
9
+ const BillingManagementDashboard: React.FC = () => {
10
+ const { t } = useTranslation();
11
+ const { billingIcon } = useConfig<ConfigObject>();
12
+
13
+ return (
14
+ <div className={styles.dashboardContainer}>
15
+ <CustomPageHeader subTitle={t('configureBilling', 'Configure billing')} iconSrc={billingIcon.src} />
16
+ <BillManagement />
17
+ </div>
18
+ );
19
+ };
20
+
21
+ export default BillingManagementDashboard;
File without changes
@@ -0,0 +1,28 @@
1
+ @use '@carbon/type';
2
+ @use '@carbon/layout';
3
+
4
+ .modalHeaderLabel {
5
+ @include type.type-style('heading-compact-02');
6
+
7
+ & > div {
8
+ display: none;
9
+ }
10
+ }
11
+ .button_spinner {
12
+ padding: 0;
13
+ margin-right: layout.$spacing-03;
14
+ }
15
+
16
+ .loading_wrapper {
17
+ display: flex;
18
+ align-items: center;
19
+ }
20
+
21
+ .contentContainer {
22
+ padding-left: layout.$spacing-05;
23
+ }
24
+
25
+ .contentValue {
26
+ @include type.type-style('heading-compact-02');
27
+ margin-bottom: layout.$spacing-03;
28
+ }
@@ -0,0 +1,67 @@
1
+ import React from 'react';
2
+ import { ModalBody, ModalFooter, Button, ModalHeader } from '@carbon/react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
5
+ import styles from './billing-delete-payment-modes.modal.scss';
6
+ import { PaymentMethod } from '../type';
7
+ import { deletePaymentMode, handleMutation } from '../billing-payment-modes-workspace/billing-payment-modes.resource';
8
+
9
+ type DeletePaymentModeModalProps = {
10
+ closeModal: () => void;
11
+ paymentMode: PaymentMethod;
12
+ };
13
+
14
+ const DeletePaymentModeModal: React.FC<DeletePaymentModeModalProps> = ({ closeModal, paymentMode }) => {
15
+ const { t } = useTranslation();
16
+ const paymentModeName = paymentMode?.name || '';
17
+
18
+ const handleDelete = async () => {
19
+ try {
20
+ await deletePaymentMode(paymentMode.uuid);
21
+ showSnackbar({
22
+ title: t('paymentModeDeleted', 'Payment mode deleted'),
23
+ subtitle: t('paymentModeDeletedSubtitle', 'The payment mode has been deleted'),
24
+ kind: 'success',
25
+ isLowContrast: true,
26
+ timeoutInMs: 5000,
27
+ autoClose: true,
28
+ });
29
+ handleMutation(`${restBaseUrl}/cashier/paymentMode?v=full`);
30
+ closeModal();
31
+ } catch (error) {
32
+ showSnackbar({
33
+ title: t('paymentModeDeletedError', 'Error deleting payment mode'),
34
+ subtitle: t('paymentModeDeletedErrorSubtitle', 'An error occurred while deleting the payment mode'),
35
+ kind: 'error',
36
+ isLowContrast: true,
37
+ timeoutInMs: 5000,
38
+ autoClose: true,
39
+ });
40
+ }
41
+ };
42
+
43
+ return (
44
+ <>
45
+ <ModalHeader className={styles.modalHeaderLabel} closeModal={closeModal}>
46
+ {t('deletePaymentMode', 'Delete Payment Mode')}
47
+ </ModalHeader>
48
+ <ModalBody className={styles.modalHeaderHeading}>
49
+ {t(
50
+ 'deletePaymentModeDescription',
51
+ `Are you sure you want to delete this {{paymentModeName}} payment mode? Proceed cautiously.`,
52
+ { paymentModeName },
53
+ )}
54
+ </ModalBody>
55
+ <ModalFooter>
56
+ <Button kind="secondary" onClick={closeModal}>
57
+ {t('cancel', 'Cancel')}
58
+ </Button>
59
+ <Button kind="danger" onClick={handleDelete}>
60
+ {t('delete', 'Delete')}
61
+ </Button>
62
+ </ModalFooter>
63
+ </>
64
+ );
65
+ };
66
+
67
+ export default DeletePaymentModeModal;