@kenyaemr/esm-billing-app 5.4.1-pre.1936 → 5.4.1-pre.1945

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.
Files changed (38) hide show
  1. package/.turbo/turbo-build.log +65 -65
  2. package/dist/300.js +1 -1
  3. package/dist/423.js +1 -0
  4. package/dist/423.js.map +1 -0
  5. package/dist/{308.js → 610.js} +1 -1
  6. package/dist/610.js.map +1 -0
  7. package/dist/917.js +2 -0
  8. package/dist/917.js.map +1 -0
  9. package/dist/kenyaemr-esm-billing-app.js +1 -1
  10. package/dist/kenyaemr-esm-billing-app.js.buildmanifest.json +71 -71
  11. package/dist/kenyaemr-esm-billing-app.js.map +1 -1
  12. package/dist/main.js +2 -2
  13. package/dist/main.js.map +1 -1
  14. package/dist/routes.json +1 -1
  15. package/package.json +1 -1
  16. package/src/benefits-package/forms/packages-and-interventions-form.component.tsx +15 -2
  17. package/src/billable-services/billiable-item/order-actions/components/base-order-button.component.tsx +42 -0
  18. package/src/billable-services/billiable-item/order-actions/components/lab-order-button.component.tsx +51 -0
  19. package/src/billable-services/billiable-item/order-actions/components/medication-order-button.component.tsx +84 -0
  20. package/src/billable-services/billiable-item/order-actions/components/order-action-button.component.tsx +29 -0
  21. package/src/billable-services/billiable-item/order-actions/hooks/useBillStatus.ts +12 -0
  22. package/src/billable-services/billiable-item/order-actions/hooks/useLabOrderAction.ts +27 -0
  23. package/src/billable-services/billiable-item/order-actions/hooks/useMedicationOrderAction.ts +106 -0
  24. package/src/billable-services/billiable-item/order-actions/hooks/useModalHandler.ts +66 -0
  25. package/src/billable-services/billiable-item/order-actions/styles/order-action.scss +0 -0
  26. package/src/claims/dashboard/form/claims-explanation-and-justification-form-input.component.tsx +120 -0
  27. package/src/claims/dashboard/form/claims-form.component.tsx +3 -40
  28. package/src/index.ts +2 -2
  29. package/src/routes.json +3 -3
  30. package/translations/en.json +2 -5
  31. package/dist/138.js +0 -2
  32. package/dist/138.js.map +0 -1
  33. package/dist/308.js.map +0 -1
  34. package/dist/614.js +0 -1
  35. package/dist/614.js.map +0 -1
  36. package/src/billable-services/billiable-item/test-order/test-order-action.component.tsx +0 -134
  37. package/src/billable-services/billiable-item/test-order/test-order-action.test.tsx +0 -178
  38. /package/dist/{138.js.LICENSE.txt → 917.js.LICENSE.txt} +0 -0
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":"billingDashboardLink","name":"billing-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"billing","title":"billing","slot":"billing-dashboard-slot"}},{"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":"billing-test-order-action","component":"testOrderAction","slot":"tests-ordered-actions-slot","order":0},{"component":"billingOverviewLink","name":"billing-overview-link","order":0,"slot":"billing-dashboard-link-slot"},{"component":"paymentHistoryLink","name":"payment-history-link","slot":"billing-dashboard-link-slot"},{"component":"paymentPointsLink","name":"payment-points-link","slot":"billing-dashboard-link-slot"},{"component":"paymentModesLink","name":"payment-modes-link","slot":"billing-dashboard-link-slot"},{"component":"billManagerLink","name":"bill-manager-link","slot":"billing-dashboard-link-slot"},{"component":"chargeableItemsLink","name":"chargeable-items-link","slot":"billing-dashboard-link-slot"},{"component":"billableExemptionsLink","name":"billable-exemptions-link","slot":"billing-dashboard-link-slot"},{"component":"claimsManagementSideNavGroup","name":"claims-management-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"claims-management","title":"Claims management Overview","slot":"case-management-slot"},"featureFlag":"healthInformationExchange"},{"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":"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"}],"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":"retry-claim-request-modal","component":"retryClaimRequestModal"},{"name":"paid-bill-receipt-print-preview-modal","component":"paidBillReceiptPrintPreviewModal"},{"name":"clock-in-modal","component":"clockIn"},{"name":"create-bill-item-modal","component":"createBillItemModal"}],"version":"5.4.1-pre.1936"}
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":"billingDashboardLink","name":"billing-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"billing","title":"billing","slot":"billing-dashboard-slot"}},{"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","slot":"prescription-action-button-slot","order":0},{"component":"billingOverviewLink","name":"billing-overview-link","order":0,"slot":"billing-dashboard-link-slot"},{"component":"paymentHistoryLink","name":"payment-history-link","slot":"billing-dashboard-link-slot"},{"component":"paymentPointsLink","name":"payment-points-link","slot":"billing-dashboard-link-slot"},{"component":"paymentModesLink","name":"payment-modes-link","slot":"billing-dashboard-link-slot"},{"component":"billManagerLink","name":"bill-manager-link","slot":"billing-dashboard-link-slot"},{"component":"chargeableItemsLink","name":"chargeable-items-link","slot":"billing-dashboard-link-slot"},{"component":"billableExemptionsLink","name":"billable-exemptions-link","slot":"billing-dashboard-link-slot"},{"component":"claimsManagementSideNavGroup","name":"claims-management-dashboard-link","slot":"homepage-dashboard-slot","meta":{"name":"claims-management","title":"Claims management Overview","slot":"case-management-slot"},"featureFlag":"healthInformationExchange"},{"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":"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"}],"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":"retry-claim-request-modal","component":"retryClaimRequestModal"},{"name":"paid-bill-receipt-print-preview-modal","component":"paidBillReceiptPrintPreviewModal"},{"name":"clock-in-modal","component":"clockIn"},{"name":"create-bill-item-modal","component":"createBillItemModal"}],"version":"5.4.1-pre.1945"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenyaemr/esm-billing-app",
3
- "version": "5.4.1-pre.1936",
3
+ "version": "5.4.1-pre.1945",
4
4
  "description": "Billing app for KenyaEMR",
5
5
  "browser": "dist/kenyaemr-esm-billing-app.js",
6
6
  "main": "src/index.ts",
@@ -1,9 +1,9 @@
1
1
  import { Column, InlineLoading, InlineNotification, MultiSelect } from '@carbon/react';
2
- import React, { useEffect } from 'react';
2
+ import React from 'react';
3
3
  import { Controller, useFormContext } from 'react-hook-form';
4
4
  import { useTranslation } from 'react-i18next';
5
- import PackageInterventions from './interventions-form.component';
6
5
  import usePackages from '../../hooks/usePackages';
6
+ import PackageInterventions from './interventions-form.component';
7
7
 
8
8
  type Props = {
9
9
  patientUuid: string;
@@ -21,6 +21,19 @@ const SHABenefitPackangesAndInterventions: React.FC<Props> = ({ patientUuid }) =
21
21
  );
22
22
  }
23
23
 
24
+ if (packageError) {
25
+ return (
26
+ <InlineNotification
27
+ aria-label="closes notification"
28
+ kind="error"
29
+ lowContrast={true}
30
+ statusIconDescription="notification"
31
+ title={t('errorLoadingpackages', 'Error loading packages')}
32
+ subtitle={packageError?.message}
33
+ />
34
+ );
35
+ }
36
+
24
37
  return (
25
38
  <>
26
39
  <Column>
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import { InlineLoading, Button } from '@carbon/react';
3
+ import { useTranslation } from 'react-i18next';
4
+ export type BaseOrderButtonProps = {
5
+ isDisabled: boolean;
6
+ isLoading: boolean;
7
+ buttonText: string;
8
+ onClick: () => void;
9
+ kind?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'tertiary';
10
+ size?: 'sm' | 'md' | 'lg';
11
+ className?: string;
12
+ Icon?;
13
+ };
14
+
15
+ export const BaseOrderButton: React.FC<BaseOrderButtonProps> = ({
16
+ isDisabled,
17
+ isLoading,
18
+ buttonText,
19
+ onClick,
20
+ kind = 'primary',
21
+ size = 'md',
22
+ className = '',
23
+ Icon,
24
+ }) => {
25
+ const { t } = useTranslation();
26
+
27
+ return (
28
+ <Button
29
+ kind={isLoading ? 'ghost' : kind}
30
+ renderIcon={!isLoading ? Icon : undefined}
31
+ className={className}
32
+ size={size}
33
+ disabled={isLoading || isDisabled}
34
+ onClick={onClick}>
35
+ {isLoading ? (
36
+ <InlineLoading description={t('verifyingBillStatus', 'Verifying bill status...')} status="active" />
37
+ ) : (
38
+ buttonText
39
+ )}
40
+ </Button>
41
+ );
42
+ };
@@ -0,0 +1,51 @@
1
+ import React, { useCallback } from 'react';
2
+ import { showModal } from '@openmrs/esm-framework';
3
+ import { Order } from '@openmrs/esm-patient-common-lib';
4
+ import { BaseOrderButton } from './base-order-button.component';
5
+ import { useLabOrderAction } from '../hooks/useLabOrderAction';
6
+ import { useModalHandler } from '../hooks/useModalHandler';
7
+ import styles from '../styles/order-action.scss';
8
+
9
+ export interface LabOrderButtonProps {
10
+ order?: Order;
11
+ modalName?: string;
12
+ additionalProps?: Record<string, unknown>;
13
+ actionText?: string;
14
+ }
15
+
16
+ export const LabOrderButton: React.FC<LabOrderButtonProps> = ({
17
+ order,
18
+ modalName = 'pickup-lab-request-modal',
19
+ additionalProps,
20
+ actionText,
21
+ }) => {
22
+ const { isLoading, isDisabled, buttonText: defaultButtonText, isInProgress } = useLabOrderAction(order);
23
+
24
+ const { handleModalClose } = useModalHandler(additionalProps?.mutateUrl as string);
25
+ const buttonText = actionText ?? defaultButtonText;
26
+
27
+ const launchModal = useCallback(() => {
28
+ const dispose = showModal(modalName, {
29
+ closeModal: () => {
30
+ handleModalClose();
31
+ dispose();
32
+ },
33
+ order,
34
+ ...(additionalProps && { additionalProps }),
35
+ });
36
+ }, [modalName, order, additionalProps, handleModalClose]);
37
+
38
+ if (isInProgress) {
39
+ return null;
40
+ }
41
+
42
+ return (
43
+ <BaseOrderButton
44
+ isLoading={isLoading}
45
+ isDisabled={isDisabled}
46
+ buttonText={buttonText}
47
+ onClick={launchModal}
48
+ className={styles.actionButton}
49
+ />
50
+ );
51
+ };
@@ -0,0 +1,84 @@
1
+ import React, { useCallback } from 'react';
2
+ import { Edit } from '@carbon/react/icons';
3
+ import { showModal, launchWorkspace } from '@openmrs/esm-framework';
4
+ import { BaseOrderButton } from './base-order-button.component';
5
+ import { useMedicationOrderAction, useOrderByUuid } from '../hooks/useMedicationOrderAction';
6
+ import { launchPrescriptionEditWorkspace, useModalHandler } from '../hooks/useModalHandler';
7
+ import { useTranslation } from 'react-i18next';
8
+ export interface MedicationOrderButtonProps {
9
+ medicationRequestBundle?: {
10
+ request: fhir.MedicationRequest;
11
+ };
12
+ modalName?: string;
13
+ additionalProps?: Record<string, unknown>;
14
+ actionText?: string;
15
+ closeable?: boolean;
16
+ }
17
+
18
+ export const MedicationOrderButton: React.FC<MedicationOrderButtonProps> = ({
19
+ medicationRequestBundle,
20
+ modalName,
21
+ additionalProps,
22
+ actionText,
23
+ closeable = true,
24
+ }) => {
25
+ const { t } = useTranslation();
26
+ const {
27
+ isLoading: isMedicationOrderLoading,
28
+ isDisabled,
29
+ buttonText: defaultButtonText,
30
+ shouldShowBillModal,
31
+ dispenseFormProps,
32
+ patientUuid,
33
+ shouldAllowModify,
34
+ } = useMedicationOrderAction(medicationRequestBundle);
35
+ const { data: order, isLoading: isOrderLoading } = useOrderByUuid(medicationRequestBundle?.request?.id);
36
+ const isLoading = isMedicationOrderLoading && isOrderLoading;
37
+
38
+ const { handleModalClose } = useModalHandler(additionalProps?.mutateUrl as string);
39
+ const buttonText = actionText ?? defaultButtonText;
40
+
41
+ const launchModal = useCallback(() => {
42
+ if (shouldShowBillModal) {
43
+ const disposeBill = showModal(modalName ?? 'create-bill-item-modal', {
44
+ closeModal: () => {
45
+ handleModalClose();
46
+ disposeBill();
47
+ },
48
+ medicationRequestBundle,
49
+ });
50
+ return;
51
+ }
52
+
53
+ if (dispenseFormProps) {
54
+ launchWorkspace('dispense-workspace', dispenseFormProps);
55
+ }
56
+ }, [modalName, shouldShowBillModal, handleModalClose, medicationRequestBundle, dispenseFormProps]);
57
+
58
+ if (!closeable) {
59
+ return null;
60
+ }
61
+
62
+ return (
63
+ <div>
64
+ {shouldAllowModify && (
65
+ <BaseOrderButton
66
+ size="lg"
67
+ kind="tertiary"
68
+ Icon={Edit}
69
+ isLoading={isLoading}
70
+ isDisabled={false}
71
+ buttonText={t('modify', 'Modify')}
72
+ onClick={() => launchPrescriptionEditWorkspace(order, patientUuid)}
73
+ />
74
+ )}
75
+ <BaseOrderButton
76
+ size="lg"
77
+ isLoading={isLoading}
78
+ isDisabled={isDisabled}
79
+ buttonText={buttonText}
80
+ onClick={launchModal}
81
+ />
82
+ </div>
83
+ );
84
+ };
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { LabOrderButton } from './lab-order-button.component';
3
+ import { MedicationOrderButton } from './medication-order-button.component';
4
+
5
+ const OrderActionButton: React.FC<Record<string, any>> = (props) => {
6
+ if (Object.hasOwn(props, 'medicationRequestBundle')) {
7
+ const { medicationRequestBundle, modalName, additionalProps, actionText, closeable } = props;
8
+ return (
9
+ <MedicationOrderButton
10
+ medicationRequestBundle={medicationRequestBundle}
11
+ modalName={modalName}
12
+ additionalProps={additionalProps}
13
+ actionText={actionText}
14
+ closeable={closeable}
15
+ />
16
+ );
17
+ }
18
+
19
+ if (props.orderType === 'lab') {
20
+ const { order, modalName, additionalProps, actionText } = props;
21
+ return (
22
+ <LabOrderButton order={order} modalName={modalName} additionalProps={additionalProps} actionText={actionText} />
23
+ );
24
+ }
25
+
26
+ return null;
27
+ };
28
+
29
+ export default OrderActionButton;
@@ -0,0 +1,12 @@
1
+ import { useOrderBill, useTestOrderBillStatus } from '../../test-order/test-order-action.resource';
2
+
3
+ export function useBillStatus(orderUuid?: string, patientUuid?: string) {
4
+ const { isLoading, hasPendingPayment } = useTestOrderBillStatus(orderUuid, patientUuid);
5
+ const { itemHasBill } = useOrderBill(patientUuid, orderUuid);
6
+
7
+ return {
8
+ isLoading,
9
+ hasPendingPayment,
10
+ itemHasBill,
11
+ };
12
+ }
@@ -0,0 +1,27 @@
1
+ import { useTranslation } from 'react-i18next';
2
+ import { Order } from '@openmrs/esm-patient-common-lib';
3
+ import { useBillStatus } from './useBillStatus';
4
+
5
+ export enum FulfillerStatus {
6
+ IN_PROGRESS = 'IN_PROGRESS',
7
+ }
8
+
9
+ export function useLabOrderAction(order?: Order) {
10
+ const { t } = useTranslation();
11
+ const orderUuid = order?.uuid;
12
+ const patientUuid = order?.patient?.uuid;
13
+
14
+ const { isLoading, hasPendingPayment } = useBillStatus(orderUuid, patientUuid);
15
+
16
+ const isInProgress = order?.fulfillerStatus === FulfillerStatus.IN_PROGRESS;
17
+ const buttonText = hasPendingPayment ? t('unsettledBill', 'Unsettled bill') : t('pickLabRequest', 'Pick Lab Request');
18
+
19
+ return {
20
+ isLoading,
21
+ isDisabled: hasPendingPayment,
22
+ buttonText,
23
+ isInProgress,
24
+ orderUuid,
25
+ patientUuid,
26
+ };
27
+ }
@@ -0,0 +1,106 @@
1
+ import { useTranslation } from 'react-i18next';
2
+ import { useStockItemQuantity } from '../../useBillableItem';
3
+ import { useBillableServices } from '../../../billable-service.resource';
4
+
5
+ import { useBillStatus } from './useBillStatus';
6
+ import { createMedicationDispenseProps } from '../../test-order/dispense.resource';
7
+
8
+ interface MedicationRequest {
9
+ request: fhir.MedicationRequest;
10
+ }
11
+
12
+ export function useMedicationOrderAction(medicationRequestBundle?: MedicationRequest) {
13
+ const { t } = useTranslation();
14
+ const request = medicationRequestBundle?.request;
15
+ const orderUuid = request?.id;
16
+ const patientUuid = request?.subject?.reference?.split('/')[1];
17
+ const drugUuid = request?.medicationReference?.reference?.split('/')[1];
18
+
19
+ const { isLoading, hasPendingPayment, itemHasBill } = useBillStatus(orderUuid, patientUuid);
20
+ const { stockItemQuantity, stockItemUuid } = useStockItemQuantity(drugUuid);
21
+ const { billableServices } = useBillableServices();
22
+
23
+ const billableItem =
24
+ billableServices?.filter((service) => {
25
+ const stockItem = service?.stockItem.split(':')[0];
26
+ return stockItem === stockItemUuid;
27
+ }) || [];
28
+
29
+ const dispenseFormProps = medicationRequestBundle ? createMedicationDispenseProps({ medicationRequestBundle }) : null;
30
+
31
+ const shouldShowBillModal = stockItemQuantity > 0 && itemHasBill.length < 1 && billableItem.length > 0;
32
+ const isDisabled = hasPendingPayment || (stockItemQuantity < 1 && !!drugUuid);
33
+
34
+ // Modification is allowed only when:
35
+ // 1. There are no pending payments
36
+ // 2. Stock item is available (quantity > 0)
37
+ // 3. Item hasn't been billed yet (no existing bills)
38
+ // 4. Item exists in billable items list
39
+ const shouldAllowModify =
40
+ !hasPendingPayment && stockItemQuantity > 0 && itemHasBill.length < 1 && billableItem.length > 0;
41
+
42
+ const getButtonText = () => {
43
+ if (hasPendingPayment) {
44
+ return t('unsettledBill', 'Unsettled bill');
45
+ }
46
+
47
+ if (stockItemQuantity < 1 && drugUuid) {
48
+ return t('outOfStock', 'Out of Stock');
49
+ }
50
+
51
+ if (shouldShowBillModal) {
52
+ return t('bill', 'Bill');
53
+ }
54
+
55
+ return t('dispense', 'Dispense');
56
+ };
57
+
58
+ return {
59
+ isLoading,
60
+ isDisabled,
61
+ buttonText: getButtonText(),
62
+ shouldShowBillModal,
63
+ dispenseFormProps,
64
+ orderUuid,
65
+ patientUuid,
66
+ billableItem,
67
+ itemHasBill,
68
+ medicationRequestBundle,
69
+ hasPendingPayment,
70
+ shouldAllowModify,
71
+ };
72
+ }
73
+
74
+ import { useMemo } from 'react';
75
+ import { FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
76
+ import { Order } from '@openmrs/esm-patient-common-lib';
77
+ import useSWR from 'swr';
78
+
79
+ const customRepresentation =
80
+ 'custom:(uuid,dosingType,orderNumber,accessionNumber,' +
81
+ 'patient:ref,action,careSetting:ref,previousOrder:ref,dateActivated,scheduledDate,dateStopped,autoExpireDate,' +
82
+ 'orderType:ref,encounter:ref,orderer:(uuid,display,person:(display)),orderReason,orderReasonNonCoded,orderType,urgency,instructions,' +
83
+ 'commentToFulfiller,drug:(uuid,display,strength,dosageForm:(display,uuid),concept),dose,doseUnits:ref,' +
84
+ 'frequency:ref,asNeeded,asNeededCondition,quantity,quantityUnits:ref,numRefills,dosingInstructions,' +
85
+ 'duration,durationUnits:ref,route:ref,brandName,dispenseAsWritten)';
86
+
87
+ /**
88
+ * Hook to get a single order by UUID.
89
+ *
90
+ * @param orderUuid The UUID of the order to fetch.
91
+ */
92
+ export function useOrderByUuid(orderUuid: string) {
93
+ const ordersUrl = useMemo(
94
+ () => (orderUuid ? `${restBaseUrl}/order/${orderUuid}?v=${customRepresentation}` : null),
95
+ [orderUuid],
96
+ );
97
+ const { data, error, isLoading, isValidating, mutate } = useSWR<FetchResponse<Order>, Error>(ordersUrl, openmrsFetch);
98
+
99
+ return {
100
+ data: data?.data,
101
+ error,
102
+ isLoading,
103
+ isValidating,
104
+ mutate,
105
+ };
106
+ }
@@ -0,0 +1,66 @@
1
+ import { launchWorkspace } from '@openmrs/esm-framework';
2
+ import { Order } from '@openmrs/esm-patient-common-lib';
3
+ import { useCallback } from 'react';
4
+ import { mutate } from 'swr';
5
+
6
+ export function useModalHandler(mutateUrl?: string) {
7
+ const handleModalClose = useCallback(() => {
8
+ if (!mutateUrl) {
9
+ return;
10
+ }
11
+
12
+ mutate((key) => typeof key === 'string' && key.startsWith(mutateUrl), undefined, {
13
+ revalidate: true,
14
+ });
15
+ }, [mutateUrl]);
16
+
17
+ return {
18
+ handleModalClose,
19
+ };
20
+ }
21
+
22
+ export const launchPrescriptionEditWorkspace = (order: Order, patientUuid: string) => {
23
+ const newItem = {
24
+ uuid: order.uuid,
25
+ display: order.drug?.display,
26
+ previousOrder: order.uuid,
27
+ startDate: new Date(),
28
+ action: 'REVISE',
29
+ drug: order.drug,
30
+ dosage: order.dose,
31
+ unit: {
32
+ value: order.doseUnits?.display,
33
+ valueCoded: order.doseUnits?.uuid,
34
+ },
35
+ frequency: {
36
+ valueCoded: order.frequency?.uuid,
37
+ value: order.frequency?.display,
38
+ },
39
+ route: {
40
+ valueCoded: order.route?.uuid,
41
+ value: order.route?.display,
42
+ },
43
+ commonMedicationName: order.drug?.display,
44
+ isFreeTextDosage: order.dosingType === 'org.openmrs.FreeTextDosingInstructions',
45
+ freeTextDosage: order.dosingType === 'org.openmrs.FreeTextDosingInstructions' ? order.dosingInstructions : '',
46
+ patientInstructions: order.dosingType !== 'org.openmrs.FreeTextDosingInstructions' ? order.dosingInstructions : '',
47
+ asNeeded: order.asNeeded,
48
+ asNeededCondition: order.asNeededCondition,
49
+ duration: order.duration,
50
+ durationUnit: {
51
+ valueCoded: order.durationUnits?.uuid,
52
+ value: order.durationUnits?.display,
53
+ },
54
+ pillsDispensed: order.quantity,
55
+ numRefills: order.numRefills,
56
+ indication: order.orderReasonNonCoded,
57
+ orderer: order.orderer?.uuid,
58
+ careSetting: order.careSetting?.uuid,
59
+ quantityUnits: {
60
+ value: order.quantityUnits?.display,
61
+ valueCoded: order.quantityUnits?.uuid,
62
+ },
63
+ };
64
+
65
+ launchWorkspace('add-drug-order', { patientUuid, order: newItem });
66
+ };
@@ -0,0 +1,120 @@
1
+ import { Column, InlineLoading, InlineNotification, Layer, TextArea } from '@carbon/react';
2
+ import { usePatient } from '@openmrs/esm-framework';
3
+ import React, { useEffect, useMemo } from 'react';
4
+ import { Controller, useFormContext } from 'react-hook-form';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { InterventionsFilter, useInterventions } from '../../../hooks/useInterventions';
7
+ import usePackages from '../../../hooks/usePackages';
8
+ import styles from './claims-form.scss';
9
+
10
+ type ClaimExplanationAndJusificationInputProps = {
11
+ patientUuid: string;
12
+ };
13
+ const ClaimExplanationAndJusificationInput: React.FC<ClaimExplanationAndJusificationInputProps> = ({ patientUuid }) => {
14
+ const { error: patientError, isLoading: isPatientLoading, patient } = usePatient(patientUuid);
15
+
16
+ const form = useFormContext<{
17
+ claimExplanation: string;
18
+ claimJustification: string;
19
+ packages: Array<string>;
20
+ interventions: Array<string>;
21
+ }>();
22
+ const { t } = useTranslation();
23
+ const { isLoading: packagesLoading, error: packageError, packages: shaPackages } = usePackages();
24
+ const { setValue } = form;
25
+ const packagesObservable = form.watch('packages');
26
+ const interventionsObservable = form.watch('interventions');
27
+ const filters = useMemo<InterventionsFilter>(
28
+ () => ({
29
+ package_code: packagesObservable.join(','),
30
+ applicable_gender: patient?.gender === 'male' ? 'MALE' : 'FEMALE',
31
+ }),
32
+ [packagesObservable, patient],
33
+ );
34
+ const { error: interventionsError, isLoading: isLoadingInterventions, allInterventions } = useInterventions(filters);
35
+ const packagesSelected = useMemo(
36
+ () =>
37
+ packagesObservable
38
+ .map((packageCode) => shaPackages.find((pkg) => pkg.uuid === packageCode))
39
+ ?.map((p) => p?.packageName ?? '')
40
+ .filter(Boolean) ?? [],
41
+ [packagesObservable, shaPackages],
42
+ );
43
+ const interventionSelected = useMemo(
44
+ () =>
45
+ interventionsObservable.map(
46
+ (interventionCode) =>
47
+ allInterventions.find((intervention) => intervention.interventionCode === interventionCode)?.interventionName,
48
+ ) ?? [],
49
+ [interventionsObservable, allInterventions],
50
+ );
51
+
52
+ useEffect(() => {
53
+ setValue('claimExplanation', packagesSelected.join(', '));
54
+ setValue('claimJustification', interventionSelected.join(', '));
55
+ }, [packagesSelected, setValue, interventionSelected]);
56
+
57
+ if (packagesLoading || isPatientLoading || isLoadingInterventions) {
58
+ return (
59
+ <InlineLoading description={t('loading', 'Loading')} iconDescription={t('loading', 'Loading data') + '...'} />
60
+ );
61
+ }
62
+
63
+ if (packageError || patientError || interventionsError) {
64
+ return (
65
+ <InlineNotification
66
+ aria-label="closes notification"
67
+ kind="error"
68
+ lowContrast={true}
69
+ statusIconDescription="notification"
70
+ title={t('errorLoadingpackages', 'Error loading packages')}
71
+ subtitle={packageError?.message ?? packageError?.message ?? interventionsError?.message}
72
+ />
73
+ );
74
+ }
75
+
76
+ return (
77
+ <>
78
+ <Column>
79
+ <Layer className={styles.input}>
80
+ <Controller
81
+ control={form.control}
82
+ name="claimExplanation"
83
+ render={({ field, fieldState: { error } }) => (
84
+ <TextArea
85
+ {...field}
86
+ labelText={t('claimExplanation', 'Claim Explanation')}
87
+ rows={3}
88
+ placeholder="Claim Explanation"
89
+ id="claimExplanation"
90
+ invalid={!!error?.message}
91
+ invalidText={error?.message}
92
+ />
93
+ )}
94
+ />
95
+ </Layer>
96
+ </Column>
97
+ <Column>
98
+ <Layer className={styles.input}>
99
+ <Controller
100
+ control={form.control}
101
+ name="claimJustification"
102
+ render={({ field, fieldState: { error } }) => (
103
+ <TextArea
104
+ {...field}
105
+ labelText={t('claimJustification', 'Claim Justification')}
106
+ rows={3}
107
+ placeholder="Claim Justification"
108
+ id="claimJustification"
109
+ invalid={!!error?.message}
110
+ invalidText={error?.message}
111
+ />
112
+ )}
113
+ />
114
+ </Layer>
115
+ </Column>
116
+ </>
117
+ );
118
+ };
119
+
120
+ export default ClaimExplanationAndJusificationInput;