Skip to content

Commit

Permalink
O3-4284 - feat/Print item transactions (Bin Card and Stock Card) - St…
Browse files Browse the repository at this point in the history
…ock Card (#250)

* first strike

* Added Bin Card Printout on Item Transactions

* Fixed recommanded areas

* Fixed logo printing

* added stock card printout

* dedup

* cleanup
  • Loading branch information
PatrickWaweru authored Dec 17, 2024
1 parent 1f3ae48 commit aea46ba
Show file tree
Hide file tree
Showing 14 changed files with 366 additions and 23 deletions.
2 changes: 2 additions & 0 deletions src/core/api/types/stockItem/StockItemTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ export interface StockItemTransactionDTO {
packagingUomName: string;
operationSourcePartyName: string;
operationDestinationPartyName: string;
patientId: number;
patientUuid: string;
}
9 changes: 7 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import StockSources from './stock-sources/stock-sources.component';
import StockLocations from './stock-locations/stock-locations.component';
import StockReports from './stock-reports/report-list/stock-reports.component';
import StockSettings from './stock-settings/stock-settings.component';
import TransactionsPrintPreview from './stock-items/add-stock-item/transactions/printout/transactions-print-preview.modal';
import TransactionsBincardPrintPreview from './stock-items/add-stock-item/transactions/printout/transactions-print-bincard-preview.modal';
import TransactionsStockcardPrintPreview from './stock-items/add-stock-item/transactions/printout/transactions-print-stockcard-preview.modal';

const moduleName = '@openmrs/esm-stock-management-app';

const options = {
Expand Down Expand Up @@ -127,7 +129,10 @@ export const deletePackagingUnitButton = getSyncLifecycle(deletePackagingUnitMod
});

export const stockManagementAppMenuItem = getSyncLifecycle(appMenu, options);
export const transactionPrintPreviewModal = getSyncLifecycle(TransactionsPrintPreview, options)

export const transactionBincardPrintPreviewModal = getSyncLifecycle(TransactionsBincardPrintPreview, options);
export const transactionStockcardPrintPreviewModal = getSyncLifecycle(TransactionsStockcardPrintPreview, options);

export function startupApp() {
defineConfigSchema(moduleName, configSchema);
}
8 changes: 6 additions & 2 deletions src/routes.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,12 @@
"component": "stockOperationModal"
},
{
"name": "transactions-print-preview-modal",
"component": "transactionPrintPreviewModal"
"name": "transactions-print-bincard-preview-modal",
"component": "transactionBincardPrintPreviewModal"
},
{
"name": "transactions-print-stockcard-preview-modal",
"component": "transactionStockcardPrintPreviewModal"
}
],
"pages": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface PrintableTransactionHeaderProps {
itemName: string;
}

const PrintableTransactionHeader: React.FC<PrintableTransactionHeaderProps> = ({ itemName }) => {
const PrintableBincardTransactionHeader: React.FC<PrintableTransactionHeaderProps> = ({ itemName }) => {
const { t } = useTranslation();
const { logo } = useConfig({ externalModuleName: '@kenyaemr/esm-login-app' });

Expand Down Expand Up @@ -49,4 +49,4 @@ const PrintableTransactionHeader: React.FC<PrintableTransactionHeaderProps> = ({
);
};

export default PrintableTransactionHeader;
export default PrintableBincardTransactionHeader;
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import styles from './printable-transaction-header.scss';
import { useConfig } from '@openmrs/esm-framework';
import { useTranslation } from 'react-i18next';
import startCase from 'lodash-es/startCase';

interface PrintableTransactionHeaderProps {
itemName: string;
}

const PrintableStockcardTransactionHeader: React.FC<PrintableTransactionHeaderProps> = ({ itemName }) => {
const { t } = useTranslation();
const { logo } = useConfig({ externalModuleName: '@kenyaemr/esm-login-app' });

return (
<div className={styles.container}>
<div className={styles.printableHeader}>
<p className={styles.heading}>{t('bincard', 'Stock Card')}</p>
{logo?.src ? (
<img className={styles.img} height={60} width={250} src={logo.src} alt={logo.alt} />
) : logo?.name ? (
logo.name
) : (
// OpenMRS Logo
<svg
className={styles.img}
role="img"
width={110}
height={40}
viewBox="0 0 380 119"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M40.29 40.328a27.755 27.755 0 0 1 19.688-8.154c7.669 0 14.613 3.102 19.647 8.116l.02-18.54A42.835 42.835 0 0 0 59.978 17c-7.089 0-13.813 1.93-19.709 4.968l.021 18.36ZM79.645 79.671a27.744 27.744 0 0 1-19.684 8.154c-7.67 0-14.614-3.101-19.651-8.116l-.02 18.54A42.857 42.857 0 0 0 59.96 103a42.833 42.833 0 0 0 19.672-4.751l.013-18.578ZM40.328 79.696c-5.038-5.037-8.154-11.995-8.154-19.685 0-7.669 3.102-14.612 8.116-19.65l-18.54-.02A42.85 42.85 0 0 0 17 60.012a42.819 42.819 0 0 0 4.752 19.672l18.576.013ZM79.634 40.289a27.753 27.753 0 0 1 8.154 19.688 27.744 27.744 0 0 1-8.117 19.646l18.542.02a42.842 42.842 0 0 0 4.749-19.666c0-7.09-1.714-13.779-4.751-19.675l-18.577-.013ZM156.184 60.002c0-8.748-6.118-15.776-15.025-15.776-8.909 0-15.025 7.028-15.025 15.776 0 8.749 6.116 15.78 15.025 15.78 8.907 0 15.025-7.031 15.025-15.78Zm-34.881 0c0-11.482 8.318-19.958 19.856-19.958 11.536 0 19.855 8.477 19.855 19.959 0 11.484-8.319 19.964-19.855 19.964-11.538 0-19.856-8.48-19.856-19.965ZM179.514 75.54c5.507 0 9.05-4.14 9.05-9.482 0-5.341-3.543-9.483-9.05-9.483-5.505 0-9.046 4.142-9.046 9.483 0 5.342 3.541 9.482 9.046 9.482ZM166.22 53.306h4.248v3.704h.11c2.344-2.725 5.449-4.36 9.154-4.36 8.014 0 13.408 5.67 13.408 13.408 0 7.63-5.613 13.406-12.752 13.406-4.58 0-8.231-2.29-9.81-5.178h-.11V90.87h-4.248V53.306ZM217.773 63.768c-.163-4.305-3-7.193-7.686-7.193-4.685 0-7.79 2.888-8.335 7.193h16.021Zm3.653 10.412c-3.001 3.868-6.596 5.284-11.339 5.284-8.01 0-12.914-5.993-12.914-13.406 0-7.901 5.559-13.407 13.08-13.407 7.196 0 12.096 4.906 12.096 13.354v1.362h-20.597c.325 4.413 3.704 8.173 8.335 8.173 3.65 0 6.105-1.307 8.12-3.868l3.219 2.508ZM227.854 59.356c0-2.346-.216-4.36-.216-6.05h4.031c0 1.363.11 2.777.11 4.195h.11c1.144-2.505 4.306-4.85 8.5-4.85 6.705 0 9.699 4.252 9.699 10.41v15.748h-4.248v-15.31c0-4.253-1.856-6.924-5.833-6.924-5.503 0-7.903 3.979-7.903 9.811V78.81h-4.25V59.356ZM259.211 41.008h6.708L278.8 70.791h.107l12.982-29.782h6.549v37.99h-4.506V47.124h-.106L280.192 79h-2.738l-13.629-31.875h-.107V79h-4.507V41.01ZM312.392 57.752h4.023c4.992 0 11.487 0 11.487-6.282 0-5.47-4.776-6.276-9.177-6.276h-6.333v12.558Zm-4.506-16.744h9.711c7.352 0 15.132 1.072 15.132 10.462 0 5.527-3.594 9.125-9.495 10.037L334.018 79h-5.525l-10.304-17.063h-5.797V79h-4.506V41.01ZM358.123 47.712c-1.506-2.413-4.187-3.486-6.926-3.486-3.973 0-8.1 1.88-8.1 6.385 0 3.49 1.931 5.047 7.994 6.98 5.903 1.878 11.377 3.809 11.377 11.267 0 7.567-6.495 11.11-13.36 11.11-4.402 0-9.125-1.45-11.7-5.262l3.862-3.165c1.61 2.794 4.83 4.24 8.105 4.24 3.862 0 8.263-2.253 8.263-6.601 0-4.669-3.165-5.474-9.928-7.728-5.366-1.771-9.442-4.134-9.442-10.463 0-7.298 6.277-10.945 12.929-10.945 4.241 0 7.836 1.178 10.625 4.45l-3.699 3.218Z"
/>
</svg>
)}
</div>

<div className={styles.printableBody}>
<div className={styles.transactionDetails}>
<p className={styles.itemHeading}>{t('itemname', 'Item Name')}</p>
<p className={styles.itemLabel}>{startCase(itemName)}</p>
</div>
</div>
</div>
);
};

export default PrintableStockcardTransactionHeader;
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
TableCell,
} from '@carbon/react';
import { useStockItem } from '../../../stock-items.resource';
import PrintableTransactionHeader from './printable-transaction-header.component';
import PrintableBincardTransactionHeader from './printable-bincard-transaction-header.component';
import PrintableTransactionFooter from './printable-transaction-footer.component';
import styles from './printable-transaction.scss';

Expand All @@ -20,10 +20,10 @@ type Props = {
data: any;
};

const TransactionsPrintout: React.FC<Props> = ({ columns, data, title }) => {
const TransactionsBincardPrintout: React.FC<Props> = ({ columns, data, title }) => {
return (
<div>
<PrintableTransactionHeader itemName={title} />
<PrintableBincardTransactionHeader itemName={title} />

<div className={styles.itemsContainer}>
<div className={styles.tableContainer}>
Expand Down Expand Up @@ -61,4 +61,4 @@ const TransactionsPrintout: React.FC<Props> = ({ columns, data, title }) => {
);
};

export default TransactionsPrintout;
export default TransactionsBincardPrintout;
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { useTranslation } from 'react-i18next';
import { useStockItem } from '../../../stock-items.resource';
import { showModal } from '@openmrs/esm-framework';
import styles from './printable-transaction.scss';
import { useEffect, useMemo, useState } from 'react';
import { StockItemInventoryFilter, useStockItemTransactions } from '../../../stock-items.resource';
import { ResourceRepresentation } from '../../../../core/api/api';

type Props = {
itemUuid: string;
Expand All @@ -15,31 +18,87 @@ type Props = {
const TransactionsPrintAction: React.FC<Props> = ({ columns, data, itemUuid }) => {
const { t } = useTranslation();

const [stockCardItemFilter, setStockCardItemFilter] = useState<StockItemInventoryFilter>({
startIndex: 0,
totalCount: true,
v: ResourceRepresentation.Full,
isPatientTransaction: 'true',
});

const { item: stockItem, isLoading: isStockItemLoading } = useStockItem(itemUuid);
const { items: stockCardData, isLoading: isStockCardLoading, error } = useStockItemTransactions(stockCardItemFilter);

const stockCardHeaders = useMemo(
() => [
{
key: 'patientId',
header: 'Patient ID',
},
{
key: 'patientName',
header: 'Patient Name',
},
{
key: 'patientIdentifier',
header: 'Patient Identifier',
},
{
key: 'date',
header: 'Date',
},
{
key: 'location',
header: 'Location',
},
{
key: 'transaction',
header: 'Transaction',
},
{
key: 'totalout',
header: 'OUT',
},
{
key: 'batch',
header: 'Batch',
},
],
[],
);

const handleClick = () => {
// stockItem.drugName || stockItem.conceptName || ''
const dispose = showModal('transactions-print-preview-modal', {
const handleBincardClick = () => {
const dispose = showModal('transactions-print-bincard-preview-modal', {
onClose: () => dispose(),
title: stockItem.drugName || stockItem.conceptName || '',
columns,
data,
});
};

const handleStockcardClick = () => {
const dispose = showModal('transactions-print-stockcard-preview-modal', {
onClose: () => dispose(),
title: stockItem.drugName || stockItem.conceptName || '',
columns: stockCardHeaders,
data: stockCardData.results,
});
};

return (
<>
<ComboButton label="Print">
<MenuItem
label={t('printStockCard', 'Print Stock Card')}
renderIcon={(props) => <Printer size={24} {...props} />}
iconDescription="Print Stock Card"
onClick={handleStockcardClick}
disabled={isStockItemLoading || isStockCardLoading}
/>
<MenuItem
label={t('printBinCard', 'Print Bin Card')}
renderIcon={(props) => <Printer size={24} {...props} />}
iconDescription="Print Bin Card"
onClick={handleClick}
onClick={handleBincardClick}
disabled={isStockItemLoading}
/>
</ComboButton>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useRef } from 'react';
import TransactionsPrintout from './transactions-printout.component';
import TransactionsBincardPrintout from './transactions-bincard-printout.component';
import { ModalBody, ModalHeader, ModalFooter, Button } from '@carbon/react';
import { useTranslation } from 'react-i18next';
import { useReactToPrint } from 'react-to-print';
Expand All @@ -8,9 +8,10 @@ type Props = {
title?: string;
columns: any;
data: any;
binOrStockCard: number;
};

const TransactionsPrintPreview: React.FC<Props> = ({ onClose, title, columns, data }) => {
const TransactionsBincardPrintPreview: React.FC<Props> = ({ onClose, title, columns, data, binOrStockCard }) => {
const { t } = useTranslation();
const ref = useRef<HTMLDivElement>(null);

Expand All @@ -22,7 +23,7 @@ const TransactionsPrintPreview: React.FC<Props> = ({ onClose, title, columns, da
<ModalHeader closeModal={onClose} title={t('printbincard', 'Print Bin Card')} />
<ModalBody>
<div ref={ref}>
<TransactionsPrintout title={title} columns={columns} data={data} />
<TransactionsBincardPrintout title={title} columns={columns} data={data} />
</div>
</ModalBody>
<ModalFooter>
Expand All @@ -37,4 +38,4 @@ const TransactionsPrintPreview: React.FC<Props> = ({ onClose, title, columns, da
);
};

export default TransactionsPrintPreview;
export default TransactionsBincardPrintPreview;
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { useRef } from 'react';
import TransactionsBincardPrintout from './transactions-bincard-printout.component';
import TransactionsStockcardPrintout from './transactions-stockcard-printout.component';
import { ModalBody, ModalHeader, ModalFooter, Button } from '@carbon/react';
import { useTranslation } from 'react-i18next';
import { useReactToPrint } from 'react-to-print';
type Props = {
onClose?: () => void;
title?: string;
columns: any;
data: any;
};

const TransactionsStockcardPrintPreview: React.FC<Props> = ({ onClose, title, columns, data }) => {
const { t } = useTranslation();
const ref = useRef<HTMLDivElement>(null);

const handlePrint = useReactToPrint({
content: () => ref.current,
});
return (
<>
<ModalHeader closeModal={onClose} title={t('printbincard', 'Print Stock Card')} />
<ModalBody>
<div ref={ref}>
<TransactionsStockcardPrintout title={title} columns={columns} items={data} />
</div>
</ModalBody>
<ModalFooter>
<Button kind="secondary" onClick={onClose}>
{t('cancel', 'Cancel')}
</Button>
<Button type="button" onClick={handlePrint}>
{t('print', 'Print')}
</Button>
</ModalFooter>
</>
);
};

export default TransactionsStockcardPrintPreview;
Loading

0 comments on commit aea46ba

Please sign in to comment.