Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feat) SJT-130 Replace the clock in and clock out module with the download button on payment point #114

Merged
merged 6 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/esm-billing-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ehospital/esm-billing-app",
"version": "1.2.4",
"version": "1.2.7",
"description": "Billing frontend module for use in O3",
"browser": "dist/ehospital-esm-billing-app.js",
"main": "src/index.ts",
Expand Down Expand Up @@ -121,5 +121,5 @@
"*.{js,jsx,ts,tsx}": "eslint --cache --fix"
},
"packageManager": "[email protected]",
"gitHead": "caab2f747b2171410773637bb6fe0a1923dab97e"
"gitHead": "6ad984b7558d3bdc3e49f86b446cfd050bc1ef4f"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
TableToolbarContent,
TableToolbarSearch,
} from '@carbon/react';
import { isDesktop, showModal, useLayoutType, usePagination } from '@openmrs/esm-framework';
import { Download } from '@carbon/react/icons';
import { isDesktop, showModal, useLayoutType, usePagination , useConfig} from '@openmrs/esm-framework';
import { usePaginationInfo } from '@openmrs/esm-patient-common-lib';
import dayjs from 'dayjs';
import React, { useState } from 'react';
Expand All @@ -26,6 +27,9 @@ import { PaymentTotals } from './payment-totals';
import { TableToolBarDateRangePicker } from './table-toolbar-date-range';
import { TimesheetsFilter } from './timesheets-filter.component';

import { exportToExcel } from '../../helpers/excelExport';
import { convertToCurrency } from '../../helpers';

export const PaymentHistoryViewer = () => {
const [dateRange, setDateRange] = useState<Array<Date>>([dayjs().startOf('day').toDate(), new Date()]);
const { paymentPointUUID } = useParams();
Expand All @@ -34,6 +38,8 @@ export const PaymentHistoryViewer = () => {
const { isClockedInCurrentPaymentPoint } = useClockInStatus(paymentPointUUID);
const { paymentPoints } = usePaymentPoints();

const {defaultCurrency} = useConfig()

const paidBillsResponse = useBills('', isOnPaymentPointPage ? '' : PaymentStatus.PAID);
const { bills } = paidBillsResponse;

Expand Down Expand Up @@ -61,19 +67,19 @@ export const PaymentHistoryViewer = () => {
setDateRange(dates);
};

const openClockInModal = () => {
const dispose = showModal('clock-in-modal', {
closeModal: () => dispose(),
paymentPoint: paymentPoints.find((paymentPoint) => paymentPoint.uuid === paymentPointUUID),
});
};
// const openClockInModal = () => {
// const dispose = showModal('clock-in-modal', {
// closeModal: () => dispose(),
// paymentPoint: paymentPoints.find((paymentPoint) => paymentPoint.uuid === paymentPointUUID),
// });
// };

const openClockOutModal = () => {
const dispose = showModal('clock-out-modal', {
closeModal: () => dispose(),
paymentPoint: paymentPoints.find((paymentPoint) => paymentPoint.uuid === paymentPointUUID),
});
};
// const openClockOutModal = () => {
// const dispose = showModal('clock-out-modal', {
// closeModal: () => dispose(),
// paymentPoint: paymentPoints.find((paymentPoint) => paymentPoint.uuid === paymentPointUUID),
// });
// };

const resetFilters = () => {
setAppliedFilters([]);
Expand All @@ -89,6 +95,44 @@ export const PaymentHistoryViewer = () => {
setAppliedTimesheet(sheet);
};

const transformedRows = results.map((row) => {
return {
...row,
totalAmount: convertToCurrency(row.payments.reduce((acc, payment) => acc + payment.amountTendered, 0), defaultCurrency),
referenceCodes: row.payments.map(({ attributes }) => attributes.map(({ value }) => value).join(' ')).join(', '),
};
});

const handleExport = () => {
const dataForExport = results.map((row) => {
return {
...row,
totalAmount: convertToCurrency(row.payments.reduce((acc, payment) => acc + payment.amountTendered, 0), defaultCurrency),
};
});
const data = dataForExport.map((row: (typeof transformedRows)[0]) => {
return {
'Receipt Number': row.receiptNumber,
'Patient ID': row.identifier,
'Patient Name': row.patientName,
'Mode of Payment': row.payments
.map((payment: (typeof row.payments)[0]) => payment.instanceType.name)
.join(', '),
'Total Amount Due': row.lineItems.reduce((acc, item) => acc + item.price, 0),
'Date of Payment': dayjs(row.payments[0].dateCreated).format('DD-MM-YYYY'),
'Total Amount Paid': row.payments.reduce((acc, payment) => acc + payment.amountTendered, 0),
'Reason/Reference': row.payments
.map(({ attributes }) => attributes.map(({ value }) => value).join(' '))
.join(', '),
};
});

exportToExcel(data, {
fileName: `Transaction History - ${dayjs().format('DDD-MMM-YYYY:HH-mm-ss')}`,
sheetName: t('paymentHistory', 'Payment History'),
});
};

return (
<div className={styles.table}>
<PaymentTotals renderedRows={renderedRows} appliedFilters={appliedFilters} />
Expand All @@ -115,7 +159,7 @@ export const PaymentHistoryViewer = () => {
dateRange={dateRange}
/>
<TableToolBarDateRangePicker onChange={handleFilterByDateRange} currentValues={dateRange} />
{isOnPaymentPointPage && !isClockedInCurrentPaymentPoint && (
{/* {isOnPaymentPointPage && !isClockedInCurrentPaymentPoint && (
<Button className={styles.clockIn} onClick={openClockInModal}>
Clock In
</Button>
Expand All @@ -124,7 +168,10 @@ export const PaymentHistoryViewer = () => {
<Button className={styles.clockIn} onClick={openClockOutModal} kind="danger">
Clock Out
</Button>
)}
)} */}
<Button className={styles.clockIn} size={responsiveSize} renderIcon={Download} iconDescription="Download" onClick={handleExport}>
{t('download', 'Download')}
</Button>
</TableToolbarContent>
</TableToolbar>
</div>
Expand Down
31 changes: 31 additions & 0 deletions packages/esm-billing-app/src/helpers/excelExport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as XLSX from 'xlsx';

interface ExcelExportOptions {
fileName?: string;
sheetName?: string;
compression?: boolean;
}

/**
* Generic function to export any data to Excel
* @param data - Array of objects to export
* @param options - Export configuration options
*/
export async function exportToExcel<T>(data: Array<T>, options: ExcelExportOptions = {}): Promise<void> {
const { fileName = 'Export', sheetName = 'Sheet1', compression = true } = options;

try {
// Convert data to worksheet
const worksheet = XLSX.utils.json_to_sheet(data);

// Create workbook and append worksheet
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);

// Write file
XLSX.writeFile(workbook, `${fileName}.xlsx`, { compression });
} catch (error) {
console.error('Error exporting to Excel:', error);
throw new Error('Failed to export data to Excel');
}
}
2 changes: 1 addition & 1 deletion packages/esm-billing-app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export const billableServicesAppMenuItem = getSyncLifecycle(appMenu, options);

export const createPaymentPoint = getSyncLifecycle(CreatePaymentPoint, options);

export const drugOrder = getSyncLifecycle(DrugOrder, options);
// export const drugOrder = getSyncLifecycle(DrugOrder, options);
export const labOrder = getSyncLifecycle(LabOrder, options);
export const procedureOrder = getSyncLifecycle(ProcedureOrder, options);
export const priceInfoOrder = getSyncLifecycle(PriceInfoOrder, options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import React from 'react';
import BillingHeader from '../billing-header/billing-header.component';
import { useTranslation } from 'react-i18next';
import PaymentModeDashboard from './payment-mode-dashboard.component';
import LeftPanel from '../left-panel/left-panel.component';

type PaymentModeHomeProps = {};

const PaymentModeHome: React.FC<PaymentModeHomeProps> = () => {
const { t } = useTranslation();
return (
<>
<LeftPanel />
<BillingHeader title={t('paymentModes', 'Payment Modes')} />
<PaymentModeDashboard />
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import BillingHeader from '../../billing-header/billing-header.component';
import { useParams } from 'react-router-dom';
import { usePaymentPoints } from '../payment-points.resource';
import { PaymentHistoryViewer } from '../../billable-services/payment-history/payment-history-viewer.component';
import LeftPanel from '../../left-panel/left-panel.component';

export const headers = [
{ header: 'Date', key: 'dateCreated' },
Expand All @@ -23,6 +24,7 @@ export const PaymentPoint = () => {

return (
<div>
<LeftPanel />
<BillingHeader title={`Payment Points / ${paymentPoint.name}`} />
<PaymentHistoryViewer />
</div>
Expand Down
5 changes: 0 additions & 5 deletions packages/esm-billing-app/src/routes.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,6 @@
"slot": "billing-home-tiles-slot",
"component": "serviceMetrics"
},
{
"name": "drug-order-billable-item",
"component": "drugOrder",
"slot": "medication-info-slot"
},
{
"name": "lab-order-billable-item",
"component": "labOrder",
Expand Down
Loading