@openmrs/esm-billing-app 1.0.2-pre.957 → 1.0.2-pre.958

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.
@@ -665,9 +665,9 @@
665
665
  "initial": false,
666
666
  "entry": false,
667
667
  "recorded": false,
668
- "size": 43608,
668
+ "size": 43617,
669
669
  "sizes": {
670
- "javascript": 43608
670
+ "javascript": 43617
671
671
  },
672
672
  "names": [],
673
673
  "idHints": [],
@@ -681,7 +681,7 @@
681
681
  "auxiliaryFiles": [
682
682
  "4739.js.map"
683
683
  ],
684
- "hash": "9e4b1737c952553a",
684
+ "hash": "23dcc92713f643e8",
685
685
  "childrenByOrder": {}
686
686
  },
687
687
  {
@@ -1187,9 +1187,9 @@
1187
1187
  "initial": false,
1188
1188
  "entry": false,
1189
1189
  "recorded": false,
1190
- "size": 1109251,
1190
+ "size": 1109271,
1191
1191
  "sizes": {
1192
- "javascript": 1109209,
1192
+ "javascript": 1109229,
1193
1193
  "consume-shared": 42
1194
1194
  },
1195
1195
  "names": [],
@@ -1203,7 +1203,7 @@
1203
1203
  "auxiliaryFiles": [
1204
1204
  "8572.js.map"
1205
1205
  ],
1206
- "hash": "b0b9fbd71c110b36",
1206
+ "hash": "889be701a774d105",
1207
1207
  "childrenByOrder": {}
1208
1208
  },
1209
1209
  {
@@ -1260,10 +1260,10 @@
1260
1260
  "initial": true,
1261
1261
  "entry": true,
1262
1262
  "recorded": false,
1263
- "size": 5390873,
1263
+ "size": 5390893,
1264
1264
  "sizes": {
1265
1265
  "consume-shared": 210,
1266
- "javascript": 5368221,
1266
+ "javascript": 5368241,
1267
1267
  "share-init": 336,
1268
1268
  "runtime": 22106
1269
1269
  },
@@ -1280,7 +1280,7 @@
1280
1280
  "auxiliaryFiles": [
1281
1281
  "main.js.map"
1282
1282
  ],
1283
- "hash": "27d37f680c3d59ae",
1283
+ "hash": "42203052844b409c",
1284
1284
  "childrenByOrder": {}
1285
1285
  },
1286
1286
  {
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"}},{"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"}},{"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"},{"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":"billable-services-left-panel-link","component":"billableServicesLeftPanelLink","slot":"billable-services-left-panel-slot","order":0},{"name":"bill-waiver-left-panel-link","component":"billWaiverLeftPanelLink","slot":"billable-services-left-panel-slot","order":1},{"name":"billing-settings-left-panel-menu","component":"billingSettingsLeftPanelMenu","slot":"billable-services-left-panel-slot","order":2}],"modals":[{"name":"add-cash-point-modal","component":"addCashPointModal"},{"name":"payment-mode-form-modal","component":"paymentModeFormModal"},{"name":"delete-payment-mode-modal","component":"deletePaymentModeModal"},{"name":"edit-bill-item-modal","component":"editBillLineItemModal"},{"name":"edit-bill-line-item-modal","component":"editBillLineItemModal"},{"name":"require-billing-modal","component":"requirePaymentModal"}],"workspaces":[{"name":"billing-form-workspace","title":"billingForm","component":"billingFormWorkspace","type":"form"},{"name":"billable-service-form","title":"billableServiceForm","component":"billableServiceFormWorkspace","type":"form","width":"wider"}],"version":"1.0.2-pre.957"}
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"}},{"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"}},{"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"},{"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":"billable-services-left-panel-link","component":"billableServicesLeftPanelLink","slot":"billable-services-left-panel-slot","order":0},{"name":"bill-waiver-left-panel-link","component":"billWaiverLeftPanelLink","slot":"billable-services-left-panel-slot","order":1},{"name":"billing-settings-left-panel-menu","component":"billingSettingsLeftPanelMenu","slot":"billable-services-left-panel-slot","order":2}],"modals":[{"name":"add-cash-point-modal","component":"addCashPointModal"},{"name":"payment-mode-form-modal","component":"paymentModeFormModal"},{"name":"delete-payment-mode-modal","component":"deletePaymentModeModal"},{"name":"edit-bill-item-modal","component":"editBillLineItemModal"},{"name":"edit-bill-line-item-modal","component":"editBillLineItemModal"},{"name":"require-billing-modal","component":"requirePaymentModal"}],"workspaces":[{"name":"billing-form-workspace","title":"billingForm","component":"billingFormWorkspace","type":"form"},{"name":"billable-service-form","title":"billableServiceForm","component":"billableServiceFormWorkspace","type":"form","width":"wider"}],"version":"1.0.2-pre.958"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-billing-app",
3
- "version": "1.0.2-pre.957",
3
+ "version": "1.0.2-pre.958",
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",
@@ -168,6 +168,7 @@ const EditBillLineItemModal: React.FC<EditBillLineItemModalProps> = ({ bill, clo
168
168
  control={control}
169
169
  render={({ field: { onChange, value } }) => (
170
170
  <NumberInput
171
+ allowEmpty
171
172
  disableWheel
172
173
  className={styles.controlField}
173
174
  hideSteppers
@@ -308,4 +308,23 @@ describe('EditBillItem', () => {
308
308
  expect(screen.queryByText(/Quantity must be at least 1/)).not.toBeInTheDocument();
309
309
  });
310
310
  });
311
+
312
+ test('shows validation error when quantity field is left empty', async () => {
313
+ const user = userEvent.setup();
314
+ render(<EditBillLineItemModal bill={mockBill} item={mockItem} closeModal={mockCloseModal} />);
315
+
316
+ const quantityInput = screen.getByRole('spinbutton', { name: /Quantity/ });
317
+ await user.clear(quantityInput);
318
+
319
+ // Try to submit with empty field
320
+ await user.click(screen.getByText(/save/i));
321
+
322
+ // Should show validation error (empty string coerces to 0, triggering min validation)
323
+ await waitFor(() => {
324
+ expect(screen.getByText(/Quantity must be at least 1/)).toBeInTheDocument();
325
+ });
326
+
327
+ // Should NOT call the update function
328
+ expect(mockUpdateBillItems).not.toHaveBeenCalled();
329
+ });
311
330
  });
@@ -80,16 +80,17 @@ 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')}
84
- helperText={t('amountToWaiveHelper', 'Specify the amount to be deducted from the bill')}
83
+ allowEmpty
85
84
  aria-label={t('amountToWaiveAriaLabel', 'Enter amount to waive')}
86
- hideSteppers
87
85
  disableWheel
88
- min={0}
89
- max={totalAmount}
86
+ helperText={t('amountToWaiveHelper', 'Specify the amount to be deducted from the bill')}
87
+ hideSteppers
90
88
  invalidText={t('invalidWaiverAmount', 'Invalid waiver amount')}
91
- value={waiverAmount}
89
+ label={t('amountToWaiveLabel', 'Amount to waive')}
90
+ max={totalAmount}
91
+ min={0}
92
92
  onChange={(event) => setWaiverAmount(event.target.value)}
93
+ value={waiverAmount}
93
94
  />
94
95
  </Layer>
95
96
  </FormGroup>
@@ -1,9 +1,17 @@
1
1
  import React, { useState } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
3
  import { mutate } from 'swr';
4
- import { Button, ButtonSet, ComboBox, Form, NumberInput, InlineLoading, InlineNotification } from '@carbon/react';
5
- import { TrashCan } from '@carbon/react/icons';
6
- import { useConfig, useLayoutType, showSnackbar, getCoreTranslation } from '@openmrs/esm-framework';
4
+ import {
5
+ Button,
6
+ ButtonSet,
7
+ ComboBox,
8
+ IconButton,
9
+ InlineLoading,
10
+ InlineNotification,
11
+ Form,
12
+ NumberInput,
13
+ } from '@carbon/react';
14
+ import { useConfig, useLayoutType, showSnackbar, getCoreTranslation, TrashCanIcon } from '@openmrs/esm-framework';
7
15
  import { processBillItems, useBillableServices } from '../billing.resource';
8
16
  import { calculateTotalAmount, convertToCurrency } from '../helpers/functions';
9
17
  import type { BillingConfig } from '../config-schema';
@@ -181,13 +189,13 @@ const BillingForm: React.FC<BillingFormProps> = ({ patientUuid, closeWorkspace }
181
189
  <div key={item.uuid} className={styles.itemCard}>
182
190
  <div className={styles.itemHeader}>
183
191
  <span className={styles.itemName}>{item.display}</span>
184
- <Button
192
+ <IconButton
193
+ align="top-end"
185
194
  kind="ghost"
186
- size="sm"
187
- renderIcon={TrashCan}
188
- iconDescription={t('remove', 'Remove')}
189
- onClick={() => removeSelectedBillableItem(item.uuid)}
190
- />
195
+ label={t('remove', 'Remove')}
196
+ onClick={() => removeSelectedBillableItem(item.uuid)}>
197
+ <TrashCanIcon size={16} />
198
+ </IconButton>
191
199
  </div>
192
200
 
193
201
  <div className={styles.itemControls}>
@@ -197,7 +205,6 @@ const BillingForm: React.FC<BillingFormProps> = ({ patientUuid, closeWorkspace }
197
205
  <ComboBox
198
206
  id={`payment-method-${item.uuid}`}
199
207
  items={item.availablePaymentMethods}
200
- size="md"
201
208
  itemToString={(method: ServicePrice) =>
202
209
  method
203
210
  ? `${method.name} - ${convertToCurrency(
@@ -226,16 +233,16 @@ const BillingForm: React.FC<BillingFormProps> = ({ patientUuid, closeWorkspace }
226
233
  <div className={styles.controlSection}>
227
234
  <label>{t('quantity', 'Quantity')}</label>
228
235
  <NumberInput
236
+ allowEmpty
229
237
  disableWheel
230
238
  hideSteppers
231
239
  id={`quantity-${item.uuid}`}
232
240
  min={1}
233
- value={item.quantity}
234
- size="md"
235
241
  onChange={(_, { value }) => {
236
242
  const number = parseFloat(String(value));
237
243
  updateQuantity(item.uuid, isNaN(number) ? 1 : number);
238
244
  }}
245
+ value={item.quantity}
239
246
  />
240
247
  </div>
241
248
 
@@ -114,8 +114,7 @@ const Invoice: React.FC = () => {
114
114
  disabled={isPrinting || isLoadingPatient || isLoadingBill}
115
115
  onClick={handlePrint}
116
116
  renderIcon={(props) => <Printer size={24} {...props} />}
117
- iconDescription={t('printBill', 'Print bill')}
118
- size="md">
117
+ iconDescription={t('printBill', 'Print bill')}>
119
118
  {t('printBill', 'Print bill')}
120
119
  </Button>
121
120
  {(bill?.status === 'PAID' || bill?.tenderedAmount > 0) && <PrintReceipt billId={bill?.id} />}
@@ -33,7 +33,6 @@ const PrintReceipt: React.FC<PrintReceiptProps> = ({ billId }) => {
33
33
  <Button
34
34
  kind="secondary"
35
35
  className={styles.button}
36
- size="md"
37
36
  renderIcon={(props) => <Printer size={24} {...props} />}
38
37
  onClick={handlePrintReceiptClick}
39
38
  disabled={isRedirecting}>