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

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.2710"}
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.2714"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenyaemr/esm-billing-app",
3
- "version": "5.4.2-pre.2710",
3
+ "version": "5.4.2-pre.2714",
4
4
  "description": "Billing app for KenyaEMR",
5
5
  "keywords": [
6
6
  "openmrs"
@@ -29,7 +29,8 @@
29
29
  .clockOutStrip {
30
30
  display: flex;
31
31
  justify-content: space-between;
32
- padding: layout.$spacing-05 layout.$spacing-05 0 layout.$spacing-05;
32
+ padding: layout.$spacing-03 layout.$spacing-05;
33
+ border-bottom: 1px solid colors.$gray-20;
33
34
  }
34
35
 
35
36
  .clockOutInfo {
@@ -47,8 +48,25 @@
47
48
  color: colors.$gray-60;
48
49
  }
49
50
 
51
+ .clockInTime {
52
+ @include type.type-style('body-01');
53
+ color: colors.$gray-90;
54
+ }
55
+
50
56
  .cashPointName {
51
57
  font-size: smaller;
52
58
  color: colors.$gray-60;
53
59
  }
54
60
  }
61
+
62
+ .clockInSkeleton,
63
+ .clockIn {
64
+ margin-right: layout.$spacing-05;
65
+ }
66
+
67
+ .clockInContainer {
68
+ display: flex;
69
+ justify-content: flex-end;
70
+ padding: layout.$spacing-03;
71
+ border-bottom: 1px solid colors.$gray-20;
72
+ }
@@ -0,0 +1,40 @@
1
+ import { Button, ButtonSkeleton } from '@carbon/react';
2
+ import { IbmCloudLogging } from '@carbon/react/icons';
3
+ import { showModal, useLayoutType } from '@openmrs/esm-framework';
4
+ import React from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { useClockInStatus } from '../bill-administration/payment-points/use-clock-in-status';
7
+ import styles from './billing-dashboard.scss';
8
+
9
+ const ClockInButton = () => {
10
+ const { t } = useTranslation();
11
+ const { isClockedIn, isLoading } = useClockInStatus();
12
+ const controlSize = useLayoutType() === 'tablet' ? 'md' : 'sm';
13
+
14
+ const openClockInModal = () => {
15
+ const dispose = showModal('clock-in-modal', {
16
+ closeModal: () => dispose(),
17
+ });
18
+ };
19
+
20
+ if (isLoading) {
21
+ return <ButtonSkeleton className={styles.clockInSkeleton} />;
22
+ }
23
+
24
+ if (isClockedIn) {
25
+ return null;
26
+ }
27
+
28
+ return (
29
+ <Button
30
+ onClick={openClockInModal}
31
+ className={styles.clockIn}
32
+ renderIcon={IbmCloudLogging}
33
+ iconDescription="Clock In"
34
+ size={controlSize}>
35
+ {t('clockIn', 'Clock In')}
36
+ </Button>
37
+ );
38
+ };
39
+
40
+ export default ClockInButton;
@@ -1,18 +1,25 @@
1
- import { Button } from '@carbon/react';
2
- import { Alarm, IbmCloudSysdigSecure, Shuffle } from '@carbon/react/icons';
3
- import { showModal } from '@openmrs/esm-framework';
4
- import dayjs from 'dayjs';
5
1
  import React from 'react';
2
+ import { Button } from '@carbon/react';
6
3
  import { useTranslation } from 'react-i18next';
4
+ import { IbmCloudSysdigSecure, Shuffle, Location as LocationIcon } from '@carbon/react/icons';
5
+ import { formatDate, parseDate, showModal, useLayoutType } from '@openmrs/esm-framework';
6
+
7
7
  import { useClockInStatus } from '../bill-administration/payment-points/use-clock-in-status';
8
+
9
+ import ClockInButton from './clock-in-button.component';
8
10
  import styles from './billing-dashboard.scss';
9
11
 
10
12
  export const ClockOutStrip = () => {
11
13
  const { isClockedIn, globalActiveSheet } = useClockInStatus();
14
+ const controlSize = useLayoutType() === 'tablet' ? 'md' : 'sm';
12
15
  const { t } = useTranslation();
13
16
 
14
17
  if (!isClockedIn) {
15
- return null;
18
+ return (
19
+ <div className={styles.clockInContainer}>
20
+ <ClockInButton />
21
+ </div>
22
+ );
16
23
  }
17
24
 
18
25
  const openClockOutModal = () => {
@@ -30,20 +37,24 @@ export const ClockOutStrip = () => {
30
37
  return (
31
38
  <div className={styles.clockOutStrip}>
32
39
  <div className={styles.clockOutInfo}>
33
- <Alarm />
34
40
  <p className={styles.clockInTime}>
35
41
  {t('clockInTime', 'Clocked in on {{clockInDate}}', {
36
- clockInDate: dayjs(globalActiveSheet.clockIn).format('D MMM YYYY, HH:mm A'),
42
+ clockInDate: formatDate(parseDate(globalActiveSheet.clockIn), { noToday: true, mode: 'wide' }),
37
43
  })}
38
44
  </p>
39
45
  <span className={styles.middot}>&middot;</span>
40
46
  <p className={styles.cashPointName}>{globalActiveSheet.cashPoint.name}</p>
41
47
  </div>
42
48
  <div>
43
- <Button kind="ghost" renderIcon={Shuffle} onClick={openClockInModal}>
49
+ <Button size={controlSize} kind="ghost" renderIcon={Shuffle} onClick={openClockInModal}>
44
50
  {t('switchPaymentPoint', 'Switch Payment Point')}
45
51
  </Button>
46
- <Button className={styles.clockIn} onClick={openClockOutModal} kind="danger" renderIcon={IbmCloudSysdigSecure}>
52
+ <Button
53
+ size={controlSize}
54
+ className={styles.clockIn}
55
+ onClick={openClockOutModal}
56
+ kind="danger"
57
+ renderIcon={IbmCloudSysdigSecure}>
47
58
  {t('clockOut', 'Clock Out')}
48
59
  </Button>
49
60
  </div>
@@ -1,3 +1,7 @@
1
+ import React, { useState } from 'react';
2
+ import { mutate } from 'swr';
3
+ import { getPatientUuidFromStore } from '@openmrs/esm-patient-common-lib';
4
+ import { type DefaultWorkspaceProps, showSnackbar, useConfig } from '@openmrs/esm-framework';
1
5
  import {
2
6
  Button,
3
7
  ButtonSet,
@@ -12,34 +16,31 @@ import {
12
16
  TableHeader,
13
17
  TableRow,
14
18
  } from '@carbon/react';
15
- import { zodResolver } from '@hookform/resolvers/zod';
16
- import { getPatientUuidFromStore } from '@openmrs/esm-patient-common-lib';
17
- import React, { useState } from 'react';
18
- import { Controller, useForm } from 'react-hook-form';
19
+ import { TrashCan } from '@carbon/react/icons';
19
20
  import { useTranslation } from 'react-i18next';
21
+ import { Controller, useForm } from 'react-hook-form';
22
+ import { zodResolver } from '@hookform/resolvers/zod';
20
23
  import { z } from 'zod';
24
+
21
25
  import { Autosuggest } from '../autosuggest/autosuggest.component';
22
- import { billingFormSchema, processBillItems } from '../billing.resource';
23
26
  import useBillableServices from '../hooks/useBillableServices';
24
- import { BillingService } from '../types';
27
+ import { billingFormSchema, processBillItems } from '../billing.resource';
28
+ import { type BillingService } from '../types';
29
+ import { type BillingConfig } from '../config-schema';
30
+
25
31
  import styles from './billing-form.scss';
26
- import { mutate } from 'swr';
27
- import { showSnackbar, useConfig } from '@openmrs/esm-framework';
28
- import { BillingConfig } from '../config-schema';
29
- import { TrashCan } from '@carbon/react/icons';
30
32
 
31
- type BillingFormProps = {
33
+ type BillingFormProps = DefaultWorkspaceProps & {
32
34
  patientUuid: string;
33
- closeWorkspace: () => void;
34
35
  };
35
36
 
36
37
  type FormType = z.infer<typeof billingFormSchema>;
37
38
 
38
- const BillingForm: React.FC<BillingFormProps> = ({ closeWorkspace }) => {
39
+ const BillingForm: React.FC<BillingFormProps> = ({ closeWorkspace, patientUuid: patientUuidProp }) => {
39
40
  const { t } = useTranslation();
40
- const patientUuid = getPatientUuidFromStore();
41
+ const patientUuid = patientUuidProp || getPatientUuidFromStore();
41
42
  const { billableServices, error, isLoading } = useBillableServices();
42
- const [searchVal, setsearchVal] = useState('');
43
+ const [searchTermValue, setSearchTermValue] = useState('');
43
44
  const { cashPointUuid, cashierUuid } = useConfig<BillingConfig>();
44
45
 
45
46
  const form = useForm<FormType>({
@@ -73,42 +74,49 @@ const BillingForm: React.FC<BillingFormProps> = ({ closeWorkspace }) => {
73
74
  };
74
75
 
75
76
  const handleSearch = async (searchText: string) => {
76
- setsearchVal(searchText);
77
+ setSearchTermValue(searchText);
77
78
  return billableServices.filter(
78
79
  (service) =>
79
80
  service?.name.toLocaleLowerCase().includes(searchText.toLocaleLowerCase()) &&
80
- lineItemsOnservable.findIndex((item) => item.billableService === service?.uuid) === -1,
81
+ lineItemsToWatch.findIndex((item) => item.billableService === service?.uuid) === -1,
81
82
  );
82
83
  };
83
84
 
84
- const lineItemsOnservable = form.watch('lineItems');
85
+ const lineItemsToWatch = form.watch('lineItems');
86
+
87
+ const handleSuggestionSelected = (field: string, value: string) => {
88
+ if (value) {
89
+ form.setValue('lineItems', [
90
+ ...lineItemsToWatch,
91
+ {
92
+ billableService: value,
93
+ lineItemOrder: 0,
94
+ quantity: 1,
95
+ price: 0,
96
+ paymentStatus: 'PENDING',
97
+ priceName: 'Default',
98
+ },
99
+ ]);
100
+ }
101
+ setSearchTermValue('');
102
+ };
103
+
104
+ const handleError = (errors: any) => {
105
+ console.error('errors', errors);
106
+ showSnackbar({ title: t('error', 'Error'), kind: 'error', subtitle: JSON.stringify(errors) });
107
+ };
85
108
 
86
109
  return (
87
- <Form onSubmit={form.handleSubmit(onSubmit)}>
110
+ <Form onSubmit={form.handleSubmit(onSubmit, handleError)}>
88
111
  <Stack gap={4} className={styles.grid}>
89
112
  <Column>
90
113
  <Autosuggest
91
- value={searchVal}
92
- onClear={() => setsearchVal('')}
114
+ value={searchTermValue}
115
+ onClear={() => setSearchTermValue('')}
93
116
  getDisplayValue={(item: BillingService) => item.name}
94
117
  getFieldValue={(item: BillingService) => item.uuid}
95
118
  getSearchResults={handleSearch}
96
- onSuggestionSelected={(field, value) => {
97
- if (value) {
98
- form.setValue('lineItems', [
99
- ...lineItemsOnservable,
100
- {
101
- billableService: value,
102
- lineItemOrder: 0,
103
- quantity: 1,
104
- price: 0,
105
- paymentStatus: 'PENDING',
106
- priceName: 'Default',
107
- },
108
- ]);
109
- }
110
- setsearchVal('');
111
- }}
119
+ onSuggestionSelected={handleSuggestionSelected}
112
120
  labelText={t('search', 'Search')}
113
121
  placeholder={t('searchPlaceHolder', 'Find your billables here...')}
114
122
  />
@@ -117,16 +125,16 @@ const BillingForm: React.FC<BillingFormProps> = ({ closeWorkspace }) => {
117
125
  <Table aria-label="sample table">
118
126
  <TableHead>
119
127
  <TableRow>
120
- <TableHeader>Item</TableHeader>
121
- <TableHeader>Quantity</TableHeader>
122
- <TableHeader>PaymentMethod</TableHeader>
123
- <TableHeader>Price</TableHeader>
124
- <TableHeader>Total</TableHeader>
128
+ <TableHeader>{t('item', 'Item')}</TableHeader>
129
+ <TableHeader>{t('quantity', 'Quantity')}</TableHeader>
130
+ <TableHeader>{t('paymentMethod', 'Payment Method')}</TableHeader>
131
+ <TableHeader>{t('price', 'Price')}</TableHeader>
132
+ <TableHeader>{t('total', 'Total')}</TableHeader>
125
133
  <TableHeader></TableHeader>
126
134
  </TableRow>
127
135
  </TableHead>
128
136
  <TableBody>
129
- {lineItemsOnservable.map(({ billableService, quantity, price }, index) => {
137
+ {lineItemsToWatch.map(({ billableService, quantity, price }, index) => {
130
138
  const service = billableServices.find((serv) => serv.uuid === billableService);
131
139
  return (
132
140
  <TableRow key={billableService}>
@@ -180,12 +188,13 @@ const BillingForm: React.FC<BillingFormProps> = ({ closeWorkspace }) => {
180
188
  <TableCell id={service?.name + 'Delete'}>
181
189
  <Button
182
190
  renderIcon={TrashCan}
191
+ iconDescription={t('delete', 'Delete')}
183
192
  kind="danger"
184
193
  hasIconOnly
185
194
  onClick={() => {
186
195
  form.setValue(
187
196
  'lineItems',
188
- lineItemsOnservable.filter((item) => item.billableService !== billableService),
197
+ lineItemsToWatch.filter((item) => item.billableService !== billableService),
189
198
  );
190
199
  }}
191
200
  />
@@ -198,11 +207,11 @@ const BillingForm: React.FC<BillingFormProps> = ({ closeWorkspace }) => {
198
207
  <TableCell></TableCell>
199
208
  <TableCell></TableCell>
200
209
 
201
- <TableCell style={{ fontWeight: 'bold' }}>Grand Total:</TableCell>
210
+ <TableCell style={{ fontWeight: 'bold' }}>{t('grandTotal', 'Grand Total')}:</TableCell>
202
211
  <TableCell id="GrandTotalSum">
203
- {lineItemsOnservable.reduce((prev, curr) => {
204
- const totoal = curr.quantity * curr.price;
205
- return prev + totoal;
212
+ {lineItemsToWatch.reduce((prev, curr) => {
213
+ const total = curr.quantity * curr.price;
214
+ return prev + total;
206
215
  }, 0)}
207
216
  </TableCell>
208
217
  <TableCell></TableCell>
@@ -213,7 +222,7 @@ const BillingForm: React.FC<BillingFormProps> = ({ closeWorkspace }) => {
213
222
  </Stack>
214
223
 
215
224
  <ButtonSet className={styles.buttonSet}>
216
- <Button className={styles.button} kind="secondary" onClick={closeWorkspace}>
225
+ <Button className={styles.button} kind="secondary" onClick={() => closeWorkspace()}>
217
226
  {t('discard', 'Discard')}
218
227
  </Button>
219
228
  <Button className={styles.button} kind="primary" type="submit" disabled={form.formState.isSubmitting}>
@@ -1,6 +1,8 @@
1
+ @use '@carbon/colors';
1
2
  @use '@carbon/layout';
2
3
 
3
- .clockInSkeleton,
4
- .clockIn {
5
- margin-right: layout.$spacing-05;
4
+ .tabsContainer {
5
+ border: 1px solid colors.$gray-20;
6
+ margin: layout.$spacing-05;
7
+ padding-top: layout.$spacing-05;
6
8
  }
@@ -1,15 +1,15 @@
1
- import { Button, ButtonSkeleton, Tab, TabList, TabPanel, TabPanels, Tabs } from '@carbon/react';
2
- import { IbmCloudLogging } from '@carbon/react/icons';
3
- import { showModal } from '@openmrs/esm-framework';
4
1
  import React, { useState } from 'react';
5
2
  import { useTranslation } from 'react-i18next';
3
+ import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@carbon/react';
4
+ import { List, Search, BaggageClaim, TwoFactorAuthentication } from '@carbon/react/icons';
5
+
6
6
  import BillsTable from '../bills-table/bills-table.component';
7
7
  import PatientBillsScreen from '../past-patient-bills/patient-bills-dashboard/patient-bills-dashboard';
8
- import { useClockInStatus } from '../bill-administration/payment-points/use-clock-in-status';
9
- import styles from './billing-tabs.scss';
10
8
  import ClaimsManagementTable from '../claims/claims-management/table/claims-list-table.component';
11
9
  import PreauthTableTemporary from '../claims/claims-management/table/preauth-table.tmp.component';
12
10
 
11
+ import styles from './billing-tabs.scss';
12
+
13
13
  const BillingTabs = () => {
14
14
  const { t } = useTranslation();
15
15
  const [activeTabIndex, setActiveTabIndex] = useState<number>(0);
@@ -18,44 +18,23 @@ const BillingTabs = () => {
18
18
  setActiveTabIndex(selectedIndex);
19
19
  };
20
20
 
21
- const { isClockedIn, isLoading } = useClockInStatus();
22
-
23
- const openClockInModal = () => {
24
- const dispose = showModal('clock-in-modal', {
25
- closeModal: () => dispose(),
26
- });
27
- };
28
-
29
21
  return (
30
- <div data-testid="BillingsList-list">
22
+ <div className={styles.tabsContainer} data-testid="BillingsList-list">
31
23
  <Tabs selectedIndex={activeTabIndex} onChange={handleTabChange}>
32
24
  <div style={{ display: 'flex' }}>
33
- <TabList style={{ paddingLeft: '1rem' }} aria-label="Billing tabs" contained>
34
- <Tab>{t('todayBills', "Today's bills")}</Tab>
35
- <Tab>{t('patientBills', 'Patient Bill')}</Tab>
36
- <Tab>{t('claims', 'Claims')}</Tab>
37
- <Tab>{t('preAuth', 'Pre-Authorization')}</Tab>
25
+ <TabList style={{ paddingLeft: '1rem' }} aria-label={t('billingTabs', 'Billing tabs')} contained>
26
+ <Tab renderIcon={Search}>{t('patientBills', 'Patient Bills')}</Tab>
27
+ <Tab renderIcon={List}>{t('billsToday', 'Bills Today')}</Tab>
28
+ <Tab renderIcon={BaggageClaim}>{t('claims', 'Claims')}</Tab>
29
+ <Tab renderIcon={TwoFactorAuthentication}>{t('preAuth', 'Pre-Authorization')}</Tab>
38
30
  </TabList>
39
- {isLoading ? (
40
- <ButtonSkeleton className={styles.clockInSkeleton} />
41
- ) : (
42
- !isClockedIn && (
43
- <Button
44
- onClick={openClockInModal}
45
- className={styles.clockIn}
46
- renderIcon={IbmCloudLogging}
47
- iconDescription="Clock In">
48
- Clock In
49
- </Button>
50
- )
51
- )}
52
31
  </div>
53
32
  <TabPanels>
54
33
  <TabPanel>
55
- <BillsTable />
34
+ <PatientBillsScreen />
56
35
  </TabPanel>
57
36
  <TabPanel>
58
- <PatientBillsScreen />
37
+ <BillsTable />
59
38
  </TabPanel>
60
39
  <TabPanel>
61
40
  <ClaimsManagementTable />
@@ -1,4 +1,4 @@
1
- import React, { Dispatch, SetStateAction } from 'react';
1
+ import React, { Dispatch, SetStateAction, useEffect, useMemo } from 'react';
2
2
  import {
3
3
  DataTable,
4
4
  TableContainer,
@@ -11,15 +11,18 @@ import {
11
11
  Button,
12
12
  InlineLoading,
13
13
  } from '@carbon/react';
14
- import { Close } from '@carbon/react/icons';
15
- import { convertToCurrency } from '../helpers';
14
+ import { Add, Close } from '@carbon/react/icons';
16
15
  import { useTranslation } from 'react-i18next';
17
- import { MappedBill } from '../types';
18
- import styles from './patient-bills.scss';
19
- import { ConfigurableLink, getPatientName, usePatient } from '@openmrs/esm-framework';
16
+ import { ConfigurableLink, getPatientName, usePatient, setCurrentVisit } from '@openmrs/esm-framework';
17
+ import { getPatientChartStore, useLaunchWorkspaceRequiringVisit } from '@openmrs/esm-patient-common-lib';
20
18
  import capitalize from 'lodash/capitalize';
19
+
20
+ import { convertToCurrency } from '../helpers';
21
+ import { type MappedBill } from '../types';
21
22
  import EmptyPatientBill from './patient-bills-dashboard/empty-patient-bill.component';
22
23
 
24
+ import styles from './patient-bills.scss';
25
+
23
26
  type PatientBillsProps = {
24
27
  patientUuid: string;
25
28
  bills: Array<MappedBill>;
@@ -125,6 +128,20 @@ export const PatientHeader: React.FC<PatientHeaderProps> = ({ patient, onCancel
125
128
  const { t } = useTranslation();
126
129
  const patientName = getPatientName(patient);
127
130
  const identifier = patient?.identifier[0]?.value ?? '--';
131
+ const state = useMemo(() => ({ patient, patientUuid: patient.id }), [patient]);
132
+ const launchPatientWorkspace = useLaunchWorkspaceRequiringVisit('billing-form');
133
+
134
+ const handleAddNewBill = () => {
135
+ setCurrentVisit(patient.id, null);
136
+ launchPatientWorkspace({ workspaceTitle: t('billingForm', 'Billing Form'), patientUuid: patient.id, patient });
137
+ };
138
+
139
+ useEffect(() => {
140
+ getPatientChartStore().setState({ ...state });
141
+ return () => {
142
+ getPatientChartStore().setState({});
143
+ };
144
+ }, [state]);
128
145
 
129
146
  return (
130
147
  <div className={styles.patientHeaderContainer}>
@@ -137,6 +154,9 @@ export const PatientHeader: React.FC<PatientHeaderProps> = ({ patient, onCancel
137
154
  <Button kind="ghost" onClick={() => onCancel('')} renderIcon={Close}>
138
155
  {t('close', 'Close')}
139
156
  </Button>
157
+ <Button kind="ghost" onClick={handleAddNewBill} renderIcon={Add}>
158
+ {t('addNewBillItem', 'Add New Bill Item')}
159
+ </Button>
140
160
  </div>
141
161
  </div>
142
162
  );
@@ -6,6 +6,7 @@
6
6
  "addBill": "የሂሳብ ዕቃ(ዎች) ይጨምሩ",
7
7
  "addCommodityChargeItem": "የክፍያ ዕቃ ይጨምሩ",
8
8
  "additionalPayment": "ተቀማጭ ክፍያ",
9
+ "addNewBillItem": "አዲስ የክፍያ ዕቃ ጨምር",
9
10
  "addPaymentMode": "Add Payment Mode",
10
11
  "addPaymentOptions": "የክፍያ አማራጭ ይጨምሩ",
11
12
  "addSchema": "ስኬማ ይጨምሩ",
@@ -40,6 +41,7 @@
40
41
  "billingForm": "የሂሳብ ቅጽ",
41
42
  "billingService": "አገልግሎት",
42
43
  "billingStatus": "የሂሳብ ሁኔታ",
44
+ "billingTabs": "የክፍያ ትሮች",
43
45
  "billItem": "የሂሳብ ዕቃ",
44
46
  "billItems": "ሂሳብ አስቀምጥ",
45
47
  "billList": "የሂሳብ ዝርዝር",
@@ -48,6 +50,7 @@
48
50
  "billPaymentRequiredMessage": "አሁን ያለው ታካሚ ቀሪ ሂሳብ አለው። ታካሚው ሂሳቡን እንዲከፍል ይመከራል።",
49
51
  "billsList": "የሂሳብ ዝርዝር",
50
52
  "billStatement": "የሂሳብ መግለጫ",
53
+ "billsToday": "የሂሳብ ቀናት",
51
54
  "billTotal": "የሂሳብ ጠቅላላ",
52
55
  "bulkUpload": "ብዛት ማስገባት",
53
56
  "cancel": "ይሰርዝ",
@@ -80,6 +83,7 @@
80
83
  "clear": "ይጽዳ",
81
84
  "clearSearch": "የፍለጋ ግቤት ይጽዳ",
82
85
  "clinicalCharges": "Clinical Charges",
86
+ "clockIn": "መቁጠሪያ ተጀመረ",
83
87
  "clockInTime": "በ{{clockInDate}} ሰዓት መቁጠሪያ ተጀመረ",
84
88
  "clockOut": "ሰዓት መውጣት",
85
89
  "close": "ይዝጋ",
@@ -145,6 +149,7 @@
145
149
  "filterTable": "ሰንጠረዥ ያጣሩ",
146
150
  "finalDiagnosis": "የመጨረሻ ምርመራ",
147
151
  "formTitle": "የቅጽ ዝርዝሮችን ይሙሉ",
152
+ "grandTotal": "ጠቅላላ ጠቅላላ",
148
153
  "hieVerificationFailure": "HIE ማረጋገጫ ውድቀት",
149
154
  "home": "ቤት",
150
155
  "identifier": "መለያ",
@@ -320,7 +325,6 @@
320
325
  "successfullyCreatedPaymentPoint": "የክፍያ ነጥብ በተሳካ ሁኔታ ተፈጥሯል",
321
326
  "switchPaymentPoint": "የክፍያ ነጥብ ያረጋግጡ",
322
327
  "timesheet": "የሰዓት ሉህ",
323
- "todayBills": "የዛሬ ሂሳቦች",
324
328
  "todayExemptedBills": "የዛሬ ነጻ የወጡ ሂሳቦች",
325
329
  "todayPaidBills": "የዛሬ የተከፈሉ ሂሳቦች",
326
330
  "todayPendingBills": "የዛሬ በመጠባበቅ ላይ ያሉ ሂሳቦች",
@@ -6,6 +6,7 @@
6
6
  "addBill": "Add bill item(s)",
7
7
  "addCommodityChargeItem": "Add charge item",
8
8
  "additionalPayment": "Additional Payment",
9
+ "addNewBillItem": "Add New Bill Item",
9
10
  "addPaymentMode": "Add Payment Mode",
10
11
  "addPaymentOptions": "Add payment option",
11
12
  "addSchema": "Add Schema",
@@ -40,6 +41,7 @@
40
41
  "billingForm": "Billing Form",
41
42
  "billingService": "Service",
42
43
  "billingStatus": "Billing status",
44
+ "billingTabs": "Billing tabs",
43
45
  "billItem": "Bill Item",
44
46
  "billItems": "Save Bill",
45
47
  "billList": "Bill list",
@@ -48,6 +50,7 @@
48
50
  "billPaymentRequiredMessage": "The current patient has pending bill. Advice patient to settle bill.",
49
51
  "billsList": "Bill list",
50
52
  "billStatement": "Bill Statement",
53
+ "billsToday": "Bills Today",
51
54
  "billTotal": "Bill total",
52
55
  "bulkUpload": "Bulk Upload",
53
56
  "cancel": "Cancel",
@@ -80,6 +83,7 @@
80
83
  "clear": "Clear",
81
84
  "clearSearch": "Clear search input",
82
85
  "clinicalCharges": "Clinical Charges",
86
+ "clockIn": "Clock In",
83
87
  "clockInTime": "Clocked in on {{clockInDate}}",
84
88
  "clockOut": "Clock Out",
85
89
  "close": "Close",
@@ -145,6 +149,7 @@
145
149
  "filterTable": "Filter table",
146
150
  "finalDiagnosis": "Final Diagnosis",
147
151
  "formTitle": "Fill in the form details",
152
+ "grandTotal": "Grand Total",
148
153
  "hieVerificationFailure": "HIE verification failure",
149
154
  "home": "Home",
150
155
  "identifier": "Identifier",
@@ -320,7 +325,6 @@
320
325
  "successfullyCreatedPaymentPoint": "Successfully created payment point",
321
326
  "switchPaymentPoint": "Switch Payment Point",
322
327
  "timesheet": "Timesheet",
323
- "todayBills": "Today's bills",
324
328
  "todayExemptedBills": "Today's Exempted Bills",
325
329
  "todayPaidBills": "Today's Paid Bills",
326
330
  "todayPendingBills": "Today's Pending Bills",