Skip to content

Commit

Permalink
(feat) KHP3-7125 : Add role and privilege to control access to bill m…
Browse files Browse the repository at this point in the history
…anager function
  • Loading branch information
donaldkibet committed Nov 27, 2024
1 parent f66deb1 commit cd64b29
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 82 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { launchWorkspace } from '@openmrs/esm-framework';
import { useTranslation } from 'react-i18next';
import { OverflowMenuItem } from '@carbon/react';
import { LineItem, MappedBill } from '../../../types';

type CancelLineItemProps = {
lineItem: LineItem;
bill: MappedBill;
};

const CancelLineItem: React.FC<CancelLineItemProps> = ({ lineItem, bill }) => {
const { t } = useTranslation();
const handleCancelLineItemWorkspace = () => {
launchWorkspace('cancel-bill-workspace', {
workspaceTitle: t('cancelBillForm', 'Cancel Bill Form'),
bill,
lineItem,
});
};

return <OverflowMenuItem itemText={t('cancelItem', 'Cancel item')} onClick={handleCancelLineItemWorkspace} />;
};

export default CancelLineItem;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import { Button } from '@carbon/react';
import { TrashCan } from '@carbon/react/icons';
import { useTranslation } from 'react-i18next';
import { MappedBill } from '../../../types';
import { showModal } from '@openmrs/esm-framework';

type DeleteBillActionButtonProps = {
bill: MappedBill;
};

const DeleteBillActionButton: React.FC<DeleteBillActionButtonProps> = ({ bill }) => {
const { t } = useTranslation();
const handleOpenDeleteBillModal = (bill: MappedBill) => {
const dispose = showModal('delete-bill-modal', {
bill,
onClose: () => dispose(),
});
};

return (
<Button
onClick={() => handleOpenDeleteBillModal(bill)}
size="sm"
renderIcon={(props) => <TrashCan size={24} {...props} />}
kind="danger--ghost"
iconDescription="TrashCan">
{t('deleteBill', 'Delete Bill')}
</Button>
);
};

export default DeleteBillActionButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { launchWorkspace } from '@openmrs/esm-framework';
import React from 'react';
import { LineItem, MappedBill } from '../../../types';
import { useTranslation } from 'react-i18next';
import { OverflowMenuItem } from '@carbon/react';

type EditLineItemProps = {
lineItem: LineItem;
bill: MappedBill;
};

const EditLineItem: React.FC<EditLineItemProps> = ({ lineItem, bill }) => {
const { t } = useTranslation();
const handleOpenEditLineItemWorkspace = (lineItem: LineItem) => {
launchWorkspace('edit-bill-form', {
workspaceTitle: t('editBillForm', 'Edit Bill Form'),
lineItem,
bill,
});
};
return (
<OverflowMenuItem itemText={t('editItem', 'Edit item')} onClick={() => handleOpenEditLineItemWorkspace(lineItem)} />
);
};

export default EditLineItem;
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { OverflowMenuItem } from '@carbon/react';
import React from 'react';
import { LineItem, MappedBill } from '../../../types';
import { showModal } from '@openmrs/esm-framework';
import { useTranslation } from 'react-i18next';

type RefundLineItemProps = {
lineItem: LineItem;
bill: MappedBill;
isRefundedBillableService: boolean;
};

const RefundLineItem: React.FC<RefundLineItemProps> = ({ lineItem, bill, isRefundedBillableService }) => {
const { t } = useTranslation();
const handleOpenRefundLineItemModal = () => {
const dispose = showModal('refund-bill-modal', {
onClose: () => dispose(),
bill,
lineItem,
});
};

if (isRefundedBillableService) {
return null;
}

return <OverflowMenuItem itemText={t('refundItem', 'Refund item')} onClick={() => handleOpenRefundLineItemModal()} />;
};

export default RefundLineItem;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import { Button } from '@carbon/react';
import { useTranslation } from 'react-i18next';
import { Scalpel } from '@carbon/react/icons';
import { MappedBill } from '../../../types';
import { launchWorkspace } from '@openmrs/esm-framework';

type WaiveBillActionButtonProps = {
bill: MappedBill;
};

const WaiveBillActionButton: React.FC<WaiveBillActionButtonProps> = ({ bill }) => {
const { t } = useTranslation();

const handleOpenWaiveBillWorkspace = (bill: MappedBill) => {
launchWorkspace('waive-bill-form', {
workspaceTitle: 'Waive Bill Form',
bill: bill,
});
};
return (
<Button
size="sm"
onClick={() => handleOpenWaiveBillWorkspace(bill)}
renderIcon={(props) => <Scalpel size={24} {...props} />}
kind="danger--ghost"
iconDescription="TrashCan">
{t('waiveBill', 'Waive Bill')}
</Button>
);
};

export default WaiveBillActionButton;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React from 'react';
import {
StructuredListHead,
StructuredListRow,
Expand All @@ -7,13 +7,12 @@ import {
StructuredListWrapper,
Layer,
OverflowMenu,
OverflowMenuItem,
} from '@carbon/react';
import { useTranslation } from 'react-i18next';
import { convertToCurrency, extractString } from '../../helpers';
import { LineItem, MappedBill } from '../../types';
import styles from './bill-manager.scss';
import { launchWorkspace, showModal } from '@openmrs/esm-framework';
import { ExtensionSlot } from '@openmrs/esm-framework';

const BillLineItems: React.FC<{ bill: MappedBill }> = ({ bill }) => {
const { t } = useTranslation();
Expand Down Expand Up @@ -41,6 +40,7 @@ const BillLineItems: React.FC<{ bill: MappedBill }> = ({ bill }) => {
};

const LineItemRow = ({ lineItem, bill }: { lineItem: LineItem; bill: MappedBill }) => {
const { t } = useTranslation();
const refundedLineItemUUIDs = bill.lineItems.filter((li) => Math.sign(li.price) === -1).map((li) => li.uuid);
const isRefundedLineItem = refundedLineItemUUIDs.includes(lineItem.uuid);

Expand All @@ -52,40 +52,6 @@ const LineItemRow = ({ lineItem, bill }: { lineItem: LineItem; bill: MappedBill
lineItem.billableService.split(':').at(0),
);

const { t } = useTranslation();

const handleOpenEditLineItemWorkspace = (lineItem: LineItem) => {
launchWorkspace('edit-bill-form', {
workspaceTitle: t('editBillForm', 'Edit Bill Form'),
lineItem,
bill,
});
};

const handleOpenRefundLineItemModal = (lineItem: LineItem) => {
const dispose = showModal('refund-bill-modal', {
onClose: () => dispose(),
bill,
lineItem,
});
};

const handleCancelLineItemWorkspace = () => {
launchWorkspace('cancel-bill-workspace', {
workspaceTitle: t('cancelBillForm', 'Cancel Bill Form'),
bill,
lineItem,
});
};

const handleOpenDeleteLineItemModal = (lineItem: LineItem) => {
const dispose = showModal('delete-bill-modal', {
onClose: () => dispose(),
bill,
lineItem,
});
};

return (
<StructuredListRow className={isRefundedLineItem && styles.refundedItem}>
<StructuredListCell>
Expand All @@ -96,17 +62,12 @@ const LineItemRow = ({ lineItem, bill }: { lineItem: LineItem; bill: MappedBill
<StructuredListCell>{convertToCurrency(lineItem.price * lineItem.quantity)}</StructuredListCell>
<StructuredListCell>
<OverflowMenu aria-label="overflow-menu">
<OverflowMenuItem
itemText={t('editItem', 'Edit item')}
onClick={() => handleOpenEditLineItemWorkspace(lineItem)}
<ExtensionSlot
style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', height: '7.5rem' }}
className="cds--overflow-menu-options__option"
name="bill-actions-overflow-menu-slot"
state={{ lineItem, bill, isRefundedBillableService }}
/>
<OverflowMenuItem itemText={t('cancelItem', 'Cancel item')} onClick={handleCancelLineItemWorkspace} />
{!isRefundedBillableService && (
<OverflowMenuItem
itemText={t('refundItem', 'Refund item')}
onClick={() => handleOpenRefundLineItemModal(lineItem)}
/>
)}
</OverflowMenu>
</StructuredListCell>
</StructuredListRow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const BillManager: React.FC<BillManagerProps> = () => {
[];

return (
<UserHasAccess privilege="coreapps.systemAdministration">
<>
<BillingHeader title={t('billManager', 'Bill Manager')} />
<div className={styles.billManagerContainer}>
<ExtensionSlot
Expand Down Expand Up @@ -61,7 +61,7 @@ const BillManager: React.FC<BillManagerProps> = () => {
)}
</div>
<WorkspaceContainer overlay contextKey="bill-manager" />
</UserHasAccess>
</>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { MappedBill, PaymentStatus } from '../../types';
import styles from '../../bills-table/bills-table.scss';
import BillLineItems from './bill-line-items.component';
import { Scalpel, ShoppingCartMinus, TrashCan } from '@carbon/react/icons';
import { launchWorkspace, showModal } from '@openmrs/esm-framework';
import { ExtensionSlot, launchWorkspace, showModal } from '@openmrs/esm-framework';

type PatientBillsProps = {
bills: Array<MappedBill>;
Expand Down Expand Up @@ -62,20 +62,6 @@ const PatientBills: React.FC<PatientBillsProps> = ({ bills }) => {
}),
}));

const handleOpenWaiveBillWorkspace = (bill: MappedBill) => {
launchWorkspace('waive-bill-form', {
workspaceTitle: 'Waive Bill Form',
bill,
});
};

const handleOpenDeleteBillModal = (bill: MappedBill) => {
const dispose = showModal('delete-bill-modal', {
bill,
onClose: () => dispose(),
});
};

if (bills.length === 0) {
return (
<div style={{ marginTop: '1rem' }}>
Expand Down Expand Up @@ -136,22 +122,11 @@ const PatientBills: React.FC<PatientBillsProps> = ({ bills }) => {
<TableCell key={cell.id}>{cell.value}</TableCell>
))}
<TableCell>
<Button
size="sm"
onClick={() => handleOpenWaiveBillWorkspace(bills[index])}
renderIcon={(props) => <Scalpel size={24} {...props} />}
kind="danger--ghost"
iconDescription="TrashCan">
{t('waiveBill', 'Waive Bill')}
</Button>
<Button
size="sm"
onClick={() => handleOpenDeleteBillModal(bills[index])}
renderIcon={(props) => <ShoppingCartMinus size={24} {...props} />}
kind="danger--tertiary"
iconDescription="TrashCan">
{t('deleteBill', 'Delete Bill')}
</Button>
<ExtensionSlot
name="bill-actions-slot"
style={{ display: 'flex', gap: '0.5rem' }}
state={{ bill: bills[index] }}
/>
</TableCell>
</TableExpandRow>
<TableExpandedRow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const WaiveBillForm: React.FC<BillWaiverFormProps> = ({
promptBeforeClosing,
closeWorkspaceWithSavedChanges,
}) => {
const { lineItems } = bill;
const { lineItems = [], payments = [] } = bill ?? {};
const isTablet = useLayoutType() === 'tablet';

const { t } = useTranslation();
Expand All @@ -45,7 +45,7 @@ export const WaiveBillForm: React.FC<BillWaiverFormProps> = ({
const waiverPaymentMode =
first(paymentModes.filter((mode) => mode.name.toLowerCase().includes('waiver')))?.attributeTypes ?? [];
// calculate amount already waived or paid this is to ensure that the amount to waive is not greater than the total amount
const amountAlreadyWaivedOrPaid = bill.payments.reduce((acc, curr) => acc + curr.amountTendered, 0);
const amountAlreadyWaivedOrPaid = payments.reduce((acc, curr) => acc + curr.amountTendered, 0);

const schema = z.object({
waiveAmount: z
Expand Down
10 changes: 10 additions & 0 deletions packages/esm-billing-app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ import CancelBillWorkspace from './billable-services/bill-manager/workspaces/can
import { DeleteBillableServiceModal } from './billable-services/bill-manager/modals/serviceItemCard.component';
import { DeleteBillModal } from './billable-services/bill-manager/modals/delete-bill.modal';
import ReceiptPrintPreviewModal from './invoice/print-bill-receipt/receipt-print-preview.modal';
import WaiveBillActionButton from './billable-services/bill-manager/bill-actions/waive-bill-action-button.component';
import DeleteBillActionButton from './billable-services/bill-manager/bill-actions/delete-bill-action-button.component';
import RefundLineItem from './billable-services/bill-manager/bill-actions/refund-line-item.component';
import CancelLineItem from './billable-services/bill-manager/bill-actions/cancel-line-item.component';
import EditLineItem from './billable-services/bill-manager/bill-actions/edit-line-item.component';

const moduleName = '@kenyaemr/esm-billing-app';

Expand Down Expand Up @@ -194,3 +199,8 @@ export function startupApp() {
}

export const bulkImportBillableServicesModal = getSyncLifecycle(BulkImportBillableServices, options);
export const waiveBillActionButton = getSyncLifecycle(WaiveBillActionButton, options);
export const deleteBillActionButton = getSyncLifecycle(DeleteBillActionButton, options);
export const refundLineItem = getSyncLifecycle(RefundLineItem, options);
export const cancelLineItem = getSyncLifecycle(CancelLineItem, options);
export const editLineItem = getSyncLifecycle(EditLineItem, options);
25 changes: 25 additions & 0 deletions packages/esm-billing-app/src/routes.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,31 @@
"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": [
Expand Down

0 comments on commit cd64b29

Please sign in to comment.