@kenyaemr/esm-billing-app 5.4.2-pre.2699 → 5.4.2-pre.2710

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},{"component":"billingAdmin","route":"billing-admin"}],"extensions":[{"component":"accountingDashboardLink","name":"accounting-dashboard-link","slots":["homepage-dashboard-slot"],"meta":{"name":"accounting","slot":"accounting-dashboard-slot","title":"Accounting"}},{"name":"billing-dashboard","component":"billingDashboard","slot":"accounting-dashboard-slot"},{"component":"benefitsPackageDashboardLink","name":"benefits-package-dashboard-link","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","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":"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":"claimsManagementOverviewDashboardLink","name":"claims-management-overview-link","slots":["claims-management-dashboard-link-slot"]},{"component":"preAuthRequestsDashboardLink","name":"preauthrequest-overview-link","slots":["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"},{"name":"patient-info-sha-status","component":"patientBannerShaStatus","slot":"patient-banner-tags-slot"},{"name":"payments-points-dashboard-link","component":"paymentPointDashboardLink","slot":"billing-admin-dashboard-slot","meta":{"name":"cashier-points","title":"Payment Point","slot":"payment-point-dashboard-slot"}},{"name":"payment-points-dashboard","component":"paymentPoints","slot":"payment-point-dashboard-slot"},{"name":"payment-mode-dashboard-link","component":"paymentModeLink","slot":"billing-admin-dashboard-slot","meta":{"name":"payment-modes","title":"Payment Mode","slot":"payment-mode-dashboard-slot"}},{"name":"payment-mode-dashboard","component":"paymentModeDashboard","slot":"payment-mode-dashboard-slot"},{"name":"bill-deposit-dashboard-link","component":"billDepositDashboardLink","slot":"billing-admin-dashboard-slot","meta":{"name":"bill-deposit","title":"Bill Deposit","slot":"billing-deposit-dashboard-slot"}},{"name":"bill-deposit-dashboard","component":"billDepositDashboard","slot":"billing-deposit-dashboard-slot"},{"name":"billable-exemptions-dashboard-link","component":"billableExemptionsLink","slot":"billing-admin-dashboard-slot","meta":{"name":"billable-exemptions","title":"Billable Exemptions","slot":"billing-exemptions-dashboard-slot"}},{"name":"billable-exemptions-dashboard","component":"billableExemptions","slot":"billing-exemptions-dashboard-slot"},{"name":"clinical-charges-dashboard-link","component":"clinicalChargesLink","slot":"billing-admin-dashboard-slot","meta":{"name":"clinical-charges","title":"Clinical Charges","slot":"clinical-charges-dashboard-slot"}},{"name":"clinical-charges-dashboard","component":"clinicalCharges","slot":"clinical-charges-dashboard-slot"},{"name":"payment-history-dashboard-link","component":"paymentHistoryLink","slot":"billing-admin-dashboard-slot","meta":{"name":"payment-history","title":"Payment History","slot":"payment-history-dashboard-slot"}},{"name":"payment-history-dashboard","component":"paymentHistoryDashboard","slot":"payment-history-dashboard-slot"},{"name":"patient-billing-dashboard-link","component":"patientBillingLink","slot":"billing-admin-dashboard-slot","meta":{"name":"patient-billing","title":"Patient Billing","slot":"patient-billing-dashboard-slot"}},{"name":"patient-billing-dashboard","component":"patientBilling","slot":"patient-billing-dashboard-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":"add-deposit-workspace","component":"addDepositWorkspace","title":"Add Deposit","type":"other-form"},{"name":"deposit-transaction-workspace","component":"depositTransactionWorkspace","title":"Deposit Transaction","type":"other-form"},{"name":"payment-workspace","component":"paymentWorkspace","title":"Payment 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":"clock-in-modal","component":"clockIn"},{"name":"create-bill-item-modal","component":"createBillItemModal"},{"name":"delete-deposit-modal","component":"deleteDepositModal"},{"name":"reverse-transaction-modal","component":"reverseTransactionModal"},{"name":"print-preview-modal","component":"printPreviewModal"},{"name":"bill-action-modal","component":"billActionModal"},{"name":"require-billing-modal","component":"requirePaymentModal"}],"version":"5.4.2-pre.2699"}
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},{"component":"billingAdmin","route":"billing-admin"}],"extensions":[{"component":"accountingDashboardLink","name":"accounting-dashboard-link","slots":["homepage-dashboard-slot"],"meta":{"name":"accounting","slot":"accounting-dashboard-slot","title":"Accounting"}},{"name":"billing-dashboard","component":"billingDashboard","slot":"accounting-dashboard-slot"},{"component":"benefitsPackageDashboardLink","name":"benefits-package-dashboard-link","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","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":"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":"claimsManagementOverviewDashboardLink","name":"claims-management-overview-link","slots":["claims-management-dashboard-link-slot"]},{"component":"preAuthRequestsDashboardLink","name":"preauthrequest-overview-link","slots":["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"},{"name":"patient-info-sha-status","component":"patientBannerShaStatus","slot":"patient-banner-tags-slot"},{"name":"payments-points-dashboard-link","component":"paymentPointDashboardLink","slot":"billing-admin-dashboard-slot","meta":{"name":"cashier-points","title":"Payment Point","slot":"payment-point-dashboard-slot"}},{"name":"payment-points-dashboard","component":"paymentPoints","slot":"payment-point-dashboard-slot"},{"name":"payment-mode-dashboard-link","component":"paymentModeLink","slot":"billing-admin-dashboard-slot","meta":{"name":"payment-modes","title":"Payment Mode","slot":"payment-mode-dashboard-slot"}},{"name":"payment-mode-dashboard","component":"paymentModeDashboard","slot":"payment-mode-dashboard-slot"},{"name":"bill-deposit-dashboard-link","component":"billDepositDashboardLink","slot":"billing-admin-dashboard-slot","meta":{"name":"bill-deposit","title":"Bill Deposit","slot":"billing-deposit-dashboard-slot"}},{"name":"bill-deposit-dashboard","component":"billDepositDashboard","slot":"billing-deposit-dashboard-slot"},{"name":"billable-exemptions-dashboard-link","component":"billableExemptionsLink","slot":"billing-admin-dashboard-slot","meta":{"name":"billable-exemptions","title":"Billable Exemptions","slot":"billing-exemptions-dashboard-slot"}},{"name":"billable-exemptions-dashboard","component":"billableExemptions","slot":"billing-exemptions-dashboard-slot"},{"name":"clinical-charges-dashboard-link","component":"clinicalChargesLink","slot":"billing-admin-dashboard-slot","meta":{"name":"clinical-charges","title":"Clinical Charges","slot":"clinical-charges-dashboard-slot"}},{"name":"clinical-charges-dashboard","component":"clinicalCharges","slot":"clinical-charges-dashboard-slot"},{"name":"payment-history-dashboard-link","component":"paymentHistoryLink","slot":"billing-admin-dashboard-slot","meta":{"name":"payment-history","title":"Payment History","slot":"payment-history-dashboard-slot"}},{"name":"payment-history-dashboard","component":"paymentHistoryDashboard","slot":"payment-history-dashboard-slot"},{"name":"patient-billing-dashboard-link","component":"patientBillingLink","slot":"billing-admin-dashboard-slot","meta":{"name":"patient-billing","title":"Patient Billing","slot":"patient-billing-dashboard-slot"}},{"name":"patient-billing-dashboard","component":"patientBilling","slot":"patient-billing-dashboard-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":"add-deposit-workspace","component":"addDepositWorkspace","title":"Add Deposit","type":"other-form"},{"name":"deposit-transaction-workspace","component":"depositTransactionWorkspace","title":"Deposit Transaction","type":"other-form"},{"name":"payment-workspace","component":"paymentWorkspace","title":"Payment 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":"clock-in-modal","component":"clockIn"},{"name":"create-bill-item-modal","component":"createBillItemModal"},{"name":"delete-deposit-modal","component":"deleteDepositModal"},{"name":"reverse-transaction-modal","component":"reverseTransactionModal"},{"name":"print-preview-modal","component":"printPreviewModal"},{"name":"bill-action-modal","component":"billActionModal"},{"name":"require-billing-modal","component":"requirePaymentModal"}],"version":"5.4.2-pre.2710"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenyaemr/esm-billing-app",
3
- "version": "5.4.2-pre.2699",
3
+ "version": "5.4.2-pre.2710",
4
4
  "description": "Billing app for KenyaEMR",
5
5
  "keywords": [
6
6
  "openmrs"
@@ -2,11 +2,11 @@ import React from 'react';
2
2
  import { render, screen, waitFor } from '@testing-library/react';
3
3
  import userEvent from '@testing-library/user-event';
4
4
  import DeleteBillableServiceModal from './delete-billable-service.modal';
5
- import { deleteBillableService } from '../../billable-service.resource';
5
+ import { deleteBillableService } from '../../service-catalog/billable-service.resource';
6
6
  import { showSnackbar } from '@openmrs/esm-framework';
7
7
  import type { ChargeAble } from '../../service-catalog/charge-summary.resource';
8
8
 
9
- jest.mock('../../billable-service.resource', () => ({
9
+ jest.mock('../../service-catalog/billable-service.resource', () => ({
10
10
  deleteBillableService: jest.fn(),
11
11
  }));
12
12
  jest.mock('@openmrs/esm-framework', () => ({
@@ -5,7 +5,7 @@ import { useConfig, useLayoutType } from '@openmrs/esm-framework';
5
5
  import { type Order, type OrderAction } from '@openmrs/esm-patient-common-lib';
6
6
  import { processBillItems } from '../../../../billing.resource';
7
7
  import CreateBillWorkspace from './create-bill.workspace';
8
- import { useBillableItem } from '../../../billable-orders/useBillableItem';
8
+ import { useBillableItem } from '../../../../billable-services/billable-orders/useBillableItem';
9
9
 
10
10
  jest.mock('react-i18next', () => ({
11
11
  useTranslation: () => ({
@@ -26,7 +26,7 @@ jest.mock('@openmrs/esm-framework', () => ({
26
26
  restBaseUrl: '/openmrs/ws/rest/v1',
27
27
  }));
28
28
 
29
- jest.mock('../../../billable-orders/useBillableItem', () => ({
29
+ jest.mock('../../../../billable-services/billable-orders/useBillableItem', () => ({
30
30
  useBillableItem: jest.fn(),
31
31
  }));
32
32
 
@@ -202,7 +202,7 @@ describe('CreateBillWorkspace', () => {
202
202
 
203
203
  // Since Carbon dropdown items might be rendered in a portal or with complex structure,
204
204
  // we need to find them by their text content regardless of their exact structure
205
- const dropdownItem = await screen.findByText(/Cash - Ksh 100.00/);
205
+ const dropdownItem = await screen.findByText(/Cash - KES 100.00/);
206
206
  await user.click(dropdownItem);
207
207
 
208
208
  // Submit form
@@ -245,7 +245,7 @@ describe('CreateBillWorkspace', () => {
245
245
  await user.type(quantityInput, '2');
246
246
 
247
247
  await user.click(priceDropdown);
248
- const dropdownItem = await screen.findByText(/Cash - Ksh 100.00/);
248
+ const dropdownItem = await screen.findByText(/Cash - KES 100.00/);
249
249
  await user.click(dropdownItem);
250
250
 
251
251
  // Submit form
@@ -119,7 +119,7 @@ describe('ChargeSummaryTable', () => {
119
119
 
120
120
  render(<ChargeSummaryTable />);
121
121
  expect(screen.getByText('There are no {{displayText}} to display for this patient')).toBeInTheDocument();
122
- const launchFormButton = screen.getByRole('button', { name: /Record Charge Items/i });
122
+ const launchFormButton = screen.getByRole('button', { name: /Record/i });
123
123
  expect(launchFormButton).toBeInTheDocument();
124
124
  await user.click(launchFormButton);
125
125
  expect(mockLaunchWorkspace).toHaveBeenCalledWith('billable-service-form');
@@ -4,9 +4,9 @@ import CommodityForm from './commodity-form.workspace';
4
4
  import userEvent from '@testing-library/user-event';
5
5
  import { useCommodityItem } from './useCommodityItem';
6
6
  import { usePaymentModes } from '../../../billing.resource';
7
- import { createBillableService } from '../../billable-service.resource';
7
+ import { createBillableService } from '../billable-service.resource';
8
8
 
9
- jest.mock('../../billable-service.resource', () => ({
9
+ jest.mock('../billable-service.resource', () => ({
10
10
  createBillableService: jest.fn(),
11
11
  }));
12
12
 
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { render, screen, fireEvent, waitFor } from '@testing-library/react';
3
3
  import userEvent from '@testing-library/user-event';
4
4
  import ServiceForm from './service-form.workspace';
5
- import { createBillableService, useConceptsSearch, useServiceTypes } from '../../billable-service.resource';
5
+ import { createBillableService, useConceptsSearch, useServiceTypes } from '../billable-service.resource';
6
6
  import { usePaymentModes } from '../../../billing.resource';
7
7
 
8
8
  const mockUseConceptsSearch = useConceptsSearch as jest.MockedFunction<typeof useConceptsSearch>;
@@ -137,7 +137,7 @@ const mockPaymentModes = {
137
137
  mutate: jest.fn(),
138
138
  };
139
139
 
140
- jest.mock('../../billable-service.resource', () => ({
140
+ jest.mock('../billable-service.resource', () => ({
141
141
  useConceptsSearch: jest.fn(),
142
142
  useServiceTypes: jest.fn(),
143
143
  createBillableService: jest.fn(),
@@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event';
4
4
  import React from 'react';
5
5
  import { mockBill, mockedActiveSheet, mockLineItems, mockPaymentModes } from '../../../../../__mocks__/bills.mock';
6
6
  import { processBillPayment, usePaymentModes } from '../../billing.resource';
7
- import { useClockInStatus } from '../../payment-points/use-clock-in-status';
7
+ import { useClockInStatus } from '../../bill-administration/payment-points/use-clock-in-status';
8
8
  import Payments from './payments.component';
9
9
  import { LineItem, PaymentMethod } from '../../types';
10
10
 
@@ -17,7 +17,7 @@ jest.mock('../../billing.resource', () => ({
17
17
  usePaymentModes: jest.fn(),
18
18
  }));
19
19
 
20
- jest.mock('../../payment-points/use-clock-in-status');
20
+ jest.mock('../../bill-administration/payment-points/use-clock-in-status');
21
21
  const mockedUseClockInStatus = useClockInStatus as jest.Mock;
22
22
 
23
23
  const updatedMockPaymentModes: PaymentMethod[] = mockPaymentModes.map((mode) => {
@@ -6,6 +6,12 @@ import userEvent from '@testing-library/user-event';
6
6
 
7
7
  window.getOpenmrsSpaBase = () => '/openmrs/spa/';
8
8
 
9
+ jest.mock('react-i18next', () => ({
10
+ useTranslation: () => ({
11
+ t: (key: string) => key,
12
+ }),
13
+ }));
14
+
9
15
  describe('LinkExtension Component', () => {
10
16
  const renderWithRouter = (component, { route = '/' } = {}) => {
11
17
  window.history.pushState({}, 'Test page', route);
@@ -12,7 +12,7 @@ import {
12
12
  InlineLoading,
13
13
  } from '@carbon/react';
14
14
  import { Close } from '@carbon/react/icons';
15
- import { convertToCurrency, extractString } from '../helpers';
15
+ import { convertToCurrency } from '../helpers';
16
16
  import { useTranslation } from 'react-i18next';
17
17
  import { MappedBill } from '../types';
18
18
  import styles from './patient-bills.scss';
@@ -40,7 +40,7 @@ export const PatientBills: React.FC<PatientBillsProps> = ({ bills, onCancel, pat
40
40
  return <InlineLoading status="active" description={t('loading', 'Loading...')} />;
41
41
  }
42
42
 
43
- const billingUrl = '${openmrsSpaBase}/home/billing/patient/${patientUuid}/${uuid}';
43
+ const billingUrl = '${openmrsSpaBase}/home/accounting/patient/${patientUuid}/${uuid}';
44
44
 
45
45
  if (bills.length === 0) {
46
46
  return (
@@ -0,0 +1,300 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { usePatient } from '@openmrs/esm-framework';
5
+ import { PatientBills, PatientHeader } from './patient-bills.component';
6
+ import { mockPatient } from '../../../../__mocks__/patient.mock';
7
+ import { MappedBill } from '../types';
8
+
9
+ // Mock dependencies
10
+ jest.mock('@openmrs/esm-framework', () => ({
11
+ ...jest.requireActual('@openmrs/esm-framework'),
12
+ usePatient: jest.fn(),
13
+ getPatientName: jest.fn((patient) => {
14
+ return `${patient?.name?.[0]?.given?.[0]} ${patient?.name?.[0]?.family}`;
15
+ }),
16
+ ConfigurableLink: jest.fn(({ children, to, templateParams }) => (
17
+ <a href={to.replace('${patientUuid}', templateParams.patientUuid).replace('${uuid}', templateParams.uuid)}>
18
+ {children}
19
+ </a>
20
+ )),
21
+ }));
22
+
23
+ jest.mock('../helpers', () => ({
24
+ convertToCurrency: jest.fn((amount) => `KES ${amount.toFixed(2)}`),
25
+ }));
26
+
27
+ jest.mock('./patient-bills-dashboard/empty-patient-bill.component', () => {
28
+ return jest.fn(({ title, subTitle }) => (
29
+ <div>
30
+ <p>{title}</p>
31
+ <p>{subTitle}</p>
32
+ </div>
33
+ ));
34
+ });
35
+
36
+ const mockUsePatient = usePatient as jest.MockedFunction<typeof usePatient>;
37
+
38
+ const mockBills: Array<MappedBill> = [
39
+ {
40
+ uuid: '65f9f19a-f70e-44f4-9c6c-55b23dab4a3f',
41
+ id: 30,
42
+ patientUuid: '8673ee4f-e2ab-4077-ba55-4980f408773e',
43
+ patientName: 'John Wilson',
44
+ cashPointUuid: '381595a0-2229-4152-9c45-bd3692aac7cc',
45
+ cashPointName: 'Pharmacy Cashier',
46
+ cashPointLocation: 'Amani Family Medical Clinic',
47
+ cashier: {
48
+ uuid: '48b55692-e061-4ffa-b1f2-fd4aaf506224',
49
+ display: 'admin - ayunda ayunda ayunda',
50
+ links: [],
51
+ },
52
+ receiptNumber: 'CP2-0011-0',
53
+ status: 'PENDING' as any,
54
+ identifier: '100GEJ',
55
+ dateCreated: '2023-11-29T09:35:20.000+0300',
56
+ dateCreatedUnformatted: '2023-11-29T09:35:20.000+0300',
57
+ lineItems: [
58
+ {
59
+ uuid: '6ff72ef2-4265-4fdb-8563-a3a2eefa484e',
60
+ display: 'BillLineItem',
61
+ billableService: 'uuid:HIV self-test kit',
62
+ voided: false,
63
+ voidReason: null,
64
+ item: 'HIV self-test kit',
65
+ quantity: 1,
66
+ price: 500.0,
67
+ priceName: '',
68
+ priceUuid: '',
69
+ lineItemOrder: 0,
70
+ resourceVersion: '1.8',
71
+ paymentStatus: 'PENDING',
72
+ itemOrServiceConceptUuid: '',
73
+ serviceTypeUuid: '',
74
+ order: null,
75
+ },
76
+ ],
77
+ billingService: 'uuid:HIV self-test kit',
78
+ payments: [],
79
+ totalAmount: 500,
80
+ tenderedAmount: 0,
81
+ },
82
+ {
83
+ uuid: '75f9f19a-f70e-44f4-9c6c-55b23dab4a3f',
84
+ id: 31,
85
+ patientUuid: '8673ee4f-e2ab-4077-ba55-4980f408773e',
86
+ patientName: 'John Wilson',
87
+ cashPointUuid: '381595a0-2229-4152-9c45-bd3692aac7cc',
88
+ cashPointName: 'Pharmacy Cashier',
89
+ cashPointLocation: 'Amani Family Medical Clinic',
90
+ cashier: {
91
+ uuid: '48b55692-e061-4ffa-b1f2-fd4aaf506224',
92
+ display: 'admin - ayunda ayunda ayunda',
93
+ links: [],
94
+ },
95
+ receiptNumber: 'CP2-0012-0',
96
+ status: 'PAID' as any,
97
+ identifier: '100GEJ',
98
+ dateCreated: '2023-11-30T10:15:20.000+0300',
99
+ dateCreatedUnformatted: '2023-11-30T10:15:20.000+0300',
100
+ lineItems: [
101
+ {
102
+ uuid: '7ff72ef2-4265-4fdb-8563-a3a2eefa484e',
103
+ display: 'BillLineItem',
104
+ billableService: 'uuid2:Medical Certificate',
105
+ voided: false,
106
+ voidReason: null,
107
+ item: 'Medical Certificate',
108
+ quantity: 1,
109
+ price: 1000.0,
110
+ priceName: '',
111
+ priceUuid: '',
112
+ lineItemOrder: 0,
113
+ resourceVersion: '1.8',
114
+ paymentStatus: 'PAID',
115
+ itemOrServiceConceptUuid: '',
116
+ serviceTypeUuid: '',
117
+ order: null,
118
+ },
119
+ ],
120
+ billingService: 'uuid2:Medical Certificate',
121
+ payments: [],
122
+ totalAmount: 1000,
123
+ tenderedAmount: 1000,
124
+ },
125
+ ];
126
+
127
+ describe('PatientBills', () => {
128
+ const mockOnCancel = jest.fn();
129
+ const patientUuid = '8673ee4f-e2ab-4077-ba55-4980f408773e';
130
+
131
+ beforeEach(() => {
132
+ jest.clearAllMocks();
133
+ mockUsePatient.mockReturnValue({
134
+ patient: mockPatient as any,
135
+ isLoading: false,
136
+ error: null,
137
+ patientUuid: patientUuid,
138
+ });
139
+ });
140
+
141
+ it('should render loading state when patient data is loading', () => {
142
+ mockUsePatient.mockReturnValue({
143
+ patient: null,
144
+ isLoading: true,
145
+ error: null,
146
+ patientUuid: patientUuid,
147
+ });
148
+
149
+ render(<PatientBills bills={mockBills} onCancel={mockOnCancel} patientUuid={patientUuid} />);
150
+
151
+ expect(screen.getByText('Loading...')).toBeInTheDocument();
152
+ });
153
+
154
+ it('should render empty state when there are no bills', () => {
155
+ render(<PatientBills bills={[]} onCancel={mockOnCancel} patientUuid={patientUuid} />);
156
+
157
+ expect(screen.getByText('No bills found')).toBeInTheDocument();
158
+ expect(screen.getByText('No bills found for this patient')).toBeInTheDocument();
159
+ });
160
+
161
+ it('should render patient header with patient information', () => {
162
+ render(<PatientBills bills={mockBills} onCancel={mockOnCancel} patientUuid={patientUuid} />);
163
+
164
+ expect(screen.getByText('John Wilson')).toBeInTheDocument();
165
+ expect(screen.getByText('Male')).toBeInTheDocument();
166
+ expect(screen.getByText('100732HE')).toBeInTheDocument();
167
+ });
168
+
169
+ it('should render bills table with correct headers', () => {
170
+ render(<PatientBills bills={mockBills} onCancel={mockOnCancel} patientUuid={patientUuid} />);
171
+
172
+ expect(screen.getByText('Date')).toBeInTheDocument();
173
+ expect(screen.getByText('Charge Item')).toBeInTheDocument();
174
+ expect(screen.getByText('Total Amount')).toBeInTheDocument();
175
+ expect(screen.getByText('Status')).toBeInTheDocument();
176
+ });
177
+
178
+ it('should render bill data in the table', () => {
179
+ render(<PatientBills bills={mockBills} onCancel={mockOnCancel} patientUuid={patientUuid} />);
180
+
181
+ expect(screen.getByText('HIV self-test kit')).toBeInTheDocument();
182
+ expect(screen.getByText('Medical Certificate')).toBeInTheDocument();
183
+ expect(screen.getByText('KES 500.00')).toBeInTheDocument();
184
+ expect(screen.getByText('KES 1000.00')).toBeInTheDocument();
185
+ expect(screen.getByText('PENDING')).toBeInTheDocument();
186
+ expect(screen.getByText('PAID')).toBeInTheDocument();
187
+ });
188
+
189
+ it('should render table title and description', () => {
190
+ render(<PatientBills bills={mockBills} onCancel={mockOnCancel} patientUuid={patientUuid} />);
191
+
192
+ expect(screen.getByText(/patient bill summary/i)).toBeInTheDocument();
193
+ expect(screen.getByText(/a list of all bills for this patient/i)).toBeInTheDocument();
194
+ });
195
+
196
+ it('should call onCancel when close button is clicked', async () => {
197
+ const user = userEvent.setup();
198
+ render(<PatientBills bills={mockBills} onCancel={mockOnCancel} patientUuid={patientUuid} />);
199
+
200
+ const closeButton = screen.getByRole('button', { name: /close/i });
201
+ await user.click(closeButton);
202
+
203
+ expect(mockOnCancel).toHaveBeenCalledWith('');
204
+ });
205
+
206
+ it('should render charge items as links', () => {
207
+ render(<PatientBills bills={mockBills} onCancel={mockOnCancel} patientUuid={patientUuid} />);
208
+
209
+ const links = screen.getAllByRole('link');
210
+ expect(links.length).toBeGreaterThan(0);
211
+ expect(links[0]).toHaveAttribute('href', expect.stringContaining('8673ee4f-e2ab-4077-ba55-4980f408773e'));
212
+ });
213
+
214
+ it('should handle bills with multiple line items correctly', () => {
215
+ const billWithMultipleItems: MappedBill = {
216
+ ...mockBills[0],
217
+ lineItems: [
218
+ mockBills[0].lineItems[0],
219
+ {
220
+ uuid: '8ff72ef2-4265-4fdb-8563-a3a2eefa484e',
221
+ display: 'BillLineItem',
222
+ billableService: 'uuid3:Lab Test',
223
+ voided: false,
224
+ voidReason: null,
225
+ item: 'Lab Test',
226
+ quantity: 1,
227
+ price: 300.0,
228
+ priceName: '',
229
+ priceUuid: '',
230
+ lineItemOrder: 1,
231
+ resourceVersion: '1.8',
232
+ paymentStatus: 'PENDING',
233
+ itemOrServiceConceptUuid: '',
234
+ serviceTypeUuid: '',
235
+ order: null,
236
+ },
237
+ ],
238
+ };
239
+
240
+ render(<PatientBills bills={[billWithMultipleItems]} onCancel={mockOnCancel} patientUuid={patientUuid} />);
241
+
242
+ expect(screen.getByText(/HIV self-test kit, Lab Test/i)).toBeInTheDocument();
243
+ });
244
+ });
245
+
246
+ describe('PatientHeader', () => {
247
+ const mockOnCancel = jest.fn();
248
+
249
+ beforeEach(() => {
250
+ jest.clearAllMocks();
251
+ });
252
+
253
+ it('should render patient name, gender, and identifier', () => {
254
+ render(<PatientHeader patient={mockPatient as any} onCancel={mockOnCancel} />);
255
+
256
+ expect(screen.getByText('John Wilson')).toBeInTheDocument();
257
+ expect(screen.getByText('Male')).toBeInTheDocument();
258
+ expect(screen.getByText('100732HE')).toBeInTheDocument();
259
+ });
260
+
261
+ it('should render close button', () => {
262
+ render(<PatientHeader patient={mockPatient as any} onCancel={mockOnCancel} />);
263
+
264
+ const closeButton = screen.getByRole('button', { name: /close/i });
265
+ expect(closeButton).toBeInTheDocument();
266
+ });
267
+
268
+ it('should call onCancel with empty string when close button is clicked', async () => {
269
+ const user = userEvent.setup();
270
+ render(<PatientHeader patient={mockPatient as any} onCancel={mockOnCancel} />);
271
+
272
+ const closeButton = screen.getByRole('button', { name: /close/i });
273
+ await user.click(closeButton);
274
+
275
+ expect(mockOnCancel).toHaveBeenCalledWith('');
276
+ expect(mockOnCancel).toHaveBeenCalledTimes(1);
277
+ });
278
+
279
+ it('should display -- when patient identifier is not available', () => {
280
+ const patientWithoutIdentifier = {
281
+ ...mockPatient,
282
+ identifier: [],
283
+ };
284
+
285
+ render(<PatientHeader patient={patientWithoutIdentifier as any} onCancel={mockOnCancel} />);
286
+
287
+ expect(screen.getByText('--')).toBeInTheDocument();
288
+ });
289
+
290
+ it('should capitalize patient gender', () => {
291
+ const patientWithLowercaseGender = {
292
+ ...mockPatient,
293
+ gender: 'female',
294
+ };
295
+
296
+ render(<PatientHeader patient={patientWithLowercaseGender as any} onCancel={mockOnCancel} />);
297
+
298
+ expect(screen.getByText('Female')).toBeInTheDocument();
299
+ });
300
+ });