@kenyaemr/esm-billing-app 5.4.2-pre.2198 → 5.4.2-pre.2203

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}],"extensions":[{"component":"benefitsPackageDashboardLink","name":"benefits-package-dashboard-link","slot":"patient-chart-dashboard-slot","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","slot":"patient-chart-dashboard-slot","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":"require-billing-modal","component":"requirePaymentModal"},{"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":"billingOverviewLink","name":"billing-overview-link","order":0,"slot":"billing-dashboard-group-nav-slot"},{"component":"billDepositDashboardLink","name":"bill-deposit-dashboard-link","slot":"billing-dashboard-group-nav-slot"},{"component":"paymentHistoryLink","name":"payment-history-link","slot":"billing-dashboard-group-nav-slot"},{"component":"paymentPointsLink","name":"payment-points-link","slot":"billing-dashboard-group-nav-slot"},{"component":"paymentModesLink","name":"payment-modes-link","slot":"billing-dashboard-group-nav-slot"},{"component":"billManagerLink","name":"bill-manager-link","slot":"billing-dashboard-group-nav-slot"},{"component":"chargeableItemsLink","name":"chargeable-items-link","slot":"billing-dashboard-group-nav-slot"},{"component":"billableExemptionsLink","name":"billable-exemptions-link","slot":"billing-dashboard-group-nav-slot"},{"component":"claimsManagementOverviewDashboardLink","name":"claims-management-overview-link","order":0,"slot":"claims-management-dashboard-link-slot"},{"component":"preAuthRequestsDashboardLink","name":"preauthrequest-overview-link","slot":"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"}],"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"}],"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":"paid-bill-receipt-print-preview-modal","component":"paidBillReceiptPrintPreviewModal"},{"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"}],"version":"5.4.2-pre.2198"}
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}],"extensions":[{"component":"benefitsPackageDashboardLink","name":"benefits-package-dashboard-link","slot":"patient-chart-dashboard-slot","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","slot":"patient-chart-dashboard-slot","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":"require-billing-modal","component":"requirePaymentModal"},{"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":"billingOverviewLink","name":"billing-overview-link","order":0,"slot":"billing-dashboard-group-nav-slot"},{"component":"billDepositDashboardLink","name":"bill-deposit-dashboard-link","slot":"billing-dashboard-group-nav-slot"},{"component":"paymentHistoryLink","name":"payment-history-link","slot":"billing-dashboard-group-nav-slot"},{"component":"paymentPointsLink","name":"payment-points-link","slot":"billing-dashboard-group-nav-slot"},{"component":"paymentModesLink","name":"payment-modes-link","slot":"billing-dashboard-group-nav-slot"},{"component":"billManagerLink","name":"bill-manager-link","slot":"billing-dashboard-group-nav-slot"},{"component":"chargeableItemsLink","name":"chargeable-items-link","slot":"billing-dashboard-group-nav-slot"},{"component":"billableExemptionsLink","name":"billable-exemptions-link","slot":"billing-dashboard-group-nav-slot"},{"component":"claimsManagementOverviewDashboardLink","name":"claims-management-overview-link","order":0,"slot":"claims-management-dashboard-link-slot"},{"component":"preAuthRequestsDashboardLink","name":"preauthrequest-overview-link","slot":"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"}],"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"}],"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":"paid-bill-receipt-print-preview-modal","component":"paidBillReceiptPrintPreviewModal"},{"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"}],"version":"5.4.2-pre.2203"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenyaemr/esm-billing-app",
3
- "version": "5.4.2-pre.2198",
3
+ "version": "5.4.2-pre.2203",
4
4
  "description": "Billing app for KenyaEMR",
5
5
  "browser": "dist/kenyaemr-esm-billing-app.js",
6
6
  "main": "src/index.ts",
@@ -1,11 +1,12 @@
1
1
  import { Button, DataTableSkeleton } from '@carbon/react';
2
2
  import { ArrowRight } from '@carbon/react/icons';
3
3
  import { getPatientUuidFromStore, launchPatientWorkspace } from '@openmrs/esm-patient-common-lib';
4
- import React from 'react';
4
+ import React, { useMemo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { usePreAuthRequests } from '../../hooks/use-pre-auth-requests';
7
7
  import GenericDataTable from './generic_data_table.component';
8
8
  import { formatDate, parseDate } from '@openmrs/esm-framework';
9
+ import { useFacilityClaims } from '../../claims/claims-management/table/use-facility-claims';
9
10
 
10
11
  const headers = [
11
12
  {
@@ -39,6 +40,12 @@ const BenefitsTable = () => {
39
40
  const patientUuid = getPatientUuidFromStore();
40
41
  const { isLoading, preAuthRequests } = usePreAuthRequests();
41
42
 
43
+ const { claims, mutate } = useFacilityClaims();
44
+
45
+ const claimsByUse = useMemo(() => {
46
+ return claims.filter((claim) => claim.use === 'preauthorization' && claim.patientId === patientUuid);
47
+ }, [claims]);
48
+
42
49
  if (isLoading) {
43
50
  return (
44
51
  <DataTableSkeleton
@@ -52,7 +59,7 @@ const BenefitsTable = () => {
52
59
  />
53
60
  );
54
61
  }
55
-
62
+ //
56
63
  const handleLaunchPreAuthForm = () => {
57
64
  launchPatientWorkspace('benefits-pre-auth-form', {
58
65
  workspaceTitle: 'Pre Auth Form',
@@ -63,10 +70,10 @@ const BenefitsTable = () => {
63
70
  return (
64
71
  <>
65
72
  <GenericDataTable
66
- rows={preAuthRequests.map((r) => ({
73
+ rows={claimsByUse.map((r) => ({
67
74
  ...r,
68
- lastUpdatedAt: formatDate(parseDate(r.lastUpdatedAt)),
69
- provider: r.provider.name,
75
+ lastUpdatedAt: formatDate(parseDate(r.dateFrom)),
76
+ provider: r.provider.person.display,
70
77
  }))}
71
78
  headers={headers}
72
79
  title={t('preAuthRequests', 'Pre Auth Requests')}
@@ -19,7 +19,7 @@ import { useTranslation } from 'react-i18next';
19
19
 
20
20
  type GenericDataTableProps = {
21
21
  headers: Array<{ key: string; header: string }>;
22
- rows: Array<Record<string, any>>;
22
+ rows: any;
23
23
  title: string;
24
24
  renderActionComponent?: () => ReactNode;
25
25
  };
@@ -59,6 +59,10 @@ export const mapBillProperties = (bill: PatientInvoice): MappedBill => {
59
59
  .map((ref) => `${ref.paymentMode}: ${ref.value}`)
60
60
  .join(', '),
61
61
  adjustmentReason: bill?.adjustmentReason,
62
+ balance: bill?.balance,
63
+ totalPayments: bill?.totalPayments,
64
+ totalDeposits: bill?.totalDeposits,
65
+ totalExempted: bill?.totalExempted,
62
66
  };
63
67
 
64
68
  return mappedBill;
@@ -134,6 +138,10 @@ export const useBill = (billUuid: string) => {
134
138
  payments: bill?.payments,
135
139
  totalAmount: bill?.lineItems?.map((item) => item.price * item.quantity).reduce((prev, curr) => prev + curr, 0),
136
140
  tenderedAmount: bill?.payments?.map((item) => item.amountTendered).reduce((prev, curr) => prev + curr, 0),
141
+ totalPayments: bill?.totalPayments,
142
+ totalDeposits: bill?.totalDeposits,
143
+ totalExempted: bill?.totalExempted,
144
+ balance: bill?.balance,
137
145
  };
138
146
 
139
147
  return mappedBill;
@@ -4,7 +4,7 @@ import { FacilityClaim } from '../../../types';
4
4
 
5
5
  export const useFacilityClaims = () => {
6
6
  const customPresentation =
7
- 'custom:(uuid,claimCode,use,dateFrom,dateTo,claimedTotal,approvedTotal,status,externalId,responseUUID,provider:(display),patient:(display))';
7
+ 'custom:(uuid,claimCode,use,dateFrom,dateTo,claimedTotal,approvedTotal,status,externalId,responseUUID,provider:(person:(display),display),patient:(uuid,display))';
8
8
  const url = `${restBaseUrl}/claim?v=${customPresentation}`;
9
9
 
10
10
  const { data, error, isLoading, mutate, isValidating } = useSWR<FetchResponse<{ results: Array<FacilityClaim> }>>(
@@ -14,13 +14,15 @@ export const useFacilityClaims = () => {
14
14
 
15
15
  const formatClaim = (
16
16
  claim: FacilityClaim,
17
- ): FacilityClaim & { id: string; providerName: string; patientName: string } => ({
17
+ ): FacilityClaim & { id: string; providerName: string; patientName: string; patientId?: string } => ({
18
18
  ...claim,
19
19
  id: claim.uuid,
20
- providerName: claim.provider?.display,
20
+ providerName: claim.provider?.person?.display,
21
21
  approvedTotal: claim.approvedTotal ?? 0,
22
22
  status: claim.status,
23
23
  patientName: claim.patient?.display,
24
+ insurer: claim.insurer ?? '',
25
+ patientId: claim.patient?.uuid,
24
26
  });
25
27
 
26
28
  const formattedClaims = data?.data.results.map(formatClaim) ?? [];
@@ -23,18 +23,14 @@ import { useBill, useDefaultFacility } from '../billing.resource';
23
23
  import { spaBasePath } from '../constants';
24
24
  import { convertToCurrency } from '../helpers';
25
25
  import { usePaymentsReconciler } from '../hooks/use-payments-reconciler';
26
- import { LineItem } from '../types';
26
+ import { LineItem, MappedBill } from '../types';
27
27
  import InvoiceTable from './invoice-table.component';
28
28
  import { removeQueuedPatient, useShaFacilityStatus, useVisitQueueEntry } from './invoice.resource';
29
29
  import styles from './invoice.scss';
30
30
  import Payments from './payments/payments.component';
31
31
  import ReceiptPrintButton from './print-bill-receipt/receipt-print-button.component';
32
32
  import PrintableInvoice from './printable-invoice/printable-invoice.component';
33
-
34
- interface InvoiceDetailsProps {
35
- label: string;
36
- value: string | number;
37
- }
33
+ import capitalize from 'lodash-es/capitalize';
38
34
 
39
35
  const Invoice: React.FC = () => {
40
36
  const { t } = useTranslation();
@@ -100,14 +96,6 @@ const Invoice: React.FC = () => {
100
96
  // eslint-disable-next-line react-hooks/exhaustive-deps
101
97
  }, [bill?.lineItems?.length]);
102
98
 
103
- const invoiceDetails = {
104
- 'Total Amount': convertToCurrency(bill?.totalAmount),
105
- 'Amount Tendered': convertToCurrency(bill?.tenderedAmount),
106
- 'Invoice Number': bill.receiptNumber,
107
- 'Date And Time': formatDatetime(parseDate(bill.dateCreated), { mode: 'standard', noToday: true }),
108
- 'Invoice Status': bill?.status,
109
- };
110
-
111
99
  if (isLoadingPatient || isLoadingBill || isVisitLoading) {
112
100
  return (
113
101
  <div className={styles.invoiceContainer}>
@@ -197,13 +185,7 @@ const Invoice: React.FC = () => {
197
185
  return (
198
186
  <div className={styles.invoiceContainer}>
199
187
  {patient && patientUuid && <ExtensionSlot name="patient-header-slot" state={{ patient, patientUuid }} />}
200
- <div className={styles.detailsContainer}>
201
- <section className={styles.details}>
202
- {Object.entries(invoiceDetails).map(([key, val]) => (
203
- <InvoiceDetails key={key} label={key} value={val} />
204
- ))}
205
- </section>
206
- </div>
188
+ <InvoiceSummary bill={bill} />
207
189
  <div className={styles.actionArea}>
208
190
  <ReceiptPrintButton bill={bill} />
209
191
  <Button
@@ -256,10 +238,50 @@ const Invoice: React.FC = () => {
256
238
  );
257
239
  };
258
240
 
259
- function InvoiceDetails({ label, value }: InvoiceDetailsProps) {
241
+ function InvoiceSummary({ bill }: { readonly bill: MappedBill }) {
242
+ const { t } = useTranslation();
243
+ return (
244
+ <>
245
+ <div className={styles.invoiceSummary}>
246
+ <span className={styles.invoiceSummaryTitle}>{t('invoiceSummary', 'Invoice Summary')}</span>
247
+ </div>
248
+ <div className={styles.invoiceSummaryContainer}>
249
+ <div className={styles.invoiceCard}>
250
+ <InvoiceSummaryItem label={t('invoiceNumber', 'Invoice Number')} value={bill.receiptNumber} />
251
+ <InvoiceSummaryItem
252
+ label={t('dateAndTime', 'Date And Time')}
253
+ value={formatDatetime(parseDate(bill.dateCreated), { mode: 'standard', noToday: true })}
254
+ />
255
+ <InvoiceSummaryItem label={t('invoiceStatus', 'Invoice Status')} value={bill?.status} />
256
+ <InvoiceSummaryItem label={t('cashPoint', 'Cash Point')} value={bill?.cashPointName} />
257
+ <InvoiceSummaryItem label={t('cashier', 'Cashier')} value={capitalize(bill?.cashier?.display)} />
258
+ </div>
259
+ <div className={styles.divider} />
260
+ <div className={styles.invoiceCard}>
261
+ <InvoiceSummaryItem label={t('totalAmount', 'Total Amount')} value={convertToCurrency(bill?.totalAmount)} />
262
+ <InvoiceSummaryItem
263
+ label={t('totalExempted', 'Total Exempted')}
264
+ value={convertToCurrency(bill?.totalExempted)}
265
+ />
266
+ <InvoiceSummaryItem
267
+ label={t('totalPayments', 'Total Payments')}
268
+ value={convertToCurrency(bill?.totalPayments)}
269
+ />
270
+ <InvoiceSummaryItem
271
+ label={t('totalDeposits', 'Total Deposits')}
272
+ value={convertToCurrency(bill?.totalDeposits)}
273
+ />
274
+ <InvoiceSummaryItem label={t('balance', 'Balance')} value={convertToCurrency(bill?.balance)} />
275
+ </div>
276
+ </div>
277
+ </>
278
+ );
279
+ }
280
+
281
+ function InvoiceSummaryItem({ label, value }: { readonly label: string; readonly value: string | number }) {
260
282
  return (
261
- <div>
262
- <h1 className={styles.label}>{label}</h1>
283
+ <div className={styles.invoiceSummaryItem}>
284
+ <span className={styles.label}>{label}</span>
263
285
  <span className={styles.value}>{value}</span>
264
286
  </div>
265
287
  );
@@ -31,18 +31,6 @@
31
31
  row-gap: 1.5rem;
32
32
  }
33
33
 
34
- .label {
35
- @include type.type-style('body-compact-02');
36
- color: colors.$gray-70;
37
- margin: layout.$spacing-01;
38
- }
39
-
40
- .value {
41
- @include type.type-style('heading-03');
42
- display: inline-block;
43
- margin-top: layout.$spacing-04;
44
- }
45
-
46
34
  .backButton {
47
35
  margin: layout.$spacing-04;
48
36
 
@@ -109,3 +97,45 @@
109
97
  max-height: 2rem;
110
98
  }
111
99
  }
100
+
101
+ .invoiceSummaryContainer {
102
+ display: grid;
103
+ grid-template-columns: 1fr auto 1fr;
104
+ gap: layout.$spacing-05;
105
+ margin: 0 layout.$spacing-05 layout.$spacing-05 layout.$spacing-05;
106
+ background-color: colors.$white;
107
+ padding: layout.$spacing-05;
108
+
109
+ .divider {
110
+ width: 1px;
111
+ background-color: colors.$gray-20;
112
+ margin: 0 layout.$spacing-05;
113
+ }
114
+ }
115
+
116
+ .invoiceSummaryItem {
117
+ display: grid;
118
+ grid-template-columns: 1fr 1fr;
119
+ gap: layout.$spacing-05;
120
+ justify-content: center;
121
+
122
+ .label {
123
+ @include type.type-style('legal-02');
124
+ color: colors.$gray-70;
125
+ }
126
+
127
+ .value {
128
+ @include type.type-style('heading-01');
129
+ color: colors.$gray-70;
130
+ }
131
+ }
132
+
133
+ .invoiceSummaryTitle {
134
+ @include type.type-style('heading-01');
135
+ color: colors.$gray-70;
136
+ margin: layout.$spacing-05 layout.$spacing-05 0 layout.$spacing-05;
137
+ background-color: colors.$white;
138
+ display: block;
139
+ border-bottom: 1px solid colors.$gray-20;
140
+ padding: layout.$spacing-04;
141
+ }
@@ -5,18 +5,18 @@
5
5
  .invoiceBreakdown {
6
6
  display: grid;
7
7
  grid-template-columns: 1fr 1fr;
8
- align-items: flex-end;
8
+ align-items: flex-start;
9
9
  margin: layout.$spacing-02 0;
10
10
  }
11
11
 
12
12
  .label {
13
- @include type.type-style('heading-03');
13
+ @include type.type-style('legal-02');
14
14
  color: colors.$gray-100;
15
- text-align: end;
15
+ text-align: start;
16
16
  }
17
17
 
18
18
  .value {
19
- @extend .label;
19
+ @include type.type-style('heading-01');
20
20
  font-weight: bold;
21
21
  margin-left: layout.$spacing-03;
22
22
  text-align: start;
@@ -42,8 +42,8 @@ const Payments: React.FC<PaymentProps> = ({ bill, selectedLineItems }) => {
42
42
  });
43
43
 
44
44
  const totalWaivedAmount = computeWaivedAmount(bill);
45
- const totalAmountTendered = formValues?.reduce((curr: number, prev) => curr + Number(prev.amount), 0) ?? 0;
46
- const amountDue = Number(bill.totalAmount) - (Number(bill.tenderedAmount) + Number(totalAmountTendered));
45
+ const totalAmountTendered = formValues?.reduce((curr: number, prev) => Number(prev.amount) + curr, 0) ?? 0;
46
+ const amountDue = bill.balance - totalAmountTendered;
47
47
 
48
48
  // selected line items amount due
49
49
  const selectedLineItemsAmountDue =
@@ -148,6 +148,10 @@ const Payments: React.FC<PaymentProps> = ({ bill, selectedLineItems }) => {
148
148
  <div className={styles.divider} />
149
149
  <div className={styles.paymentTotals}>
150
150
  <InvoiceBreakDown label={t('totalAmount', 'Total Amount')} value={convertToCurrency(bill.totalAmount)} />
151
+ <InvoiceBreakDown
152
+ label={t('totalDeposits', 'Total Deposits')}
153
+ value={convertToCurrency(bill.totalDeposits)}
154
+ />
151
155
  <InvoiceBreakDown
152
156
  label={t('totalTendered', 'Total Tendered')}
153
157
  value={convertToCurrency(bill.tenderedAmount + totalAmountTendered)}
@@ -6,6 +6,8 @@ import { mockBill, mockedActiveSheet, mockLineItems, mockPaymentModes } from '..
6
6
  import { processBillPayment, usePaymentModes } from '../../billing.resource';
7
7
  import { useClockInStatus } from '../../payment-points/use-clock-in-status';
8
8
  import Payments from './payments.component';
9
+ import { LineItem, PaymentMethod } from '../../types';
10
+
9
11
  const mockProcessBillPayment = processBillPayment as jest.MockedFunction<typeof processBillPayment>;
10
12
  const mockUsePaymentModes = usePaymentModes as jest.MockedFunction<typeof usePaymentModes>;
11
13
  const mockShowSnackbar = showSnackbar as jest.MockedFunction<typeof showSnackbar>;
@@ -18,6 +20,37 @@ jest.mock('../../billing.resource', () => ({
18
20
  jest.mock('../../payment-points/use-clock-in-status');
19
21
  const mockedUseClockInStatus = useClockInStatus as jest.Mock;
20
22
 
23
+ // Update mockPaymentModes to include all required properties
24
+ const updatedMockPaymentModes: PaymentMethod[] = mockPaymentModes.map((mode) => ({
25
+ ...mode,
26
+ retireReason: null,
27
+ auditInfo: {
28
+ dateCreated: '2024-01-01',
29
+ creator: {
30
+ uuid: 'user-1',
31
+ display: 'Test User',
32
+ links: [{ rel: 'self', uri: '/ws/rest/v1/user/user-1', resourceAlias: 'user' }],
33
+ },
34
+ dateChanged: null,
35
+ changedBy: null,
36
+ },
37
+ sortOrder: null,
38
+ resourceVersion: '1.8',
39
+ }));
40
+
41
+ // Update mockLineItems to include all required properties
42
+ const updatedMockLineItems: LineItem[] = mockLineItems.map((item) => ({
43
+ ...item,
44
+ itemOrServiceConceptUuid: 'concept-uuid-1',
45
+ serviceTypeUuid: 'servicetype-uuid-1',
46
+ order: {
47
+ uuid: 'order-uuid-1',
48
+ display: item.billableService.split(':')[1],
49
+ links: [],
50
+ type: 'testorder',
51
+ },
52
+ }));
53
+
21
54
  describe('Payment', () => {
22
55
  test('should display error when posting payment fails', async () => {
23
56
  const user = userEvent.setup();
@@ -33,7 +66,7 @@ describe('Payment', () => {
33
66
  };
34
67
  mockProcessBillPayment.mockRejectedValueOnce(mockFieldErrorResponse);
35
68
  mockUsePaymentModes.mockReturnValue({
36
- paymentModes: mockPaymentModes,
69
+ paymentModes: updatedMockPaymentModes,
37
70
  isLoading: false,
38
71
  error: null,
39
72
  mutate: jest.fn(),
@@ -48,7 +81,7 @@ describe('Payment', () => {
48
81
  isClockedInCurrentPaymentPoint: false,
49
82
  });
50
83
 
51
- render(<Payments bill={mockBill as any} selectedLineItems={mockLineItems} />);
84
+ render(<Payments bill={mockBill as any} selectedLineItems={updatedMockLineItems} />);
52
85
  const addPaymentMethod = screen.getByRole('button', { name: /Add payment option/i });
53
86
  await user.click(addPaymentMethod);
54
87
  await user.click(screen.getByRole('combobox', { name: /Payment method/i }));
@@ -72,8 +105,13 @@ describe('Payment', () => {
72
105
  display: 'BillLineItem',
73
106
  item: 'c15d25b9-12bb-441d-9241-cae541dd4575',
74
107
  lineItemOrder: 0,
75
- order: null,
76
- paymentStatus: 'PAID',
108
+ order: {
109
+ uuid: 'order-uuid-1',
110
+ display: 'Medical Certificate',
111
+ links: [],
112
+ type: 'testorder',
113
+ },
114
+ paymentStatus: 'PENDING',
77
115
  price: 500,
78
116
  priceName: 'Default',
79
117
  priceUuid: '',
@@ -82,14 +120,21 @@ describe('Payment', () => {
82
120
  uuid: '314c25fd-2c90-4a7f-9f98-c99cd3f153e8',
83
121
  voidReason: null,
84
122
  voided: false,
123
+ itemOrServiceConceptUuid: 'concept-uuid-1',
124
+ serviceTypeUuid: 'servicetype-uuid-1',
85
125
  },
86
126
  {
87
127
  billableService: '04be5832-5440-44d0-83d2-5c0dfd0ac7de',
88
128
  display: 'BillLineItem',
89
129
  item: '04be5832-5440-44d0-83d2-5c0dfd0ac7de',
90
130
  lineItemOrder: 1,
91
- order: null,
92
- paymentStatus: 'PAID',
131
+ order: {
132
+ uuid: 'order-uuid-1',
133
+ display: 'Registration New',
134
+ links: [],
135
+ type: 'testorder',
136
+ },
137
+ paymentStatus: 'PENDING',
93
138
  price: 100,
94
139
  priceName: 'Default',
95
140
  priceUuid: '',
@@ -98,14 +143,21 @@ describe('Payment', () => {
98
143
  uuid: '60365e7e-d29e-4f13-b64b-9aecb5d36031',
99
144
  voidReason: null,
100
145
  voided: false,
146
+ itemOrServiceConceptUuid: 'concept-uuid-1',
147
+ serviceTypeUuid: 'servicetype-uuid-1',
101
148
  },
102
149
  {
103
150
  billableService: '3f5d0684-a280-477e-a67b-2a956a1f6dca',
104
151
  display: 'BillLineItem',
105
152
  item: '3f5d0684-a280-477e-a67b-2a956a1f6dca',
106
153
  lineItemOrder: 2,
107
- order: null,
108
- paymentStatus: 'PAID',
154
+ order: {
155
+ uuid: 'order-uuid-1',
156
+ display: 'Registration Revist',
157
+ links: [],
158
+ type: 'testorder',
159
+ },
160
+ paymentStatus: 'PENDING',
109
161
  price: 50,
110
162
  priceName: 'Default',
111
163
  priceUuid: '',
@@ -114,6 +166,8 @@ describe('Payment', () => {
114
166
  uuid: '006ee634-f1cf-4552-b751-f721679527af',
115
167
  voidReason: null,
116
168
  voided: false,
169
+ itemOrServiceConceptUuid: 'concept-uuid-1',
170
+ serviceTypeUuid: 'servicetype-uuid-1',
117
171
  },
118
172
  {
119
173
  billableService: 'Hemoglobin',
@@ -153,12 +207,12 @@ describe('Payment', () => {
153
207
  test('should automatically focus on the payment method field when user clicks add payment options', async () => {
154
208
  const user = userEvent.setup();
155
209
  mockUsePaymentModes.mockReturnValue({
156
- paymentModes: mockPaymentModes,
210
+ paymentModes: updatedMockPaymentModes,
157
211
  isLoading: false,
158
212
  error: null,
159
213
  mutate: jest.fn(),
160
214
  });
161
- render(<Payments bill={mockBill as any} selectedLineItems={mockLineItems} />);
215
+ render(<Payments bill={mockBill as any} selectedLineItems={updatedMockLineItems} />);
162
216
  const addPaymentMethod = screen.getByRole('button', { name: /Add payment option/i });
163
217
  await user.click(addPaymentMethod);
164
218
 
@@ -78,6 +78,10 @@ const mockMappedBill = [
78
78
  display: 'Bill #BILL-001',
79
79
  referenceCodes: 'REF-001',
80
80
  adjustmentReason: undefined,
81
+ balance: 50.0,
82
+ totalPayments: 50.0,
83
+ totalDeposits: 50.0,
84
+ totalExempted: 50.0,
81
85
  },
82
86
  ];
83
87
 
@@ -49,12 +49,7 @@ export const checkPaymentMethodExclusion = (currentVisit: Visit | null, excluded
49
49
  };
50
50
 
51
51
  const calculateBillBalance = (bills: Array<MappedBill>): number => {
52
- const flattenBills = bills.flatMap((bill) => bill.lineItems.filter((item) => item.paymentStatus !== 'EXEMPTED'));
53
-
54
- const totalBill = flattenBills.reduce((acc, curr) => acc + curr.price * curr.quantity, 0);
55
- const totalPayments = bills.flatMap((bill) => bill.payments).reduce((acc, curr) => acc + curr.amountTendered, 0);
56
-
57
- return totalBill - totalPayments;
52
+ return bills.reduce((acc, curr) => acc + curr.balance, 0);
58
53
  };
59
54
 
60
55
  /**
@@ -22,6 +22,10 @@ export interface MappedBill {
22
22
  display?: string;
23
23
  referenceCodes?: string;
24
24
  adjustmentReason?: string;
25
+ totalPayments?: number;
26
+ totalDeposits?: number;
27
+ totalExempted?: number;
28
+ balance?: number;
25
29
  }
26
30
 
27
31
  interface LocationLink {
@@ -137,6 +141,10 @@ export interface PatientInvoice {
137
141
  adjustmentReason: any;
138
142
  id: number;
139
143
  resourceVersion: string;
144
+ totalPayments?: number;
145
+ totalDeposits?: number;
146
+ totalExempted?: number;
147
+ balance?: number;
140
148
  }
141
149
 
142
150
  export interface PatientDetails {
@@ -547,10 +555,12 @@ export type FacilityClaim = {
547
555
  status: 'REJECTED' | 'ENTERED' | 'CHECKED' | 'VALUATED' | 'ERRORED';
548
556
  provider: {
549
557
  display: string;
558
+ person?: { display?: string };
550
559
  } | null;
551
- patient?: { display: string };
560
+ patient?: { display: string; uuid?: string };
552
561
  externalId: string;
553
562
  responseUUID: string;
563
+ insurer?: string;
554
564
  };
555
565
  export type BillingPromptType = 'patient-chart' | 'billing-orders';
556
566
 
@@ -24,6 +24,7 @@
24
24
  "attributeRequired": "Attribute required",
25
25
  "attributeRetired": "Attribute retired",
26
26
  "attributeRetiredReason": "Attribute retired reason",
27
+ "balance": "Balance",
27
28
  "benefits": "Benefits",
28
29
  "billableExemptionAdministration": "Exemption Administration",
29
30
  "billableServicesError": "Billable services error",
@@ -53,6 +54,7 @@
53
54
  "cancelItem": "Cancel item",
54
55
  "cancelled": "Cancelled",
55
56
  "cashier": "Cashier",
57
+ "cashPoint": "Cash Point",
56
58
  "cashPointName": "Cash Point Name",
57
59
  "chargeItem": "Charge items table",
58
60
  "chargeItems": "Charge Items",
@@ -81,6 +83,7 @@
81
83
  "createNewDeposit": "Create a new deposit for this patient",
82
84
  "creating": "Creating",
83
85
  "date": "Date of Claim",
86
+ "dateAndTime": "Date And Time",
84
87
  "dateCreated": "Date Created",
85
88
  "delete": "Delete",
86
89
  "deleteBill": "Delete Bill",
@@ -146,6 +149,9 @@
146
149
  "invalidJsonError": "Invalid JSON received for the schema.",
147
150
  "invoice": "Invoice",
148
151
  "invoiceError": "Invoice error",
152
+ "invoiceNumber": "Invoice Number",
153
+ "invoiceStatus": "Invoice Status",
154
+ "invoiceSummary": "Invoice Summary",
149
155
  "isPatientExemptedLegend": "Is patient exempted from payment?",
150
156
  "item": "Item",
151
157
  "items": "Items",
@@ -289,6 +295,9 @@
289
295
  "timesheet": "Timesheet",
290
296
  "total": "Total",
291
297
  "totalAmount": "Total Amount",
298
+ "totalDeposits": "Total Deposits",
299
+ "totalExempted": "Total Exempted",
300
+ "totalPayments": "Total Payments",
292
301
  "totalTendered": "Total Tendered",
293
302
  "transactionHistory": "Transaction History",
294
303
  "transactionList": "Transaction List",