@openmrs/esm-billing-app 1.0.1-pre.49 → 1.0.1-pre.53

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.
@@ -32,10 +32,10 @@
32
32
  "initial": true,
33
33
  "entry": true,
34
34
  "recorded": false,
35
- "size": 3924822,
35
+ "size": 3926402,
36
36
  "sizes": {
37
37
  "consume-shared": 210,
38
- "javascript": 3903906,
38
+ "javascript": 3905486,
39
39
  "share-init": 210,
40
40
  "runtime": 20496
41
41
  },
@@ -52,7 +52,7 @@
52
52
  "auxiliaryFiles": [
53
53
  "main.js.map"
54
54
  ],
55
- "hash": "7c1c500ac7087214",
55
+ "hash": "ff84fda83499e6b0",
56
56
  "childrenByOrder": {}
57
57
  },
58
58
  {
@@ -84,9 +84,9 @@
84
84
  "initial": false,
85
85
  "entry": false,
86
86
  "recorded": false,
87
- "size": 3688,
87
+ "size": 3751,
88
88
  "sizes": {
89
- "javascript": 3688
89
+ "javascript": 3751
90
90
  },
91
91
  "names": [],
92
92
  "idHints": [],
@@ -98,7 +98,7 @@
98
98
  "319.js"
99
99
  ],
100
100
  "auxiliaryFiles": [],
101
- "hash": "85f40c398640df7e",
101
+ "hash": "e994e9d3a961bab0",
102
102
  "childrenByOrder": {}
103
103
  },
104
104
  {
@@ -207,9 +207,9 @@
207
207
  "initial": false,
208
208
  "entry": false,
209
209
  "recorded": false,
210
- "size": 348101,
210
+ "size": 349681,
211
211
  "sizes": {
212
- "javascript": 348101
212
+ "javascript": 349681
213
213
  },
214
214
  "names": [],
215
215
  "idHints": [],
@@ -222,7 +222,7 @@
222
222
  "auxiliaryFiles": [
223
223
  "547.js.map"
224
224
  ],
225
- "hash": "878a6402db533011",
225
+ "hash": "cb9d2a76b5046766",
226
226
  "childrenByOrder": {}
227
227
  },
228
228
  {
@@ -230,9 +230,9 @@
230
230
  "initial": false,
231
231
  "entry": false,
232
232
  "recorded": false,
233
- "size": 3688,
233
+ "size": 3751,
234
234
  "sizes": {
235
- "javascript": 3688
235
+ "javascript": 3751
236
236
  },
237
237
  "names": [],
238
238
  "idHints": [],
@@ -244,7 +244,7 @@
244
244
  "574.js"
245
245
  ],
246
246
  "auxiliaryFiles": [],
247
- "hash": "abcaca794998764d",
247
+ "hash": "b91a335059d19c61",
248
248
  "childrenByOrder": {}
249
249
  },
250
250
  {
@@ -273,9 +273,9 @@
273
273
  "initial": false,
274
274
  "entry": false,
275
275
  "recorded": false,
276
- "size": 3688,
276
+ "size": 3751,
277
277
  "sizes": {
278
- "javascript": 3688
278
+ "javascript": 3751
279
279
  },
280
280
  "names": [],
281
281
  "idHints": [],
@@ -287,7 +287,7 @@
287
287
  "757.js"
288
288
  ],
289
289
  "auxiliaryFiles": [],
290
- "hash": "49e12e466ed9d679",
290
+ "hash": "9eba956efc09103d",
291
291
  "childrenByOrder": {}
292
292
  },
293
293
  {
@@ -295,9 +295,9 @@
295
295
  "initial": false,
296
296
  "entry": false,
297
297
  "recorded": false,
298
- "size": 3688,
298
+ "size": 3751,
299
299
  "sizes": {
300
- "javascript": 3688
300
+ "javascript": 3751
301
301
  },
302
302
  "names": [],
303
303
  "idHints": [],
@@ -309,7 +309,7 @@
309
309
  "788.js"
310
310
  ],
311
311
  "auxiliaryFiles": [],
312
- "hash": "a1f46249e68ba343",
312
+ "hash": "67642acd4101304e",
313
313
  "childrenByOrder": {}
314
314
  },
315
315
  {
@@ -344,9 +344,9 @@
344
344
  "initial": false,
345
345
  "entry": false,
346
346
  "recorded": false,
347
- "size": 3688,
347
+ "size": 3751,
348
348
  "sizes": {
349
- "javascript": 3688
349
+ "javascript": 3751
350
350
  },
351
351
  "names": [],
352
352
  "idHints": [],
@@ -358,7 +358,7 @@
358
358
  "807.js"
359
359
  ],
360
360
  "auxiliaryFiles": [],
361
- "hash": "8b032e0438d8b411",
361
+ "hash": "224710844eeec81c",
362
362
  "childrenByOrder": {}
363
363
  },
364
364
  {
@@ -366,9 +366,9 @@
366
366
  "initial": false,
367
367
  "entry": false,
368
368
  "recorded": false,
369
- "size": 3688,
369
+ "size": 3751,
370
370
  "sizes": {
371
- "javascript": 3688
371
+ "javascript": 3751
372
372
  },
373
373
  "names": [],
374
374
  "idHints": [],
@@ -380,7 +380,7 @@
380
380
  "833.js"
381
381
  ],
382
382
  "auxiliaryFiles": [],
383
- "hash": "0da57eb06315c8bb",
383
+ "hash": "413ff22ef577e6ea",
384
384
  "childrenByOrder": {}
385
385
  },
386
386
  {
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"kenyaemr":"^18.2.0"},"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":"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":"billing-form","component":"billingForm"},{"name":"require-billing-modal","component":"requirePaymentModal"},{"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"}],"version":"1.0.1-pre.49"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"kenyaemr":"^18.2.0"},"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":"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":"billing-form","component":"billingForm"},{"name":"require-billing-modal","component":"requirePaymentModal"},{"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"}],"version":"1.0.1-pre.53"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-billing-app",
3
- "version": "1.0.1-pre.49",
3
+ "version": "1.0.1-pre.53",
4
4
  "description": "Billing frontend module for use in O3",
5
5
  "browser": "dist/openmrs-esm-billing-app.js",
6
6
  "main": "src/index.ts",
@@ -83,7 +83,7 @@ const BillingCheckInForm: React.FC<BillingCheckInFormProps> = ({ patientUuid, se
83
83
  if (paymentMethod) {
84
84
  lineList = [];
85
85
  lineList = lineItems.filter((e) =>
86
- e.servicePrices.some((p) => p.paymentMode && p.paymentMode.uuid === paymentMethod?.paymentMethods),
86
+ e.servicePrices.some((p) => p.paymentMode && p.paymentMode.uuid === paymentMethod),
87
87
  );
88
88
  }
89
89
 
@@ -1,4 +1,4 @@
1
- import React, { useState, useRef } from 'react';
1
+ import React, { useState, useRef, useEffect } from 'react';
2
2
  import {
3
3
  ButtonSet,
4
4
  Button,
@@ -14,10 +14,11 @@ import {
14
14
  } from '@carbon/react';
15
15
  import styles from './billing-form.scss';
16
16
  import { useTranslation } from 'react-i18next';
17
- import { showSnackbar, useConfig } from '@openmrs/esm-framework';
17
+ import { showSnackbar, showToast, useConfig } from '@openmrs/esm-framework';
18
18
  import { useFetchSearchResults, processBillItems } from '../billing.resource';
19
19
  import { mutate } from 'swr';
20
20
  import { convertToCurrency } from '../helpers';
21
+ import { z } from 'zod';
21
22
 
22
23
  type BillingFormProps = {
23
24
  patientUuid: string;
@@ -32,26 +33,46 @@ const BillingForm: React.FC<BillingFormProps> = ({ patientUuid, closeWorkspace }
32
33
  const [billItems, setBillItems] = useState([]);
33
34
  const [searchVal, setSearchVal] = useState('');
34
35
  const [category, setCategory] = useState('');
36
+ const [saveDisabled, setSaveDisabled] = useState<boolean>(false);
35
37
 
36
38
  const toggleSearch = (choiceSelected) => {
37
39
  (document.getElementById('searchField') as HTMLInputElement).disabled = false;
38
40
  setCategory(choiceSelected === 'Stock Item' ? 'Stock Item' : 'Service');
39
41
  };
40
42
 
43
+ const billItemSchema = z.object({
44
+ Qnty: z.number().min(1, t('quantityGreaterThanZero', 'Quantity must be at least one for all items.')), // zod logic
45
+ });
46
+
41
47
  const calculateTotal = (event, itemName) => {
42
48
  const quantity = parseInt(event.target.value);
49
+ let isValid = true;
50
+
51
+ try {
52
+ billItemSchema.parse({ Qnty: quantity });
53
+ } catch (error) {
54
+ isValid = false;
55
+ const parsedErrorMessage = JSON.parse(error.message);
56
+ showToast({
57
+ title: t('billItems', 'Save Bill'),
58
+ kind: 'error',
59
+ description: parsedErrorMessage[0].message,
60
+ });
61
+ }
62
+
43
63
  const updatedItems = billItems.map((item) => {
44
64
  if (item.Item.toLowerCase().includes(itemName.toLowerCase())) {
45
- const price = item.Price;
46
- const total = price * quantity;
47
- return { ...item, Qnty: quantity, Total: total };
65
+ return { ...item, Qnty: quantity, isValid: quantity > 0 };
48
66
  }
49
67
  return item;
50
68
  });
51
69
 
70
+ const anyInvalidQuantity = updatedItems.some((item) => item.Qnty <= 0);
71
+
52
72
  setBillItems(updatedItems);
73
+ setSaveDisabled(!isValid || anyInvalidQuantity);
53
74
 
54
- const updatedGrandTotal = updatedItems.reduce((acc, item) => acc + item.Total, 0);
75
+ const updatedGrandTotal = updatedItems.reduce((acc, item) => acc + item.Price * item.Qnty, 0);
55
76
  setGrandTotal(updatedGrandTotal);
56
77
  };
57
78
 
@@ -215,7 +236,7 @@ const BillingForm: React.FC<BillingFormProps> = ({ patientUuid, closeWorkspace }
215
236
  <TableCell>
216
237
  <input
217
238
  type="number"
218
- className="form-control"
239
+ className={`form-control ${row.Qnty <= 0 ? styles.invalidInput : ''}`}
219
240
  id={row.Item}
220
241
  min={0}
221
242
  max={100}
@@ -248,7 +269,12 @@ const BillingForm: React.FC<BillingFormProps> = ({ patientUuid, closeWorkspace }
248
269
  <Button kind="secondary" onClick={closeWorkspace}>
249
270
  Discard
250
271
  </Button>
251
- <Button kind="primary" onClick={postBillItems}>
272
+ <Button
273
+ kind="primary"
274
+ disabled={saveDisabled}
275
+ onClick={() => {
276
+ postBillItems();
277
+ }}>
252
278
  Save & Close
253
279
  </Button>
254
280
  </ButtonSet>
@@ -22,4 +22,8 @@
22
22
  border-bottom: 0.1rem solid;
23
23
  border-bottom-color: silver;
24
24
  cursor: pointer;
25
+ }
26
+
27
+ .invalidInput {
28
+ border: 2px solid red;
25
29
  }
@@ -51,16 +51,14 @@ const VisitAttributesForm: React.FC<VisitAttributesFormProps> = ({ setAttributes
51
51
  }, [paymentDetails, paymentMethods, insuranceSchema, policyNumber, patientCategory]);
52
52
 
53
53
  const createVisitAttributesPayload = () => {
54
- const paymentMethods = getValues();
54
+ const { paymentDetails, paymentMethods, insuranceScheme, policyNumber, patientCategory } = getValues();
55
55
  setPaymentMethod(paymentMethods);
56
56
  const formPayload = [
57
- patientCatergory.paymentDetails,
58
- patientCatergory.paymentMethods,
59
- patientCatergory.policyNumber,
60
- patientCatergory.insuranceScheme,
61
- patientCatergory.patientCategory,
62
- patientCatergory.formPayloadPending,
63
- true,
57
+ { uuid: patientCatergory.paymentDetails, value: paymentDetails },
58
+ { uuid: patientCatergory.paymentMethods, value: paymentMethods },
59
+ { uuid: patientCatergory.insuranceScheme, value: insuranceScheme },
60
+ { uuid: patientCatergory.policyNumber, value: policyNumber },
61
+ { uuid: patientCatergory.patientCategory, value: patientCategory },
64
62
  ];
65
63
  const visitAttributesPayload = formPayload.filter(
66
64
  (item) => item.value !== undefined && item.value !== null && item.value !== '',
@@ -92,7 +90,7 @@ const VisitAttributesForm: React.FC<VisitAttributesFormProps> = ({ setAttributes
92
90
  onChange={(selected) => field.onChange(selected)}
93
91
  orientation="vertical"
94
92
  legendText={t('paymentDetails', 'Payment Details')}
95
- name="payment-details-group">
93
+ name="payment-details">
96
94
  <RadioButton labelText="Paying" value={catergoryConcepts.payingDetails} id="radio-1" />
97
95
  <RadioButton labelText="Non paying" value={catergoryConcepts.nonPayingDetails} id="radio-2" />
98
96
  </RadioButtonGroup>
@@ -7,10 +7,10 @@ export const configSchema = {
7
7
  _type: Type.Object,
8
8
  _description: 'Patient Category Custom UUIDs',
9
9
  _default: {
10
- paymentDetails: 'caf2124f-00a9-4620-a250-efd8535afd6d',
11
- paymentMethods: 'c39b684c-250f-4781-a157-d6ad7353bc90',
12
- policyNumber: '0f4f3306-f01b-43c6-af5b-fdb60015cb02',
13
- insuranceScheme: '2d0fa959-6780-41f1-85b1-402045935068',
10
+ paymentDetails: 'fbc0702d-b4c9-4968-be63-af8ad3ad6239',
11
+ paymentMethods: '8553afa0-bdb9-4d3c-8a98-05fa9350aa85',
12
+ policyNumber: '3a988e33-a6c0-4b76-b924-01abb998944b',
13
+ insuranceScheme: 'aac48226-d143-4274-80e0-264db4e368ee',
14
14
  patientCategory: '3b9dfac8-9e4d-11ee-8c90-0242ac120002',
15
15
  formPayloadPending: '919b51c9-8e2e-468f-8354-181bf3e55786',
16
16
  },
@@ -20,10 +20,10 @@ export const configSchema = {
20
20
  _type: Type.Object,
21
21
  _description: 'Patient Category Concept UUIDs',
22
22
  _default: {
23
- payingDetails: '1c30ee58-82d4-4ea4-a8c1-4bf2f9dfc8cf',
24
- nonPayingDetails: 'a28d7929-050a-4249-a61a-551e9b8cc102',
23
+ payingDetails: '44b34972-6630-4e5a-a9f6-a6eb0f109650',
24
+ nonPayingDetails: 'f3fb2d88-cccd-422c-8766-be101ba7bd2e',
25
25
  insuranceDetails: 'beac329b-f1dc-4a33-9e7c-d95821a137a6',
26
- childUnder5: '2d61b762-6e32-4e2e-811f-ac72cbd3600a',
26
+ childUnder5: '1528AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
27
27
  student: '159465AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
28
28
  },
29
29
  },
@@ -81,6 +81,7 @@
81
81
  "printReceipt": "Print receipt",
82
82
  "processPayment": "Process Payment",
83
83
  "quantity": "Quantity",
84
+ "quantityGreaterThanZero": "Quantity must be greater than zero",
84
85
  "referenceNumber": "Reference number",
85
86
  "save": "Save",
86
87
  "searchConcepts": "Search associated concept",
@@ -81,6 +81,7 @@
81
81
  "printReceipt": "Print receipt",
82
82
  "processPayment": "Process Payment",
83
83
  "quantity": "Quantity",
84
+ "quantityGreaterThanZero": "Quantity must be greater than zero",
84
85
  "referenceNumber": "Reference number",
85
86
  "save": "Save",
86
87
  "searchConcepts": "Search associated concept",
@@ -81,6 +81,7 @@
81
81
  "printReceipt": "Print receipt",
82
82
  "processPayment": "Process Payment",
83
83
  "quantity": "Quantity",
84
+ "quantityGreaterThanZero": "Quantity must be greater than zero",
84
85
  "referenceNumber": "Reference number",
85
86
  "save": "Save",
86
87
  "searchConcepts": "Search associated concept",
@@ -81,6 +81,7 @@
81
81
  "printReceipt": "Print receipt",
82
82
  "processPayment": "Process Payment",
83
83
  "quantity": "Quantity",
84
+ "quantityGreaterThanZero": "Quantity must be greater than zero",
84
85
  "referenceNumber": "Reference number",
85
86
  "save": "Save",
86
87
  "searchConcepts": "Search associated concept",
@@ -81,6 +81,7 @@
81
81
  "printReceipt": "Print receipt",
82
82
  "processPayment": "Process Payment",
83
83
  "quantity": "Quantity",
84
+ "quantityGreaterThanZero": "Quantity must be greater than zero",
84
85
  "referenceNumber": "Reference number",
85
86
  "save": "Save",
86
87
  "searchConcepts": "Search associated concept",
@@ -81,6 +81,7 @@
81
81
  "printReceipt": "Print receipt",
82
82
  "processPayment": "Process Payment",
83
83
  "quantity": "Quantity",
84
+ "quantityGreaterThanZero": "Quantity must be greater than zero",
84
85
  "referenceNumber": "Reference number",
85
86
  "save": "Save",
86
87
  "searchConcepts": "Search associated concept",