@openmrs/esm-billing-app 1.0.2-pre.834 → 1.0.2-pre.838

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 (41) hide show
  1. package/dist/4300.js +1 -1
  2. package/dist/4344.js +1 -1
  3. package/dist/4344.js.map +1 -1
  4. package/dist/4739.js +1 -1
  5. package/dist/4739.js.map +1 -1
  6. package/dist/main.js +1 -1
  7. package/dist/main.js.map +1 -1
  8. package/dist/openmrs-esm-billing-app.js.buildmanifest.json +12 -12
  9. package/dist/routes.json +1 -1
  10. package/package.json +1 -1
  11. package/src/bill-history/bill-history.component.tsx +3 -3
  12. package/src/bill-item-actions/edit-bill-item.modal.tsx +1 -1
  13. package/src/bill-item-actions/edit-bill-item.test.tsx +7 -7
  14. package/src/billable-services/bill-waiver/bill-selection.component.tsx +1 -1
  15. package/src/billable-services/bill-waiver/bill-waiver-form.component.tsx +2 -2
  16. package/src/billable-services/bill-waiver/patient-bills.component.tsx +6 -6
  17. package/src/billable-services/billable-services-home.component.tsx +3 -3
  18. package/src/billable-services/billable-services.component.tsx +10 -6
  19. package/src/billable-services/billable-services.test.tsx +4 -4
  20. package/src/billable-services/cash-point/add-cash-point.modal.tsx +1 -1
  21. package/src/billable-services/cash-point/cash-point-configuration.component.tsx +2 -2
  22. package/src/billable-services/create-edit/add-billable-service.component.tsx +8 -10
  23. package/src/billable-services/create-edit/add-billable-service.test.tsx +4 -4
  24. package/src/billable-services/create-edit/edit-billable-service.modal.tsx +1 -1
  25. package/src/billable-services/dashboard/service-metrics.component.tsx +6 -1
  26. package/src/billable-services/payment-modes/add-payment-mode.modal.tsx +3 -3
  27. package/src/billable-services/payment-modes/payment-modes-config.component.tsx +2 -2
  28. package/src/billing-form/billing-checkin-form.component.tsx +1 -1
  29. package/src/billing-form/billing-checkin-form.test.tsx +2 -2
  30. package/src/billing-form/billing-form.component.tsx +8 -8
  31. package/src/billing-form/visit-attributes/visit-attributes-form.component.tsx +1 -1
  32. package/src/bills-table/bills-table.component.tsx +3 -3
  33. package/src/invoice/invoice-table.component.tsx +2 -2
  34. package/src/invoice/invoice-table.test.tsx +1 -1
  35. package/src/invoice/invoice.component.tsx +7 -9
  36. package/src/invoice/payments/payments.component.tsx +3 -3
  37. package/src/invoice/payments/payments.test.tsx +5 -5
  38. package/src/invoice/printable-invoice/printable-invoice.component.tsx +4 -4
  39. package/src/metrics-cards/metrics-cards.component.tsx +6 -1
  40. package/src/modal/require-payment.modal.tsx +1 -1
  41. package/translations/en.json +73 -72
@@ -547,9 +547,9 @@
547
547
  "initial": false,
548
548
  "entry": false,
549
549
  "recorded": false,
550
- "size": 8890,
550
+ "size": 8971,
551
551
  "sizes": {
552
- "javascript": 8890
552
+ "javascript": 8971
553
553
  },
554
554
  "names": [],
555
555
  "idHints": [],
@@ -561,7 +561,7 @@
561
561
  "4300.js"
562
562
  ],
563
563
  "auxiliaryFiles": [],
564
- "hash": "78058774c4fea3fd",
564
+ "hash": "141498f23f6a5d9f",
565
565
  "childrenByOrder": {}
566
566
  },
567
567
  {
@@ -591,9 +591,9 @@
591
591
  "initial": false,
592
592
  "entry": false,
593
593
  "recorded": false,
594
- "size": 1177606,
594
+ "size": 1177948,
595
595
  "sizes": {
596
- "javascript": 1177564,
596
+ "javascript": 1177906,
597
597
  "consume-shared": 42
598
598
  },
599
599
  "names": [],
@@ -607,7 +607,7 @@
607
607
  "auxiliaryFiles": [
608
608
  "4344.js.map"
609
609
  ],
610
- "hash": "8f70c43832a1c75b",
610
+ "hash": "c7fea203c75a305b",
611
611
  "childrenByOrder": {}
612
612
  },
613
613
  {
@@ -686,9 +686,9 @@
686
686
  "initial": false,
687
687
  "entry": false,
688
688
  "recorded": false,
689
- "size": 43598,
689
+ "size": 43608,
690
690
  "sizes": {
691
- "javascript": 43598
691
+ "javascript": 43608
692
692
  },
693
693
  "names": [],
694
694
  "idHints": [],
@@ -702,7 +702,7 @@
702
702
  "auxiliaryFiles": [
703
703
  "4739.js.map"
704
704
  ],
705
- "hash": "d1c777178a6f760b",
705
+ "hash": "0506434628a69e0e",
706
706
  "childrenByOrder": {}
707
707
  },
708
708
  {
@@ -1236,10 +1236,10 @@
1236
1236
  "initial": true,
1237
1237
  "entry": true,
1238
1238
  "recorded": false,
1239
- "size": 5461060,
1239
+ "size": 5461402,
1240
1240
  "sizes": {
1241
1241
  "consume-shared": 210,
1242
- "javascript": 5438404,
1242
+ "javascript": 5438746,
1243
1243
  "share-init": 336,
1244
1244
  "runtime": 22110
1245
1245
  },
@@ -1256,7 +1256,7 @@
1256
1256
  "auxiliaryFiles": [
1257
1257
  "main.js.map"
1258
1258
  ],
1259
- "hash": "009ffa3a12559b3b",
1259
+ "hash": "311d3f6d2c9ae9d6",
1260
1260
  "childrenByOrder": {}
1261
1261
  },
1262
1262
  {
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":">=2.24.0","fhir2":">=1.2"},"pages":[{"component":"billableServicesHome","route":"billable-services"}],"extensions":[{"component":"billingDashboardLink","name":"billing-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"billing","title":"billing","slot":"billing-dashboard-slot"},"featureFlag":"billing"},{"component":"root","name":"billing-dashboard-root","slot":"billing-dashboard-slot"},{"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 history"},"featureFlag":"billing"},{"name":"billable-services-app-menu-item","component":"billableServicesAppMenuItem","slot":"app-menu-item-slot","meta":{"name":"Billable Services"}},{"name":"billing-checkin-form","slot":"extra-visit-attribute-slot","component":"billingCheckInForm","featureFlag":"billing"},{"slot":"system-admin-page-card-link-slot","component":"billableServicesCardLink","name":"billable-services-admin-card-link"},{"name":"patient-banner-billing-tags","component":"visitAttributeTags","slot":"patient-banner-tags-slot","order":2},{"name":"billing-home-tiles-ext","slot":"billing-home-tiles-slot","component":"serviceMetrics"}],"modals":[{"name":"add-cash-point-modal","component":"addCashPointModal"},{"name":"add-payment-mode-modal","component":"addPaymentModeModal"},{"name":"delete-payment-mode-modal","component":"deletePaymentModeModal"},{"name":"edit-bill-item-modal","component":"editBillLineItemModal"},{"name":"edit-bill-line-item-modal","component":"editBillLineItemModal"},{"name":"edit-billable-service-modal","component":"editBillableServiceModal"},{"name":"require-billing-modal","component":"requirePaymentModal"}],"workspaces":[{"name":"billing-form-workspace","title":"billingForm","component":"billingFormWorkspace","type":"form"}],"featureFlags":[{"flagName":"billing","label":"Billing module","description":"This feature introduces navigation links on the patient chart and home page to allow accessing the billing module features"}],"version":"1.0.2-pre.834"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":">=2.24.0","fhir2":">=1.2"},"pages":[{"component":"billableServicesHome","route":"billable-services"}],"extensions":[{"component":"billingDashboardLink","name":"billing-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"billing","title":"billing","slot":"billing-dashboard-slot"},"featureFlag":"billing"},{"component":"root","name":"billing-dashboard-root","slot":"billing-dashboard-slot"},{"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 history"},"featureFlag":"billing"},{"name":"billable-services-app-menu-item","component":"billableServicesAppMenuItem","slot":"app-menu-item-slot","meta":{"name":"Billable Services"}},{"name":"billing-checkin-form","slot":"extra-visit-attribute-slot","component":"billingCheckInForm","featureFlag":"billing"},{"slot":"system-admin-page-card-link-slot","component":"billableServicesCardLink","name":"billable-services-admin-card-link"},{"name":"patient-banner-billing-tags","component":"visitAttributeTags","slot":"patient-banner-tags-slot","order":2},{"name":"billing-home-tiles-ext","slot":"billing-home-tiles-slot","component":"serviceMetrics"}],"modals":[{"name":"add-cash-point-modal","component":"addCashPointModal"},{"name":"add-payment-mode-modal","component":"addPaymentModeModal"},{"name":"delete-payment-mode-modal","component":"deletePaymentModeModal"},{"name":"edit-bill-item-modal","component":"editBillLineItemModal"},{"name":"edit-bill-line-item-modal","component":"editBillLineItemModal"},{"name":"edit-billable-service-modal","component":"editBillableServiceModal"},{"name":"require-billing-modal","component":"requirePaymentModal"}],"workspaces":[{"name":"billing-form-workspace","title":"billingForm","component":"billingFormWorkspace","type":"form"}],"featureFlags":[{"flagName":"billing","label":"Billing module","description":"This feature introduces navigation links on the patient chart and home page to allow accessing the billing module features"}],"version":"1.0.2-pre.838"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-billing-app",
3
- "version": "1.0.2-pre.834",
3
+ "version": "1.0.2-pre.838",
4
4
  "description": "O3 frontend module for handling billing concerns in healthcare settings",
5
5
  "browser": "dist/openmrs-esm-billing-app.js",
6
6
  "main": "src/index.ts",
@@ -81,7 +81,7 @@ const BillHistory: React.FC<BillHistoryProps> = ({ patientUuid }) => {
81
81
  return (
82
82
  <div className={styles.errorContainer}>
83
83
  <Layer>
84
- <ErrorState error={error} headerTitle={t('billsList', 'Bill list')} />
84
+ <ErrorState error={error} headerTitle={t('billList', 'Bill list')} />
85
85
  </Layer>
86
86
  </div>
87
87
  );
@@ -107,7 +107,7 @@ const BillHistory: React.FC<BillHistoryProps> = ({ patientUuid }) => {
107
107
  <div>
108
108
  <CardHeader title={t('billingHistory', 'Billing History')}>
109
109
  <Button renderIcon={Add} onClick={() => launchWorkspace('billing-form-workspace', {})} kind="ghost">
110
- {t('addBill', 'Add bill item(s)')}
110
+ {t('addBill', 'Add bill items')}
111
111
  </Button>
112
112
  </CardHeader>
113
113
  <div className={styles.billHistoryContainer}>
@@ -122,7 +122,7 @@ const BillHistory: React.FC<BillHistoryProps> = ({ patientUuid }) => {
122
122
  rows,
123
123
  }) => (
124
124
  <TableContainer {...getTableContainerProps}>
125
- <Table className={styles.table} {...getTableProps()} aria-label="Bill list">
125
+ <Table className={styles.table} {...getTableProps()} aria-label={t('billList', 'Bill list')}>
126
126
  <TableHead>
127
127
  <TableRow>
128
128
  <TableExpandHeader enableToggle {...getExpandHeaderProps()} />
@@ -191,7 +191,7 @@ const EditBillLineItemModal: React.FC<EditBillLineItemModalProps> = ({ bill, clo
191
191
  className={styles.controlField}
192
192
  helperText={t('unitPriceHelperText', 'This is the unit price for this item')}
193
193
  id="priceInput"
194
- labelText={t('price', 'Unit Price')}
194
+ labelText={t('unitPrice', 'Unit price')}
195
195
  readOnly
196
196
  value={value}
197
197
  />
@@ -94,24 +94,24 @@ describe('EditBillItem', () => {
94
94
  test('renders the form with correct fields and default values', () => {
95
95
  render(<EditBillLineItemModal bill={mockBill} item={mockItem} closeModal={mockCloseModal} />);
96
96
 
97
- expect(screen.getByText('Edit bill line item')).toBeInTheDocument();
97
+ expect(screen.getByText(/edit bill line item/i)).toBeInTheDocument();
98
98
  expect(screen.getByText(/John Doe/)).toBeInTheDocument();
99
99
  expect(screen.getByText(/Main Cashpoint/)).toBeInTheDocument();
100
100
  expect(screen.getByText(/123456/)).toBeInTheDocument();
101
- expect(screen.getByRole('spinbutton', { name: /Quantity/ })).toHaveValue(2);
102
- expect(screen.getByLabelText(/Unit Price/)).toHaveValue('100');
103
- expect(screen.getByText(/Total/)).toHaveTextContent(/200/);
101
+ expect(screen.getByRole('spinbutton', { name: /quantity/i })).toHaveValue(2);
102
+ expect(screen.getByLabelText(/unit price/i)).toHaveValue('100');
103
+ expect(screen.getByText(/total/i)).toHaveTextContent(/200/);
104
104
  });
105
105
 
106
106
  test('updates total when quantity is changed', async () => {
107
107
  const user = userEvent.setup();
108
108
  render(<EditBillLineItemModal bill={mockBill} item={mockItem} closeModal={mockCloseModal} />);
109
109
 
110
- const quantityInput = screen.getByRole('spinbutton', { name: /Quantity/ });
110
+ const quantityInput = screen.getByRole('spinbutton', { name: /quantity/i });
111
111
  await user.clear(quantityInput);
112
112
  await user.type(quantityInput, '3');
113
113
 
114
- expect(screen.getByText(/Total/)).toHaveTextContent(/300/);
114
+ expect(screen.getByText(/total/i)).toHaveTextContent(/300/);
115
115
  });
116
116
 
117
117
  test('submits the form and shows a success notification', async () => {
@@ -120,7 +120,7 @@ describe('EditBillItem', () => {
120
120
 
121
121
  render(<EditBillLineItemModal bill={mockBill} item={mockItem} closeModal={mockCloseModal} />);
122
122
 
123
- await user.click(screen.getByText(/Save/));
123
+ await user.click(screen.getByText(/save/i));
124
124
 
125
125
  await waitFor(() => {
126
126
  expect(mockUpdateBillItems).toHaveBeenCalled();
@@ -42,7 +42,7 @@ const PatientBillsSelections: React.FC<{ bills: MappedBill; setPatientUuid: (pat
42
42
  <StructuredListRow head>
43
43
  <StructuredListCell head>{t('billItem', 'Bill item')}</StructuredListCell>
44
44
  <StructuredListCell head>{t('quantity', 'Quantity')}</StructuredListCell>
45
- <StructuredListCell head>{t('unitPrice', 'Unit Price')}</StructuredListCell>
45
+ <StructuredListCell head>{t('unitPrice', 'Unit price')}</StructuredListCell>
46
46
  <StructuredListCell head>{t('total', 'Total')}</StructuredListCell>
47
47
  <StructuredListCell head>{getCoreTranslation('actions')}</StructuredListCell>
48
48
  </StructuredListRow>
@@ -68,7 +68,7 @@ const BillWaiverForm: React.FC<BillWaiverFormProps> = ({ bill, lineItems, setPat
68
68
  <section className={styles.billWaiverDescription}>
69
69
  <label className={styles.label}>{t('billItems', 'Bill Items')}</label>
70
70
  <p className={styles.value}>
71
- {t('billName', ' {{billName}} ', {
71
+ {t('billName', '{{billName}}', {
72
72
  billName: lineItems.map((item) => item.item || item.billableService).join(', ') ?? '--',
73
73
  })}
74
74
  </p>
@@ -80,7 +80,7 @@ const BillWaiverForm: React.FC<BillWaiverFormProps> = ({ bill, lineItems, setPat
80
80
 
81
81
  <Layer className={styles.formControlLayer}>
82
82
  <NumberInput
83
- label={t('amountToWaiveLabel', 'Amount to Waive')}
83
+ label={t('amountToWaiveLabel', 'Amount to waive')}
84
84
  helperText={t('amountToWaiveHelper', 'Specify the amount to be deducted from the bill')}
85
85
  aria-label={t('amountToWaiveAriaLabel', 'Enter amount to waive')}
86
86
  hideSteppers
@@ -38,8 +38,8 @@ const PatientBills: React.FC<PatientBillsProps> = ({ patientUuid, bills, setPati
38
38
 
39
39
  const tableHeaders = [
40
40
  { header: t('date', 'Date'), key: 'date' },
41
- { header: t('billableService', 'Billable Service'), key: 'billableService' },
42
- { header: t('totalAmount', 'Total Amount'), key: 'totalAmount' },
41
+ { header: t('billableService', 'Billable service'), key: 'billableService' },
42
+ { header: t('totalAmount', 'Total amount'), key: 'totalAmount' },
43
43
  ];
44
44
 
45
45
  const tableRows = bills.map((bill) => ({
@@ -58,7 +58,7 @@ const PatientBills: React.FC<PatientBillsProps> = ({ patientUuid, bills, setPati
58
58
  <div className={styles.illo}>
59
59
  <EmptyDataIllustration />
60
60
  </div>
61
- <p className={styles.content}>{t('noBilltoDisplay', 'There are no bills to display for this patient')}</p>
61
+ <p className={styles.content}>{t('noBillToDisplay', 'There are no bills to display for this patient')}</p>
62
62
  </Tile>
63
63
  </Layer>
64
64
  </div>
@@ -84,13 +84,13 @@ const PatientBills: React.FC<PatientBillsProps> = ({ patientUuid, bills, setPati
84
84
  getTableContainerProps,
85
85
  }) => (
86
86
  <TableContainer
87
- title={t('patientBills', 'Patient bill')}
87
+ title={t('patientBills', 'Patient bills')}
88
88
  description={t('patientBillsDescription', 'List of patient bills')}
89
89
  {...getTableContainerProps()}>
90
- <Table {...getTableProps()} aria-label="sample table">
90
+ <Table {...getTableProps()} aria-label={t('billsTable', 'Bills table')}>
91
91
  <TableHead>
92
92
  <TableRow>
93
- <TableExpandHeader enableToggle={true} {...getExpandHeaderProps()} />
93
+ <TableExpandHeader enableToggle {...getExpandHeaderProps()} />
94
94
  {headers.map((header, i) => (
95
95
  <TableHeader
96
96
  key={i}
@@ -37,12 +37,12 @@ const BillableServiceHome: React.FC = () => {
37
37
  <SideNavLink onClick={() => handleNavigation('waive-bill')} renderIcon={Money}>
38
38
  {t('billWaiver', 'Bill waiver')}
39
39
  </SideNavLink>
40
- <SideNavMenu title={t('billingSettings', 'Billing Settings')} renderIcon={Settings}>
40
+ <SideNavMenu title={t('billingSettings', 'Billing settings')} renderIcon={Settings}>
41
41
  <SideNavMenuItem onClick={() => handleNavigation('cash-point-config')}>
42
- {t('cashPointConfig', 'Cash Point Config')}
42
+ {t('cashPointConfig', 'Cash point configuration')}
43
43
  </SideNavMenuItem>
44
44
  <SideNavMenuItem onClick={() => handleNavigation('payment-modes-config')}>
45
- {t('paymentModesConfig', 'Payment Modes Config')}
45
+ {t('paymentModesConfig', 'Payment modes configuration')}
46
46
  </SideNavMenuItem>
47
47
  </SideNavMenu>
48
48
  </UserHasAccess>
@@ -57,19 +57,19 @@ const BillableServices = () => {
57
57
 
58
58
  const headerData = [
59
59
  {
60
- header: t('serviceName', 'Service Name'),
60
+ header: t('serviceName', 'Service name'),
61
61
  key: 'serviceName',
62
62
  },
63
63
  {
64
- header: t('shortName', 'Short Name'),
64
+ header: t('shortName', 'Short name'),
65
65
  key: 'shortName',
66
66
  },
67
67
  {
68
- header: t('serviceType', 'Service Type'),
68
+ header: t('serviceType', 'Service type'),
69
69
  key: 'serviceType',
70
70
  },
71
71
  {
72
- header: t('serviceStatus', 'Service Status'),
72
+ header: t('serviceStatus', 'Service status'),
73
73
  key: 'status',
74
74
  },
75
75
  {
@@ -138,7 +138,11 @@ const BillableServices = () => {
138
138
 
139
139
  if (isLoading) {
140
140
  return (
141
- <InlineLoading status="active" iconDescription={getCoreTranslation('loading')} description="Loading data..." />
141
+ <InlineLoading
142
+ status="active"
143
+ iconDescription={getCoreTranslation('loading')}
144
+ description={t('loading', 'Loading data') + '...'}
145
+ />
142
146
  );
143
147
  }
144
148
 
@@ -174,7 +178,7 @@ const BillableServices = () => {
174
178
  useZebraStyles={rowData?.length > 1}>
175
179
  {({ rows, headers, getHeaderProps, getRowProps, getTableProps }) => (
176
180
  <TableContainer>
177
- <Table {...getTableProps()} aria-label="service list">
181
+ <Table {...getTableProps()} aria-label={t('serviceList', 'Service list')}>
178
182
  <TableHead>
179
183
  <TableRow>
180
184
  {headers.map((header) => (
@@ -57,10 +57,10 @@ describe('BillableService', () => {
57
57
  render(<BillableServices />);
58
58
 
59
59
  // Check table headers
60
- expect(screen.getByText('Service Name')).toBeInTheDocument();
61
- expect(screen.getByText('Short Name')).toBeInTheDocument();
62
- expect(screen.getByText('Service Type')).toBeInTheDocument();
63
- expect(screen.getByText('Service Status')).toBeInTheDocument();
60
+ expect(screen.getByText('Service name')).toBeInTheDocument();
61
+ expect(screen.getByText('Short name')).toBeInTheDocument();
62
+ expect(screen.getByText('Service type')).toBeInTheDocument();
63
+ expect(screen.getByText('Service status')).toBeInTheDocument();
64
64
 
65
65
  // Check service data
66
66
  expect(screen.getByText('Service 1')).toBeInTheDocument();
@@ -114,7 +114,7 @@ const AddCashPointModal: React.FC<AddCashPointModalProps> = ({ closeModal, onCas
114
114
  <TextInput
115
115
  id="cash-point-name"
116
116
  labelText={t('cashPointName', 'Cash Point Name')}
117
- placeholder={t('cashPointNamePlaceholder', 'e.g., Pharmacy Cash Point')}
117
+ placeholder={t('cashPointNamePlaceholder', 'For example, Pharmacy Cash Point')}
118
118
  invalid={!!errors.name}
119
119
  invalidText={errors.name?.message}
120
120
  {...field}
@@ -61,9 +61,9 @@ const CashPointConfiguration: React.FC = () => {
61
61
  return (
62
62
  <div className={styles.container}>
63
63
  <div className={styles.card}>
64
- <CardHeader title={t('cashPointHistory', 'Cash Point History')}>
64
+ <CardHeader title={t('cashPointHistory', 'Cash point history')}>
65
65
  <Button renderIcon={Add} onClick={handleAddCashPoint} kind="ghost">
66
- {t('addNewCashPoint', 'Add New Cash Point')}
66
+ {t('addNewCashPoint', 'Add new cash point')}
67
67
  </Button>
68
68
  </CardHeader>
69
69
  <div>
@@ -79,7 +79,7 @@ const createBillableServiceSchema = (t: TFunction) => {
79
79
  if (isNaN(numValue) || numValue <= 0) {
80
80
  ctx.addIssue({
81
81
  code: z.ZodIssueCode.custom,
82
- message: t('priceMustBeGreaterThanZero', 'Price must be greater than 0'),
82
+ message: t('priceMustBePositive', 'Price must be greater than 0'),
83
83
  });
84
84
  }
85
85
  }),
@@ -246,7 +246,7 @@ const AddBillableService: React.FC<AddBillableServiceProps> = ({
246
246
  <InlineLoading
247
247
  status="active"
248
248
  iconDescription={t('loadingDescription', 'Loading')}
249
- description={t('loadingData', 'Loading data') + '...'}
249
+ description={t('loading', 'Loading data') + '...'}
250
250
  />
251
251
  );
252
252
  }
@@ -256,8 +256,8 @@ const AddBillableService: React.FC<AddBillableServiceProps> = ({
256
256
  <Stack gap={5}>
257
257
  <h4>
258
258
  {serviceToEdit
259
- ? t('editBillableServices', 'Edit Billable Services')
260
- : t('addBillableServices', 'Add Billable Services')}
259
+ ? t('editBillableService', 'Edit billable service')
260
+ : t('addBillableService', 'Add billable service')}
261
261
  </h4>
262
262
  <section>
263
263
  {serviceToEdit ? (
@@ -294,7 +294,7 @@ const AddBillableService: React.FC<AddBillableServiceProps> = ({
294
294
  value={field.value || ''}
295
295
  id="serviceShortName"
296
296
  type="text"
297
- labelText={t('serviceShortName', 'Short Name')}
297
+ labelText={t('shortName', 'Short name')}
298
298
  placeholder={t('enterServiceShortName', 'Enter service short name')}
299
299
  maxLength={MAX_NAME_LENGTH}
300
300
  invalid={!!errors.shortName}
@@ -310,7 +310,7 @@ const AddBillableService: React.FC<AddBillableServiceProps> = ({
310
310
  <Search
311
311
  ref={searchInputRef}
312
312
  id="conceptsSearch"
313
- labelText={t('enterConcept', 'Associated concept')}
313
+ labelText={t('associatedConcept', 'Associated concept')}
314
314
  placeholder={t('searchConcepts', 'Search associated concept')}
315
315
  onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSearchTerm(e.target.value)}
316
316
  onClear={() => {
@@ -349,9 +349,7 @@ const AddBillableService: React.FC<AddBillableServiceProps> = ({
349
349
  return (
350
350
  <Layer>
351
351
  <Tile className={styles.emptyResults}>
352
- <span>
353
- {t('noResultsFor', 'No results for')} <strong>"{debouncedSearchTerm}"</strong>
354
- </span>
352
+ <span>{t('noResultsFor', 'No results for {searchTerm}', { searchTerm: debouncedSearchTerm })}</span>
355
353
  </Tile>
356
354
  </Layer>
357
355
  );
@@ -413,7 +411,7 @@ const AddBillableService: React.FC<AddBillableServiceProps> = ({
413
411
  id={`price-${index}`}
414
412
  invalid={!!errors?.payment?.[index]?.price}
415
413
  invalidText={errors?.payment?.[index]?.price?.message}
416
- label={t('sellingPrice', 'Selling Price')}
414
+ label={t('sellingPrice', 'Selling price')}
417
415
  placeholder={t('enterSellingPrice', 'Enter selling price')}
418
416
  min={0}
419
417
  step={0.01}
@@ -85,10 +85,10 @@ const fillRequiredFields = async (user, options: FillOptions = {}) => {
85
85
  const { serviceName = 'Test Service Name', shortName = 'Test Short Name', skipPrice = false } = options;
86
86
 
87
87
  if (serviceName) {
88
- await user.type(screen.getByRole('textbox', { name: /Service Name/i }), serviceName);
88
+ await user.type(screen.getByRole('textbox', { name: /Service name/i }), serviceName);
89
89
  }
90
90
  if (shortName) {
91
- await user.type(screen.getByRole('textbox', { name: /Short Name/i }), shortName);
91
+ await user.type(screen.getByRole('textbox', { name: /Short name/i }), shortName);
92
92
  }
93
93
 
94
94
  await user.click(screen.getByRole('combobox', { name: /Service type/i }));
@@ -114,7 +114,7 @@ describe('AddBillableService', () => {
114
114
  const mockOnClose = jest.fn();
115
115
  renderAddBillableService({ onClose: mockOnClose });
116
116
 
117
- const formTitle = screen.getByRole('heading', { name: /Add Billable Services/i });
117
+ const formTitle = screen.getByRole('heading', { name: /Add billable service/i });
118
118
  expect(formTitle).toBeInTheDocument();
119
119
 
120
120
  await fillRequiredFields(user);
@@ -188,7 +188,7 @@ describe('AddBillableService', () => {
188
188
  renderAddBillableService();
189
189
 
190
190
  // Fill all fields except service name
191
- await user.type(screen.getByRole('textbox', { name: /Short Name/i }), 'Test Short Name');
191
+ await user.type(screen.getByRole('textbox', { name: /Short name/i }), 'Test Short Name');
192
192
 
193
193
  await user.click(screen.getByRole('combobox', { name: /Service type/i }));
194
194
  await user.click(screen.getByRole('option', { name: /Lab service/i }));
@@ -20,7 +20,7 @@ const EditBillableServiceModal: React.FC<EditBillableServiceModalProps> = ({
20
20
 
21
21
  return (
22
22
  <>
23
- <ModalHeader closeModal={closeModal} title={t('billableService', 'Billable Service')} />
23
+ <ModalHeader closeModal={closeModal} title={t('billableService', 'Billable service')} />
24
24
  <ModalBody>
25
25
  <AddBillableService
26
26
  serviceToEdit={serviceToEdit}
@@ -2,6 +2,7 @@ import React, { useMemo } from 'react';
2
2
  import { InlineLoading } from '@carbon/react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { ErrorState } from '@openmrs/esm-patient-common-lib';
5
+ import { getCoreTranslation } from '@openmrs/esm-framework';
5
6
  import { useBillableServices } from '../billable-service.resource';
6
7
  import Card from '../../metrics-cards/card.component';
7
8
  import styles from '../../metrics-cards/metrics-cards.scss';
@@ -22,7 +23,11 @@ export default function ServiceMetrics() {
22
23
  if (isLoading) {
23
24
  return (
24
25
  <section className={styles.container}>
25
- <InlineLoading status="active" iconDescription="Loading" description="Loading service metrics..." />
26
+ <InlineLoading
27
+ status="active"
28
+ iconDescription={getCoreTranslation('loading')}
29
+ description={t('loadingServiceMetrics', 'Loading service metrics') + '...'}
30
+ />
26
31
  </section>
27
32
  );
28
33
  }
@@ -81,8 +81,8 @@ const AddPaymentModeModal: React.FC<AddPaymentModeModalProps> = ({ closeModal, o
81
81
  render={({ field }) => (
82
82
  <TextInput
83
83
  id="payment-mode-name"
84
- labelText={t('paymentModeName', 'Payment Mode Name')}
85
- placeholder={t('paymentModeNamePlaceholder', 'e.g., Cash, Credit Card')}
84
+ labelText={t('paymentModeNameLabel', 'Payment Mode Name')}
85
+ placeholder={t('paymentModeNamePlaceholder', 'For example, Cash, Credit Card')}
86
86
  invalid={!!errors.name}
87
87
  invalidText={errors.name?.message}
88
88
  {...field}
@@ -96,7 +96,7 @@ const AddPaymentModeModal: React.FC<AddPaymentModeModalProps> = ({ closeModal, o
96
96
  <TextInput
97
97
  id="payment-mode-description"
98
98
  labelText={t('description', 'Description')}
99
- placeholder={t('descriptionPlaceholder', 'e.g., Used for all cash transactions')}
99
+ placeholder={t('descriptionPlaceholder', 'For example, Used for all cash transactions')}
100
100
  invalid={!!errors.description}
101
101
  invalidText={errors.description?.message}
102
102
  {...field}
@@ -71,9 +71,9 @@ const PaymentModesConfig: React.FC = () => {
71
71
  return (
72
72
  <div className={styles.container}>
73
73
  <div className={styles.card}>
74
- <CardHeader title={t('paymentModeHistory', 'Payment Mode History')}>
74
+ <CardHeader title={t('paymentModeHistory', 'Payment mode history')}>
75
75
  <Button renderIcon={Add} onClick={handleAddPaymentMode} kind="ghost">
76
- {t('addNewPaymentMode', 'Add New Payment Mode')}
76
+ {t('addNewPaymentMode', 'Add new payment mode')}
77
77
  </Button>
78
78
  </CardHeader>
79
79
  <DataTable rows={rowData} headers={headerData} isSortable size="lg">
@@ -101,7 +101,7 @@ const BillingCheckInForm: React.FC<BillingCheckInFormProps> = ({ patientUuid, se
101
101
  <InlineNotification
102
102
  kind="error"
103
103
  lowContrast
104
- title={t('billErrorService', 'Bill service error')}
104
+ title={t('billErrorService', 'Billing service error')}
105
105
  subtitle={t('errorLoadingBillServices', 'Error loading bill services')}
106
106
  />
107
107
  );
@@ -132,8 +132,8 @@ describe('BillingCheckInForm', () => {
132
132
  mockUseCashPoint.mockReturnValueOnce({ cashPoints: [], isLoading: false, error });
133
133
  renderBillingCheckinForm();
134
134
 
135
- expect(screen.getByText('Bill service error')).toBeInTheDocument();
136
- expect(screen.getByText('Error loading bill services')).toBeInTheDocument();
135
+ expect(screen.getByText(/billing service error/i)).toBeInTheDocument();
136
+ expect(screen.getByText(/error loading bill services/i)).toBeInTheDocument();
137
137
  });
138
138
 
139
139
  test('should render the form correctly and generate the required payload', async () => {
@@ -95,8 +95,8 @@ const BillingForm: React.FC<BillingFormProps> = ({ patientUuid, closeWorkspace }
95
95
  for (const item of selectedItems) {
96
96
  if (item.availablePaymentMethods && item.availablePaymentMethods.length > 1 && !item.selectedPaymentMethod) {
97
97
  showSnackbar({
98
- title: t('validationError', 'Validation Error'),
99
- subtitle: t('selectPaymentMethodRequired', 'Please select a payment method for all items'),
98
+ title: t('validationError', 'Validation error'),
99
+ subtitle: t('paymentMethodRequired', 'Payment method is required for all items'),
100
100
  kind: 'error',
101
101
  });
102
102
  return false;
@@ -138,8 +138,8 @@ const BillingForm: React.FC<BillingFormProps> = ({ patientUuid, closeWorkspace }
138
138
  closeWorkspace();
139
139
  mutate((key) => typeof key === 'string' && key.startsWith(url), undefined, { revalidate: true });
140
140
  showSnackbar({
141
- title: t('saveBill', 'Save Bill'),
142
- subtitle: t('billProcessingSuccess', 'Bill processing has been successful'),
141
+ title: t('saveBill', 'Save bill'),
142
+ subtitle: t('billProcessedSuccessfully', 'Bill processed successfully'),
143
143
  kind: 'success',
144
144
  });
145
145
  } catch (error) {
@@ -162,8 +162,8 @@ const BillingForm: React.FC<BillingFormProps> = ({ patientUuid, closeWorkspace }
162
162
  <InlineNotification
163
163
  kind="error"
164
164
  lowContrast
165
- title={t('billErrorService', 'Bill service error')}
166
- subtitle={t('errorLoadingBillServices', 'Error loading bill services')}
165
+ title={t('errorLoadingBillableServices', 'Error loading billable services')}
166
+ subtitle={error?.message}
167
167
  />
168
168
  ) : (
169
169
  <ComboBox
@@ -176,7 +176,7 @@ const BillingForm: React.FC<BillingFormProps> = ({ patientUuid, closeWorkspace }
176
176
  )}
177
177
  {selectedItems && selectedItems.length > 0 && (
178
178
  <div className={styles.selectedItemsContainer}>
179
- <h4>{t('selectedItems', 'Selected Items')}</h4>
179
+ <h4>{t('selectedItems', 'Selected items')}</h4>
180
180
  {selectedItems.map((item) => (
181
181
  <div key={item.uuid} className={styles.itemCard}>
182
182
  <div className={styles.itemHeader}>
@@ -218,7 +218,7 @@ const BillingForm: React.FC<BillingFormProps> = ({ patientUuid, closeWorkspace }
218
218
  </div>
219
219
  ) : (
220
220
  <div className={styles.controlSection}>
221
- <label>{t('unitPrice', 'Unit Price')}</label>
221
+ <label>{t('unitPrice', 'Unit price')}</label>
222
222
  <span className={styles.priceDisplay}>{convertToCurrency(item.price, defaultCurrency)}</span>
223
223
  </div>
224
224
  )}
@@ -100,7 +100,7 @@ const VisitAttributesForm: React.FC<VisitAttributesFormProps> = ({ setAttributes
100
100
  <InlineLoading
101
101
  status="active"
102
102
  iconDescription={t('loadingDescription', 'Loading')}
103
- description={t('loading', 'Loading data...')}
103
+ description={t('loading', 'Loading data') + '...'}
104
104
  />
105
105
  );
106
106
  }