diff --git a/package.json b/package.json
index c5f2d3c..6e4a7f3 100644
--- a/package.json
+++ b/package.json
@@ -43,5 +43,7 @@
"files": [
"dist"
],
- "dependencies": {}
+ "dependencies": {
+ "react-to-print": "^2.15.1"
+ }
}
diff --git a/src/components/VoucherDetailsPanel.js b/src/components/VoucherDetailsPanel.js
index 6430d90..ad59434 100644
--- a/src/components/VoucherDetailsPanel.js
+++ b/src/components/VoucherDetailsPanel.js
@@ -1,12 +1,22 @@
-import React from 'react';
+/* eslint-disable import/no-extraneous-dependencies */
+import React, { useRef } from 'react';
+import { useReactToPrint } from 'react-to-print';
-import { Divider, Grid, Typography } from '@material-ui/core';
+import {
+ Divider, Grid, Typography, Button,
+} from '@material-ui/core';
import { makeStyles } from '@material-ui/styles';
+import PrintIcon from '@material-ui/icons/Print';
+import ReceiptIcon from '@material-ui/icons/Receipt';
-import { FormattedMessage } from '@openimis/fe-core';
+import {
+ FormattedMessage, useModulesManager, useHistory, historyPush,
+} from '@openimis/fe-core';
+import { REF_ROUTE_BILL, VOUCHER_RIGHT_SEARCH } from '../constants';
import VoucherDetailsEmployer from './VoucherDetailsEmployer';
import VoucherDetailsVoucher from './VoucherDetailsVoucher';
import VoucherDetailsWorker from './VoucherDetailsWorker';
+import VoucherDetailsPrintTemplate from './VoucherDetailsPrintTemplate';
const useStyles = makeStyles((theme) => ({
tableTitle: theme.table.title,
@@ -14,19 +24,35 @@ const useStyles = makeStyles((theme) => ({
fullHeight: {
height: '100%',
},
+ actionButtons: {
+ display: 'flex',
+ flexDirection: 'row',
+ gap: '4px',
+ },
}));
-function VoucherDetailsPanel({ workerVoucher, readOnly = true, formatMessage }) {
+function VoucherDetailsPanel({
+ workerVoucher, readOnly = true, formatMessage, rights, logo,
+}) {
+ const modulesManager = useModulesManager();
+ const history = useHistory();
+ const voucherPrintTemplateRef = useRef(null);
const classes = useStyles();
+ const handlePrint = useReactToPrint({
+ documentTitle: `${workerVoucher.code}`,
+ });
+
+ const redirectToTheLinkedBill = () => historyPush(modulesManager, history, REF_ROUTE_BILL, [workerVoucher.billId]);
+
return (
- <>
+
@@ -34,6 +60,31 @@ function VoucherDetailsPanel({ workerVoucher, readOnly = true, formatMessage })
+ {rights.includes(VOUCHER_RIGHT_SEARCH) && (
+
+ }
+ onClick={(e) => {
+ e.preventDefault();
+ handlePrint(null, () => voucherPrintTemplateRef.current);
+ }}
+ >
+ {formatMessage('workerVoucher.printVoucher')}
+
+ }
+ onClick={redirectToTheLinkedBill}
+ >
+ {formatMessage('workerVoucher.navigateToTheBill.tooltip')}
+
+
+ )}
@@ -43,17 +94,12 @@ function VoucherDetailsPanel({ workerVoucher, readOnly = true, formatMessage })
classes={classes}
formatMessage={formatMessage}
/>
-
-
- >
+
+
+
+
+
+
);
}
diff --git a/src/components/VoucherDetailsPrintTemplate.js b/src/components/VoucherDetailsPrintTemplate.js
new file mode 100644
index 0000000..9aaf458
--- /dev/null
+++ b/src/components/VoucherDetailsPrintTemplate.js
@@ -0,0 +1,140 @@
+import React, {
+ forwardRef, useState, useEffect, useMemo,
+} from 'react';
+import { useDispatch } from 'react-redux';
+
+import { Divider } from '@material-ui/core';
+import { makeStyles } from '@material-ui/styles';
+
+import { useTranslations, useModulesManager, formatDateFromISO } from '@openimis/fe-core';
+import { MODULE_NAME, REF_GET_BILL_LINE_ITEM } from '../constants';
+
+const useStyles = makeStyles(() => ({
+ topHeader: {
+ display: 'flex',
+ justifyContent: 'start',
+ alignItems: 'center',
+ width: '100%',
+
+ '& img': {
+ minWidth: '250px',
+ maxWidth: '300px',
+ width: 'auto',
+ height: 'auto',
+ },
+ },
+ printContainer: {
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ padding: '20px',
+ fontWeight: '500',
+ },
+ date: {
+ fontSize: '16px',
+ },
+ detailsContainer: {
+ display: 'flex',
+ flexDirection: 'column',
+ padding: '12px',
+ width: '100%',
+ },
+ detailRow: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ padding: '4px',
+ },
+ detailName: {
+ fontWeight: '600',
+ fontSize: '16px',
+ textTransform: 'uppercase',
+ },
+ detailValue: {
+ fontWeight: '500',
+ backgroundColor: '#f5f5f5',
+ padding: '6px',
+ borderRadius: '8px',
+ fontSize: '15px',
+ },
+ containerPadding: {
+ padding: '32px',
+ },
+ dividerMargin: {
+ margin: '12px 0',
+ },
+}));
+
+const VoucherDetailsPrintTemplate = forwardRef(({ workerVoucher, logo }, ref) => {
+ const dispatch = useDispatch();
+ const classes = useStyles();
+ const modulesManager = useModulesManager();
+ const { formatMessage } = useTranslations(modulesManager, MODULE_NAME);
+
+ const getBillLineItem = useMemo(() => modulesManager.getRef(REF_GET_BILL_LINE_ITEM), [modulesManager]);
+ const [voucherValue, setVoucherValue] = useState(null);
+
+ useEffect(() => {
+ const fetchVoucherValue = async () => {
+ try {
+ const value = await dispatch(getBillLineItem([`lineId: "${workerVoucher.uuid}"`])).then(
+ (response) => response?.payload?.data?.billItem?.edges?.[0]?.node?.unitPrice,
+ );
+
+ setVoucherValue(value);
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.error('Error fetching voucher value:', error);
+ }
+ };
+
+ fetchVoucherValue();
+ }, [dispatch, getBillLineItem, workerVoucher.uuid]);
+
+ return (
+
+
+
+
+
+
+
+
{formatMessage('workerVoucher.template.voucherCode')}
+
{workerVoucher.code}
+
+
+
{formatMessage('workerVoucher.template.status')}
+
{workerVoucher.status}
+
+
+
{formatMessage('workerVoucher.template.worker')}
+
+ {`${workerVoucher.insuree?.otherNames} ${workerVoucher.insuree?.lastName}`}
+
+
+
+
{formatMessage('workerVoucher.template.employer')}
+
+ {`${workerVoucher.policyholder?.code} ${workerVoucher.policyholder?.tradeName}`}
+
+
+
+
{formatMessage('workerVoucher.template.createdDate')}
+
{formatDateFromISO(modulesManager, null, workerVoucher.dateCreated)}
+
+
+
{formatMessage('workerVoucher.template.assignedDate')}
+
{formatDateFromISO(modulesManager, null, workerVoucher.assignedDate)}
+
+
+
{formatMessage('workerVoucher.template.valueOfVoucher')}
+
{`${formatMessage('currency')} ${voucherValue}`}
+
+
+
+ );
+});
+
+export default VoucherDetailsPrintTemplate;
diff --git a/src/constants.js b/src/constants.js
index 645b8c2..7355a3e 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -8,6 +8,7 @@ export const MODULE_NAME = 'workerVoucher';
export const REF_ROUTE_WORKER_VOUCHER = 'workerVoucher.route.workerVoucher';
export const REF_ROUTE_WORKER_VOUCHERS = 'workerVoucher.route.workerVouchers';
export const REF_ROUTE_BILL = 'bill.route.bill';
+export const REF_GET_BILL_LINE_ITEM = 'bill.action.fetchBillLineItems';
export const ECONOMIC_UNIT_STORAGE_KEY = 'userEconomicUnit';
export const MPAY_BILL_URL = '/msystems/mpay_payment/';
diff --git a/src/pages/VoucherDetailsPage.js b/src/pages/VoucherDetailsPage.js
index 70426f8..971aff0 100644
--- a/src/pages/VoucherDetailsPage.js
+++ b/src/pages/VoucherDetailsPage.js
@@ -2,14 +2,13 @@ import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { makeStyles } from '@material-ui/styles';
-import ReceiptIcon from '@material-ui/icons/Receipt';
import {
- Form, Helmet, useHistory, useModulesManager, useTranslations, historyPush,
+ Form, Helmet, useHistory, useModulesManager, useTranslations,
} from '@openimis/fe-core';
import { clearWorkerVoucher, fetchWorkerVoucher } from '../actions';
import {
- EMPTY_STRING, MODULE_NAME, REF_ROUTE_BILL, VOUCHER_RIGHT_SEARCH,
+ EMPTY_STRING, MODULE_NAME, VOUCHER_RIGHT_SEARCH,
} from '../constants';
import VoucherDetailsPanel from '../components/VoucherDetailsPanel';
@@ -17,7 +16,7 @@ const useStyles = makeStyles((theme) => ({
page: theme.page,
}));
-function VoucherDetailsPage({ match }) {
+function VoucherDetailsPage({ match, logo }) {
const classes = useStyles();
const dispatch = useDispatch();
const modulesManager = useModulesManager();
@@ -44,17 +43,6 @@ function VoucherDetailsPage({ match }) {
return () => dispatch(clearWorkerVoucher());
}, [workerVoucherUuid]);
- const redirectToTheLinkedBill = () => historyPush(modulesManager, history, REF_ROUTE_BILL, [workerVoucher.billId]);
-
- const voucherActions = [
- {
- doIt: redirectToTheLinkedBill,
- icon: ,
- disabled: !workerVoucher?.billId,
- tooltip: formatMessage('navigateToTheBill.tooltip'),
- },
- ];
-
return (
rights.includes(VOUCHER_RIGHT_SEARCH) && (
@@ -70,9 +58,9 @@ function VoucherDetailsPage({ match }) {
back={() => history.goBack()}
HeadPanel={VoucherDetailsPanel}
readOnly
+ logo={logo}
formatMessage={formatMessage}
rights={rights}
- actions={voucherActions}
/>
)
diff --git a/src/translations/en.json b/src/translations/en.json
index db8b5b8..702ee4a 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -93,5 +93,14 @@
"workerVoucher.filter.date": "Date",
"business_config.validation.date_range_overlap": "Unable to create the voucher price for the specified period. There is an existing voucher price defined within the selected date range.",
"workerVoucher.navigateToTheBill.tooltip": "Bill",
- "workerVoucher.MPayBillButton": "Pay with MPay"
+ "workerVoucher.MPayBillButton": "Pay with MPay",
+ "workerVoucher.printVoucher": "Print",
+ "workerVoucher.printVoucher.title": "Voucher {voucherCode}",
+ "workerVoucher.template.voucherCode": "Voucher Code",
+ "workerVoucher.template.status": "Status",
+ "workerVoucher.template.worker": "Worker",
+ "workerVoucher.template.employer": "Employer",
+ "workerVoucher.template.createdDate": "Created Date",
+ "workerVoucher.template.assignedDate": "Assigned Date",
+ "workerVoucher.template.valueOfVoucher": "Value of voucher"
}