@ampath/esm-dha-workflow-app 4.0.0-claim-workflows.159
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.
- package/.editorconfig +12 -0
- package/.eslintignore +2 -0
- package/.eslintrc +57 -0
- package/.husky/pre-commit +7 -0
- package/.husky/pre-push +6 -0
- package/.prettierignore +14 -0
- package/.turbo.json +18 -0
- package/.yarn/plugins/@yarnpkg/plugin-outdated.cjs +35 -0
- package/LICENSE +401 -0
- package/README.md +37 -0
- package/__mocks__/react-i18next.js +50 -0
- package/dist/1197.js +1 -0
- package/dist/1277.js +1 -0
- package/dist/1277.js.map +1 -0
- package/dist/1558.js +2 -0
- package/dist/1558.js.LICENSE.txt +14 -0
- package/dist/1558.js.map +1 -0
- package/dist/1729.js +1 -0
- package/dist/1729.js.map +1 -0
- package/dist/182.js +1 -0
- package/dist/182.js.map +1 -0
- package/dist/1826.js +1 -0
- package/dist/1826.js.map +1 -0
- package/dist/1833.js +1 -0
- package/dist/1833.js.map +1 -0
- package/dist/1856.js +1 -0
- package/dist/1856.js.map +1 -0
- package/dist/1925.js +1 -0
- package/dist/1925.js.map +1 -0
- package/dist/2021.js +1 -0
- package/dist/2021.js.map +1 -0
- package/dist/2054.js +1 -0
- package/dist/2054.js.map +1 -0
- package/dist/2177.js +2 -0
- package/dist/2177.js.LICENSE.txt +9 -0
- package/dist/2177.js.map +1 -0
- package/dist/2333.js +1 -0
- package/dist/2333.js.map +1 -0
- package/dist/2801.js +1 -0
- package/dist/2801.js.map +1 -0
- package/dist/282.js +2 -0
- package/dist/282.js.LICENSE.txt +32 -0
- package/dist/282.js.map +1 -0
- package/dist/3041.js +1 -0
- package/dist/3041.js.map +1 -0
- package/dist/3099.js +1 -0
- package/dist/3184.js +2 -0
- package/dist/3184.js.LICENSE.txt +14 -0
- package/dist/3184.js.map +1 -0
- package/dist/3654.js +1 -0
- package/dist/3654.js.map +1 -0
- package/dist/4055.js +1 -0
- package/dist/4205.js +1 -0
- package/dist/4205.js.map +1 -0
- package/dist/4225.js +1 -0
- package/dist/4225.js.map +1 -0
- package/dist/4300.js +1 -0
- package/dist/4335.js +1 -0
- package/dist/4353.js +1 -0
- package/dist/4353.js.map +1 -0
- package/dist/4517.js +1 -0
- package/dist/4517.js.map +1 -0
- package/dist/4652.js +1 -0
- package/dist/4674.js +1 -0
- package/dist/4674.js.map +1 -0
- package/dist/4947.js +1 -0
- package/dist/4947.js.map +1 -0
- package/dist/5015.js +1 -0
- package/dist/5015.js.map +1 -0
- package/dist/5422.js +1 -0
- package/dist/5422.js.map +1 -0
- package/dist/5428.js +1 -0
- package/dist/5428.js.map +1 -0
- package/dist/5752.js +1 -0
- package/dist/5752.js.map +1 -0
- package/dist/5851.js +1 -0
- package/dist/5851.js.map +1 -0
- package/dist/6260.js +1 -0
- package/dist/6260.js.map +1 -0
- package/dist/6264.js +1 -0
- package/dist/6264.js.map +1 -0
- package/dist/6540.js +2 -0
- package/dist/6540.js.LICENSE.txt +9 -0
- package/dist/6540.js.map +1 -0
- package/dist/6606.js +1 -0
- package/dist/6606.js.map +1 -0
- package/dist/693.js +1 -0
- package/dist/693.js.map +1 -0
- package/dist/6991.js +1 -0
- package/dist/6991.js.map +1 -0
- package/dist/7199.js +1 -0
- package/dist/7199.js.map +1 -0
- package/dist/7255.js +1 -0
- package/dist/7255.js.map +1 -0
- package/dist/7258.js +1 -0
- package/dist/7258.js.map +1 -0
- package/dist/7420.js +1 -0
- package/dist/7420.js.map +1 -0
- package/dist/8114.js +1 -0
- package/dist/8114.js.map +1 -0
- package/dist/8321.js +1 -0
- package/dist/8321.js.map +1 -0
- package/dist/8339.js +1 -0
- package/dist/8339.js.map +1 -0
- package/dist/8558.js +1 -0
- package/dist/8558.js.map +1 -0
- package/dist/8778.js +1 -0
- package/dist/8778.js.map +1 -0
- package/dist/8803.js +2 -0
- package/dist/8803.js.LICENSE.txt +54 -0
- package/dist/8803.js.map +1 -0
- package/dist/8865.js +1 -0
- package/dist/8865.js.map +1 -0
- package/dist/8895.js +1 -0
- package/dist/8895.js.map +1 -0
- package/dist/9037.js +1 -0
- package/dist/9037.js.map +1 -0
- package/dist/9091.js +1 -0
- package/dist/9091.js.map +1 -0
- package/dist/9093.js +1 -0
- package/dist/9093.js.map +1 -0
- package/dist/9117.js +1 -0
- package/dist/9117.js.map +1 -0
- package/dist/961.js +2 -0
- package/dist/961.js.LICENSE.txt +19 -0
- package/dist/961.js.map +1 -0
- package/dist/9721.js +1 -0
- package/dist/9721.js.map +1 -0
- package/dist/esm-dha-workflow-app.js +1 -0
- package/dist/esm-dha-workflow-app.js.buildmanifest.json +1594 -0
- package/dist/esm-dha-workflow-app.js.map +1 -0
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -0
- package/dist/routes.json +1 -0
- package/e2e/README.md +115 -0
- package/e2e/core/global-setup.ts +32 -0
- package/e2e/core/index.ts +1 -0
- package/e2e/core/test.ts +20 -0
- package/e2e/fixtures/api.ts +26 -0
- package/e2e/fixtures/index.ts +1 -0
- package/e2e/pages/index.ts +1 -0
- package/e2e/pages/root-page.ts +32 -0
- package/e2e/specs/template-app.spec.ts +23 -0
- package/e2e/support/github/Dockerfile +34 -0
- package/e2e/support/github/docker-compose.yml +24 -0
- package/e2e/support/github/run-e2e-docker-env.sh +37 -0
- package/example.env +6 -0
- package/jest.config.js +33 -0
- package/package.json +117 -0
- package/playwright.config.ts +32 -0
- package/prettier.config.js +8 -0
- package/src/accounting/accounting.component.tsx +13 -0
- package/src/admissions/admission-request-list/admission-request-list.scss +0 -0
- package/src/admissions/admission-request-list/admission-request-list.tsx +134 -0
- package/src/admissions/admissions-dashboard.component.scss +15 -0
- package/src/admissions/admissions-dashboard.component.tsx +160 -0
- package/src/admissions/admissions.resource.ts +101 -0
- package/src/admissions/admitted-list/admitted-patients-list.tsx +141 -0
- package/src/admissions/constants/index.ts +33 -0
- package/src/admissions/discharged-list/discharged-list.scss +0 -0
- package/src/admissions/discharged-list/discharged-list.tsx +58 -0
- package/src/admissions/inpatient/admission-history/patient-admission-history.tsx +76 -0
- package/src/admissions/inpatient/admission-requests/patient-admission-requests.scss +19 -0
- package/src/admissions/inpatient/admission-requests/patient-admission-requests.tsx +72 -0
- package/src/admissions/inpatient/inpatient-admissions.component.scss +7 -0
- package/src/admissions/inpatient/inpatient-admissions.component.tsx +46 -0
- package/src/admissions/modal/admit-elsewhere/admit-elsewhere.modal.scss +23 -0
- package/src/admissions/modal/admit-elsewhere/admit-elsewhere.modal.tsx +156 -0
- package/src/admissions/modal/admit-patient/admit-patient.modal.scss +0 -0
- package/src/admissions/modal/admit-patient/admit-patient.modal.tsx +109 -0
- package/src/admissions/modal/bed-swap/bed-swap.modal.scss +0 -0
- package/src/admissions/modal/bed-swap/bed-swap.modal.tsx +102 -0
- package/src/admissions/modal/cancel-admission-request/cancel-admission-request.scss +11 -0
- package/src/admissions/modal/cancel-admission-request/cancel-admission-request.tsx +105 -0
- package/src/admissions/modal/discharge/discharge-patient.modal.scss +13 -0
- package/src/admissions/modal/discharge/discharge-patient.modal.tsx +84 -0
- package/src/admissions/types/index.ts +192 -0
- package/src/appointments/appointments.component.tsx +13 -0
- package/src/billing/api/billing.api.ts +107 -0
- package/src/billing/billing-root.tsx +20 -0
- package/src/billing/dashboard/billingDashboard.component.scss +0 -0
- package/src/billing/dashboard/billingDashboard.component.tsx +25 -0
- package/src/billing/extensions/visit-billing/visit-billing.extension.scss +0 -0
- package/src/billing/extensions/visit-billing/visit-billing.extension.tsx +508 -0
- package/src/billing/invoice/bill.resource.ts +47 -0
- package/src/billing/invoice/invoice-header/header-card/header-card.scss +17 -0
- package/src/billing/invoice/invoice-header/header-card/header-card.tsx +21 -0
- package/src/billing/invoice/invoice.scss +113 -0
- package/src/billing/invoice/invoice.tsx +1441 -0
- package/src/billing/invoice/line-items/line-items.scss +0 -0
- package/src/billing/invoice/line-items/line-items.tsx +120 -0
- package/src/billing/invoice/modal/delete-bill-item/delete-bill-item.modal.scss +23 -0
- package/src/billing/invoice/modal/delete-bill-item/delete-bill-item.modal.tsx +114 -0
- package/src/billing/invoice/modal/edit-bill-item/edit-bill-item.modal.scss +0 -0
- package/src/billing/invoice/modal/edit-bill-item/edit-bill-item.modal.tsx +122 -0
- package/src/billing/invoice/payment-details/payment-details.scss +0 -0
- package/src/billing/invoice/payment-details/payment-details.tsx +43 -0
- package/src/billing/invoice/print-invoice/print-receipt.component.tsx +44 -0
- package/src/billing/invoice/print-invoice/print-receipt.scss +14 -0
- package/src/billing/types/index.ts +84 -0
- package/src/billing/utils/index.ts +17 -0
- package/src/billing/widgets/billingTotalsRow.component.scss +0 -0
- package/src/billing/widgets/billingTotalsRow.component.tsx +712 -0
- package/src/billing/workspaces/create-order-bill-form-workspace/create-order-bill-form.resource.ts +103 -0
- package/src/billing/workspaces/create-order-bill-form-workspace/create-order-bill-form.scss +58 -0
- package/src/billing/workspaces/create-order-bill-form-workspace/create-order-bill-form.workspace.tsx +357 -0
- package/src/billing/workspaces/create-order-bill-form-workspace/schema.ts +11 -0
- package/src/bookings/bookings.component.scss +7 -0
- package/src/bookings/bookings.component.tsx +31 -0
- package/src/bookings/daily/daily-bookings.component.scss +38 -0
- package/src/bookings/daily/daily-bookings.component.tsx +138 -0
- package/src/bookings/daily/daily-bookings.resource.ts +28 -0
- package/src/bookings/daily/filters/daily-bookings-filter.component.scss +15 -0
- package/src/bookings/daily/filters/daily-bookings-filter.component.tsx +80 -0
- package/src/bookings/daily/patient-list/daily-bookings-patient-list.component.tsx +97 -0
- package/src/bookings/types/index.ts +68 -0
- package/src/claims/claims.component.tsx +142 -0
- package/src/claims/claims.resource.ts +168 -0
- package/src/claims/index.ts +206 -0
- package/src/claims/interventions.resource.ts +49 -0
- package/src/claims/utils.ts +59 -0
- package/src/config-schema.ts +215 -0
- package/src/createDashboardLink.tsx +9 -0
- package/src/dashboard/charts/chart.component.scss +13 -0
- package/src/dashboard/charts/chart.component.tsx +56 -0
- package/src/dashboard/dashboard.component.scss +7 -0
- package/src/dashboard/dashboard.component.tsx +51 -0
- package/src/dashboard/overview/overview.component.scss +150 -0
- package/src/dashboard/overview/overview.component.tsx +134 -0
- package/src/dashboard/patient-list/patient-list.component.tsx +41 -0
- package/src/dashboard-meta/accounting-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/admissions-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/billing-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/bookings-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/consultation-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/dha-workflow-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/inpatient-admissions.meta.ts +6 -0
- package/src/dashboard-meta/maternity-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/mch-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/pharmacy-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/queue-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/registers-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/registry-dashboard.meta.ts +6 -0
- package/src/dashboard-meta/service-queue-admin.meta.ts +6 -0
- package/src/dashboard-meta/triage-dashboard.meta.ts +6 -0
- package/src/declarations.d.ts +5 -0
- package/src/hooks/useActions.ts +165 -0
- package/src/index.ts +161 -0
- package/src/laboratory/laboratory.component.tsx +13 -0
- package/src/left-panel/left-panel.component.tsx +20 -0
- package/src/left-panel/left-panel.scss +42 -0
- package/src/mnch/maternity/maternity-queues.component.scss +7 -0
- package/src/mnch/maternity/maternity-queues.component.tsx +28 -0
- package/src/mnch/maternity/queues/triage/maternity-triage.tsx +15 -0
- package/src/mnch/mch/mch-queues.component.scss +7 -0
- package/src/mnch/mch/mch-queues.component.tsx +32 -0
- package/src/mnch/mch/queues/consultation/mch-consultation.tsx +18 -0
- package/src/mnch/mch/queues/triage/mch-triage.tsx +15 -0
- package/src/mnch/mnch-root.tsx +17 -0
- package/src/modals/sign-off-modal.scss +7 -0
- package/src/modals/sign-off-modal.tsx +52 -0
- package/src/mortuary/mortuary.component.tsx +13 -0
- package/src/pharmacy/pharmacy.component.tsx +13 -0
- package/src/registers/registers.component.tsx +8 -0
- package/src/registry/client-details/client-details.tsx +40 -0
- package/src/registry/eligibility/eligibility-details/eligibility-details.scss +38 -0
- package/src/registry/eligibility/eligibility-details/eligibility-details.tsx +101 -0
- package/src/registry/eligibility/eliigibility-tags/eligibility-tags.scss +6 -0
- package/src/registry/eligibility/eliigibility-tags/eligibility-tags.tsx +120 -0
- package/src/registry/eligibility/modal/eligibility-details.modal.scss +0 -0
- package/src/registry/eligibility/modal/eligibility-details.modal.tsx +45 -0
- package/src/registry/modal/client-details-modal/client-details-modal.scss +28 -0
- package/src/registry/modal/client-details-modal/client-details-modal.tsx +119 -0
- package/src/registry/modal/otp-verification-modal/otp-verification-modal.scss +43 -0
- package/src/registry/modal/otp-verification-modal/otp-verification-modal.tsx +280 -0
- package/src/registry/modal/send-to-triage/send-to-triage.modal.scss +39 -0
- package/src/registry/modal/send-to-triage/send-to-triage.modal.tsx +921 -0
- package/src/registry/payment-details/payment-options/payment-options.scss +13 -0
- package/src/registry/payment-details/payment-options/payment-options.tsx +68 -0
- package/src/registry/registry.component.scss +89 -0
- package/src/registry/registry.component.tsx +490 -0
- package/src/registry/registry.resource.ts +62 -0
- package/src/registry/types/index.ts +401 -0
- package/src/registry/utils/error-handler.ts +37 -0
- package/src/registry/utils/format-dependant-display-data.ts +8 -0
- package/src/registry/utils/hie-adapter.ts +56 -0
- package/src/registry/utils/hie-client-adapter.ts +312 -0
- package/src/registry/utils/mask-data.ts +32 -0
- package/src/registry/utils/phone-number-formatter.ts +11 -0
- package/src/resources/dashboard.resource.ts +20 -0
- package/src/resources/hie-amrs-automatic-registration.service.ts +16 -0
- package/src/resources/identifier-types.ts +29 -0
- package/src/resources/patient-resource.ts +62 -0
- package/src/resources/patient-search.resource.ts +22 -0
- package/src/resources/queue.resource.ts +60 -0
- package/src/resources/superset.resource.ts +21 -0
- package/src/resources/visit.resource.ts +38 -0
- package/src/root.component.tsx +48 -0
- package/src/root.scss +11 -0
- package/src/root.test.tsx +51 -0
- package/src/routes.json +292 -0
- package/src/service-queues/action-button.component.tsx +34 -0
- package/src/service-queues/action-overflow-menu-item.component.tsx +34 -0
- package/src/service-queues/admin/queue/modal/create-queue/create-queue.modal.scss +31 -0
- package/src/service-queues/admin/queue/modal/create-queue/create-queue.modal.tsx +143 -0
- package/src/service-queues/admin/queue/modal/edit-queue/edit-queue.modal.scss +0 -0
- package/src/service-queues/admin/queue/modal/edit-queue/edit-queue.modal.tsx +154 -0
- package/src/service-queues/admin/queue/queue-list/queue-list.scss +33 -0
- package/src/service-queues/admin/queue/queue-list/queue-list.tsx +113 -0
- package/src/service-queues/admin/queue-entry/queue-entry-list.component.scss +6 -0
- package/src/service-queues/admin/queue-entry/queue-entry-list.component.tsx +137 -0
- package/src/service-queues/admin/queue-room/modal/create-queue-room/create-queue-room.modal.scss +31 -0
- package/src/service-queues/admin/queue-room/modal/create-queue-room/create-queue-room.modal.tsx +137 -0
- package/src/service-queues/admin/queue-room/modal/edit-queue-room/edit-queue-room.modal.scss +0 -0
- package/src/service-queues/admin/queue-room/modal/edit-queue-room/edit-queue-room.modal.tsx +146 -0
- package/src/service-queues/admin/queue-room/queue-room-list/queue-room-list.scss +22 -0
- package/src/service-queues/admin/queue-room/queue-room-list/queue-room-list.tsx +120 -0
- package/src/service-queues/admin/service-queue-admin-dashboard.component.scss +6 -0
- package/src/service-queues/admin/service-queue-admin-dashboard.component.tsx +34 -0
- package/src/service-queues/consultation/consultation.component.scss +7 -0
- package/src/service-queues/consultation/consultation.component.tsx +15 -0
- package/src/service-queues/extensions/service-queue-patient-banner/service-queue-patient-banner.scss +30 -0
- package/src/service-queues/extensions/service-queue-patient-banner/service-queue-patient-banner.tsx +108 -0
- package/src/service-queues/metrics/metrics-cards/attended-patients.extension.tsx +38 -0
- package/src/service-queues/metrics/metrics-cards/metrics-card.component.tsx +86 -0
- package/src/service-queues/metrics/metrics-cards/metrics-card.scss +106 -0
- package/src/service-queues/metrics/metrics-cards/waiting-patients.extension.tsx +34 -0
- package/src/service-queues/metrics/metrics-container.component.tsx +23 -0
- package/src/service-queues/metrics/metrics-container.scss +36 -0
- package/src/service-queues/metrics/metrics.resource.ts +65 -0
- package/src/service-queues/modals/daily-report-patient-list/daily-report-patient-list.scss +26 -0
- package/src/service-queues/modals/daily-report-patient-list/daily-report-patient-list.tsx +110 -0
- package/src/service-queues/modals/move/move-patient.component.scss +35 -0
- package/src/service-queues/modals/move/move-patient.component.tsx +152 -0
- package/src/service-queues/modals/serve/serve-patient.comppnent.scss +0 -0
- package/src/service-queues/modals/serve/serve-patient.comppnent.tsx +80 -0
- package/src/service-queues/modals/sign-off/sign-off.modal.scss +0 -0
- package/src/service-queues/modals/sign-off/sign-off.modal.tsx +79 -0
- package/src/service-queues/modals/transition/transition-patient.component.scss +0 -0
- package/src/service-queues/modals/transition/transition-patient.component.tsx +122 -0
- package/src/service-queues/queue-list/check-in.service.ts +26 -0
- package/src/service-queues/queue-list/queue-list.component.scss +56 -0
- package/src/service-queues/queue-list/queue-list.component.tsx +311 -0
- package/src/service-queues/queue-room.component.tsx +39 -0
- package/src/service-queues/room/room.component.tsx +58 -0
- package/src/service-queues/service-queue/service-queue.component.scss +14 -0
- package/src/service-queues/service-queue/service-queue.component.tsx +387 -0
- package/src/service-queues/service-queue/stats/stat-details/stat-details.component.scss +12 -0
- package/src/service-queues/service-queue/stats/stat-details/stat-details.component.tsx +63 -0
- package/src/service-queues/service-queue.scss +27 -0
- package/src/service-queues/service-queue.tsx +37 -0
- package/src/service-queues/service-queues.resource.ts +361 -0
- package/src/service-queues/service.resource.ts +28 -0
- package/src/shared/constants/civil-status.ts +29 -0
- package/src/shared/constants/concepts.ts +35 -0
- package/src/shared/constants/index.ts +1 -0
- package/src/shared/constants/patient-category.ts +6 -0
- package/src/shared/constants/patient-type.ts +10 -0
- package/src/shared/constants/person-attributes.ts +33 -0
- package/src/shared/constants/visit-types.ts +7 -0
- package/src/shared/services/billing.resource.ts +38 -0
- package/src/shared/services/client-payment-mode.resource.ts +27 -0
- package/src/shared/services/client-payment.resource.ts +17 -0
- package/src/shared/services/eligibility.resource.ts +20 -0
- package/src/shared/services/encounters.resource.ts +27 -0
- package/src/shared/services/location.resource.ts +9 -0
- package/src/shared/types/index.ts +153 -0
- package/src/shared/ui/aggregate-stat-card/aggregate-stat-card.scss +42 -0
- package/src/shared/ui/aggregate-stat-card/aggregate-stat-card.tsx +42 -0
- package/src/shared/ui/confirm-modal/confirm.modal.scss +18 -0
- package/src/shared/ui/confirm-modal/confirm.modal.tsx +38 -0
- package/src/shared/ui/otp-input/otp-input.component.scss +14 -0
- package/src/shared/ui/otp-input/otp-input.component.tsx +90 -0
- package/src/shared/ui/stat-card/stat-card.component.scss +10 -0
- package/src/shared/ui/stat-card/stat-card.component.tsx +26 -0
- package/src/shared/ui/timer/timer.component.scss +5 -0
- package/src/shared/ui/timer/timer.component.tsx +40 -0
- package/src/shared/utils/get-base-url.ts +27 -0
- package/src/shared/utils/get-tag-type.ts +66 -0
- package/src/side-nav/side-menu.scss +38 -0
- package/src/side-nav-menu/mnch-nav-link-config.ts +16 -0
- package/src/side-nav-menu/mnch-nav-links.tsx +42 -0
- package/src/side-nav-menu/nav-link-config.ts +78 -0
- package/src/side-nav-menu/nav-links.tsx +42 -0
- package/src/triage/metrics/attended-patients.extension.tsx +42 -0
- package/src/triage/metrics/metrics.scss +36 -0
- package/src/triage/metrics/triage-metrics.component.tsx +21 -0
- package/src/triage/metrics/waiting-patients.extension.tsx +39 -0
- package/src/triage/room/room.scss +29 -0
- package/src/triage/triage.component.tsx +15 -0
- package/src/triage/triage.resource.ts +19 -0
- package/src/triage/types.ts +16 -0
- package/src/types/types.ts +180 -0
- package/src/widgets/workflow-registry-link.extension.tsx +12 -0
- package/tools/i18next-parser.config.js +89 -0
- package/tools/setup-tests.ts +1 -0
- package/tools/update-openmrs-deps.mjs +43 -0
- package/translations/am.json +24 -0
- package/translations/en.json +24 -0
- package/translations/es.json +24 -0
- package/translations/fr.json +24 -0
- package/translations/he.json +24 -0
- package/translations/km.json +24 -0
- package/tsconfig.json +24 -0
- package/webpack.config.js +1 -0
|
@@ -0,0 +1,921 @@
|
|
|
1
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Checkbox,
|
|
5
|
+
ComboBox,
|
|
6
|
+
Modal,
|
|
7
|
+
ModalBody,
|
|
8
|
+
Select,
|
|
9
|
+
SelectItem,
|
|
10
|
+
Table,
|
|
11
|
+
TableBody,
|
|
12
|
+
TableCell,
|
|
13
|
+
TableHead,
|
|
14
|
+
TableHeader,
|
|
15
|
+
TableRow,
|
|
16
|
+
TextInput,
|
|
17
|
+
} from '@carbon/react';
|
|
18
|
+
import styles from './send-to-triage.modal.scss';
|
|
19
|
+
import { type Patient, useSession, showSnackbar, type Visit, useConfig, ExtensionSlot } from '@openmrs/esm-framework';
|
|
20
|
+
import {
|
|
21
|
+
type HieClient,
|
|
22
|
+
type CreateVisitDto,
|
|
23
|
+
type QueueEntryDto,
|
|
24
|
+
type ServiceQueue,
|
|
25
|
+
PaymentDetail,
|
|
26
|
+
type VisitAttribute,
|
|
27
|
+
} from '../../types';
|
|
28
|
+
import { createQueueEntry, getFacilityServiceQueues } from '../../../resources/queue.resource';
|
|
29
|
+
import { QUEUE_PRIORITIES_UUIDS, QUEUE_STATUS_UUIDS } from '../../../shared/constants/concepts';
|
|
30
|
+
import { createVisit } from '../../../resources/visit.resource';
|
|
31
|
+
import {
|
|
32
|
+
createBill,
|
|
33
|
+
fetchBillableServices,
|
|
34
|
+
fetchCashPoints,
|
|
35
|
+
fetchPaymentModes,
|
|
36
|
+
} from '../../../shared/services/billing.resource';
|
|
37
|
+
import {
|
|
38
|
+
type PayableBillableService,
|
|
39
|
+
type ServicePrice,
|
|
40
|
+
type BillableService,
|
|
41
|
+
type PaymentMode,
|
|
42
|
+
type CreateBillDto,
|
|
43
|
+
type CashPoint,
|
|
44
|
+
type CreateOrderEncounterDto,
|
|
45
|
+
} from '../../../shared/types';
|
|
46
|
+
import { PatientCategories } from '../../../shared/constants/patient-category';
|
|
47
|
+
import { VisitTypeUuids } from '../../../shared/constants/visit-types';
|
|
48
|
+
import { type Bill } from '../../../billing/types';
|
|
49
|
+
import { fetchPatientBills } from '../../../billing/invoice/bill.resource';
|
|
50
|
+
import { type QueueEntry } from '../../../types/types';
|
|
51
|
+
import { getActiveQueueEntryByPatientUuid } from '../../../service-queues/service-queues.resource';
|
|
52
|
+
import { createOrderEncounter } from '../../../shared/services/encounters.resource';
|
|
53
|
+
import { type ConfigObject } from '../../../config-schema';
|
|
54
|
+
import { PatientTypes } from '../../../shared/constants/patient-type';
|
|
55
|
+
import ClaimsComponent from '../../../claims/claims.component';
|
|
56
|
+
|
|
57
|
+
interface SendToTriageModalProps {
|
|
58
|
+
patients: Patient[];
|
|
59
|
+
open: boolean;
|
|
60
|
+
onModalClose: (modalCloseResp?: { success: boolean }) => void;
|
|
61
|
+
onSubmit: () => void;
|
|
62
|
+
client: HieClient;
|
|
63
|
+
onCreateAmrsPatient: (client: HieClient) => void;
|
|
64
|
+
onManualRegistration: () => void;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const SendToTriageModal: React.FC<SendToTriageModalProps> = ({
|
|
68
|
+
patients,
|
|
69
|
+
open,
|
|
70
|
+
onModalClose,
|
|
71
|
+
onSubmit,
|
|
72
|
+
client,
|
|
73
|
+
onCreateAmrsPatient,
|
|
74
|
+
onManualRegistration,
|
|
75
|
+
}) => {
|
|
76
|
+
const [selectedPatient, setSelectedPatient] = useState<Patient>();
|
|
77
|
+
const [selectedVisitType, setSelectedVisitType] = useState<string>();
|
|
78
|
+
const [selectedPatientType, setSelectedPatientType] = useState<string>();
|
|
79
|
+
const [serviceQueues, setServiceQueues] = useState<ServiceQueue[]>();
|
|
80
|
+
const [selectedServiceQueue, setSelectedServiceQueue] = useState<string>();
|
|
81
|
+
const [paymentModes, setPaymentModes] = useState<PaymentMode[]>([]);
|
|
82
|
+
const [cashPoints, setCashPoints] = useState<CashPoint[]>([]);
|
|
83
|
+
const [selectedCashPoint, setSelectedCashPoint] = useState<CashPoint>(null);
|
|
84
|
+
const [selectedPaymentMode, setSelectedPaymentMode] = useState<PaymentMode>(null);
|
|
85
|
+
const [selectedPriority, setSelectedPriority] = useState<string>('');
|
|
86
|
+
const [selectedPaymentDetail, setSelectedPaymentDetail] = useState<string>();
|
|
87
|
+
const [billableServices, setBillableServices] = useState<BillableService[]>([]);
|
|
88
|
+
const [servicePrices, setServicePrices] = useState<ServicePrice[]>([]);
|
|
89
|
+
const [filteredBillableServices, setFilteredBillableServices] = useState<ServicePrice[]>(null);
|
|
90
|
+
const [selectedBillableService, setSelectedBillableService] = useState<ServicePrice | null>(null);
|
|
91
|
+
const [selectedInsuranceScheme, setSelectedInsuranceScheme] = useState<string>('');
|
|
92
|
+
const [selectedInsurancePolicy, setSelectedInsurancePolicy] = useState<string>('');
|
|
93
|
+
const [selectedPatientCategory, setSelectedPatientCategory] = useState<string>('');
|
|
94
|
+
const [currentQueueEntry, setCurrentQueueEntry] = useState<QueueEntry>();
|
|
95
|
+
const [patientBills, setPatientBills] = useState<Bill[]>([]);
|
|
96
|
+
const [billCreated, setBillCreated] = useState<boolean>(false);
|
|
97
|
+
const [disableSubmission, setDisableSubmission] = useState<boolean>(false);
|
|
98
|
+
const [loading, setLoading] = useState<boolean>(false);
|
|
99
|
+
const session = useSession();
|
|
100
|
+
const locationUuid = session.sessionLocation.uuid;
|
|
101
|
+
const {
|
|
102
|
+
registrationBillableServices,
|
|
103
|
+
cashConsulationConceptUuid,
|
|
104
|
+
shaConsulationConceptUuid,
|
|
105
|
+
outPatientCareSettingUuid,
|
|
106
|
+
orderEncounterTypeUuid,
|
|
107
|
+
registrationServicequeues
|
|
108
|
+
} = useConfig<ConfigObject>();
|
|
109
|
+
|
|
110
|
+
const facilityCashPoints = useMemo(() => getfacilityCashpoints(), [cashPoints, locationUuid]);
|
|
111
|
+
|
|
112
|
+
const visitTypeOptions = useMemo(
|
|
113
|
+
() => [
|
|
114
|
+
{
|
|
115
|
+
text: 'OPD',
|
|
116
|
+
id: VisitTypeUuids.OPD_VISIT_TYPE_UUID,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
text: 'Inpatient',
|
|
120
|
+
id: VisitTypeUuids.INPATIENT_VISIT_TYPE_UUID,
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
[client],
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const patientTypeOptions = useMemo(
|
|
127
|
+
() => [
|
|
128
|
+
{
|
|
129
|
+
text: 'Walk-In',
|
|
130
|
+
id: PatientTypes.WALK_IN_UUID,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
text: 'Self-Referral',
|
|
134
|
+
id: PatientTypes.SELF_RERERRAL_UUID,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
text: 'Referral from another Facility',
|
|
138
|
+
id: PatientTypes.REFERRAL_FROM_ANOTHER_FACILITY_UUID,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
text: 'Referral from Community',
|
|
142
|
+
id: PatientTypes.REFERRED_BY_COMMUNITY_HEALTH_WORKER_UUID,
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
[client],
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
const patientIdentifiers = useMemo(() => {
|
|
149
|
+
if (selectedPatient) {
|
|
150
|
+
const identifiers = selectedPatient.identifiers;
|
|
151
|
+
return {
|
|
152
|
+
crIdentifierId: identifiers?.find(i => i.identifierType.uuid == "e88dc246-3614-4ee3-8141-1f2a83054e72").identifier
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}, [selectedPatient])
|
|
156
|
+
|
|
157
|
+
const paymentDetails = Object.values(PaymentDetail).map((value) => {
|
|
158
|
+
return {
|
|
159
|
+
id: value,
|
|
160
|
+
label: value,
|
|
161
|
+
};
|
|
162
|
+
});
|
|
163
|
+
useEffect(() => {
|
|
164
|
+
getServiceQueues();
|
|
165
|
+
getPaymentMethods();
|
|
166
|
+
getBillableServices();
|
|
167
|
+
getCashPoints();
|
|
168
|
+
getPatientBills();
|
|
169
|
+
getPatientActiveQueue();
|
|
170
|
+
}, [patients]);
|
|
171
|
+
if (!patients) {
|
|
172
|
+
return <>No Client data</>;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function getPatientActiveQueue() {
|
|
176
|
+
if (patients && patients.length > 0) {
|
|
177
|
+
const activePatient = patients[0];
|
|
178
|
+
try {
|
|
179
|
+
const resp = await getActiveQueueEntryByPatientUuid(activePatient.uuid);
|
|
180
|
+
setCurrentQueueEntry(resp.length > 0 ? resp[0] : null);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
showAlert('error', 'Error getting patient active queue', '');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async function getPatientBills() {
|
|
188
|
+
if (patients) {
|
|
189
|
+
let bills: Bill[] = [];
|
|
190
|
+
setPatientBills([]);
|
|
191
|
+
for (let i = 0; i < patients.length; i++) {
|
|
192
|
+
const resp = await fetchPatientBills(patients[i].uuid);
|
|
193
|
+
const todaysBills = getTodaysBills(resp);
|
|
194
|
+
setPatientBills(todaysBills);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function getTodaysBills(bills: Bill[]) {
|
|
199
|
+
const today = new Date();
|
|
200
|
+
return bills.filter((b) => {
|
|
201
|
+
const billDate = new Date(b.dateCreated);
|
|
202
|
+
return (
|
|
203
|
+
billDate.getFullYear() === today.getFullYear() &&
|
|
204
|
+
billDate.getMonth() === today.getMonth() &&
|
|
205
|
+
billDate.getDate() === today.getDate()
|
|
206
|
+
);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
const sendToTriage = async () => {
|
|
210
|
+
if (disableSubmission) {
|
|
211
|
+
showAlert(
|
|
212
|
+
'error',
|
|
213
|
+
'Form already Submitted',
|
|
214
|
+
'Form has already been submitted, please wait for the visit,queue and bill to be created',
|
|
215
|
+
);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
setDisableSubmission(true);
|
|
219
|
+
if (!validateVisitQueueBill()) {
|
|
220
|
+
setDisableSubmission(false);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
setLoading(true);
|
|
224
|
+
try {
|
|
225
|
+
const newVisit: Visit = await createPatientVisit();
|
|
226
|
+
if (newVisit) {
|
|
227
|
+
const addToTriageQueueDto: QueueEntryDto = generateAddToTriageDto(newVisit);
|
|
228
|
+
const queueEntryResp = await createQueueEntry(addToTriageQueueDto);
|
|
229
|
+
|
|
230
|
+
if (queueEntryResp) {
|
|
231
|
+
showAlert('success', 'Patient has succesfully been moved to the Triage queue', '');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// add bill if it was a paying client
|
|
235
|
+
let createBillResp = null;
|
|
236
|
+
if (selectedPaymentDetail === PaymentDetail.Paying) {
|
|
237
|
+
const createBillDto = generateCreateBillDto();
|
|
238
|
+
if (isValidCreateBillDto(createBillDto) && !billCreated) {
|
|
239
|
+
createBillResp = await createBill(createBillDto);
|
|
240
|
+
if (createBillResp) {
|
|
241
|
+
setBillCreated(true);
|
|
242
|
+
showAlert('success', 'Bill succesfully created', '');
|
|
243
|
+
}
|
|
244
|
+
// create consulation order
|
|
245
|
+
await createOrder(selectedPatient.uuid, newVisit.uuid);
|
|
246
|
+
} else {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (
|
|
252
|
+
(queueEntryResp && PaymentDetail.Paying && (createBillResp || billCreated)) ||
|
|
253
|
+
(queueEntryResp && PaymentDetail.NonPaying)
|
|
254
|
+
) {
|
|
255
|
+
onModalClose({ success: true });
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
} catch (error) {
|
|
259
|
+
setDisableSubmission(false);
|
|
260
|
+
showAlert('error', error.message ?? 'Error creating visit', '');
|
|
261
|
+
} finally {
|
|
262
|
+
setLoading(false);
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
function validateVisitQueueBill(): boolean {
|
|
266
|
+
if (!selectedPatient) {
|
|
267
|
+
showAlert('error', 'Please select a patient', '');
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
if (!selectedPaymentDetail) {
|
|
271
|
+
showAlert('error', 'Please select a paying or non paying option', '');
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (!isValidServiceQueueSelected()) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (selectedPaymentDetail === PaymentDetail.Paying) {
|
|
280
|
+
if (!selectedPaymentMode) {
|
|
281
|
+
showAlert('error', 'Please select a payment method', '');
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
if (!selectedBillableService) {
|
|
285
|
+
showAlert('error', 'Please select a billable service', '');
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
if (!selectedCashPoint) {
|
|
289
|
+
showAlert('error', 'Please select a cashpoint', '');
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (selectedPaymentDetail === PaymentDetail.NonPaying) {
|
|
294
|
+
if (!selectedPatientCategory) {
|
|
295
|
+
showAlert('error', 'Please select a patient category', '');
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if (!selectedVisitType) {
|
|
300
|
+
showAlert('error', 'Please select a visit type', '');
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
if (!selectedServiceQueue) {
|
|
304
|
+
showAlert('error', 'Please select a service queue', '');
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
if (!selectedPriority) {
|
|
308
|
+
showAlert('error', 'Please select a service queue priority', '');
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
const generateAddToTriageDto = (newVisit: Visit): QueueEntryDto => {
|
|
314
|
+
const payload: QueueEntryDto = {
|
|
315
|
+
visit: {
|
|
316
|
+
uuid: newVisit.uuid,
|
|
317
|
+
},
|
|
318
|
+
queueEntry: {
|
|
319
|
+
status: {
|
|
320
|
+
uuid: QUEUE_STATUS_UUIDS.WAITING_UUID,
|
|
321
|
+
},
|
|
322
|
+
priority: {
|
|
323
|
+
uuid: selectedPriority ?? QUEUE_PRIORITIES_UUIDS.NORMAL_PRIORITY_UUID,
|
|
324
|
+
},
|
|
325
|
+
queue: {
|
|
326
|
+
uuid: selectedServiceQueue,
|
|
327
|
+
},
|
|
328
|
+
patient: {
|
|
329
|
+
uuid: selectedPatient.uuid,
|
|
330
|
+
},
|
|
331
|
+
startedAt: newVisit.startDatetime,
|
|
332
|
+
sortWeight: 0,
|
|
333
|
+
},
|
|
334
|
+
};
|
|
335
|
+
return payload;
|
|
336
|
+
};
|
|
337
|
+
const onPatientSelect = (patient: Patient) => {
|
|
338
|
+
setSelectedPatient(patient);
|
|
339
|
+
};
|
|
340
|
+
const visitTypeChangeHandler = (selectedVisitType: { selectedItem: { id: string; text: string } }) => {
|
|
341
|
+
const vt = selectedVisitType.selectedItem.id;
|
|
342
|
+
setSelectedVisitType(vt);
|
|
343
|
+
};
|
|
344
|
+
const isValidServiceQueueSelected = () => {
|
|
345
|
+
if (!currentQueueEntry) {
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
if (currentQueueEntry.queue.uuid) {
|
|
349
|
+
showAlert(
|
|
350
|
+
'error',
|
|
351
|
+
'Patient already in queue',
|
|
352
|
+
`Patient is already in the ${currentQueueEntry.queue.display} queue, remove them first or contact support`,
|
|
353
|
+
);
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
return true;
|
|
357
|
+
};
|
|
358
|
+
const serviceChangeHandler = ($event: any) => {
|
|
359
|
+
if (isValidServiceQueueSelected()) {
|
|
360
|
+
const sq = $event.target.value as unknown as string;
|
|
361
|
+
setSelectedServiceQueue(sq);
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
const priorityChangeHandler = (priorityUuid: string) => {
|
|
365
|
+
setSelectedPriority(priorityUuid);
|
|
366
|
+
};
|
|
367
|
+
const paymentDetailsHandler = (paymentDetailSelected: string) => {
|
|
368
|
+
setSelectedPaymentDetail(paymentDetailSelected);
|
|
369
|
+
};
|
|
370
|
+
const paymentMethodHandler = (selectedPaymentModeUuid: string) => {
|
|
371
|
+
const selectedPaymentMode = paymentModes.find((pm) => {
|
|
372
|
+
return pm.uuid === selectedPaymentModeUuid;
|
|
373
|
+
});
|
|
374
|
+
setSelectedPaymentMode(selectedPaymentMode);
|
|
375
|
+
const paymentModeBillableServices = getBillableServiceByPaymentMode(selectedPaymentMode);
|
|
376
|
+
setFilteredBillableServices(paymentModeBillableServices);
|
|
377
|
+
setSelectedInsuranceScheme('');
|
|
378
|
+
setSelectedInsurancePolicy('');
|
|
379
|
+
setSelectedPriority('');
|
|
380
|
+
};
|
|
381
|
+
const getBillableServiceByPaymentMode = (paymentMode: PaymentMode): PayableBillableService[] => {
|
|
382
|
+
const paymentBillableServices: ServicePrice[] = [];
|
|
383
|
+
servicePrices.forEach((sp) => {
|
|
384
|
+
if (sp.paymentMode) {
|
|
385
|
+
if (
|
|
386
|
+
sp.paymentMode.uuid === paymentMode.uuid &&
|
|
387
|
+
registrationBillableServices.includes(sp.billableService.uuid)
|
|
388
|
+
) {
|
|
389
|
+
paymentBillableServices.push(sp);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
return paymentBillableServices;
|
|
394
|
+
};
|
|
395
|
+
const billableServicesHandler = (selectedBillableServiceUuid: string) => {
|
|
396
|
+
const selectedBillableService = servicePrices.find((sp) => {
|
|
397
|
+
return sp.uuid === selectedBillableServiceUuid;
|
|
398
|
+
});
|
|
399
|
+
if (isValidBillableService(selectedBillableService)) {
|
|
400
|
+
setSelectedBillableService(selectedBillableService);
|
|
401
|
+
} else {
|
|
402
|
+
setSelectedBillableService(null);
|
|
403
|
+
showAlert('error', 'Existing bill', 'Patient has a similar bill');
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
const isValidBillableService = (selectedService: ServicePrice) => {
|
|
407
|
+
// check if patient has been billed for similar service
|
|
408
|
+
let isValid = true;
|
|
409
|
+
patientBills.forEach((b) => {
|
|
410
|
+
const lineItems = b.lineItems;
|
|
411
|
+
lineItems.forEach((l) => {
|
|
412
|
+
if (l.billableService === selectedService.billableService.display) {
|
|
413
|
+
isValid = false;
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
return isValid;
|
|
418
|
+
};
|
|
419
|
+
const cashPointsHandler = (selectedCashPointUuid: string) => {
|
|
420
|
+
const selectedCashPoint = cashPoints.find((cp) => {
|
|
421
|
+
return cp.uuid === selectedCashPointUuid;
|
|
422
|
+
});
|
|
423
|
+
setSelectedCashPoint(selectedCashPoint);
|
|
424
|
+
};
|
|
425
|
+
const patientTypeHandler = (selectedPatientType: { selectedItem: { id: string; text: string } }) => {
|
|
426
|
+
const pt = selectedPatientType.selectedItem.id;
|
|
427
|
+
setSelectedPatientType(pt);
|
|
428
|
+
};
|
|
429
|
+
const insuranceSchemeHandler = (selectedInsuranceScheme: string) => {
|
|
430
|
+
setSelectedInsuranceScheme(selectedInsuranceScheme);
|
|
431
|
+
};
|
|
432
|
+
const insurancePolicyHandler = (selectedInsurancePolicy: string) => {
|
|
433
|
+
setSelectedInsurancePolicy(selectedInsurancePolicy);
|
|
434
|
+
};
|
|
435
|
+
const patientCategoryHandler = (categoryUuid: string) => {
|
|
436
|
+
setSelectedPatientCategory(categoryUuid);
|
|
437
|
+
};
|
|
438
|
+
const createPatientVisit = async () => {
|
|
439
|
+
const visitDto = getCreateVisitDto();
|
|
440
|
+
if (!isValidCreateVisitDto(visitDto)) {
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const result = await createVisit(visitDto);
|
|
445
|
+
if (result) {
|
|
446
|
+
showAlert('success', 'Visit has been created succesfully', '');
|
|
447
|
+
return result;
|
|
448
|
+
} else {
|
|
449
|
+
showAlert('error', 'Error creating patient visit', '');
|
|
450
|
+
throw new Error('Error creating patient visit');
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
const isValidCreateVisitDto = (createVisitDto: CreateVisitDto): boolean => {
|
|
454
|
+
if (!createVisitDto.location) {
|
|
455
|
+
showAlert('error', 'Missing location in create visits', '');
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
if (!createVisitDto.patient) {
|
|
459
|
+
showAlert('error', 'Please select a patient', '');
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (!createVisitDto.visitType) {
|
|
464
|
+
showAlert('error', 'Please select a visit', '');
|
|
465
|
+
return false;
|
|
466
|
+
}
|
|
467
|
+
if (!selectedPatientType) {
|
|
468
|
+
showAlert('error', 'Please select a patient type', '');
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
return true;
|
|
472
|
+
};
|
|
473
|
+
const getCreateVisitDto = (): CreateVisitDto => {
|
|
474
|
+
const visitAttributes = getVisitAttributes();
|
|
475
|
+
const visitDto: CreateVisitDto = {
|
|
476
|
+
visitType: selectedVisitType,
|
|
477
|
+
location: locationUuid,
|
|
478
|
+
startDatetime: null,
|
|
479
|
+
stopDatetime: null,
|
|
480
|
+
patient: selectedPatient?.uuid,
|
|
481
|
+
};
|
|
482
|
+
if (visitAttributes.length > 0) {
|
|
483
|
+
visitDto['attributes'] = visitAttributes;
|
|
484
|
+
}
|
|
485
|
+
return visitDto;
|
|
486
|
+
};
|
|
487
|
+
const showAlert = (alertType: 'error' | 'success', title: string, subtitle: string) => {
|
|
488
|
+
showSnackbar({
|
|
489
|
+
kind: alertType,
|
|
490
|
+
title: title,
|
|
491
|
+
subtitle: subtitle,
|
|
492
|
+
});
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
function getVisitAttributes(): VisitAttribute[] {
|
|
496
|
+
const attributes: VisitAttribute[] = [];
|
|
497
|
+
if (selectedInsuranceScheme) {
|
|
498
|
+
attributes.push({
|
|
499
|
+
attributeType: '3a988e33-a6c0-4b76-b924-01abb998944b',
|
|
500
|
+
value: selectedInsuranceScheme,
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
if (selectedInsurancePolicy) {
|
|
504
|
+
attributes.push({
|
|
505
|
+
attributeType: 'aac48226-d143-4274-80e0-264db4e368ee',
|
|
506
|
+
value: selectedInsurancePolicy,
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
if (selectedPaymentMode) {
|
|
510
|
+
attributes.push({
|
|
511
|
+
attributeType: '8553afa0-bdb9-4d3c-8a98-05fa9350aa85',
|
|
512
|
+
value: selectedPaymentMode.uuid,
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
if (selectedPatientType) {
|
|
516
|
+
attributes.push({
|
|
517
|
+
attributeType: 'fbc0702d-b4c9-4968-be63-af8ad3ad6239',
|
|
518
|
+
value: selectedPatientType,
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
if (selectedPaymentDetail === PaymentDetail.NonPaying) {
|
|
522
|
+
attributes.push({
|
|
523
|
+
attributeType: 'df0362f9-782e-4d92-8bb2-3112e9e9eb3c',
|
|
524
|
+
value: 'true',
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
return attributes;
|
|
528
|
+
}
|
|
529
|
+
async function getServiceQueues() {
|
|
530
|
+
try {
|
|
531
|
+
const sqs = await getFacilityServiceQueues(locationUuid);
|
|
532
|
+
if (sqs && sqs.length > 0) {
|
|
533
|
+
const triageServiceQueues = getTriageServiceQueues(sqs);
|
|
534
|
+
setServiceQueues(triageServiceQueues);
|
|
535
|
+
}
|
|
536
|
+
} catch (e) {
|
|
537
|
+
showSnackbar({
|
|
538
|
+
kind: 'error',
|
|
539
|
+
title: 'An error occurred while fetching service queues',
|
|
540
|
+
subtitle: e.message ?? 'An error occurred while fetching service queues, please try agin',
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
function getTriageServiceQueues(serviceQueues: ServiceQueue[]) {
|
|
545
|
+
return serviceQueues.filter((sq) => {
|
|
546
|
+
return registrationServicequeues.includes(sq.uuid ?? '')
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
async function getPaymentMethods() {
|
|
551
|
+
const methods = await fetchPaymentModes();
|
|
552
|
+
setPaymentModes(methods);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
async function getBillableServices() {
|
|
556
|
+
const billableServices = await fetchBillableServices();
|
|
557
|
+
setBillableServices(billableServices);
|
|
558
|
+
generateServiceTypesList(billableServices);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
async function getCashPoints() {
|
|
562
|
+
const cp = await fetchCashPoints();
|
|
563
|
+
setCashPoints(cp);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
function getfacilityCashpoints() {
|
|
567
|
+
return cashPoints.filter((cp) => {
|
|
568
|
+
return cp && cp.location?.uuid === locationUuid;
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
function generateServiceTypesList(billableServices: BillableService[]) {
|
|
573
|
+
const sp: ServicePrice[] = [];
|
|
574
|
+
for (let bs of billableServices) {
|
|
575
|
+
if (bs.servicePrices) {
|
|
576
|
+
const servicePrices = bs.servicePrices;
|
|
577
|
+
for (let servicePrice of servicePrices) {
|
|
578
|
+
sp.push(servicePrice);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
setServicePrices(sp);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
function generateCreateBillDto(): CreateBillDto {
|
|
586
|
+
const payload: CreateBillDto = {
|
|
587
|
+
lineItems: [
|
|
588
|
+
{
|
|
589
|
+
billableService: selectedBillableService.billableService.uuid,
|
|
590
|
+
quantity: 1,
|
|
591
|
+
price: selectedBillableService.price,
|
|
592
|
+
priceName: selectedBillableService.name,
|
|
593
|
+
priceUuid: selectedBillableService.uuid,
|
|
594
|
+
lineItemOrder: 0,
|
|
595
|
+
paymentStatus: 'PENDING',
|
|
596
|
+
},
|
|
597
|
+
],
|
|
598
|
+
cashPoint: selectedCashPoint.uuid,
|
|
599
|
+
patient: selectedPatient.uuid,
|
|
600
|
+
status: 'PENDING',
|
|
601
|
+
payments: [],
|
|
602
|
+
};
|
|
603
|
+
return payload;
|
|
604
|
+
}
|
|
605
|
+
function isValidCreateBillDto(createBillDto: CreateBillDto): boolean {
|
|
606
|
+
if (!createBillDto.patient) {
|
|
607
|
+
showAlert('error', 'Please select a patient', '');
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
if (!createBillDto.status) {
|
|
611
|
+
showAlert('error', 'Bill does not have a status', '');
|
|
612
|
+
return false;
|
|
613
|
+
}
|
|
614
|
+
if (!createBillDto.cashPoint) {
|
|
615
|
+
showAlert('error', 'Please select a valid cashpoint', '');
|
|
616
|
+
return false;
|
|
617
|
+
}
|
|
618
|
+
if (!createBillDto.lineItems || createBillDto.lineItems.length === 0) {
|
|
619
|
+
showAlert('error', 'Please select a valid billable service', '');
|
|
620
|
+
return false;
|
|
621
|
+
}
|
|
622
|
+
return true;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
function hasSelectedPaymentMode(paymentMode: string): boolean {
|
|
626
|
+
if (!selectedPaymentMode) {
|
|
627
|
+
return false;
|
|
628
|
+
}
|
|
629
|
+
console.log(selectedPaymentMode);
|
|
630
|
+
return selectedPaymentMode.name.trim().toLowerCase().includes(paymentMode.trim().toLowerCase());
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function generateOrderEncounterPayload(patientUuid: string, visitUuid: string): CreateOrderEncounterDto {
|
|
634
|
+
return {
|
|
635
|
+
patient: patientUuid,
|
|
636
|
+
location: locationUuid,
|
|
637
|
+
encounterType: orderEncounterTypeUuid,
|
|
638
|
+
visit: visitUuid,
|
|
639
|
+
obs: [],
|
|
640
|
+
orders: [
|
|
641
|
+
{
|
|
642
|
+
action: 'NEW',
|
|
643
|
+
type: 'order',
|
|
644
|
+
patient: patientUuid,
|
|
645
|
+
careSetting: outPatientCareSettingUuid,
|
|
646
|
+
orderer: session.currentProvider.uuid ?? 'pd25871c-1359-11df-a1f1-0026b9348838',
|
|
647
|
+
encounter: null,
|
|
648
|
+
concept: getOrderConcept(selectedPaymentMode),
|
|
649
|
+
accessionNumber: null,
|
|
650
|
+
urgency: 'ROUTINE',
|
|
651
|
+
scheduledDate: null,
|
|
652
|
+
},
|
|
653
|
+
],
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
function getOrderConcept(paymentMode: PaymentMode) {
|
|
657
|
+
const paymentModeName = paymentMode.name.toLowerCase().trim();
|
|
658
|
+
if (paymentModeName.includes('cash')) {
|
|
659
|
+
return cashConsulationConceptUuid;
|
|
660
|
+
} else if (paymentModeName.includes('sha')) {
|
|
661
|
+
return shaConsulationConceptUuid;
|
|
662
|
+
} else {
|
|
663
|
+
return '';
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
async function createOrder(patientUuid: string, visitUuid: string) {
|
|
667
|
+
const createOrderPayload = generateOrderEncounterPayload(patientUuid, visitUuid);
|
|
668
|
+
try {
|
|
669
|
+
const resp = await createOrderEncounter(createOrderPayload);
|
|
670
|
+
if (resp) {
|
|
671
|
+
showAlert('success', 'Consultation order created', 'Consultation order has been succesfully created');
|
|
672
|
+
}
|
|
673
|
+
} catch (error) {
|
|
674
|
+
showAlert(
|
|
675
|
+
'error',
|
|
676
|
+
'Error creating consulation order',
|
|
677
|
+
'An error occurred while generating the consultation order. Please contact support',
|
|
678
|
+
);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
return (
|
|
683
|
+
<>
|
|
684
|
+
<Modal
|
|
685
|
+
open={open}
|
|
686
|
+
size="md"
|
|
687
|
+
onSecondarySubmit={() => onModalClose({ success: false })}
|
|
688
|
+
onRequestClose={() => onModalClose({ success: false })}
|
|
689
|
+
onRequestSubmit={sendToTriage}
|
|
690
|
+
primaryButtonText={loading ? 'Sending...please wait' : 'Send to Triage'}
|
|
691
|
+
secondaryButtonText="Cancel"
|
|
692
|
+
>
|
|
693
|
+
<ModalBody>
|
|
694
|
+
<div className={styles.clientDetailsLayout}>
|
|
695
|
+
<div className={styles.sectionHeader}>
|
|
696
|
+
<h4 className={styles.sectionTitle}>Send To Triage</h4>
|
|
697
|
+
</div>
|
|
698
|
+
{patients.length > 0 ? (
|
|
699
|
+
<div className={styles.sectionContent}>
|
|
700
|
+
<div className={styles.patientSelect}>
|
|
701
|
+
<Table>
|
|
702
|
+
<TableHead>
|
|
703
|
+
<TableRow>
|
|
704
|
+
<TableHeader>No</TableHeader>
|
|
705
|
+
<TableHeader>Name</TableHeader>
|
|
706
|
+
<TableHeader>Gender</TableHeader>
|
|
707
|
+
<TableHeader>Select Patient</TableHeader>
|
|
708
|
+
</TableRow>
|
|
709
|
+
</TableHead>
|
|
710
|
+
<TableBody>
|
|
711
|
+
{patients.map((p, index) => (
|
|
712
|
+
<TableRow key={p.uuid}>
|
|
713
|
+
<TableCell>{index + 1}</TableCell>
|
|
714
|
+
<TableCell>{p.person.preferredName.display}</TableCell>
|
|
715
|
+
<TableCell>{p.person.gender}</TableCell>
|
|
716
|
+
<TableCell>
|
|
717
|
+
<Checkbox id={p.uuid} labelText="" onChange={() => onPatientSelect(p)} />
|
|
718
|
+
</TableCell>
|
|
719
|
+
</TableRow>
|
|
720
|
+
))}
|
|
721
|
+
</TableBody>
|
|
722
|
+
</Table>
|
|
723
|
+
</div>
|
|
724
|
+
<div className={styles.formSection}>
|
|
725
|
+
<div className={styles.formRow}>
|
|
726
|
+
<div className={styles.formControl}>
|
|
727
|
+
<ComboBox
|
|
728
|
+
onChange={patientTypeHandler}
|
|
729
|
+
id="patient-type-combobox"
|
|
730
|
+
items={patientTypeOptions}
|
|
731
|
+
itemToString={(item) => (item ? item.text : '')}
|
|
732
|
+
titleText="Patient Type"
|
|
733
|
+
/>
|
|
734
|
+
</div>
|
|
735
|
+
<div className={styles.formControl}>
|
|
736
|
+
<Select
|
|
737
|
+
id="payment-details"
|
|
738
|
+
labelText="Payment Details"
|
|
739
|
+
onChange={($event) => paymentDetailsHandler($event.target.value)}
|
|
740
|
+
>
|
|
741
|
+
<SelectItem value="" text="Select" />;
|
|
742
|
+
{paymentDetails.map((pd) => {
|
|
743
|
+
return <SelectItem value={pd.id} text={pd.label} />;
|
|
744
|
+
})}
|
|
745
|
+
</Select>
|
|
746
|
+
</div>
|
|
747
|
+
</div>
|
|
748
|
+
</div>
|
|
749
|
+
<div className={styles.formSection}>
|
|
750
|
+
{selectedPaymentDetail === PaymentDetail.Paying ? (
|
|
751
|
+
<>
|
|
752
|
+
<div className={styles.formRow}>
|
|
753
|
+
<div className={styles.formControl}>
|
|
754
|
+
<Select
|
|
755
|
+
id="payment-method"
|
|
756
|
+
labelText="Payment Method"
|
|
757
|
+
onChange={($event) => paymentMethodHandler($event.target.value)}
|
|
758
|
+
>
|
|
759
|
+
<SelectItem value="" text="Select" />;
|
|
760
|
+
{paymentModes &&
|
|
761
|
+
paymentModes.map((pm) => {
|
|
762
|
+
return <SelectItem value={pm.uuid} text={pm.name} />;
|
|
763
|
+
})}
|
|
764
|
+
</Select>
|
|
765
|
+
</div>
|
|
766
|
+
<div className={styles.formControl}>
|
|
767
|
+
<Select
|
|
768
|
+
id="billable-service"
|
|
769
|
+
labelText="Billable Services"
|
|
770
|
+
onChange={($event) => billableServicesHandler($event.target.value)}
|
|
771
|
+
>
|
|
772
|
+
<SelectItem value="" text="Select" />;
|
|
773
|
+
{filteredBillableServices &&
|
|
774
|
+
filteredBillableServices.map((sp) => {
|
|
775
|
+
return (
|
|
776
|
+
<SelectItem
|
|
777
|
+
value={sp.uuid}
|
|
778
|
+
text={`${sp.billableService.display}(${sp.name}:${sp.price})`}
|
|
779
|
+
/>
|
|
780
|
+
);
|
|
781
|
+
})}
|
|
782
|
+
</Select>
|
|
783
|
+
</div>
|
|
784
|
+
</div>
|
|
785
|
+
{/* If using SHA claim */}
|
|
786
|
+
{
|
|
787
|
+
hasSelectedPaymentMode('SHIF') ? (<>
|
|
788
|
+
{/* <ClaimsComponent clientRegistryId={patientIdentifiers.crIdentifierId} onSelectChange={() => { }} /> */}
|
|
789
|
+
<ExtensionSlot name='billing-claims-slot' state={{ clientRegistryId: patientIdentifiers?.crIdentifierId, onSelectChange: () => { } }} />
|
|
790
|
+
</>) : (<></>)
|
|
791
|
+
}
|
|
792
|
+
{hasSelectedPaymentMode('insurance') ? (
|
|
793
|
+
<>
|
|
794
|
+
<div className={styles.formRow}>
|
|
795
|
+
<div className={styles.formControl}>
|
|
796
|
+
<TextInput
|
|
797
|
+
id="insurance-scheme"
|
|
798
|
+
labelText="Insurance scheme"
|
|
799
|
+
onChange={(e) => insuranceSchemeHandler(e.target.value)}
|
|
800
|
+
/>
|
|
801
|
+
</div>
|
|
802
|
+
<div className={styles.formControl}>
|
|
803
|
+
<TextInput
|
|
804
|
+
id="policy-number"
|
|
805
|
+
labelText="Policy number"
|
|
806
|
+
onChange={(e) => insurancePolicyHandler(e.target.value)}
|
|
807
|
+
/>
|
|
808
|
+
</div>
|
|
809
|
+
</div>
|
|
810
|
+
</>
|
|
811
|
+
) : (
|
|
812
|
+
<></>
|
|
813
|
+
)}
|
|
814
|
+
<div className={styles.formRow}>
|
|
815
|
+
<div className={styles.formControl}>
|
|
816
|
+
<Select
|
|
817
|
+
id="cash-point"
|
|
818
|
+
labelText="Cash Point"
|
|
819
|
+
onChange={($event) => cashPointsHandler($event.target.value)}
|
|
820
|
+
>
|
|
821
|
+
<SelectItem value="" text="Select" />;
|
|
822
|
+
{facilityCashPoints &&
|
|
823
|
+
facilityCashPoints.map((cp) => {
|
|
824
|
+
return <SelectItem value={cp.uuid} text={cp.name} />;
|
|
825
|
+
})}
|
|
826
|
+
</Select>
|
|
827
|
+
</div>
|
|
828
|
+
</div>
|
|
829
|
+
</>
|
|
830
|
+
) : (
|
|
831
|
+
<></>
|
|
832
|
+
)}
|
|
833
|
+
|
|
834
|
+
{selectedPaymentDetail === PaymentDetail.NonPaying ? (
|
|
835
|
+
<>
|
|
836
|
+
<div className={styles.formRow}>
|
|
837
|
+
<div className={styles.formControl}>
|
|
838
|
+
<Select
|
|
839
|
+
id="patient-category"
|
|
840
|
+
labelText="Patient Category"
|
|
841
|
+
onChange={($event) => patientCategoryHandler($event.target.value)}
|
|
842
|
+
>
|
|
843
|
+
<SelectItem value="" text="Select" />;
|
|
844
|
+
<SelectItem value={PatientCategories.CCC_PATIENT_UUID} text="CCC" />;
|
|
845
|
+
<SelectItem value={PatientCategories.MCH_PATIENT_UUID} text="MCH" />;
|
|
846
|
+
</Select>
|
|
847
|
+
</div>
|
|
848
|
+
</div>
|
|
849
|
+
</>
|
|
850
|
+
) : (
|
|
851
|
+
<></>
|
|
852
|
+
)}
|
|
853
|
+
</div>
|
|
854
|
+
<div className={styles.formSection}>
|
|
855
|
+
<div className={styles.formRow}>
|
|
856
|
+
<div className={styles.formControl}>
|
|
857
|
+
<ComboBox
|
|
858
|
+
onChange={visitTypeChangeHandler}
|
|
859
|
+
id="visit-type-combobox"
|
|
860
|
+
items={visitTypeOptions}
|
|
861
|
+
itemToString={(item) => (item ? item.text : '')}
|
|
862
|
+
titleText="Visit Type"
|
|
863
|
+
/>
|
|
864
|
+
</div>
|
|
865
|
+
<div className={styles.formControl}>
|
|
866
|
+
<Select id="service" labelText="Select a Queue Service" onChange={serviceChangeHandler}>
|
|
867
|
+
<SelectItem value="" text="Select" />;
|
|
868
|
+
{serviceQueues &&
|
|
869
|
+
serviceQueues.map((sq) => {
|
|
870
|
+
return <SelectItem value={sq.uuid} text={`${sq.display}`} />;
|
|
871
|
+
})}
|
|
872
|
+
</Select>
|
|
873
|
+
</div>
|
|
874
|
+
</div>
|
|
875
|
+
<div className={styles.formRow}>
|
|
876
|
+
<div className={styles.formControl}>
|
|
877
|
+
<Select
|
|
878
|
+
id="priority"
|
|
879
|
+
labelText="Select Priority"
|
|
880
|
+
onChange={($event) => priorityChangeHandler($event.target.value)}
|
|
881
|
+
>
|
|
882
|
+
<SelectItem value="" text="Select" />;
|
|
883
|
+
<SelectItem value={QUEUE_PRIORITIES_UUIDS.NORMAL_PRIORITY_UUID} text="PRIORITY" />;
|
|
884
|
+
<SelectItem value={QUEUE_PRIORITIES_UUIDS.NOT_URGENT_PRIORITY_UUID} text="NON URGENT" />;
|
|
885
|
+
<SelectItem value={QUEUE_PRIORITIES_UUIDS.EMERGENCY_PRIORITY_UUID} text="EMERGENCY" />;
|
|
886
|
+
</Select>
|
|
887
|
+
</div>
|
|
888
|
+
</div>
|
|
889
|
+
</div>
|
|
890
|
+
</div>
|
|
891
|
+
) : (
|
|
892
|
+
<></>
|
|
893
|
+
)}
|
|
894
|
+
<div className={styles.actionSection}>
|
|
895
|
+
{patients.length === 0 ? (
|
|
896
|
+
<>
|
|
897
|
+
<div className={styles.patientAction}>
|
|
898
|
+
<div className={styles.btnContainer}>
|
|
899
|
+
<Button kind="primary" onClick={() => onCreateAmrsPatient(client)}>
|
|
900
|
+
Automatically Register in AMRS
|
|
901
|
+
</Button>
|
|
902
|
+
</div>
|
|
903
|
+
<div className={styles.btnContainer}>
|
|
904
|
+
<Button kind="secondary" onClick={onManualRegistration}>
|
|
905
|
+
Manually Register
|
|
906
|
+
</Button>
|
|
907
|
+
</div>
|
|
908
|
+
</div>
|
|
909
|
+
</>
|
|
910
|
+
) : (
|
|
911
|
+
<></>
|
|
912
|
+
)}
|
|
913
|
+
</div>
|
|
914
|
+
</div>
|
|
915
|
+
</ModalBody>
|
|
916
|
+
</Modal>
|
|
917
|
+
</>
|
|
918
|
+
);
|
|
919
|
+
};
|
|
920
|
+
|
|
921
|
+
export default SendToTriageModal;
|