@kenyaemr/esm-billing-app 5.4.1-pre.2093 → 5.4.1-pre.2099

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.
@@ -1,239 +1,266 @@
1
- import {
2
- DataTable,
3
- DataTableSkeleton,
4
- OverflowMenu,
5
- OverflowMenuItem,
6
- Pagination,
7
- Table,
8
- TableBody,
9
- TableCell,
10
- TableContainer,
11
- TableHead,
12
- TableHeader,
13
- TableRow,
14
- Tag,
15
- } from '@carbon/react';
16
- import { formatDate, isDesktop, parseDate, showModal, useLayoutType, usePagination } from '@openmrs/esm-framework';
17
- import { CardHeader, EmptyState, usePaginationInfo } from '@openmrs/esm-patient-common-lib';
18
- import React, { useMemo, useState } from 'react';
19
- import { useTranslation } from 'react-i18next';
20
- import { ClaimsPreAuthFilter } from '../../../types';
21
- import ClaimsFilterHeader from '../header/filter-header.component';
22
- import styles from './claims-list-table.scss';
23
- import { useFacilityClaims } from './use-facility-claims';
1
+ // import {
2
+ // DataTable,
3
+ // DataTableSkeleton,
4
+ // OverflowMenu,
5
+ // OverflowMenuItem,
6
+ // Pagination,
7
+ // Table,
8
+ // TableBody,
9
+ // TableCell,
10
+ // TableContainer,
11
+ // TableHead,
12
+ // TableHeader,
13
+ // TableRow,
14
+ // Tag,
15
+ // } from '@carbon/react';
16
+ // import { formatDate, isDesktop, parseDate, showModal, useLayoutType, usePagination } from '@openmrs/esm-framework';
17
+ // import { CardHeader, EmptyState, usePaginationInfo } from '@openmrs/esm-patient-common-lib';
18
+ // import React, { useMemo, useState } from 'react';
19
+ // import { useTranslation } from 'react-i18next';
20
+ // import { ClaimsPreAuthFilter } from '../../../types';
21
+ // import ClaimsFilterHeader from '../header/filter-header.component';
22
+ // import styles from './claims-list-table.scss';
23
+ // import { useFacilityClaims } from './use-facility-claims';
24
+ // import { statusColors } from '../../utils';
24
25
 
25
- const ClaimsManagementTable: React.FC = () => {
26
- const { claims, isLoading } = useFacilityClaims();
27
- const { t } = useTranslation();
28
- const [filters, setFilters] = useState<ClaimsPreAuthFilter>({
29
- status: 'all',
30
- });
31
- const status = useMemo(
32
- () => [
33
- { value: 'all', label: t('all', 'All') },
34
- { value: 'ENTERED', label: t('entered', 'Entered') },
35
- { value: 'ERRORED', label: t('errored', 'Errored') },
36
- { value: 'REJECTED', label: t('rejected', 'Rejected') },
37
- { value: 'CHECKED', label: t('checked', 'Checked') },
38
- { value: 'VALUATED', label: t('valuated', 'Valuated') },
39
- { value: 'APPROVED', label: t('approved', 'Approved') },
40
- ],
41
- [t],
42
- );
43
- const [pageSize, setPageSize] = useState(5);
44
- const filterClaims = (claim) => {
45
- const status = filters?.status;
46
- const search = filters?.search?.toLowerCase();
47
- const fromDate = filters?.fromDate ? new Date(filters.fromDate) : null;
48
- const toDate = filters?.toDate ? new Date(filters.toDate) : null;
49
-
50
- const patientName = claim.patientName?.toLowerCase();
51
- const providerName = claim.providerName?.toLowerCase();
52
- const timeStamp = new Date(claim.dateFrom);
53
- const preauthStatus = claim.status;
54
-
55
- // Check status (allow 'all' to bypass the filter)
56
- const statusMatch = status === 'all' || preauthStatus === status;
57
-
58
- // Check search filter (patient name or provider name contains the search term)
59
- const searchMatch = !search || patientName?.includes(search) || providerName?.includes(search);
60
-
61
- // Check date range filter (timestamp is between fromDate and toDate if provided)
62
- const dateMatch = (!fromDate || timeStamp >= fromDate) && (!toDate || timeStamp <= toDate);
63
-
64
- // Return true if all conditions match
65
- return statusMatch && searchMatch && dateMatch;
66
- };
67
-
68
- const filteredClaims = claims.filter(filterClaims);
69
- const { paginated, goTo, results, currentPage } = usePagination(filteredClaims, pageSize);
70
- const { pageSizes } = usePaginationInfo(pageSize, claims.length, currentPage, results.length);
71
- const responsiveSize = isDesktop(useLayoutType()) ? 'sm' : 'lg';
72
- const layout = useLayoutType();
73
- const size = layout === 'tablet' ? 'lg' : 'md';
74
-
75
- const headers = [
76
- { key: 'claimCode', header: t('claimCode', 'Claim Code') },
77
- { key: 'status', header: t('status', 'Status') },
78
- { key: 'providerName', header: t('provider', 'Provider') },
79
- { key: 'patientName', header: t('patient', 'Patient') },
80
- { key: 'claimedTotal', header: t('claimedAmount', 'Claimed Amount') },
81
- { key: 'approvedTotal', header: t('approvedTotal', 'Approved Total') },
82
- { key: 'dateFrom', header: t('dateCreated', 'Date Created') },
83
- { key: 'action', header: t('action', 'Action') },
84
- ];
85
-
86
- if (isLoading) {
87
- return (
88
- <div className={styles.dataTableSkeleton}>
89
- <DataTableSkeleton
90
- headers={headers}
91
- showToolbar={false}
92
- showHeader={false}
93
- columnCount={Object.keys(headers).length}
94
- zebra
95
- rowCount={pageSize}
96
- />
97
- </div>
98
- );
99
- }
100
-
101
- if (claims.length === 0) {
102
- return (
103
- <div className={styles.claimsTable}>
104
- <EmptyState
105
- displayText={t('emptyClaimsState', 'There are no claims to display')}
106
- headerTitle={t('emptyClaimsHeader', 'No Claims')}
107
- />
108
- </div>
109
- );
110
- }
111
-
112
- const handleClaimAction = (claimId: string, modalType: 'retry' | 'update') => {
113
- const dispose = showModal('manage-claim-request-modal', {
114
- closeModal: () => dispose(),
115
- claimId,
116
- modalType,
117
- });
118
- };
26
+ // const ClaimsManagementTable: React.FC = () => {
27
+ // const { claims, isLoading } = useFacilityClaims();
28
+ // const { t } = useTranslation();
29
+ // const [filters, setFilters] = useState<ClaimsPreAuthFilter>({
30
+ // status: 'all',
31
+ // });
32
+ // const status = useMemo(
33
+ // () => [
34
+ // { value: 'all', label: t('all', 'All') },
35
+ // { value: 'ENTERED', label: t('entered', 'Entered') },
36
+ // { value: 'ERRORED', label: t('errored', 'Errored') },
37
+ // { value: 'REJECTED', label: t('rejected', 'Rejected') },
38
+ // { value: 'CHECKED', label: t('checked', 'Checked') },
39
+ // { value: 'VALUATED', label: t('valuated', 'Valuated') },
40
+ // { value: 'APPROVED', label: t('approved', 'Approved') },
41
+ // ],
42
+ // [t],
43
+ // );
44
+ // const [pageSize, setPageSize] = useState(5);
45
+ // const filterClaims = (claim) => {
46
+ // const status = filters?.status;
47
+ // const search = filters?.search?.toLowerCase();
48
+ // const fromDate = filters?.fromDate ? new Date(filters.fromDate) : null;
49
+ // const toDate = filters?.toDate ? new Date(filters.toDate) : null;
119
50
 
120
- return (
121
- <div className={styles.dataTableSkeleton}>
122
- <div className={styles.tableHeader}>
123
- <CardHeader title={t('claims', 'Claims')}>{''}</CardHeader>
124
- <ClaimsFilterHeader filters={filters} onFilterChanged={setFilters} statusOptions={status} />
125
- </div>
126
- <DataTable rows={results} headers={headers} isSortable useZebraStyles>
127
- {({ rows, headers, getHeaderProps, getRowProps, getTableProps }) => (
128
- <TableContainer className={styles.claimsTable}>
129
- <Table {...getTableProps()} aria-label="sample table">
130
- <TableHead>
131
- <TableRow>
132
- {headers.map((header) => (
133
- <TableHeader
134
- key={header.key}
135
- {...getHeaderProps({
136
- header,
137
- })}>
138
- {header.header}
139
- </TableHeader>
140
- ))}
141
- </TableRow>
142
- </TableHead>
143
- <TableBody>
144
- {rows.map((row) => {
145
- const rowStatus = row.cells.find((cell) => cell.info.header === 'status')?.value;
146
- return (
147
- <TableRow
148
- {...getRowProps({
149
- row,
150
- })}>
151
- {row.cells.map((cell) => (
152
- <TableCell key={cell.id}>
153
- {cell.info.header === 'status' ? (
154
- <ClaimStatus row={row} />
155
- ) : cell.info.header === 'action' ? (
156
- <OverflowMenu size={size} flipped>
157
- {['ENTERED', 'ERRORED'].includes(rowStatus) && (
158
- <OverflowMenuItem
159
- itemText={t('retryRequest', 'Retry request')}
160
- onClick={() => handleClaimAction(row.id, 'retry')}
161
- />
162
- )}
163
- <OverflowMenuItem
164
- itemText={t('updateStatus', 'Update status')}
165
- onClick={() => handleClaimAction(row.id, 'update')}
166
- />
167
- </OverflowMenu>
168
- ) : cell.info.header === 'dateFrom' ? (
169
- formatDate(parseDate(cell.value))
170
- ) : cell.info.header === 'approvedTotal' ? (
171
- ['APPROVED'].includes(rowStatus) ? (
172
- row.cells.find((c) => c.info.header === 'claimedTotal')?.value || cell.value
173
- ) : (
174
- cell.value
175
- )
176
- ) : (
177
- cell.value
178
- )}
179
- </TableCell>
180
- ))}
181
- </TableRow>
182
- );
183
- })}
184
- </TableBody>
185
- </Table>
186
- {paginated && !isLoading && (
187
- <Pagination
188
- forwardText=""
189
- backwardText=""
190
- page={currentPage}
191
- pageSize={pageSize}
192
- pageSizes={pageSizes}
193
- totalItems={filteredClaims.length}
194
- size={responsiveSize}
195
- onChange={({ page: newPage, pageSize }) => {
196
- if (newPage !== currentPage) {
197
- goTo(newPage);
198
- }
199
- setPageSize(pageSize);
200
- }}
201
- />
202
- )}
203
- </TableContainer>
204
- )}
205
- </DataTable>
206
- </div>
207
- );
208
- };
51
+ // const patientName = claim.patientName?.toLowerCase();
52
+ // const providerName = claim.providerName?.toLowerCase();
53
+ // const timeStamp = new Date(claim.dateFrom);
54
+ // const preauthStatus = claim.status;
209
55
 
210
- export default ClaimsManagementTable;
211
- const ClaimStatus = ({ row }: { row: any }) => {
212
- const { claims } = useFacilityClaims();
213
- const { t } = useTranslation();
214
-
215
- const claim = claims.find((claim) => claim.id === row.id);
216
-
217
- const getTagType = (status) => {
218
- switch (status) {
219
- case 'ENTERED':
220
- return 'blue';
221
- case 'ERRORED':
222
- return 'red';
223
- case 'REJECTED':
224
- return 'red';
225
- case 'CHECKED':
226
- return 'green';
227
- case 'VALUATED':
228
- return 'purple';
229
- default:
230
- return 'gray';
231
- }
232
- };
56
+ // // Check status (allow 'all' to bypass the filter)
57
+ // const statusMatch = status === 'all' || preauthStatus === status;
58
+
59
+ // // Check search filter (patient name or provider name contains the search term)
60
+ // const searchMatch = !search || patientName?.includes(search) || providerName?.includes(search);
61
+
62
+ // // Check date range filter (timestamp is between fromDate and toDate if provided)
63
+ // const dateMatch = (!fromDate || timeStamp >= fromDate) && (!toDate || timeStamp <= toDate);
64
+
65
+ // // Return true if all conditions match
66
+ // return statusMatch && searchMatch && dateMatch;
67
+ // };
68
+
69
+ // const filteredClaims = claims.filter(filterClaims);
70
+ // const { paginated, goTo, results, currentPage } = usePagination(filteredClaims, pageSize);
71
+ // const { pageSizes } = usePaginationInfo(pageSize, claims.length, currentPage, results.length);
72
+ // const responsiveSize = isDesktop(useLayoutType()) ? 'sm' : 'lg';
73
+ // const layout = useLayoutType();
74
+ // const size = layout === 'tablet' ? 'lg' : 'md';
75
+
76
+ // const headers = [
77
+ // { key: 'claimCode', header: t('claimCode', 'Claim Code') },
78
+ // { key: 'status', header: t('status', 'Status') },
79
+ // { key: 'providerName', header: t('provider', 'Provider') },
80
+ // { key: 'patientName', header: t('patient', 'Patient') },
81
+ // { key: 'claimedTotal', header: t('claimedAmount', 'Claimed Amount') },
82
+ // { key: 'approvedTotal', header: t('approvedTotal', 'Approved Total') },
83
+ // { key: 'dateFrom', header: t('dateCreated', 'Date Created') },
84
+ // { key: 'action', header: t('action', 'Action') },
85
+ // ];
86
+
87
+ // if (isLoading) {
88
+ // return (
89
+ // <div className={styles.dataTableSkeleton}>
90
+ // <DataTableSkeleton
91
+ // headers={headers}
92
+ // showToolbar={false}
93
+ // showHeader={false}
94
+ // columnCount={Object.keys(headers).length}
95
+ // zebra
96
+ // rowCount={pageSize}
97
+ // />
98
+ // </div>
99
+ // );
100
+ // }
101
+
102
+ // if (claims.length === 0) {
103
+ // return (
104
+ // <div className={styles.claimsTable}>
105
+ // <EmptyState
106
+ // displayText={t('emptyClaimsState', 'There are no claims to display')}
107
+ // headerTitle={t('emptyClaimsHeader', 'No Claims')}
108
+ // />
109
+ // </div>
110
+ // );
111
+ // }
112
+
113
+ // const handleClaimAction = (claimId: string, modalType: 'retry' | 'update') => {
114
+ // const dispose = showModal('manage-claim-request-modal', {
115
+ // closeModal: () => dispose(),
116
+ // claimId,
117
+ // modalType,
118
+ // });
119
+ // };
120
+
121
+ // const renderStatusCell = (row) => {
122
+ // return <ClaimStatus row={row} />;
123
+ // };
124
+
125
+ // const renderActionCell = (row, rowStatus, size) => {
126
+ // return (
127
+ // <OverflowMenu size={size} flipped>
128
+ // {['ENTERED', 'ERRORED'].includes(rowStatus) && (
129
+ // <OverflowMenuItem
130
+ // itemText={t('retryRequest', 'Retry request')}
131
+ // onClick={() => handleClaimAction(row.id, 'retry')}
132
+ // />
133
+ // )}
134
+ // <OverflowMenuItem
135
+ // itemText={t('updateStatus', 'Update status')}
136
+ // onClick={() => handleClaimAction(row.id, 'update')}
137
+ // />
138
+ // </OverflowMenu>
139
+ // );
140
+ // };
233
141
 
142
+ // const renderDateFromCell = (cellValue) => {
143
+ // return formatDate(parseDate(cellValue));
144
+ // };
145
+
146
+ // const renderApprovedTotalCell = (row, rowStatus, cellValue) => {
147
+ // if (['APPROVED'].includes(rowStatus)) {
148
+ // const claimedTotal = row.cells.find((c) => c.info.header === 'claimedTotal')?.value;
149
+ // return claimedTotal || cellValue;
150
+ // }
151
+ // return cellValue;
152
+ // };
153
+
154
+ // const renderCellContent = (cell, row, rowStatus) => {
155
+ // const header = cell.info.header;
156
+
157
+ // if (header === 'status') {
158
+ // return renderStatusCell(row);
159
+ // }
160
+
161
+ // if (header === 'action') {
162
+ // return renderActionCell(row, rowStatus, size);
163
+ // }
164
+
165
+ // if (header === 'dateFrom') {
166
+ // return renderDateFromCell(cell.value);
167
+ // }
168
+
169
+ // if (header === 'approvedTotal') {
170
+ // return renderApprovedTotalCell(row, rowStatus, cell.value);
171
+ // }
172
+
173
+ // return cell.value;
174
+ // };
175
+
176
+ // return (
177
+ // <div className={styles.dataTableSkeleton}>
178
+ // <div className={styles.tableHeader}>
179
+ // <CardHeader title={t('claims', 'Claims')}>{''}</CardHeader>
180
+ // <ClaimsFilterHeader filters={filters} onFilterChanged={setFilters} statusOptions={status} />
181
+ // </div>
182
+ // <DataTable rows={results} headers={headers} isSortable useZebraStyles>
183
+ // {({ rows, headers, getHeaderProps, getRowProps, getTableProps }) => (
184
+ // <TableContainer className={styles.claimsTable}>
185
+ // <Table {...getTableProps()} aria-label="sample table">
186
+ // <TableHead>
187
+ // <TableRow>
188
+ // {headers.map((header) => (
189
+ // <TableHeader
190
+ // key={header.key}
191
+ // {...getHeaderProps({
192
+ // header,
193
+ // })}>
194
+ // {header.header}
195
+ // </TableHeader>
196
+ // ))}
197
+ // </TableRow>
198
+ // </TableHead>
199
+ // <TableBody>
200
+ // {rows.map((row) => {
201
+ // const rowStatus = row.cells.find((cell) => cell.info.header === 'status')?.value;
202
+ // return (
203
+ // <TableRow {...getRowProps({ row })}>
204
+ // {row.cells.map((cell) => (
205
+ // <TableCell key={cell.id}>{renderCellContent(cell, row, rowStatus)}</TableCell>
206
+ // ))}
207
+ // </TableRow>
208
+ // );
209
+ // })}
210
+ // </TableBody>
211
+ // </Table>
212
+ // {paginated && !isLoading && (
213
+ // <Pagination
214
+ // forwardText=""
215
+ // backwardText=""
216
+ // page={currentPage}
217
+ // pageSize={pageSize}
218
+ // pageSizes={pageSizes}
219
+ // totalItems={filteredClaims.length}
220
+ // size={responsiveSize}
221
+ // onChange={({ page: newPage, pageSize }) => {
222
+ // if (newPage !== currentPage) {
223
+ // goTo(newPage);
224
+ // }
225
+ // setPageSize(pageSize);
226
+ // }}
227
+ // />
228
+ // )}
229
+ // </TableContainer>
230
+ // )}
231
+ // </DataTable>
232
+ // </div>
233
+ // );
234
+ // };
235
+
236
+ // export default ClaimsManagementTable;
237
+ // const ClaimStatus = ({ row }: { row: any }) => {
238
+ // const { claims } = useFacilityClaims();
239
+ // const { t } = useTranslation();
240
+
241
+ // const claim = claims.find((claim) => claim.id === row.id);
242
+
243
+ // // Default to 'gray' if status not found in the mapping
244
+ // const tagType = statusColors[claim.status] || 'gray';
245
+
246
+ // return (
247
+ // <div className={styles.claimStatus}>
248
+ // <Tag type={tagType}>{claim.status}</Tag>
249
+ // </div>
250
+ // );
251
+ // };
252
+ import React from 'react';
253
+ import ClaimsTable from './claim-table.component';
254
+
255
+ const ClaimsManagementTable: React.FC = () => {
234
256
  return (
235
- <div className={styles.claimStatus}>
236
- <Tag type={getTagType(claim.status)}>{claim.status}</Tag>
237
- </div>
257
+ <ClaimsTable
258
+ title="claims"
259
+ emptyStateText="emptyClaimsState"
260
+ emptyStateHeader="emptyClaimsHeader"
261
+ includeClaimCode={true}
262
+ />
238
263
  );
239
264
  };
265
+
266
+ export default ClaimsManagementTable;
@@ -1,4 +1,4 @@
1
- import { Button, Loading, ModalBody, ModalFooter, ModalHeader } from '@carbon/react';
1
+ import { Button, InlineLoading, ModalBody, ModalFooter, ModalHeader } from '@carbon/react';
2
2
  import { showSnackbar } from '@openmrs/esm-framework';
3
3
  import React, { useState } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
@@ -47,7 +47,7 @@ export const ManageClaimRequest = ({
47
47
 
48
48
  const handleUpdateStatus = () => {
49
49
  setIsSubmitting(true);
50
- updateClaimStatus(claim.externalId)
50
+ updateClaimStatus(claim.responseUUID)
51
51
  .then(() => {
52
52
  mutate();
53
53
  showSnackbar({
@@ -96,7 +96,7 @@ export const ManageClaimRequest = ({
96
96
  <Button type="submit" onClick={handleSubmit}>
97
97
  {isSubmitting ? (
98
98
  <>
99
- <Loading withOverlay={false} small />
99
+ <InlineLoading withOverlay={false} small />
100
100
  {modalType === 'retry' ? t('retrying', 'Retrying') : t('updating', 'Updating')}
101
101
  </>
102
102
  ) : modalType === 'retry' ? (