@kenyaemr/esm-billing-app 5.4.1-pre.2100 → 5.4.1-pre.2103

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/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":"order-action-button","component":"orderActionButton","slots":["prescription-action-button-slot","imaging-orders-action","procedure-orders-action","tests-ordered-actions-slot"],"order":0},{"component":"billingOverviewLink","name":"billing-overview-link","order":0,"slot":"billing-dashboard-link-slot"},{"component":"paymentHistoryLink","name":"payment-history-link","slot":"billing-dashboard-link-slot"},{"component":"paymentPointsLink","name":"payment-points-link","slot":"billing-dashboard-link-slot"},{"component":"paymentModesLink","name":"payment-modes-link","slot":"billing-dashboard-link-slot"},{"component":"billManagerLink","name":"bill-manager-link","slot":"billing-dashboard-link-slot"},{"component":"chargeableItemsLink","name":"chargeable-items-link","slot":"billing-dashboard-link-slot"},{"component":"billableExemptionsLink","name":"billable-exemptions-link","slot":"billing-dashboard-link-slot"},{"component":"claimsManagementSideNavGroup","name":"claims-management-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"claims-management","title":"Claims management Overview","slot":"case-management-slot"},"featureFlag":"healthInformationExchange"},{"component":"claimsManagementOverviewDashboardLink","name":"claims-management-overview-link","order":0,"slot":"claims-management-dashboard-link-slot"},{"component":"preAuthRequestsDashboardLink","name":"preauthrequest-overview-link","slot":"claims-management-dashboard-link-slot"},{"component":"claimsOverview","name":"claims-overview-dashboard-link","slot":"claims-management-overview-slot"},{"component":"waiveBillActionButton","name":"waive-bill-action-button","slot":"bill-actions-slot"},{"component":"deleteBillActionButton","name":"delete-bill-action-button","slot":"bill-actions-slot"},{"component":"refundLineItem","name":"refund-line-item","slot":"bill-actions-overflow-menu-slot"},{"name":"edit-line-item","component":"editLineItem","slot":"bill-actions-overflow-menu-slot"},{"name":"cancel-line-item","component":"cancelLineItem","slot":"bill-actions-overflow-menu-slot"}],"workspaces":[{"name":"create-bill-workspace","component":"createBillWorkspace","title":"Create Bill Workspace","type":"other-form"},{"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"},{"name":"bill-deposit-workspace","component":"billDepositWorkspace","title":"Bill Deposit Workspace","type":"other-form"}],"modals":[{"name":"create-payment-point","component":"createPaymentPoint"},{"name":"clock-out-modal","component":"clockOut"},{"name":"bulk-import-billable-services-modal","component":"bulkImportBillableServicesModal"},{"name":"delete-payment-mode-modal","component":"deletePaymentModeModal"},{"name":"manage-claim-request-modal","component":"manageClaimRequestModal"},{"name":"paid-bill-receipt-print-preview-modal","component":"paidBillReceiptPrintPreviewModal"},{"name":"clock-in-modal","component":"clockIn"},{"name":"create-bill-item-modal","component":"createBillItemModal"}],"version":"5.4.1-pre.2100"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"kenyaemr":"^19.0.0"},"pages":[{"component":"billableServicesHome","route":"billable-services"},{"component":"requirePaymentModal","routeRegex":"^patient/.+/chart","online":true,"offline":false}],"extensions":[{"component":"billingDashboardLink","name":"billing-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"billing","title":"billing","slot":"billing-dashboard-slot"}},{"component":"benefitsPackageDashboardLink","name":"benefits-package-dashboard-link","slot":"patient-chart-dashboard-slot","meta":{"name":"benefits-package","slot":"patient-chart-benefits-dashboard-slot","path":"insurance-benefits","columns":1,"columnSpan":1},"featureFlag":"healthInformationExchange"},{"component":"benefitsPackage","name":"benefits-package","slot":"patient-chart-benefits-dashboard-slot"},{"component":"root","name":"billing-dashboard-root","slot":"billing-dashboard-slot"},{"component":"benefitsEligibilyRequestForm","name":"benefits-eligibility-request-form"},{"component":"benefitsPreAuthForm","name":"benefits-pre-auth-form"},{"name":"billing-patient-summary","component":"billingPatientSummary","slot":"patient-chart-billing-dashboard-slot","order":10,"meta":{"columnSpan":4}},{"name":"billing-summary-dashboard-link","component":"billingSummaryDashboardLink","slot":"patient-chart-dashboard-slot","order":11,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-billing-dashboard-slot","path":"Billing","layoutMode":"anchored"}},{"name":"billing-check-in-form","slot":"extra-visit-attribute-slot","component":"billingCheckInForm"},{"name":"require-billing-modal","component":"requirePaymentModal"},{"name":"patient-banner-billing-tags","component":"visitAttributeTags","slot":"patient-banner-tags-slot","order":2},{"name":"initiate-payment-modal","component":"initiatePaymentDialog"},{"name":"delete-billableservice-modal","component":"deleteBillableServiceModal"},{"name":"refund-bill-modal","component":"refundBillModal"},{"name":"delete-bill-modal","component":"deleteBillModal"},{"name":"lab-order-billable-item","component":"labOrder","slot":"top-of-lab-order-form-slot"},{"name":"procedure-order-billable-item","component":"procedureOrder","slot":"top-of-procedure-order-form-slot"},{"name":"imaging-order-billable-item","component":"imagingOrder","slot":"top-of-imaging-order-form-slot"},{"name":"price-info-order","component":"priceInfoOrder"},{"name":"drug-order-billable-item","component":"drugOrder","slot":"medication-info-slot"},{"name":"order-action-button","component":"orderActionButton","slots":["prescription-action-button-slot","imaging-orders-action","procedure-orders-action","tests-ordered-actions-slot"],"order":0},{"component":"billingOverviewLink","name":"billing-overview-link","order":0,"slot":"billing-dashboard-link-slot"},{"component":"paymentHistoryLink","name":"payment-history-link","slot":"billing-dashboard-link-slot"},{"component":"paymentPointsLink","name":"payment-points-link","slot":"billing-dashboard-link-slot"},{"component":"paymentModesLink","name":"payment-modes-link","slot":"billing-dashboard-link-slot"},{"component":"billManagerLink","name":"bill-manager-link","slot":"billing-dashboard-link-slot"},{"component":"chargeableItemsLink","name":"chargeable-items-link","slot":"billing-dashboard-link-slot"},{"component":"billableExemptionsLink","name":"billable-exemptions-link","slot":"billing-dashboard-link-slot"},{"component":"claimsManagementSideNavGroup","name":"claims-management-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"claims-management","title":"Claims management Overview","slot":"case-management-slot"},"featureFlag":"healthInformationExchange"},{"component":"claimsManagementOverviewDashboardLink","name":"claims-management-overview-link","order":0,"slot":"claims-management-dashboard-link-slot"},{"component":"preAuthRequestsDashboardLink","name":"preauthrequest-overview-link","slot":"claims-management-dashboard-link-slot"},{"component":"claimsOverview","name":"claims-overview-dashboard-link","slot":"claims-management-overview-slot"},{"component":"waiveBillActionButton","name":"waive-bill-action-button","slot":"bill-actions-slot"},{"component":"deleteBillActionButton","name":"delete-bill-action-button","slot":"bill-actions-slot"},{"component":"refundLineItem","name":"refund-line-item","slot":"bill-actions-overflow-menu-slot"},{"name":"edit-line-item","component":"editLineItem","slot":"bill-actions-overflow-menu-slot"},{"name":"cancel-line-item","component":"cancelLineItem","slot":"bill-actions-overflow-menu-slot"}],"workspaces":[{"name":"create-bill-workspace","component":"createBillWorkspace","title":"Create Bill Workspace","type":"other-form"},{"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"},{"name":"bill-deposit-workspace","component":"billDepositWorkspace","title":"Bill Deposit Workspace","type":"other-form"}],"modals":[{"name":"create-payment-point","component":"createPaymentPoint"},{"name":"clock-out-modal","component":"clockOut"},{"name":"bulk-import-billable-services-modal","component":"bulkImportBillableServicesModal"},{"name":"delete-payment-mode-modal","component":"deletePaymentModeModal"},{"name":"manage-claim-request-modal","component":"manageClaimRequestModal"},{"name":"paid-bill-receipt-print-preview-modal","component":"paidBillReceiptPrintPreviewModal"},{"name":"clock-in-modal","component":"clockIn"},{"name":"create-bill-item-modal","component":"createBillItemModal"}],"version":"5.4.1-pre.2103"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenyaemr/esm-billing-app",
3
- "version": "5.4.1-pre.2100",
3
+ "version": "5.4.1-pre.2103",
4
4
  "description": "Billing app for KenyaEMR",
5
5
  "browser": "dist/kenyaemr-esm-billing-app.js",
6
6
  "main": "src/index.ts",
@@ -70,6 +70,7 @@ const PackageInterventions: React.FC<PackageInterventionsProps> = ({ categories,
70
70
  render={({ field }) => (
71
71
  <MultiSelect
72
72
  ref={field.ref}
73
+ disabled={!categories || categories.length === 0}
73
74
  invalid={form.formState.errors[field.name]?.message}
74
75
  invalidText={form.formState.errors[field.name]?.message}
75
76
  id="interventions"
@@ -1,21 +1,32 @@
1
- import { DatePicker, DatePickerInput, Dropdown, Search } from '@carbon/react';
1
+ import { DatePicker, DatePickerInput, Dropdown, Search, Button } from '@carbon/react';
2
2
  import React, { useMemo } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { ClaimsPreAuthFilter } from '../../../types';
5
5
  import styles from './filter-header.scss';
6
+ import { showModal } from '@openmrs/esm-framework';
6
7
 
7
8
  type ClaimsFilterHeaderProps = {
8
9
  filters: ClaimsPreAuthFilter;
9
10
  onFilterChanged: React.Dispatch<React.SetStateAction<ClaimsPreAuthFilter>>;
10
11
  statusOptions?: Array<{ value: string; label: string }>;
12
+ filteredClaimIds?: Array<string>;
11
13
  };
12
14
 
13
15
  const ClaimsFilterHeader: React.FC<ClaimsFilterHeaderProps> = ({
14
16
  filters,
15
17
  onFilterChanged,
16
18
  statusOptions: status = [],
19
+ filteredClaimIds = [],
17
20
  }) => {
18
21
  const { t } = useTranslation();
22
+
23
+ const handleUpdateAllStatuses = () => {
24
+ const dispose = showModal('manage-claim-request-modal', {
25
+ closeModal: () => dispose(),
26
+ multipleIds: filteredClaimIds,
27
+ modalType: 'all',
28
+ });
29
+ };
19
30
  return (
20
31
  <div className={styles.filterContainer}>
21
32
  <Search
@@ -41,6 +52,9 @@ const ClaimsFilterHeader: React.FC<ClaimsFilterHeaderProps> = ({
41
52
  <DatePickerInput id="date-picker-input-id-start" placeholder="mm/dd/yyyy" size="md" />
42
53
  <DatePickerInput id="date-picker-input-id-finish" placeholder="mm/dd/yyyy" size="md" />
43
54
  </DatePicker>
55
+ <Button kind="primary" onClick={handleUpdateAllStatuses} disabled={filteredClaimIds.length === 0}>
56
+ {t('updateAllStatuses', 'Update All')}
57
+ </Button>
44
58
  </div>
45
59
  );
46
60
  };
@@ -91,6 +91,7 @@ const ClaimsTable: React.FC<TableProps> = ({ title, emptyStateText, emptyStateHe
91
91
  const responsiveSize = isDesktop(useLayoutType()) ? 'sm' : 'lg';
92
92
  const layout = useLayoutType();
93
93
  const size = layout === 'tablet' ? 'lg' : 'md';
94
+ const filteredClaimIds = filteredClaims.map((claim) => claim.responseUUID);
94
95
 
95
96
  const getHeaders = (): Header[] => {
96
97
  let baseHeaders = [
@@ -135,7 +136,7 @@ const ClaimsTable: React.FC<TableProps> = ({ title, emptyStateText, emptyStateHe
135
136
  );
136
137
  }
137
138
 
138
- const handleClaimAction = (claimId: string, modalType: 'retry' | 'update') => {
139
+ const handleClaimAction = (claimId: string, modalType: 'retry' | 'update' | 'all') => {
139
140
  const dispose = showModal('manage-claim-request-modal', {
140
141
  closeModal: () => dispose(),
141
142
  claimId,
@@ -203,7 +204,12 @@ const ClaimsTable: React.FC<TableProps> = ({ title, emptyStateText, emptyStateHe
203
204
  <div className={styles.dataTableSkeleton}>
204
205
  <div className={styles.tableHeader}>
205
206
  <CardHeader title={t(title)}>{''}</CardHeader>
206
- <ClaimsFilterHeader filters={filters} onFilterChanged={setFilters} statusOptions={status} />
207
+ <ClaimsFilterHeader
208
+ filters={filters}
209
+ onFilterChanged={setFilters}
210
+ statusOptions={status}
211
+ filteredClaimIds={filteredClaimIds}
212
+ />
207
213
  </div>
208
214
  <DataTable rows={results} headers={headers} isSortable useZebraStyles>
209
215
  {({ rows, headers, getHeaderProps, getRowProps, getTableProps }) => (
@@ -4,19 +4,27 @@ import React, { useState } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { retryClaim, updateClaimStatus } from '../../dashboard/form/claims-form.resource';
6
6
  import { useFacilityClaims } from './use-facility-claims';
7
+ import { ProgressTracker } from '../../../types';
8
+ import { updateMultipleClaimStatuses } from '../../utils';
7
9
 
8
10
  export const ManageClaimRequest = ({
9
11
  closeModal,
10
12
  claimId,
11
13
  modalType = 'retry',
14
+ multipleIds = [],
12
15
  }: {
13
16
  closeModal: () => void;
14
17
  claimId: string;
15
- modalType: 'retry' | 'update';
18
+ modalType: 'retry' | 'update' | 'all';
19
+ multipleIds?: string[];
16
20
  }) => {
17
21
  const { t } = useTranslation();
18
22
  const [isSubmitting, setIsSubmitting] = useState(false);
19
23
  const { claims, mutate } = useFacilityClaims();
24
+ const [progress, setProgress] = useState({ completed: 0, total: multipleIds.length });
25
+ const responseUUIDs = multipleIds
26
+ .map((claimId) => claims.find((c) => c.responseUUID === claimId)?.responseUUID)
27
+ .filter((uuid) => uuid);
20
28
 
21
29
  const claim = claims.find((claim) => claim.id === claimId);
22
30
 
@@ -71,9 +79,54 @@ export const ManageClaimRequest = ({
71
79
  });
72
80
  };
73
81
 
82
+ const handleUpdateMultipleStatus = async () => {
83
+ setIsSubmitting(true);
84
+ setProgress({ completed: 0, total: responseUUIDs.length });
85
+
86
+ const updateProgressCallback = (progressData: ProgressTracker) => {
87
+ setProgress({
88
+ completed: progressData.completed,
89
+ total: progressData.total,
90
+ });
91
+ };
92
+
93
+ const results = await updateMultipleClaimStatuses(responseUUIDs, updateProgressCallback);
94
+
95
+ mutate();
96
+ if (results.failed === 0) {
97
+ showSnackbar({
98
+ kind: 'success',
99
+ title: t('success', 'Success'),
100
+ subtitle: t('allSuccessfulUpdate', 'Claim status updated successfully'),
101
+ timeoutInMs: 3000,
102
+ });
103
+ } else if (results.success === 0) {
104
+ showSnackbar({
105
+ kind: 'error',
106
+ title: t('error', 'Error'),
107
+ subtitle: t('updateAllStatusesError', 'Failed to update any claim statuses'),
108
+ timeoutInMs: 2500,
109
+ });
110
+ } else {
111
+ showSnackbar({
112
+ kind: 'warning',
113
+ title: t('partialSuccess', 'Partial Success'),
114
+ subtitle: t(
115
+ 'updateAllStatusesPartialSuccess',
116
+ `Claim status updated successfully for ${results.success} claims, failed for ${results.failed} claims`,
117
+ ),
118
+ timeoutInMs: 3000,
119
+ });
120
+ }
121
+ setIsSubmitting(false);
122
+ closeModal();
123
+ };
124
+
74
125
  const handleSubmit = () => {
75
126
  if (modalType === 'retry') {
76
127
  handleRetryClaim();
128
+ } else if (modalType === 'all') {
129
+ handleUpdateMultipleStatus();
77
130
  } else {
78
131
  handleUpdateStatus();
79
132
  }
@@ -82,12 +135,27 @@ export const ManageClaimRequest = ({
82
135
  return (
83
136
  <React.Fragment>
84
137
  <ModalHeader closeModal={closeModal}>
85
- {modalType === 'retry' ? t('retryClaim', 'Retry Claim') : t('updateClaimStatus', 'Update Claim Status')}
138
+ {modalType === 'retry'
139
+ ? t('retryClaim', 'Retry Claim')
140
+ : modalType === 'all'
141
+ ? t('updateAllStatuses', 'Update All Statuses')
142
+ : t('updateClaimStatus', 'Update Claim Status')}
86
143
  </ModalHeader>
87
144
  <ModalBody>
88
145
  {modalType === 'retry'
89
146
  ? t('retryClaimMessage', `Are you sure you want to retry making the request for ${claim.claimCode}?`)
147
+ : modalType === 'all'
148
+ ? t('updateAllStatusesMessage', `You are about to update statuses for ${responseUUIDs.length} claims?`)
90
149
  : t('updateStatusMessage', `You are updating claim status for ${claim.claimCode}:`)}
150
+
151
+ {isSubmitting && modalType === 'all' && (
152
+ <div className="mt-4">
153
+ <InlineLoading
154
+ description={t('updatingProgress', `Updating ${progress.completed} of ${progress.total} claims...`)}
155
+ status="active"
156
+ />
157
+ </div>
158
+ )}
91
159
  </ModalBody>
92
160
  <ModalFooter>
93
161
  <Button kind="secondary" onClick={closeModal} type="button">
@@ -96,8 +164,12 @@ export const ManageClaimRequest = ({
96
164
  <Button type="submit" onClick={handleSubmit}>
97
165
  {isSubmitting ? (
98
166
  <>
99
- <InlineLoading withOverlay={false} small />
100
- {modalType === 'retry' ? t('retrying', 'Retrying') : t('updating', 'Updating')}
167
+ <InlineLoading status="active" />
168
+ {modalType === 'retry'
169
+ ? t('retrying', 'Retrying')
170
+ : modalType === 'all'
171
+ ? t('updatingProgress', `Updating ${progress.completed} of ${progress.total} claims...`)
172
+ : t('updating', 'Updating')}
101
173
  </>
102
174
  ) : modalType === 'retry' ? (
103
175
  t('retry', 'Retry')
@@ -1,3 +1,5 @@
1
+ import { updateClaimStatus } from './dashboard/form/claims-form.resource';
2
+
1
3
  export const statusColors = {
2
4
  ENTERED: 'blue',
3
5
  ERRORED: 'red',
@@ -5,3 +7,36 @@ export const statusColors = {
5
7
  CHECKED: 'green',
6
8
  VALUATED: 'purple',
7
9
  };
10
+
11
+ /**
12
+ * Update multiple claim statuses in sequence
13
+ *
14
+ * @param {Array<string>} responseUUIDs - Array of response UUIDs to update
15
+ * @param {Function} progressCallback - Callback to track progress
16
+ * @returns {Promise<{success: number, failed: number}>} - Object containing success and failed counts
17
+ */
18
+ export async function updateMultipleClaimStatuses(responseUUIDs: Array<string>, progressCallback = null) {
19
+ const results = { success: 0, failed: 0 };
20
+
21
+ for (let i = 0; i < responseUUIDs.length; i++) {
22
+ const responseUUID = responseUUIDs[i];
23
+
24
+ try {
25
+ await updateClaimStatus(responseUUID);
26
+ results.success++;
27
+ } catch (error) {
28
+ results.failed++;
29
+ }
30
+
31
+ if (progressCallback) {
32
+ progressCallback({
33
+ completed: i + 1,
34
+ total: responseUUIDs.length,
35
+ success: results.success,
36
+ failed: results.failed,
37
+ });
38
+ }
39
+ }
40
+
41
+ return results;
42
+ }
@@ -79,54 +79,95 @@ interface Intervention {
79
79
  benefit: number;
80
80
  }
81
81
 
82
+ /**
83
+ * Hook to fetch and filter interventions based on provided filters
84
+ * @param filters Object containing filtering criteria
85
+ * @returns Object with loading state, filtered interventions, all interventions, and any errors
86
+ */
82
87
  export const useInterventions = (filters: InterventionsFilter) => {
83
88
  const { error: facilityLevelError, isLoading: isLoadingFacilityLevel, level } = useFacilityLevel();
89
+
90
+ // Build URL parameters for the API call
84
91
  const urlParams = new URLSearchParams({
85
- ...filters,
92
+ ...(filters || {}),
86
93
  synchronize: 'false',
87
94
  });
95
+
88
96
  const url = `${restBaseUrl}/kenyaemr/sha-interventions?${urlParams.toString()}`;
89
97
  const { isLoading, error, data } = useSWR<FetchResponse<{ results: Array<Intervention> }>>(url, openmrsFetch);
90
- const mapper = ({ benefitCode, name, parentBenefitCode }: Intervention): any => ({
98
+
99
+ // Mapper function to transform intervention data
100
+ const mapper = ({ benefitCode, name, parentBenefitCode }: Intervention): SHAIntervention => ({
91
101
  interventionCode: benefitCode,
92
102
  interventionName: name,
93
103
  interventionPackage: parentBenefitCode,
104
+ ...({} as any),
94
105
  });
95
106
 
107
+ // Filter and map interventions
96
108
  const interventions = useMemo(() => {
97
- const packageCodes = filters.package_code?.split(',') || [];
98
- return data?.data?.results
99
- ?.filter((d) => {
100
- // 1. Filter by package code (only if defined)
101
- if (packageCodes.length > 0 && !packageCodes.includes(d.parentBenefitCode)) {
102
- return false;
103
- }
104
-
105
- // 2. Filter by applicable gender (only if defined)
106
- if (
107
- filters.applicable_gender &&
108
- d.applicableGender &&
109
- !['ALL', filters.applicable_gender].includes(d.applicableGender)
110
- ) {
111
- return false;
112
- }
113
-
114
- if (level && d.levelsApplicable && !d.levelsApplicable.some((l) => level.includes(l))) {
115
- return false;
116
- }
117
-
118
- return true; // Keep item if it passes all filters
119
- })
120
- ?.map(mapper);
121
- }, [data, filters, level]); // Ensure proper memoization
109
+ if (!data?.data?.results) {
110
+ return [];
111
+ }
112
+
113
+ const packageCodes = filters.package_code?.split(',').filter(Boolean) || [];
114
+
115
+ // Filter based on criteria
116
+ const filteredResults = data.data.results.filter((intervention) => {
117
+ // Filter by package code (only if defined)
118
+ if (packageCodes.length > 0 && !packageCodes.includes(intervention.parentBenefitCode)) {
119
+ return false;
120
+ }
121
+
122
+ // Filter by applicable gender (only if defined)
123
+ if (
124
+ filters.applicable_gender &&
125
+ intervention.applicableGender &&
126
+ !['ALL', filters.applicable_gender].includes(intervention.applicableGender)
127
+ ) {
128
+ return false;
129
+ }
130
+
131
+ // Filter by facility level
132
+ if (level && intervention.levelsApplicable && !intervention.levelsApplicable.some((l) => level.includes(l))) {
133
+ return false;
134
+ }
135
+
136
+ return true; // Keep item if it passes all filters
137
+ });
138
+
139
+ // Map to the required format and ensure uniqueness by interventionCode
140
+ const mappedInterventions = filteredResults.map(mapper);
141
+
142
+ // Remove duplicates based on interventionCode
143
+ const uniqueInterventions = Array.from(
144
+ new Map(mappedInterventions.map((item) => [item.interventionCode, item])),
145
+ ).map(([, value]) => value);
146
+
147
+ return uniqueInterventions;
148
+ }, [data, filters, level]);
149
+
150
+ // Map all interventions without filtering
122
151
  const allInterventions = useMemo(() => {
123
- return (data?.data?.results ?? []).map(mapper);
152
+ if (!data?.data?.results) {
153
+ return [];
154
+ }
155
+
156
+ // Map to the required format and ensure uniqueness
157
+ const mappedInterventions = data.data.results.map(mapper);
158
+
159
+ // Remove duplicates based on interventionCode
160
+ const uniqueInterventions = Array.from(
161
+ new Map(mappedInterventions.map((item) => [item.interventionCode, item])),
162
+ ).map(([, value]) => value);
163
+
164
+ return uniqueInterventions;
124
165
  }, [data]);
125
166
 
126
167
  return {
127
168
  isLoading: isLoading || isLoadingFacilityLevel,
128
- interventions: (interventions ?? []) as Array<SHAIntervention>,
129
- allInterventions: (allInterventions ?? []) as Array<SHAIntervention>,
169
+ interventions: interventions as Array<SHAIntervention>,
170
+ allInterventions: allInterventions as Array<SHAIntervention>,
130
171
  error: error || facilityLevelError,
131
172
  };
132
173
  };
@@ -606,3 +606,10 @@ export interface TableProps {
606
606
  emptyStateHeader: string;
607
607
  includeClaimCode?: boolean;
608
608
  }
609
+
610
+ export interface ProgressTracker {
611
+ completed: number;
612
+ total: number;
613
+ success?: number;
614
+ failed?: number;
615
+ }
@@ -14,6 +14,7 @@
14
14
  "amount": "Amount",
15
15
  "anErrorOccurred": "An Error Occurred",
16
16
  "anErrorOccurredCreatingPaymentPoint": "An error occurred creating payment point",
17
+ "approved": "Approved",
17
18
  "approvedTotal": "Approved Total",
18
19
  "attributeDescription": "Attribute description",
19
20
  "attributeFormat": "Attribute format",
@@ -95,10 +96,6 @@
95
96
  "editSchema": "Edit Schema",
96
97
  "editServiceChargeItem": "Edit Service Charge Item",
97
98
  "eligibleBenefits": "Eligible benefits",
98
- "emptyClaimsHeader": "No Claims",
99
- "emptyClaimsState": "There are no claims to display",
100
- "emptyPreauthHeader": "No Preauths",
101
- "emptyPreauthState": "There are no preauth to display",
102
99
  "endDate": "End date",
103
100
  "endVisitAndClaim": "End visit and Process claims",
104
101
  "enterAmount": "Enter amount",
@@ -215,7 +212,6 @@
215
212
  "Phone Number": "Phone Number",
216
213
  "pleaseSelectItems": "Please select line items to raise a claim",
217
214
  "policyNumber": "Policy number",
218
- "preathsRequests": "Preauth Requests",
219
215
  "preauthRequest": "Preauth requests",
220
216
  "preAuthRequests": "Pre-auth requests",
221
217
  "preAuthRequets": "Pre-Auth Requests",
@@ -292,6 +288,7 @@
292
288
  "type": "Type",
293
289
  "unitPrice": "Unit price",
294
290
  "updateRegistration": "Update registration",
291
+ "updateStatus": "Update status",
295
292
  "valuated": "Valuated",
296
293
  "verifyingBillStatus": "Verifying bill status...",
297
294
  "visitEnded": "Visit ended",