From 15ed20fc9c5658a9552d7eadae8fc139bac1ab92 Mon Sep 17 00:00:00 2001 From: Parth Kothari Date: Mon, 5 Feb 2024 14:03:33 +0530 Subject: [PATCH 001/139] Intial commit for develop for testing --- .eslintrc.json | 4 +- package-lock.json | 251 ++++++++-- package.json | 1 + .../app-footer/app-footer.component.css | 54 +++ .../app-footer/app-footer.component.html | 58 +++ .../app-footer/app-footer.component.spec.ts | 45 ++ .../app-footer/app-footer.component.ts | 60 +++ .../app-header/app-header.component.css | 129 +++++ .../app-header/app-header.component.html | 217 +++++++++ .../app-header/app-header.component.spec.ts | 221 +++++++++ .../app-header/app-header.component.ts | 345 ++++++++++++++ .../batch-adjustment.component.css | 44 ++ .../batch-adjustment.component.html | 111 +++++ .../batch-adjustment.component.spec.ts | 45 ++ .../batch-adjustment.component.ts | 96 ++++ .../batch-search/batch-search.component.css | 42 ++ .../batch-search/batch-search.component.html | 110 +++++ .../batch-search.component.spec.ts | 45 ++ .../batch-search/batch-search.component.ts | 96 ++++ .../beneficiary-details.component.css | 15 + .../beneficiary-details.component.html | 63 +++ .../beneficiary-details.component.spec.ts | 45 ++ .../beneficiary-details.component.ts | 96 ++++ .../indent-item-list.component.css | 35 ++ .../indent-item-list.component.html | 93 ++++ .../indent-item-list.component.spec.ts | 45 ++ .../indent-item-list.component.ts | 92 ++++ .../item-dispense/item-dispense.component.css | 36 ++ .../item-dispense.component.html | 89 ++++ .../item-dispense.component.spec.ts | 45 ++ .../item-dispense/item-dispense.component.ts | 87 ++++ .../item-search/item-search.component.css | 36 ++ .../item-search/item-search.component.html | 185 ++++++++ .../item-search/item-search.component.spec.ts | 45 ++ .../item-search/item-search.component.ts | 87 ++++ .../rx-batch-view/rx-batch-view.component.css | 75 +++ .../rx-batch-view.component.html | 71 +++ .../rx-batch-view.component.spec.ts | 45 ++ .../rx-batch-view/rx-batch-view.component.ts | 176 +++++++ .../components/search/search.component.css | 52 ++ .../components/search/search.component.html | 377 +++++++++++++++ .../search/search.component.spec.ts | 45 ++ .../components/search/search.component.ts | 290 ++++++++++++ ...w-commit-and-version-details.component.css | 24 + ...-commit-and-version-details.component.html | 33 ++ ...mmit-and-version-details.component.spec.ts | 45 ++ ...ow-commit-and-version-details.component.ts | 57 +++ .../components/spinner/spinner.component.css | 35 ++ .../components/spinner/spinner.component.html | 5 + .../spinner/spinner.component.spec.ts | 45 ++ .../components/spinner/spinner.component.ts | 49 ++ .../textarea-dialog.component.css | 3 + .../textarea-dialog.component.html | 16 + .../textarea-dialog.component.spec.ts | 45 ++ .../textarea-dialog.component.ts | 60 +++ .../textarea-dialog.service.ts | 37 ++ .../transfer-search.component.css | 42 ++ .../transfer-search.component.html | 105 +++++ .../transfer-search.component.spec.ts | 45 ++ .../transfer-search.component.ts | 96 ++++ src/app/app-modules/core/core.module.ts | 161 ++++--- .../MobileNumber/myMobileNumber.directive.ts | 88 ++++ .../directives/batch-adjustment.directive.ts | 115 +++++ .../core/directives/batch-search.directive.ts | 115 +++++ .../disableFormControl.directive.ts | 39 ++ .../directives/email/myEmail.directive.ts | 68 +++ .../directives/indent-dispense.directive.ts | 75 +++ .../directives/indent-request.directive.ts | 99 ++++ .../directives/item-dispense.directive.ts | 80 ++++ .../core/directives/item-search.directive.ts | 79 ++++ .../directives/item-transfer.directive.ts | 117 +++++ .../minNumberValidator.directive.ts | 80 ++++ .../core/directives/name/myName.directive.ts | 48 ++ .../null-default-value.directive.ts | 49 ++ .../directives/numberValidator.directive.ts | 81 ++++ .../password/myPassword.directive.ts | 78 +++ .../directives/stringValidator.directive.ts | 206 ++++++++ .../app-modules/core/pipes/ist-date.pipe.ts | 32 ++ .../core/services/confirmation.service.ts | 14 +- .../core/services/http-interceptor.service.ts | 103 +++- .../dashboard/dashboard.component.css | 3 + .../dashboard/dashboard.component.html | 5 + .../dashboard/dashboard.component.spec.ts | 45 ++ .../dashboard/dashboard.component.ts | 31 ++ .../dynamic-print/dynamic-print.component.css | 54 +++ .../dynamic-print.component.html | 103 ++++ .../dynamic-print.component.spec.ts | 45 ++ .../dynamic-print/dynamic-print.component.ts | 93 ++++ .../inventory/inventory-routing.module.ts | 219 +++++++++ .../app-modules/inventory/inventory.module.ts | 249 ++++++++++ .../manual-medicine-dispense.component.css | 35 ++ .../manual-medicine-dispense.component.html | 130 +++++ ...manual-medicine-dispense.component.spec.ts | 45 ++ .../manual-medicine-dispense.component.ts | 388 +++++++++++++++ .../select-batch/select-batch.component.css | 58 +++ .../select-batch/select-batch.component.html | 117 +++++ .../select-batch.component.spec.ts | 45 ++ .../select-batch/select-batch.component.ts | 276 +++++++++++ .../medicine-dispense.component.css | 46 ++ .../medicine-dispense.component.html | 217 +++++++++ .../medicine-dispense.component.spec.ts | 45 ++ .../medicine-dispense.component.ts | 343 ++++++++++++++ .../show-batch-item.component.css | 38 ++ .../show-batch-item.component.html | 67 +++ .../show-batch-item.component.spec.ts | 45 ++ .../show-batch-item.component.ts | 129 +++++ .../system-medicine-dispense.component.css | 31 ++ .../system-medicine-dispense.component.html | 222 +++++++++ ...system-medicine-dispense.component.spec.ts | 45 ++ .../system-medicine-dispense.component.ts | 390 +++++++++++++++ ...ew-medicine-dispense-details.component.css | 39 ++ ...w-medicine-dispense-details.component.html | 119 +++++ ...edicine-dispense-details.component.spec.ts | 45 ++ ...iew-medicine-dispense-details.component.ts | 209 +++++++++ .../view-medicine-dispense.component.css | 50 ++ .../view-medicine-dispense.component.html | 308 ++++++++++++ .../view-medicine-dispense.component.spec.ts | 45 ++ .../view-medicine-dispense.component.ts | 216 +++++++++ .../benificiary-details.component.css | 37 ++ .../benificiary-details.component.html | 61 +++ .../benificiary-details.component.spec.ts | 45 ++ .../benificiary-details.component.ts | 67 +++ ...h-details-for-patient-return.component.css | 83 ++++ ...-details-for-patient-return.component.html | 91 ++++ ...tails-for-patient-return.component.spec.ts | 47 ++ ...ch-details-for-patient-return.component.ts | 259 ++++++++++ ...patient-return-batch-details.component.css | 38 ++ ...atient-return-batch-details.component.html | 120 +++++ ...ent-return-batch-details.component.spec.ts | 45 ++ .../patient-return-batch-details.component.ts | 305 ++++++++++++ ...tient-return-previous-record.component.css | 33 ++ ...ient-return-previous-record.component.html | 163 +++++++ ...t-return-previous-record.component.spec.ts | 45 ++ ...atient-return-previous-record.component.ts | 154 ++++++ .../patient-return.component.css | 83 ++++ .../patient-return.component.html | 111 +++++ .../patient-return.component.spec.ts | 45 ++ .../patient-return.component.ts | 222 +++++++++ .../physical-stock-entry.component.css | 47 ++ .../physical-stock-entry.component.html | 283 +++++++++++ .../physical-stock-entry.component.spec.ts | 45 ++ .../physical-stock-entry.component.ts | 262 +++++++++++ .../view-physical-stock-details.component.css | 34 ++ ...view-physical-stock-details.component.html | 148 ++++++ ...w-physical-stock-details.component.spec.ts | 45 ++ .../view-physical-stock-details.component.ts | 119 +++++ .../view-physical-stock.component.css | 25 + .../view-physical-stock.component.html | 399 ++++++++++++++++ .../view-physical-stock.component.spec.ts | 45 ++ .../view-physical-stock.component.ts | 331 +++++++++++++ .../service/data-storage.service.spec.ts | 39 ++ .../shared/service/data-storage.service.ts | 34 ++ .../shared/service/indent-dispense.service.ts | 42 ++ .../service/inventory-master.service.spec.ts | 39 ++ .../service/inventory-master.service.ts | 25 + .../shared/service/inventory.service.spec.ts | 39 ++ .../shared/service/inventory.service.ts | 378 +++++++++++++++ .../service/prescribed-drug.service.spec.ts | 39 ++ .../shared/service/prescribed-drug.service.ts | 69 +++ .../store-self-consumption.component.css | 51 ++ .../store-self-consumption.component.html | 299 ++++++++++++ .../store-self-consumption.component.spec.ts | 45 ++ .../store-self-consumption.component.ts | 233 +++++++++ ...ore-self-consumption-details.component.css | 34 ++ ...re-self-consumption-details.component.html | 120 +++++ ...self-consumption-details.component.spec.ts | 45 ++ ...tore-self-consumption-details.component.ts | 103 ++++ .../view-store-self-consumption.component.css | 29 ++ ...view-store-self-consumption.component.html | 172 +++++++ ...w-store-self-consumption.component.spec.ts | 45 ++ .../view-store-self-consumption.component.ts | 322 +++++++++++++ .../store-stock-adjustment.component.css | 74 +++ .../store-stock-adjustment.component.html | 419 +++++++++++++++++ .../store-stock-adjustment.component.spec.ts | 45 ++ .../store-stock-adjustment.component.ts | 443 ++++++++++++++++++ ...iew-stock-adjustment-details.component.css | 34 ++ ...ew-stock-adjustment-details.component.html | 121 +++++ ...stock-adjustment-details.component.spec.ts | 45 ++ ...view-stock-adjustment-details.component.ts | 119 +++++ ...ock-adjustment-draft-details.component.css | 38 ++ ...ck-adjustment-draft-details.component.html | 125 +++++ ...adjustment-draft-details.component.spec.ts | 45 ++ ...tock-adjustment-draft-details.component.ts | 121 +++++ ...store-stock-adjustment-draft.component.css | 30 ++ ...tore-stock-adjustment-draft.component.html | 163 +++++++ ...e-stock-adjustment-draft.component.spec.ts | 45 ++ ...-store-stock-adjustment-draft.component.ts | 268 +++++++++++ .../view-store-stock-adjustment.component.css | 33 ++ ...view-store-stock-adjustment.component.html | 163 +++++++ ...w-store-stock-adjustment.component.spec.ts | 45 ++ .../view-store-stock-adjustment.component.ts | 270 +++++++++++ .../store-stock-transfer.component.css | 50 ++ .../store-stock-transfer.component.html | 148 ++++++ .../store-stock-transfer.component.spec.ts | 45 ++ .../store-stock-transfer.component.ts | 289 ++++++++++++ ...store-stock-transfer-details.component.css | 34 ++ ...tore-stock-transfer-details.component.html | 121 +++++ ...e-stock-transfer-details.component.spec.ts | 45 ++ ...-store-stock-transfer-details.component.ts | 104 ++++ .../view-store-stock-transfer.component.css | 81 ++++ .../view-store-stock-transfer.component.html | 193 ++++++++ ...iew-store-stock-transfer.component.spec.ts | 45 ++ .../view-store-stock-transfer.component.ts | 340 ++++++++++++++ .../inventory/workarea/workarea.component.css | 13 + .../workarea/workarea.component.html | 1 + .../workarea/workarea.component.spec.ts | 45 ++ .../inventory/workarea/workarea.component.ts | 44 ++ src/app/app-routing.module.ts | 45 +- src/app/app.component.html | 2 +- src/app/app.module.ts | 36 +- .../facility-selection.component.css | 15 + .../facility-selection.component.html | 118 +++++ .../facility-selection.component.spec.ts | 45 ++ .../facility-selection.component.ts | 171 +++++++ .../facilty-resolve.service.ts | 25 + src/app/facility-selection/facilty.service.ts | 43 ++ .../load-store-details.component.css | 35 ++ .../load-store-details.component.html | 5 + .../load-store-details.component.spec.ts | 45 ++ .../load-store-details.component.ts | 35 ++ src/app/login/login.component.html | 8 +- src/environments/environment.ts | 16 +- src/index.html | 13 + src/service/service.component.css | 52 ++ src/service/service.component.html | 29 ++ src/service/service.component.spec.ts | 45 ++ src/service/service.component.ts | 52 ++ 227 files changed, 22204 insertions(+), 172 deletions(-) create mode 100644 src/app/app-modules/core/components/app-footer/app-footer.component.css create mode 100644 src/app/app-modules/core/components/app-footer/app-footer.component.html create mode 100644 src/app/app-modules/core/components/app-footer/app-footer.component.spec.ts create mode 100644 src/app/app-modules/core/components/app-footer/app-footer.component.ts create mode 100644 src/app/app-modules/core/components/app-header/app-header.component.css create mode 100644 src/app/app-modules/core/components/app-header/app-header.component.html create mode 100644 src/app/app-modules/core/components/app-header/app-header.component.spec.ts create mode 100644 src/app/app-modules/core/components/app-header/app-header.component.ts create mode 100644 src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.css create mode 100644 src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.html create mode 100644 src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.spec.ts create mode 100644 src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.ts create mode 100644 src/app/app-modules/core/components/batch-search/batch-search.component.css create mode 100644 src/app/app-modules/core/components/batch-search/batch-search.component.html create mode 100644 src/app/app-modules/core/components/batch-search/batch-search.component.spec.ts create mode 100644 src/app/app-modules/core/components/batch-search/batch-search.component.ts create mode 100644 src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.css create mode 100644 src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.html create mode 100644 src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.spec.ts create mode 100644 src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.ts create mode 100644 src/app/app-modules/core/components/indent-item-list/indent-item-list.component.css create mode 100644 src/app/app-modules/core/components/indent-item-list/indent-item-list.component.html create mode 100644 src/app/app-modules/core/components/indent-item-list/indent-item-list.component.spec.ts create mode 100644 src/app/app-modules/core/components/indent-item-list/indent-item-list.component.ts create mode 100644 src/app/app-modules/core/components/item-dispense/item-dispense.component.css create mode 100644 src/app/app-modules/core/components/item-dispense/item-dispense.component.html create mode 100644 src/app/app-modules/core/components/item-dispense/item-dispense.component.spec.ts create mode 100644 src/app/app-modules/core/components/item-dispense/item-dispense.component.ts create mode 100644 src/app/app-modules/core/components/item-search/item-search.component.css create mode 100644 src/app/app-modules/core/components/item-search/item-search.component.html create mode 100644 src/app/app-modules/core/components/item-search/item-search.component.spec.ts create mode 100644 src/app/app-modules/core/components/item-search/item-search.component.ts create mode 100644 src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.css create mode 100644 src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.html create mode 100644 src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.spec.ts create mode 100644 src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.ts create mode 100644 src/app/app-modules/core/components/search/search.component.css create mode 100644 src/app/app-modules/core/components/search/search.component.html create mode 100644 src/app/app-modules/core/components/search/search.component.spec.ts create mode 100644 src/app/app-modules/core/components/search/search.component.ts create mode 100644 src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.css create mode 100644 src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.html create mode 100644 src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.spec.ts create mode 100644 src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.ts create mode 100644 src/app/app-modules/core/components/spinner/spinner.component.css create mode 100644 src/app/app-modules/core/components/spinner/spinner.component.html create mode 100644 src/app/app-modules/core/components/spinner/spinner.component.spec.ts create mode 100644 src/app/app-modules/core/components/spinner/spinner.component.ts create mode 100644 src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.css create mode 100644 src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.html create mode 100644 src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.spec.ts create mode 100644 src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.ts create mode 100644 src/app/app-modules/core/components/textarea-dialog/textarea-dialog.service.ts create mode 100644 src/app/app-modules/core/components/transfer-search/transfer-search.component.css create mode 100644 src/app/app-modules/core/components/transfer-search/transfer-search.component.html create mode 100644 src/app/app-modules/core/components/transfer-search/transfer-search.component.spec.ts create mode 100644 src/app/app-modules/core/components/transfer-search/transfer-search.component.ts create mode 100644 src/app/app-modules/core/directives/MobileNumber/myMobileNumber.directive.ts create mode 100644 src/app/app-modules/core/directives/batch-adjustment.directive.ts create mode 100644 src/app/app-modules/core/directives/batch-search.directive.ts create mode 100644 src/app/app-modules/core/directives/disableFormControl.directive.ts create mode 100644 src/app/app-modules/core/directives/email/myEmail.directive.ts create mode 100644 src/app/app-modules/core/directives/indent-dispense.directive.ts create mode 100644 src/app/app-modules/core/directives/indent-request.directive.ts create mode 100644 src/app/app-modules/core/directives/item-dispense.directive.ts create mode 100644 src/app/app-modules/core/directives/item-search.directive.ts create mode 100644 src/app/app-modules/core/directives/item-transfer.directive.ts create mode 100644 src/app/app-modules/core/directives/minNumberValidator.directive.ts create mode 100644 src/app/app-modules/core/directives/name/myName.directive.ts create mode 100644 src/app/app-modules/core/directives/null-default-value.directive.ts create mode 100644 src/app/app-modules/core/directives/numberValidator.directive.ts create mode 100644 src/app/app-modules/core/directives/password/myPassword.directive.ts create mode 100644 src/app/app-modules/core/directives/stringValidator.directive.ts create mode 100644 src/app/app-modules/core/pipes/ist-date.pipe.ts create mode 100644 src/app/app-modules/inventory/dashboard/dashboard.component.css create mode 100644 src/app/app-modules/inventory/dashboard/dashboard.component.html create mode 100644 src/app/app-modules/inventory/dashboard/dashboard.component.spec.ts create mode 100644 src/app/app-modules/inventory/dashboard/dashboard.component.ts create mode 100644 src/app/app-modules/inventory/dynamic-print/dynamic-print.component.css create mode 100644 src/app/app-modules/inventory/dynamic-print/dynamic-print.component.html create mode 100644 src/app/app-modules/inventory/dynamic-print/dynamic-print.component.spec.ts create mode 100644 src/app/app-modules/inventory/dynamic-print/dynamic-print.component.ts create mode 100644 src/app/app-modules/inventory/inventory-routing.module.ts create mode 100644 src/app/app-modules/inventory/inventory.module.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.css create mode 100644 src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.html create mode 100644 src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.spec.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.css create mode 100644 src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.html create mode 100644 src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.spec.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.css create mode 100644 src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.html create mode 100644 src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.spec.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.css create mode 100644 src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.html create mode 100644 src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.spec.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.css create mode 100644 src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.html create mode 100644 src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.spec.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.css create mode 100644 src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.html create mode 100644 src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.spec.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.css create mode 100644 src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.html create mode 100644 src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.spec.ts create mode 100644 src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.ts create mode 100644 src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.css create mode 100644 src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.html create mode 100644 src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.spec.ts create mode 100644 src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.ts create mode 100644 src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.css create mode 100644 src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.html create mode 100644 src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.spec.ts create mode 100644 src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.ts create mode 100644 src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.css create mode 100644 src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.html create mode 100644 src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.spec.ts create mode 100644 src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.ts create mode 100644 src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.css create mode 100644 src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.html create mode 100644 src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.spec.ts create mode 100644 src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.ts create mode 100644 src/app/app-modules/inventory/patient-return/patient-return.component.css create mode 100644 src/app/app-modules/inventory/patient-return/patient-return.component.html create mode 100644 src/app/app-modules/inventory/patient-return/patient-return.component.spec.ts create mode 100644 src/app/app-modules/inventory/patient-return/patient-return.component.ts create mode 100644 src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.css create mode 100644 src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.html create mode 100644 src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.spec.ts create mode 100644 src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.ts create mode 100644 src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.css create mode 100644 src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.html create mode 100644 src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.spec.ts create mode 100644 src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.ts create mode 100644 src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.css create mode 100644 src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.html create mode 100644 src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.spec.ts create mode 100644 src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.ts create mode 100644 src/app/app-modules/inventory/shared/service/data-storage.service.spec.ts create mode 100644 src/app/app-modules/inventory/shared/service/data-storage.service.ts create mode 100644 src/app/app-modules/inventory/shared/service/indent-dispense.service.ts create mode 100644 src/app/app-modules/inventory/shared/service/inventory-master.service.spec.ts create mode 100644 src/app/app-modules/inventory/shared/service/inventory-master.service.ts create mode 100644 src/app/app-modules/inventory/shared/service/inventory.service.spec.ts create mode 100644 src/app/app-modules/inventory/shared/service/inventory.service.ts create mode 100644 src/app/app-modules/inventory/shared/service/prescribed-drug.service.spec.ts create mode 100644 src/app/app-modules/inventory/shared/service/prescribed-drug.service.ts create mode 100644 src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.css create mode 100644 src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.html create mode 100644 src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.spec.ts create mode 100644 src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.ts create mode 100644 src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.css create mode 100644 src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.html create mode 100644 src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.spec.ts create mode 100644 src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.ts create mode 100644 src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.css create mode 100644 src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.html create mode 100644 src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.spec.ts create mode 100644 src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.ts create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.css create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.html create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.spec.ts create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.ts create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.css create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.html create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.spec.ts create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.ts create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.css create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.html create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.spec.ts create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.ts create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.css create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.html create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.spec.ts create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.ts create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.css create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.html create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.spec.ts create mode 100644 src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.ts create mode 100644 src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.css create mode 100644 src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.html create mode 100644 src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.spec.ts create mode 100644 src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.ts create mode 100644 src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.css create mode 100644 src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.html create mode 100644 src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.spec.ts create mode 100644 src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.ts create mode 100644 src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.css create mode 100644 src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.html create mode 100644 src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.spec.ts create mode 100644 src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.ts create mode 100644 src/app/app-modules/inventory/workarea/workarea.component.css create mode 100644 src/app/app-modules/inventory/workarea/workarea.component.html create mode 100644 src/app/app-modules/inventory/workarea/workarea.component.spec.ts create mode 100644 src/app/app-modules/inventory/workarea/workarea.component.ts create mode 100644 src/app/facility-selection/facility-selection.component.css create mode 100644 src/app/facility-selection/facility-selection.component.html create mode 100644 src/app/facility-selection/facility-selection.component.spec.ts create mode 100644 src/app/facility-selection/facility-selection.component.ts create mode 100644 src/app/facility-selection/facilty-resolve.service.ts create mode 100644 src/app/facility-selection/facilty.service.ts create mode 100644 src/app/load-store-details/load-store-details.component.css create mode 100644 src/app/load-store-details/load-store-details.component.html create mode 100644 src/app/load-store-details/load-store-details.component.spec.ts create mode 100644 src/app/load-store-details/load-store-details.component.ts create mode 100644 src/service/service.component.css create mode 100644 src/service/service.component.html create mode 100644 src/service/service.component.spec.ts create mode 100644 src/service/service.component.ts diff --git a/.eslintrc.json b/.eslintrc.json index 62b4bcd..531cf78 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -35,7 +35,9 @@ ], "@typescript-eslint/no-explicit-any": 0, "@typescript-eslint/no-empty-function": 0, - "@typescript-eslint/no-unused-vars": 0 + "@typescript-eslint/no-unused-vars": 0, + "@angular-eslint/template/click-events-have-key-events": 0 + } }, { diff --git a/package-lock.json b/package-lock.json index 8a122f1..af606bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@angular/platform-browser-dynamic": "^16.2.0", "@angular/router": "^16.2.0", "angular": "^1.6.10", + "angular-moment": "^1.3.0", "bootstrap": "^5.3.2", "crypto-js": "^4.2.0", "rxjs": "~7.8.0", @@ -92,15 +93,15 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "16.2.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.2.11.tgz", - "integrity": "sha512-yNzUiAeg1WHMsFG9IBg4S/7dsMcEAMYQ1I360ib80c0T/IwRb8pHhOokrl5Mu8zfNqZ/dxH4ItKY1uIMDmuMGQ==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.2.12.tgz", + "integrity": "sha512-VVGKZ0N3gyR0DP7VrcZl4io3ruWYT94mrlyJsJMLlrYy/EX8JCvqrJC9c+dscrtKjhZzjwdyhszkJQY4JfwACA==", "dev": true, "dependencies": { "@ampproject/remapping": "2.2.1", - "@angular-devkit/architect": "0.1602.11", - "@angular-devkit/build-webpack": "0.1602.11", - "@angular-devkit/core": "16.2.11", + "@angular-devkit/architect": "0.1602.12", + "@angular-devkit/build-webpack": "0.1602.12", + "@angular-devkit/core": "16.2.12", "@babel/core": "7.22.9", "@babel/generator": "7.22.9", "@babel/helper-annotate-as-pure": "7.22.5", @@ -112,7 +113,7 @@ "@babel/runtime": "7.22.6", "@babel/template": "7.22.5", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "16.2.11", + "@ngtools/webpack": "16.2.12", "@vitejs/plugin-basic-ssl": "1.0.1", "ansi-colors": "4.1.3", "autoprefixer": "10.4.14", @@ -155,7 +156,7 @@ "text-table": "0.2.0", "tree-kill": "1.2.2", "tslib": "2.6.1", - "vite": "4.5.1", + "vite": "4.5.2", "webpack": "5.88.2", "webpack-dev-middleware": "6.1.1", "webpack-dev-server": "4.15.1", @@ -213,6 +214,48 @@ } } }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": { + "version": "0.1602.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1602.12.tgz", + "integrity": "sha512-19Fwwfx+KvJ01SyI6cstRgqT9+cwer8Ro1T27t1JqlGyOX8tY3pV78ulwxy2+wCzPjR18V6W7cb7Cv6fyK4xog==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "16.2.12", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.12.tgz", + "integrity": "sha512-o6ziQs+EcEonFezrsA46jbZqkQrs4ckS1bAQj93g5ZjGtieUz8l/U3lclvKpL/iEzWkGVViSYuP2KyW2oqTDiQ==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "2.3.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, "node_modules/@angular-devkit/build-angular/node_modules/tslib": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", @@ -220,12 +263,12 @@ "dev": true }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1602.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1602.11.tgz", - "integrity": "sha512-2Au6xRMxNugFkXP0LS1TwNE5gAfGW4g6yxC9P5j5p3kdGDnAVaZRTOKB9dg73i3uXtJHUMciYOThV0b78XRxwA==", + "version": "0.1602.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1602.12.tgz", + "integrity": "sha512-1lmR4jCkxPJuAFXReesEY3CB+/5jSebGE5ry6qJJvNm6kuSc9bzfTytrcwosVY+Q7kAA2ij7kAYw0loGbTjLWA==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1602.11", + "@angular-devkit/architect": "0.1602.12", "rxjs": "7.8.1" }, "engines": { @@ -238,6 +281,48 @@ "webpack-dev-server": "^4.0.0" } }, + "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/architect": { + "version": "0.1602.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1602.12.tgz", + "integrity": "sha512-19Fwwfx+KvJ01SyI6cstRgqT9+cwer8Ro1T27t1JqlGyOX8tY3pV78ulwxy2+wCzPjR18V6W7cb7Cv6fyK4xog==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "16.2.12", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/core": { + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.12.tgz", + "integrity": "sha512-o6ziQs+EcEonFezrsA46jbZqkQrs4ckS1bAQj93g5ZjGtieUz8l/U3lclvKpL/iEzWkGVViSYuP2KyW2oqTDiQ==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "2.3.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, "node_modules/@angular-devkit/core": { "version": "16.2.11", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.11.tgz", @@ -4091,9 +4176,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "16.2.11", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.2.11.tgz", - "integrity": "sha512-4ndXJ4s94ZsryVGSDk/waIDrUqXqdGWftoOEn81Zu+nkL9ncI/G1fNUlSJ5OqeKmMLxMFouoy+BuJfvT+gEgnQ==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.2.12.tgz", + "integrity": "sha512-f9R9Qsk8v+ffDxryl6PQ7Wnf2JCNd4dDXOH+d/AuF06VFiwcwGDRDZpmqkAXbFxQfcWTbT1FFvfoJ+SFcJgXLA==", "dev": true, "engines": { "node": "^16.14.0 || >=18.10.0", @@ -5770,6 +5855,17 @@ "integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw==", "deprecated": "For the actively supported Angular, see https://www.npmjs.com/package/@angular/core. AngularJS support has officially ended. For extended AngularJS support options, see https://goo.gle/angularjs-path-forward." }, + "node_modules/angular-moment": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.3.0.tgz", + "integrity": "sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==", + "dependencies": { + "moment": ">=2.8.0 <3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -6162,9 +6258,9 @@ "dev": true }, "node_modules/bonjour-service": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.0.tgz", - "integrity": "sha512-xdzMA6JGckxyJzZByjEWRcfKmDxXaGXZWVftah3FkCqdlePNS9DjHSUN5zkP4oEfz/t0EXXlro88EIhzwMB4zA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", @@ -12035,6 +12131,14 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "engines": { + "node": "*" + } + }, "node_modules/mrmime": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", @@ -16223,9 +16327,9 @@ } }, "node_modules/vite": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.1.tgz", - "integrity": "sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz", + "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==", "dev": true, "dependencies": { "esbuild": "^0.18.10", @@ -16977,15 +17081,15 @@ } }, "@angular-devkit/build-angular": { - "version": "16.2.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.2.11.tgz", - "integrity": "sha512-yNzUiAeg1WHMsFG9IBg4S/7dsMcEAMYQ1I360ib80c0T/IwRb8pHhOokrl5Mu8zfNqZ/dxH4ItKY1uIMDmuMGQ==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.2.12.tgz", + "integrity": "sha512-VVGKZ0N3gyR0DP7VrcZl4io3ruWYT94mrlyJsJMLlrYy/EX8JCvqrJC9c+dscrtKjhZzjwdyhszkJQY4JfwACA==", "dev": true, "requires": { "@ampproject/remapping": "2.2.1", - "@angular-devkit/architect": "0.1602.11", - "@angular-devkit/build-webpack": "0.1602.11", - "@angular-devkit/core": "16.2.11", + "@angular-devkit/architect": "0.1602.12", + "@angular-devkit/build-webpack": "0.1602.12", + "@angular-devkit/core": "16.2.12", "@babel/core": "7.22.9", "@babel/generator": "7.22.9", "@babel/helper-annotate-as-pure": "7.22.5", @@ -16997,7 +17101,7 @@ "@babel/runtime": "7.22.6", "@babel/template": "7.22.5", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "16.2.11", + "@ngtools/webpack": "16.2.12", "@vitejs/plugin-basic-ssl": "1.0.1", "ansi-colors": "4.1.3", "autoprefixer": "10.4.14", @@ -17041,7 +17145,7 @@ "text-table": "0.2.0", "tree-kill": "1.2.2", "tslib": "2.6.1", - "vite": "4.5.1", + "vite": "4.5.2", "webpack": "5.88.2", "webpack-dev-middleware": "6.1.1", "webpack-dev-server": "4.15.1", @@ -17049,6 +17153,30 @@ "webpack-subresource-integrity": "5.1.0" }, "dependencies": { + "@angular-devkit/architect": { + "version": "0.1602.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1602.12.tgz", + "integrity": "sha512-19Fwwfx+KvJ01SyI6cstRgqT9+cwer8Ro1T27t1JqlGyOX8tY3pV78ulwxy2+wCzPjR18V6W7cb7Cv6fyK4xog==", + "dev": true, + "requires": { + "@angular-devkit/core": "16.2.12", + "rxjs": "7.8.1" + } + }, + "@angular-devkit/core": { + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.12.tgz", + "integrity": "sha512-o6ziQs+EcEonFezrsA46jbZqkQrs4ckS1bAQj93g5ZjGtieUz8l/U3lclvKpL/iEzWkGVViSYuP2KyW2oqTDiQ==", + "dev": true, + "requires": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "2.3.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + } + }, "tslib": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", @@ -17058,13 +17186,39 @@ } }, "@angular-devkit/build-webpack": { - "version": "0.1602.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1602.11.tgz", - "integrity": "sha512-2Au6xRMxNugFkXP0LS1TwNE5gAfGW4g6yxC9P5j5p3kdGDnAVaZRTOKB9dg73i3uXtJHUMciYOThV0b78XRxwA==", + "version": "0.1602.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1602.12.tgz", + "integrity": "sha512-1lmR4jCkxPJuAFXReesEY3CB+/5jSebGE5ry6qJJvNm6kuSc9bzfTytrcwosVY+Q7kAA2ij7kAYw0loGbTjLWA==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1602.11", + "@angular-devkit/architect": "0.1602.12", "rxjs": "7.8.1" + }, + "dependencies": { + "@angular-devkit/architect": { + "version": "0.1602.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1602.12.tgz", + "integrity": "sha512-19Fwwfx+KvJ01SyI6cstRgqT9+cwer8Ro1T27t1JqlGyOX8tY3pV78ulwxy2+wCzPjR18V6W7cb7Cv6fyK4xog==", + "dev": true, + "requires": { + "@angular-devkit/core": "16.2.12", + "rxjs": "7.8.1" + } + }, + "@angular-devkit/core": { + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.12.tgz", + "integrity": "sha512-o6ziQs+EcEonFezrsA46jbZqkQrs4ckS1bAQj93g5ZjGtieUz8l/U3lclvKpL/iEzWkGVViSYuP2KyW2oqTDiQ==", + "dev": true, + "requires": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "2.3.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + } + } } }, "@angular-devkit/core": { @@ -19912,9 +20066,9 @@ } }, "@ngtools/webpack": { - "version": "16.2.11", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.2.11.tgz", - "integrity": "sha512-4ndXJ4s94ZsryVGSDk/waIDrUqXqdGWftoOEn81Zu+nkL9ncI/G1fNUlSJ5OqeKmMLxMFouoy+BuJfvT+gEgnQ==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.2.12.tgz", + "integrity": "sha512-f9R9Qsk8v+ffDxryl6PQ7Wnf2JCNd4dDXOH+d/AuF06VFiwcwGDRDZpmqkAXbFxQfcWTbT1FFvfoJ+SFcJgXLA==", "dev": true, "requires": {} }, @@ -21171,6 +21325,14 @@ "resolved": "https://registry.npmjs.org/angular/-/angular-1.8.3.tgz", "integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw==" }, + "angular-moment": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.3.0.tgz", + "integrity": "sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==", + "requires": { + "moment": ">=2.8.0 <3.0.0" + } + }, "ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -21468,9 +21630,9 @@ } }, "bonjour-service": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.0.tgz", - "integrity": "sha512-xdzMA6JGckxyJzZByjEWRcfKmDxXaGXZWVftah3FkCqdlePNS9DjHSUN5zkP4oEfz/t0EXXlro88EIhzwMB4zA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.3", @@ -25809,6 +25971,11 @@ "minimist": "^1.2.6" } }, + "moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==" + }, "mrmime": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", @@ -28866,9 +29033,9 @@ "dev": true }, "vite": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.1.tgz", - "integrity": "sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz", + "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==", "dev": true, "requires": { "esbuild": "^0.18.10", diff --git a/package.json b/package.json index 37653db..13214d8 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@angular/platform-browser-dynamic": "^16.2.0", "@angular/router": "^16.2.0", "angular": "^1.6.10", + "angular-moment": "^1.3.0", "bootstrap": "^5.3.2", "crypto-js": "^4.2.0", "rxjs": "~7.8.0", diff --git a/src/app/app-modules/core/components/app-footer/app-footer.component.css b/src/app/app-modules/core/components/app-footer/app-footer.component.css new file mode 100644 index 0000000..3cf8484 --- /dev/null +++ b/src/app/app-modules/core/components/app-footer/app-footer.component.css @@ -0,0 +1,54 @@ +footer { + background: rgb(37, 55, 70); + height: 25px; + padding: 3px; + color: white; +} + + .footer-text { + margin: 0px; + } + + .online { + background: green; + display: inline-block; + height: 10px; + width: 10px; + border-radius: 50%; + } + + .offline { + background: red; + display: inline-block; + height: 10px; + width: 10px; + border-radius: 50%; + } + + .spec { + margin-top: -6px; + } + + .netstate { + margin-top: 8px; + } + + .swymed-btn { + background: #354f64 + } + + .footer-text-year { + text-align: center; + } + + .footer-text-status { + text-align: right; + } + + .footerAlign { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 5px; + margin-right: 10px; + } \ No newline at end of file diff --git a/src/app/app-modules/core/components/app-footer/app-footer.component.html b/src/app/app-modules/core/components/app-footer/app-footer.component.html new file mode 100644 index 0000000..ac1c414 --- /dev/null +++ b/src/app/app-modules/core/components/app-footer/app-footer.component.html @@ -0,0 +1,58 @@ + diff --git a/src/app/app-modules/core/components/app-footer/app-footer.component.spec.ts b/src/app/app-modules/core/components/app-footer/app-footer.component.spec.ts new file mode 100644 index 0000000..da8b059 --- /dev/null +++ b/src/app/app-modules/core/components/app-footer/app-footer.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AppFooterComponent } from './app-footer.component'; + +describe('AppFooterComponent', () => { + let component: AppFooterComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [AppFooterComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AppFooterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + xit('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/app-footer/app-footer.component.ts b/src/app/app-modules/core/components/app-footer/app-footer.component.ts new file mode 100644 index 0000000..0f8ec96 --- /dev/null +++ b/src/app/app-modules/core/components/app-footer/app-footer.component.ts @@ -0,0 +1,60 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, DoCheck, OnInit } from '@angular/core'; +import { LanguageService } from '../../services/language.service'; +import { SetLanguageComponent } from '../set-language.component'; + +@Component({ + selector: 'app-footer', + templateUrl: './app-footer.component.html', + styleUrls: ['./app-footer.component.css'], +}) +export class AppFooterComponent implements OnInit, DoCheck { + today!: Date; + year: any; + status!: boolean; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor(public http_service: LanguageService) {} + + ngOnInit() { + this.today = new Date(); + this.year = this.today.getFullYear(); + setInterval(() => { + this.status = navigator.onLine; + }, 1000); + this.fetchLanguageResponse(); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/components/app-header/app-header.component.css b/src/app/app-modules/core/components/app-header/app-header.component.css new file mode 100644 index 0000000..ffe1ce8 --- /dev/null +++ b/src/app/app-modules/core/components/app-header/app-header.component.css @@ -0,0 +1,129 @@ +.navbar-iemr { + background-color: #253746; + color: white; + border-radius: 0px; + margin-bottom: 5px; + min-height: unset; + padding: 3px 0px; +} + +.icon-bar { + background-color: white; +} + +.navbar-brand { + padding: 0px 15px; + height: unset; +} + +li a { + outline: none; +} + +.navbar-iemr li { + float: right !important; +} + +.navbar-iemr li a:hover { + background: unset; +} + +.navbar-iemr .nav li a { + padding: 6px 8px; +} + +span.logoutIcon { + height: 21px; + width: 24px; + display: inline-block; + vertical-align: middle; + background: url(../../../../../assets/images/logoutIcon.png) no-repeat; +} + +li.telemed a img { + height: 24px; + width: 24px; +} + +li.logout a span.logoutIcon:hover { + background-position-y: -21px; +} + +#main-navbar { + padding: 5px 15px; + font-weight: bold; + background-color: rgba(37, 55, 70, 0.2); + box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, 0.1); +} + +.active { + background: rgba(37, 55, 70, 0.1); +} + +button.mat-button { + font-weight: bold; + width: 100%; +} + +.role-menu { + width: 100%; +} + +.helpAlign { + font-size: 26px; + vertical-align: middle; + text-align: center; + padding: 0px; + color: rgba(245, 245, 245, 0.877); + margin-top: 4px; +} + +@media (max-width: 500px) { + .container-fluid .navbar-collapse, + .container-fluid .navbar-header { + margin-left: 0px; + margin-right: 0px; + } +} + +@media (max-width: 760px) { + .navbar-brand { + padding: 5px 15px; + } +} + +.userInfo-btn { + width: 200px; + display: flex; + align-items: center; +} + +.userInfo-btn span { + margin-left: 10px; +} + +.alignDropDown { + margin-top: 3px; +} +.alignWord { + margin: 8px 10px; + +} +.container-fluid { + display: flex; + justify-content: space-between ; +} +.fluid-activities{ + display: flex; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid\9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} \ No newline at end of file diff --git a/src/app/app-modules/core/components/app-header/app-header.component.html b/src/app/app-modules/core/components/app-header/app-header.component.html new file mode 100644 index 0000000..86b1767 --- /dev/null +++ b/src/app/app-modules/core/components/app-header/app-header.component.html @@ -0,0 +1,217 @@ + + + + diff --git a/src/app/app-modules/core/components/app-header/app-header.component.spec.ts b/src/app/app-modules/core/components/app-header/app-header.component.spec.ts new file mode 100644 index 0000000..ce1cc76 --- /dev/null +++ b/src/app/app-modules/core/components/app-header/app-header.component.spec.ts @@ -0,0 +1,221 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + async, + ComponentFixture, + tick, + inject, + fakeAsync, + TestBed, +} from '@angular/core/testing'; +import { AuthService } from '../../services/auth.service'; +import { AppHeaderComponent } from './app-header.component'; +import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/from'; +import 'rxjs/add/observable/empty'; +import 'rxjs/add/observable/throw'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { Router, ActivatedRoute } from '@angular/router'; +import { MaterialModule } from '../../../core/material.module'; + +class RouterStub { + navigate(something) {} +} +class MockActivatedRoute { + snapshot = { + params: [null], + }; +} +class authServiceMock { + logoutUser() {} +} + +describe('AppHeaderComponent', () => { + let component: AppHeaderComponent; + let fixture: ComponentFixture; + let authService: AuthService; + let router: Router; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA], + imports: [MaterialModule, NoopAnimationsModule], + declarations: [AppHeaderComponent], + providers: [ + { provide: Router, useClass: RouterStub }, + { provide: ActivatedRoute, useClass: MockActivatedRoute }, + { provide: AuthService, useClass: authServiceMock }, + ], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AppHeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + component.showRoles = false; + authService = TestBed.get(AuthService); + router = TestBed.get(Router); + window.localStorage.setItem('servicePointName', 'Barpeta SP'); + window.localStorage.setItem('userName', 'Prabhsimran Singh'); + window.sessionStorage.setItem('isAuthenticated', 'true'); + }); + + it('should create app header component', () => { + expect(component).toBeTruthy(); + }); + + it('should get servicePointName from localstorage when init', () => { + fixture.autoDetectChanges(); + expect(component.servicePoint).toEqual( + window.localStorage.getItem('servicePointName'), + ); + }); + + it('should get userName from localstorage when init', () => { + fixture.autoDetectChanges(); + expect(component.userName).toEqual(window.localStorage.getItem('userName')); + }); + + it('should get isAuthenticated from localstorage when init', () => { + fixture.autoDetectChanges(); + expect(component.isAuthenticated.toString()).toBe( + window.sessionStorage.getItem('isAuthenticated'), + ); + }); + + it("should keep roles as undefined as we've kept showroles as no", () => { + fixture.autoDetectChanges(); + expect(component.roles).toBe(undefined); + }); + + it("should keep filteredNavigation as undefined as we've kept showroles as no", () => { + fixture.autoDetectChanges(); + expect(component.filteredNavigation).toBe(undefined); + }); + + it('should set roles as per save in localstorage when we have showRoles set to true', () => { + component.showRoles = true; + const role = + '["Registrar","Nurse","Doctor","TC Specialist","Oncologist","Lab Technician","Pharmacist"]'; + window.localStorage.setItem('role', role); + component.ngOnInit(); + fixture.detectChanges(); + expect(component.roles).toBeTruthy(); + }); + + it("should not set roles as per save in localstorage when we don't have showRoles set to true", () => { + const role = + '["Registrar","Nurse","Doctor","TC Specialist","Oncologist","Lab Technician","Pharmacist"]'; + window.localStorage.setItem('role', role); + component.ngOnInit(); + fixture.detectChanges(); + expect(component.roles).not.toBeTruthy(); + }); + + it('should filteredNavigation as per save in localstorage when we have showRoles set to true', () => { + component.showRoles = true; + const role = + '["Registrar","Nurse","Doctor","TC Specialist","Oncologist","Lab Technician","Pharmacist"]'; + window.localStorage.setItem('role', role); + component.ngOnInit(); + fixture.detectChanges(); + expect(component.filteredNavigation).toBeTruthy(); + }); + + it('should call logout method on click of logout tag', fakeAsync(() => { + const spy = spyOn(authService, 'logoutUser').and.returnValue( + Observable.of(1), + ); + component.ngOnInit(); + fixture.detectChanges(); + const el = fixture.debugElement.query(By.css('#logoutButton')); + el.triggerEventHandler('click', null); + tick(); + fixture.detectChanges(); + expect(spy).toHaveBeenCalled(); + })); + + it('should not clear local storage asresponse is not correct', () => { + const spy = spyOn(authService, 'logoutUser').and.returnValue( + Observable.of({ statusCode: 401 }), + ); + component.ngOnInit(); + component.logout(); + + expect(localStorage.length).not.toEqual(0); + }); + + it('should not clear session storage asresponse is not correct', () => { + const spy = spyOn(authService, 'logoutUser').and.returnValue( + Observable.of({ statusCode: 401 }), + ); + component.ngOnInit(); + component.logout(); + + expect(sessionStorage.length).not.toEqual(0); + }); + + it('should clear local storage as response is correct', () => { + const spy = spyOn(authService, 'logoutUser').and.returnValue( + Observable.of({ statusCode: 200 }), + ); + component.ngOnInit(); + component.logout(); + + expect(localStorage.length).toEqual(0); + }); + + it('should clear local storage as response is correct', () => { + const spy = spyOn(authService, 'logoutUser').and.returnValue( + Observable.of({ statusCode: 200 }), + ); + component.ngOnInit(); + component.logout(); + + expect(sessionStorage.length).toEqual(0); + }); + + it('should call to navigate to other component', () => { + const spy = spyOn(authService, 'logoutUser').and.returnValue( + Observable.of({ statusCode: 200 }), + ); + const spier = spyOn(router, 'navigate'); + component.ngOnInit(); + component.logout(); + expect(spier).toHaveBeenCalled(); + }); + + it('should call to navigate to login component', () => { + const spy = spyOn(authService, 'logoutUser').and.returnValue( + Observable.of({ statusCode: 200 }), + ); + const spier = spyOn(router, 'navigate'); + component.ngOnInit(); + component.logout(); + expect(spier).toHaveBeenCalledWith(['/login']); + }); +}); diff --git a/src/app/app-modules/core/components/app-header/app-header.component.ts b/src/app/app-modules/core/components/app-header/app-header.component.ts new file mode 100644 index 0000000..3fa7e58 --- /dev/null +++ b/src/app/app-modules/core/components/app-header/app-header.component.ts @@ -0,0 +1,345 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Input, OnChanges } from '@angular/core'; +import { Router } from '@angular/router'; +import { AuthService } from '../../services/auth.service'; +import { ConfirmationService } from '../../services/confirmation.service'; +import { LanguageService } from '../../services/language.service'; +import { MatDialog } from '@angular/material/dialog'; +import { environment } from 'src/environments/environment'; +import { ShowCommitAndVersionDetailsComponent } from '../show-commit-and-version-details/show-commit-and-version-details.component'; +@Component({ + selector: 'app-header', + templateUrl: './app-header.component.html', + styleUrls: ['./app-header.component.css'], +}) +export class AppHeaderComponent implements OnInit, OnChanges { + @Input() + showRoles = false; + storeName: any; + facility: any; + userName!: string; + designation!: string; + providerServiceID!: string; + isAuthenticated!: boolean; + isExternal!: boolean; + filteredNavigation: any; + roles: any; + parent_app: any; + parent_url = sessionStorage.getItem('return'); + reportsList: any = []; + languageArray: any[] = []; + language_file_path: any = './assets/'; + language: any = 'English'; + currentLanguageSet: any; + navigation: any; + + constructor( + private router: Router, + private auth: AuthService, + private dialog: MatDialog, + private http_service: LanguageService, + private confirmationService: ConfirmationService, + ) {} + license: any; + ngOnInit() { + this.getUIVersionAndCommitDetails(); + const userName = localStorage.getItem('userName'); + if (userName != null) { + this.userName = userName; + } + const designation = localStorage.getItem('designation'); + if (designation != null) { + this.designation = designation; + } + this.isExternal = sessionStorage.getItem('isExternal') == 'true'; + this.parent_app = sessionStorage.getItem('host'); + const providerServiceID = localStorage.getItem('providerServiceID'); + if (providerServiceID != null) { + this.providerServiceID = providerServiceID; + } + this.isAuthenticated = sessionStorage.getItem('isAuthenticated') == 'true'; + this.license = environment.licenseUrl; + this.reportsList = [ + 'Inward stock Report', + 'Consumption Report', + 'Expiry Report', + 'Beneficiary drug issue Report', + ]; + if (this.isAuthenticated) { + this.fetchLanguageSet(); + } + } + fetchLanguageSet() { + this.http_service.fetchLanguageSet().subscribe((languageRes: any) => { + if (languageRes && Array.isArray(languageRes.data)) { + this.languageArray = languageRes.data; + this.getLanguage(); + } + }); + } + + // fetchLanguageSet() { + // this.http_service.fetchLanguageSet().subscribe((languageRes: any) => { + // if (languageRes !== undefined && languageRes !== null) { + // this.languageArray = languageRes; + // this.getLanguage(); + // } + // }); + // } + getLanguage() { + if (localStorage.getItem('currentLanguage') != null) { + this.changeLanguage(localStorage.getItem('currentLanguage')); + } else { + this.changeLanguage(this.language); + } + } + changeLanguage(language: any) { + this.http_service + .getLanguage(this.language_file_path + language + '.json') + .subscribe( + (response) => { + if (response !== undefined && response !== null) { + this.languageSuccessHandler(response, language); + } else { + alert(this.currentLanguageSet.alerts.langNotDefinesd); + } + }, + (error) => { + alert( + this.currentLanguageSet.alerts.comingUpWithThisLang + + ' ' + + language, + ); + }, + ); + } + languageSuccessHandler(response: any, language: any) { + console.log('language is ', response); + if (response == undefined) { + alert(this.currentLanguageSet.alerts.langNotDefinesd); + } + if (response[language] != undefined) { + this.currentLanguageSet = response[language]; + localStorage.setItem('currentLanguage', language); + if (this.currentLanguageSet) { + // if(Array.isArray(this.languageArray)){ + // this.languageArray.forEach((item: any) => { + // if (item.languageName == language) { + // this.language = language; + // } + // }); + + // } + this.languageArray.forEach((item: any) => { + if (item.languageName == language) { + this.language = language; + } + }); + } else { + this.language = language; + } + this.http_service.getCurrentLanguage(response[language]); + this.roleNavigation(); + } else { + alert( + this.currentLanguageSet.alerts.info.comingUpWithThisLang + + ' ' + + language, + ); + } + } + + ngOnChanges() { + const facility = localStorage.getItem('facilityDetail'); + if (facility != null) { + this.facility = JSON.parse(facility); + } + if (this.facility) { + this.storeName = this.facility.facilityName; + } + } + + roleNavigation() { + this.navigation = [ + { + role: this.currentLanguageSet.itemDispense.pharmacist, + work: [ + { + link: '/inventory/medicineDispense', + label: this.currentLanguageSet.inventory.patientIssueWithoutRx, + }, + { + link: '/inventory/physicalStockEntry', + label: this.currentLanguageSet.inventory.physicalStockEntry, + }, + { + link: '/inventory/storeStockAdjustment', + label: this.currentLanguageSet.inventory.stockAdjustment, + }, + { + link: '/inventory/storeSelfConsumption', + label: this.currentLanguageSet.inventory.storeConsumption, + }, + { + link: '/inventory/storeStockTransfer', + label: this.currentLanguageSet.inventory.stockTransfer, + }, + { + link: '/inventory/patientReturn', + label: this.currentLanguageSet.inventory.patientReturns, + }, + { + link: '/inventory/indentOrderWorklist', + label: this.currentLanguageSet.inventory.indent, + }, + ], + }, + { + role: this.currentLanguageSet.inventory.reports, + work: [ + { + link: '/inventory/inwardStockReport', + label: this.currentLanguageSet.inventory.inwardStockReport, + }, + { + link: '/inventory/consumptionReport', + label: this.currentLanguageSet.inventory.consumptionReport, + }, + { + link: '/inventory/expiryReport', + label: this.currentLanguageSet.inventory.expiryReport, + }, + { + link: '/inventory/beneficiaryDrugIssueReport', + label: this.currentLanguageSet.inventory.beneficiaryDrugIssueReport, + }, + { + link: '/inventory/dailyStockReportDetails', + label: this.currentLanguageSet.inventory.dailyStockReportDetails, + }, + { + link: '/inventory/dailyStockReportSummary', + label: this.currentLanguageSet.inventory.dailyStockReportSummary, + }, + { + link: '/inventory/monthlyReport', + label: this.currentLanguageSet.inventory.monthlyReport, + }, + { + link: '/inventory/yearlyReport', + label: this.currentLanguageSet.inventory.yearlyReport, + }, + { + link: '/inventory/shortExpiryReport', + label: this.currentLanguageSet.inventory.shortExpiryReport, + }, + { + link: '/inventory/transitReport', + label: this.currentLanguageSet.inventory.transitReport, + }, + ], + }, + ]; + } + handleKeyLogout(event: KeyboardEvent): void { + if (event.key == 'Enter' || event.key == 'Spacebar' || event.key == ' ') { + this.logout(); + } + } + + logout() { + this.auth.logoutUser().subscribe((res: any) => { + if (res && res.statusCode == 200) { + this.router.navigate(['/login']); + this.changeLanguage('English'); + localStorage.clear(); + sessionStorage.clear(); + } + }); + } + commitDetailsUI: any; + versionUI: any; + getUIVersionAndCommitDetails() { + const commitDetailsPath: any = 'assets/git-version.json'; + this.auth.getUIVersionAndCommitDetails(commitDetailsPath).subscribe( + (res) => { + console.log('res', res); + this.commitDetailsUI = res; + this.versionUI = this.commitDetailsUI['version']; + }, + (err) => { + console.log('err', err); + }, + ); + } + showVersionAndCommitDetails() { + this.auth.getAPIVersionAndCommitDetails().subscribe( + (res: any) => { + if (res.statusCode == 200) { + this.constructAPIAndUIDetails(res.data); + } + }, + (err) => {}, + ); + } + constructAPIAndUIDetails(apiVersionAndCommitDetails: any) { + const data = { + commitDetailsUI: { + version: this.commitDetailsUI['version'], + commit: this.commitDetailsUI['commit'], + }, + commitDetailsAPI: { + version: apiVersionAndCommitDetails['git.build.version'] || 'NA', + commit: apiVersionAndCommitDetails['git.commit.id'] || 'NA', + }, + }; + if (data) { + this.showData(data); + } + } + showData(versionData: any) { + const dialogRef = this.dialog.open(ShowCommitAndVersionDetailsComponent, { + data: versionData, + }); + } + + backToParent() { + sessionStorage.removeItem('parentBen'); + sessionStorage.removeItem('parentBenVisit'); + sessionStorage.removeItem('isExternal'); + sessionStorage.removeItem('host'); + sessionStorage.removeItem('fallback'); + sessionStorage.removeItem('return'); + localStorage.removeItem('facilityDetail'); + let language: any; + if (localStorage.getItem('currentLanguage') == 'undefined') { + language = 'English'; + } else { + language = localStorage.getItem('currentLanguage'); + } + window.location.href = `${this.parent_url}?currentLanguage=${language}`; + localStorage.removeItem('currentLanguage'); + // } + // }) + } +} diff --git a/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.css b/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.css new file mode 100644 index 0000000..a43ebdf --- /dev/null +++ b/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.css @@ -0,0 +1,44 @@ +.dialog-container { + height: 100%; + overflow-x: hidden; +} + +.dialog-title { + margin: 0px; + padding: 15px 24px 15px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; +} + +.dialog-title h4 { + display: inline-block; +} + +.dialog-title .exit { + cursor: pointer; +} + +.scrolling-content { + max-height: 75vh; + overflow-y: hidden; + overflow-x: hidden; +} + +.input-full-width { + width: 100%; +} + +.m-b-20 { + margin-bottom: 20px; +} + +@media screen and (max-width: 768px) { + .search-btn { + width: 100%; + } +} + +.enableScroll { height: 250px; flex: auto; } \ No newline at end of file diff --git a/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.html b/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.html new file mode 100644 index 0000000..17de734 --- /dev/null +++ b/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.html @@ -0,0 +1,111 @@ +
+
+

{{ currentLanguageSet?.inventory?.batchSelection }}

+ +
+ +
+
+
+
+ + + +
+
+ +
+
+ +
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
diff --git a/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.spec.ts b/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.spec.ts new file mode 100644 index 0000000..407529d --- /dev/null +++ b/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BatchAdjustmentComponent } from './batch-adjustment.component'; + +describe('BatchAdjustmentComponent', () => { + let component: BatchAdjustmentComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [BatchAdjustmentComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BatchAdjustmentComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.ts b/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.ts new file mode 100644 index 0000000..e45cbc0 --- /dev/null +++ b/src/app/app-modules/core/components/batch-adjustment/batch-adjustment.component.ts @@ -0,0 +1,96 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { BatchSearchService } from '../../services/batch-search.service'; +import { ConfirmationService } from '../../services/confirmation.service'; + +import { Observable, Subject } from 'rxjs'; +import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; +import { SetLanguageComponent } from '../set-language.component'; +import { LanguageService } from '../../services/language.service'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-batch-adjustment', + templateUrl: './batch-adjustment.component.html', + styleUrls: ['./batch-adjustment.component.css'], +}) +export class BatchAdjustmentComponent implements OnInit, DoCheck { + searchTerms!: string; + items$!: Observable; + selectedBatchList: any = []; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + @Inject(MAT_DIALOG_DATA) public input: any, + private confirmationService: ConfirmationService, + public dialogRef: MatDialogRef, + public http_service: LanguageService, + private batchSearchService: BatchSearchService, + ) {} + + ngOnInit() { + this.search(this.input.searchTerm); + this.fetchLanguageResponse(); + } + + search(term: string): void { + this.items$ = this.batchSearchService.searchAdjustmentBatch(term); + } + + selectBatch(event: any, batch: any) { + if (event.checked) { + batch.selected = true; + this.selectedBatchList.push(batch); + } else { + const index = this.selectedBatchList.indexOf(batch); + this.selectedBatchList.splice(index, 1); + batch.selected = false; + } + } + + disableSelection(batch: any) { + const addedStock = this.input.addedStock; + const temp = addedStock.filter( + (stock: any) => stock.itemStockEntryID == batch.itemStockEntryID, + ); + if (temp.length > 0) return true; + else return false; + } + + submitBatch() { + this.dialogRef.close(this.selectedBatchList); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/components/batch-search/batch-search.component.css b/src/app/app-modules/core/components/batch-search/batch-search.component.css new file mode 100644 index 0000000..2044250 --- /dev/null +++ b/src/app/app-modules/core/components/batch-search/batch-search.component.css @@ -0,0 +1,42 @@ +.dialog-container { + height: 100%; + overflow-x: hidden; +} + +.dialog-title { + margin: 0px; + padding: 15px 24px 15px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; +} + +.dialog-title h4 { + display: inline-block; +} + +.dialog-title .exit { + cursor: pointer; +} + +.scrolling-content { + max-height: 75vh; + overflow-y: auto; + overflow-x: hidden; +} + +.input-full-width { + width: 100%; +} + +.m-b-20 { + margin-bottom: 20px; +} + +@media screen and (max-width: 768px) { + .search-btn { + width: 100%; + } +} \ No newline at end of file diff --git a/src/app/app-modules/core/components/batch-search/batch-search.component.html b/src/app/app-modules/core/components/batch-search/batch-search.component.html new file mode 100644 index 0000000..bd843c5 --- /dev/null +++ b/src/app/app-modules/core/components/batch-search/batch-search.component.html @@ -0,0 +1,110 @@ +
+
+

{{ currentLanguageSet?.inventory?.batchSelection }}

+ +
+ +
+
+
+
+ + + +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+ +
+
+
+
diff --git a/src/app/app-modules/core/components/batch-search/batch-search.component.spec.ts b/src/app/app-modules/core/components/batch-search/batch-search.component.spec.ts new file mode 100644 index 0000000..137163d --- /dev/null +++ b/src/app/app-modules/core/components/batch-search/batch-search.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BatchSearchComponent } from './batch-search.component'; + +describe('BatchSearchComponent', () => { + let component: BatchSearchComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [BatchSearchComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BatchSearchComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/batch-search/batch-search.component.ts b/src/app/app-modules/core/components/batch-search/batch-search.component.ts new file mode 100644 index 0000000..17969bf --- /dev/null +++ b/src/app/app-modules/core/components/batch-search/batch-search.component.ts @@ -0,0 +1,96 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { BatchSearchService } from '../../services/batch-search.service'; +import { ConfirmationService } from '../../services/confirmation.service'; + +import { Observable, Subject } from 'rxjs'; +import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; +import { SetLanguageComponent } from '../set-language.component'; +import { LanguageService } from '../../services/language.service'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-batch-search', + templateUrl: './batch-search.component.html', + styleUrls: ['./batch-search.component.css'], +}) +export class BatchSearchComponent implements OnInit, DoCheck { + searchTerms!: string; + items$!: Observable; + selectedBatchList: any = []; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + @Inject(MAT_DIALOG_DATA) public input: any, + private confirmationService: ConfirmationService, + public http_service: LanguageService, + public dialogRef: MatDialogRef, + private batchSearchService: BatchSearchService, + ) {} + + ngOnInit() { + this.search(this.input.searchTerm); + this.fetchLanguageResponse(); + } + + search(term: string): void { + this.items$ = this.batchSearchService.searchItemBatch(term); + } + + selectBatch(event: any, batch: any) { + if (event.checked) { + batch.selected = true; + this.selectedBatchList.push(batch); + } else { + const index = this.selectedBatchList.indexOf(batch); + this.selectedBatchList.splice(index, 1); + batch.selected = false; + } + } + + disableSelection(batch: any) { + const addedStock = this.input.addedStock; + const temp = addedStock.filter( + (stock: any) => stock.itemStockEntryID == batch.itemStockEntryID, + ); + if (temp.length > 0) return true; + else return false; + } + + submitBatch() { + this.dialogRef.close(this.selectedBatchList); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.css b/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.css new file mode 100644 index 0000000..a9f0e63 --- /dev/null +++ b/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.css @@ -0,0 +1,15 @@ +.profileData tr td span { + font-weight: bold; +} + +img { + border-radius: 50%; + width: 100px; + height: 100px; +} + +.table>tbody>tr>td, .table>tbody>tr>th { + padding: 4px; + border-top: none; + vertical-align: middle; +} \ No newline at end of file diff --git a/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.html b/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.html new file mode 100644 index 0000000..f905444 --- /dev/null +++ b/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.html @@ -0,0 +1,63 @@ +
+
+ Default Patient Image + Patient Image + +
+
diff --git a/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.spec.ts b/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.spec.ts new file mode 100644 index 0000000..485b11f --- /dev/null +++ b/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BeneficiaryDetailsComponent } from './beneficiary-details.component'; + +describe('BeneficiaryDetailsComponent', () => { + let component: BeneficiaryDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [BeneficiaryDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BeneficiaryDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.ts b/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.ts new file mode 100644 index 0000000..c14c625 --- /dev/null +++ b/src/app/app-modules/core/components/beneficiary-details/beneficiary-details.component.ts @@ -0,0 +1,96 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, DoCheck, OnDestroy, OnInit } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; + +import { BeneficiaryDetailsService } from '../../services/beneficiary-details.service'; +import { LanguageService } from '../../services/language.service'; +import { SetLanguageComponent } from '../set-language.component'; + +@Component({ + selector: 'app-beneficiary-details', + templateUrl: './beneficiary-details.component.html', + styleUrls: ['./beneficiary-details.component.css'], +}) +export class BeneficiaryDetailsComponent implements OnInit, DoCheck, OnDestroy { + beneficiary: any; + today: any; + beneficiaryDetailsSubscription: any; + currentLanguageSet: any; + languageComponent!: SetLanguageComponent; + healthIDValue!: string; + + constructor( + private router: Router, + private route: ActivatedRoute, + private http_service: LanguageService, + private beneficiaryDetailsService: BeneficiaryDetailsService, + ) {} + + ngOnInit() { + this.today = new Date(); + const healthIDValue: any = localStorage.getItem('healthID'); + this.healthIDValue = healthIDValue; + this.route.params.subscribe((param) => { + const benFlowId: any = localStorage.getItem('benFlowID'); + this.beneficiaryDetailsService.getBeneficiaryDetails( + param['beneficiaryRegID'], + benFlowId, + ); + this.beneficiaryDetailsSubscription = + this.beneficiaryDetailsService.beneficiaryDetails$.subscribe((res) => { + if (res != null) { + this.beneficiary = res; + if (res.serviceDate) { + this.today = res.serviceDate; + } + } + }); + + this.beneficiaryDetailsService + .getBeneficiaryImage(param['beneficiaryRegID']) + .subscribe((data) => { + if (data && data.benImage) { + this.beneficiary.benImage = data.benImage; + } + }); + }); + this.fetchLanguageResponse(); + } + + ngOnDestroy() { + if (this.beneficiaryDetailsSubscription) + this.beneficiaryDetailsSubscription.unsubscribe(); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.css b/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.css new file mode 100644 index 0000000..8c6c23c --- /dev/null +++ b/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.css @@ -0,0 +1,35 @@ +.input-full-width { + width: 100%; +} + +.m-t-30 { + margin-top: 30px; +} + +.container-fluid { + padding: 24px !important; +} + +.title { + margin: 0px 0px 10px; + padding: 15px 24px 15px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; +} + +.title h4 { + display: inline-block; +} + +.title .exit { + cursor: pointer; +} + +@media screen and (max-width: 768px) { + .search-btn { + width: 100%; + } +} \ No newline at end of file diff --git a/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.html b/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.html new file mode 100644 index 0000000..ef22932 --- /dev/null +++ b/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.html @@ -0,0 +1,93 @@ +
+

{{ currentLanguageSet?.inventory?.itemForIndentRequest }}

+ +
+ +
+
+
+ + + +
+
+ +
+
+ + +
+ +
+
+
+
+ +
+
+
diff --git a/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.spec.ts b/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.spec.ts new file mode 100644 index 0000000..0be8f33 --- /dev/null +++ b/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { IndentItemListComponent } from './indent-item-list.component'; + +describe('IndentItemListComponent', () => { + let component: IndentItemListComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [IndentItemListComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(IndentItemListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.ts b/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.ts new file mode 100644 index 0000000..c26ff65 --- /dev/null +++ b/src/app/app-modules/core/components/indent-item-list/indent-item-list.component.ts @@ -0,0 +1,92 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { ConfirmationService } from '../../services/confirmation.service'; +import { Observable, Subject } from 'rxjs'; +import { BatchSearchService } from '../../services/batch-search.service'; +import { SetLanguageComponent } from '../set-language.component'; +import { LanguageService } from '../../services/language.service'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-indent-item-list', + templateUrl: './indent-item-list.component.html', + styleUrls: ['./indent-item-list.component.css'], +}) +export class IndentItemListComponent implements OnInit, DoCheck { + searchTerms!: string; + items!: Observable; + selectedItemList: any = []; + + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + @Inject(MAT_DIALOG_DATA) public input: any, + private confirmationService: ConfirmationService, + public dialogRef: MatDialogRef, + public http_service: LanguageService, + private batchSearchService: BatchSearchService, + ) {} + + ngOnInit() { + this.search(this.input.searchTerm); + this.fetchLanguageResponse(); + } + + search(term: string): void { + this.items = this.batchSearchService.searchItem(term); + } + selectItem(event: any, item: any) { + if (event.checked) { + item.selected = true; + this.selectedItemList.push(item); + } else { + const index = this.selectedItemList.indexOf(item); + this.selectedItemList.splice(index, 1); + item.selected = false; + } + } + disableSelection(item: any) { + const addedIndent = this.input.addedIndent; + const temp = addedIndent.filter( + (indent: any) => indent.itemName == item.itemName, + ); + if (temp.length > 0) return true; + else return false; + } + submitIndentList() { + this.dialogRef.close(this.selectedItemList); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/components/item-dispense/item-dispense.component.css b/src/app/app-modules/core/components/item-dispense/item-dispense.component.css new file mode 100644 index 0000000..1e7148b --- /dev/null +++ b/src/app/app-modules/core/components/item-dispense/item-dispense.component.css @@ -0,0 +1,36 @@ +.input-full-width { + width: 100%; +} + +.m-t-30 { + margin-top: 30px; +} + +.container-fluid { + padding: 24px !important; +} + +.title { + margin: 0px 0px 10px; + padding: 15px 24px 15px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; + overflow-y: hidden; +} + +.title h4 { + display: inline-block; +} + +.title .exit { + cursor: pointer; +} + +@media screen and (max-width: 768px) { + .search-btn { + width: 100%; + } +} \ No newline at end of file diff --git a/src/app/app-modules/core/components/item-dispense/item-dispense.component.html b/src/app/app-modules/core/components/item-dispense/item-dispense.component.html new file mode 100644 index 0000000..f4c85f3 --- /dev/null +++ b/src/app/app-modules/core/components/item-dispense/item-dispense.component.html @@ -0,0 +1,89 @@ +
+

{{ currentLanguageSet?.inventory?.itemSelection }}

+ +
+ +
+
+
+ + + +
+
+ +
+
+ +
+ + +
+ +
+
+
diff --git a/src/app/app-modules/core/components/item-dispense/item-dispense.component.spec.ts b/src/app/app-modules/core/components/item-dispense/item-dispense.component.spec.ts new file mode 100644 index 0000000..925a8fc --- /dev/null +++ b/src/app/app-modules/core/components/item-dispense/item-dispense.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ItemDispenseComponent } from './item-dispense.component'; + +describe('ItemDispenseComponent', () => { + let component: ItemDispenseComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ItemDispenseComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ItemDispenseComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/item-dispense/item-dispense.component.ts b/src/app/app-modules/core/components/item-dispense/item-dispense.component.ts new file mode 100644 index 0000000..d48c149 --- /dev/null +++ b/src/app/app-modules/core/components/item-dispense/item-dispense.component.ts @@ -0,0 +1,87 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { ItemSearchService } from '../../services/item-search.service'; +import { ConfirmationService } from '../../services/confirmation.service'; + +import { Observable, Subject } from 'rxjs'; +import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; +import { SetLanguageComponent } from '../set-language.component'; +import { LanguageService } from '../../services/language.service'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-item-dispense', + templateUrl: './item-dispense.component.html', + styleUrls: ['./item-dispense.component.css'], +}) +export class ItemDispenseComponent implements OnInit, DoCheck { + searchTerms!: string; + items$!: Observable; + selectedItem = null; + + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + @Inject(MAT_DIALOG_DATA) public input: any, + private itemSearchService: ItemSearchService, + public http_service: LanguageService, + public dialogRef: MatDialogRef, + private confirmationService: ConfirmationService, + ) {} + + ngOnInit() { + this.search(this.input.searchTerm); + this.fetchLanguageResponse(); + } + + search(term: string): void { + this.items$ = this.itemSearchService.getItemDetailsByName(term); + } + + selectSelectedItem(selectedItem: any) { + const dispenseItemList = this.input.dispenseItemList; + + const temp = dispenseItemList.filter( + (item: any) => item.itemID == selectedItem.item.itemID, + ); + + if (temp.length <= 0) this.dialogRef.close(selectedItem); + else + this.confirmationService.alert( + this.currentLanguageSet.inventory.itemAdded, + ); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/components/item-search/item-search.component.css b/src/app/app-modules/core/components/item-search/item-search.component.css new file mode 100644 index 0000000..1e7148b --- /dev/null +++ b/src/app/app-modules/core/components/item-search/item-search.component.css @@ -0,0 +1,36 @@ +.input-full-width { + width: 100%; +} + +.m-t-30 { + margin-top: 30px; +} + +.container-fluid { + padding: 24px !important; +} + +.title { + margin: 0px 0px 10px; + padding: 15px 24px 15px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; + overflow-y: hidden; +} + +.title h4 { + display: inline-block; +} + +.title .exit { + cursor: pointer; +} + +@media screen and (max-width: 768px) { + .search-btn { + width: 100%; + } +} \ No newline at end of file diff --git a/src/app/app-modules/core/components/item-search/item-search.component.html b/src/app/app-modules/core/components/item-search/item-search.component.html new file mode 100644 index 0000000..f1b7373 --- /dev/null +++ b/src/app/app-modules/core/components/item-search/item-search.component.html @@ -0,0 +1,185 @@ +
+

{{ currentLanguageSet?.inventory?.itemSelection }}

+ +
+ +
+
+
+ + + +
+
+ +
+
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{ currentLanguageSet?.inventory?.itemCode }} + {{ item?.itemCode }} + {{ currentLanguageSet?.inventory?.itemName }} + {{ item?.itemName }} + {{ currentLanguageSet?.inventory?.itemCategory }} + + {{ item?.itemCategory?.itemCategoryName }} + + {{ currentLanguageSet?.inventory?.itemForm }} + + {{ item?.itemForm?.itemForm }} + + {{ currentLanguageSet?.inventory?.pharmacologicalCategory }} + + {{ item?.pharmacologyCategory?.pharmCategoryName }} + + {{ currentLanguageSet?.inventory?.strength }} + + {{ item?.strength ? item?.strength : " " }} + {{ item?.uom?.uOMName ? item?.uom?.uOMName : " " }} + + {{ currentLanguageSet?.inventory?.action }} + + +
+ {{ + currentLanguageSet?.inventory?.norecordsfound + }} +
+ + +
+
+
diff --git a/src/app/app-modules/core/components/item-search/item-search.component.spec.ts b/src/app/app-modules/core/components/item-search/item-search.component.spec.ts new file mode 100644 index 0000000..8f1b0cd --- /dev/null +++ b/src/app/app-modules/core/components/item-search/item-search.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ItemSearchComponent } from './item-search.component'; + +describe('ItemSearchComponent', () => { + let component: ItemSearchComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ItemSearchComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ItemSearchComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/item-search/item-search.component.ts b/src/app/app-modules/core/components/item-search/item-search.component.ts new file mode 100644 index 0000000..286a21e --- /dev/null +++ b/src/app/app-modules/core/components/item-search/item-search.component.ts @@ -0,0 +1,87 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { ItemSearchService } from '../../services/item-search.service'; + +import { Observable, Subject } from 'rxjs'; +import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; +import { SetLanguageComponent } from '../set-language.component'; +import { LanguageService } from '../../services/language.service'; +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { MatTableDataSource } from '@angular/material/table'; + +@Component({ + selector: 'app-item-search', + templateUrl: './item-search.component.html', + styleUrls: ['./item-search.component.css'], +}) +export class ItemSearchComponent implements OnInit, DoCheck { + searchTerms!: string; + items$!: Observable; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + displayedColumns: string[] = [ + 'itemCode', + 'itemName', + 'itemCategory', + 'itemForm', + 'pharmacologicalCategory', + 'strength', + 'action', + ]; + // dataSource!: MatTableDataSource; + dataSource = new MatTableDataSource([{}]); + constructor( + @Inject(MAT_DIALOG_DATA) public input: any, + public http_service: LanguageService, + private itemSearchService: ItemSearchService, + ) {} + + ngOnInit() { + this.search(this.input.searchTerm); + this.fetchLanguageResponse(); + // this.items$.subscribe(data => { + // this.dataSource = new MatTableDataSource(data); + // }) + } + + search(term: string): void { + this.items$ = this.itemSearchService.searchDrugItem(term); + this.items$.subscribe((data: any) => { + if (data) { + this.dataSource = new MatTableDataSource(data); + } + }); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.css b/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.css new file mode 100644 index 0000000..b6b4ba7 --- /dev/null +++ b/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.css @@ -0,0 +1,75 @@ +.title { + margin: 0px; + padding: 15px 24px 15px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; +} + + + +.input-full-width { + width: 100%; +} +.action { + box-sizing: border-box; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + padding: 8px; + width: 100%; + text-align: right; + border-top: 1px solid lightgrey; +} + +::ng-deep.md2-datepicker-disabled .md2-datepicker-button { + display:none !important; +} + +.action button { + border: 1px solid lightgray; +} + +.success { + background: #43a047; +} + +.info { + background: #0277bd; +} + +.warn, +.error { + background: #F44336; +} + +.center-btn { + justify-content: center !important; + display: flex !important; +} + +.checkbox-fix { + height: 50px; + display: flex; + justify-content: center; + align-items: center; +} +.p-5 { + padding: 5px; +} + +.alert-border { + border: 1px solid #F44336; +} + +.row-shade:nth-child(odd) { +background-color: rgba(240, 245, 245, 0.5); +} + +@media only screen and (min-width: 980px) { + .right-padding-remove-desktop { + padding-right: 0 !important; + } + .left-padding-remove-desktop { + padding-left: 0 !important; + } +} diff --git a/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.html b/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.html new file mode 100644 index 0000000..a8c258a --- /dev/null +++ b/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.html @@ -0,0 +1,71 @@ + + + diff --git a/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.spec.ts b/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.spec.ts new file mode 100644 index 0000000..c32ddde --- /dev/null +++ b/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RxBatchViewComponent } from './rx-batch-view.component'; + +describe('RxBatchViewComponent', () => { + let component: RxBatchViewComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [RxBatchViewComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(RxBatchViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.ts b/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.ts new file mode 100644 index 0000000..4ea6f7b --- /dev/null +++ b/src/app/app-modules/core/components/rx-batch-view/rx-batch-view.component.ts @@ -0,0 +1,176 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, DoCheck, OnInit } from '@angular/core'; +import { FormBuilder, FormArray, FormControl, FormGroup } from '@angular/forms'; +import { ConfirmationService } from './../../services/confirmation.service'; +import { LanguageService } from '../../services/language.service'; +import { SetLanguageComponent } from '../set-language.component'; +import { MatDialogRef } from '@angular/material/dialog'; +@Component({ + selector: 'app-rx-batch-view', + templateUrl: './rx-batch-view.component.html', + styleUrls: ['./rx-batch-view.component.css'], +}) +export class RxBatchViewComponent implements OnInit, DoCheck { + public items: any; + public prescribed: any; + public editSelection!: number; + dispensed: any; + itemsForm!: FormGroup; + alertDays = 30; + currentLanguageSet: any; + languageComponent!: SetLanguageComponent; + constructor( + private fb: FormBuilder, + private confirmationService: ConfirmationService, + public dialogRef: MatDialogRef, + private http_service: LanguageService, + ) {} + ngOnInit() { + this.fetchLanguageResponse(); + console.log(this.items); + this.itemsForm = this.fb.group({}); + this.loadtoForm(this.items); + } + + loadtoForm(items: any) { + const formArray = this.initBatchListArray(items, this.editSelection); + console.log(formArray.value, 'noted'); + this.itemsForm.addControl('formArray', formArray); + this.setDispensed(formArray.value); + console.log(this.itemsForm.value); + } + setDispensed(formArray: any, index = -1) { + this.checkQuant(formArray, index); + let quantity = 0; + formArray.map((arr: any) => (quantity += +arr.quantity)); + console.log(quantity, ' quant'); + console.log(formArray); + if (quantity <= this.prescribed) { + this.dispensed = quantity; + } else if (index >= 0) { + this.confirmationService.alert( + this.currentLanguageSet.inventory.dispenseQuantityPrescribed, + 'warn', + ); + const formItems = this.itemsForm.controls['formArray']; + const currentGroup: FormGroup = formItems.at(index); + currentGroup.patchValue({ + quantity: null, + }); + } + } + + checkQuant(formArrayVals: any, index: any) { + console.log(formArrayVals, index); + if (index != -1) { + if ( + formArrayVals[index].quantity === '' || + formArrayVals[index].quantity === null || + formArrayVals[index].quantity === 0 || + formArrayVals[index].quantity === '0' || + formArrayVals[index].quantity === undefined + ) { + const formItems = this.itemsForm.controls['formArray']; + formItems.at(index).patchValue({ selection: false }); + } + } + } + + save() { + const formItems = this.itemsForm.controls['formArray']; + + if (!formItems.invalid) { + this.dialogRef.close({ + selectionBatchList: formItems.value, + batchList: formItems.value.filter( + (item: any) => item.selection == true, + ), + dispensed: this.dispensed > 0 ? this.dispensed : null, + }); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.detailsRequired, + 'warn', + ); + } + } + + enableBatch(val: any, index: any) { + console.log(val); + const selection = val.selection; + this.setEnable(index); + // if (this.editSelection == 0 && !selection) { + // this.confirmationService.alert('Please select the batch first', 'info'); + // } + } + + setEnable(index: any) { + const formItems = this.itemsForm.controls['formArray']; + formItems.at(index).patchValue({ + selection: true, + }); + } + + checkboxChange(event: any, index: any) { + if (!event.checked) { + const formItems = this.itemsForm.controls['formArray']; + const currentGroup: FormGroup = formItems.at(index); + currentGroup.patchValue({ + quantity: null, + }); + this.setDispensed(formItems.value, index); + } + } + + initBatchListElement(batch: any, selection: any): FormGroup { + return this.fb.group({ + expiryDate: batch.expiryDate, + batchNo: batch.batchNo, + quantity: batch.quantity, + quantityInHand: batch.qty || batch.quantityInHand, + expiresIn: batch.expiresIn, + itemStockEntryID: batch.itemStockEntryID, + selection: batch.selection || selection == '1' ? true : false, + }); + } + + initBatchListArray(batchList: any, selection: any): FormArray { + const batches: FormArray = this.fb.array([]); + batchList.forEach((element: any) => { + batches.push(this.initBatchListElement(element, selection)); + }); + return batches; + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/components/search/search.component.css b/src/app/app-modules/core/components/search/search.component.css new file mode 100644 index 0000000..858dd3c --- /dev/null +++ b/src/app/app-modules/core/components/search/search.component.css @@ -0,0 +1,52 @@ +.input-full-width { + width: 100%; +} + +.m-b-30 { + margin-bottom: 30px; +} + +.mat-form-field { + line-height: unset !important; +} + +.vertical-align-middle { + vertical-align: middle; +} + +.title { + margin: 0px 0px 10px; + padding: 5px 24px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; + overflow-x: hidden; +} + +.title h4 { + display: inline-block; +} + +.title .exit { + cursor: pointer; +} + +.scrolling-content { + max-height: 75vh; + overflow: auto; +} + +.box { + height: 65px; +} + +.m-r-5{ + margin-right: 5px; +} + +/* .scrolling-content{ + overflow: auto; + max-height: 80vh; +} */ \ No newline at end of file diff --git a/src/app/app-modules/core/components/search/search.component.html b/src/app/app-modules/core/components/search/search.component.html new file mode 100644 index 0000000..431d79a --- /dev/null +++ b/src/app/app-modules/core/components/search/search.component.html @@ -0,0 +1,377 @@ +
+

{{ currentLanguageSet?.inventory?.advanceBeneficiarySearch }}

+ +
+ +
+
+
+
+
+ + + {{ + currentLanguageSet?.inventory?.firstNameIsRequired + }} + {{ + currentLanguageSet?.inventory?.minimumLength + }} + +
+ +
+ + + +
+
+ +
+
+ + {{ gender.genderName }} + + +
+
+ + {{ state.stateName | titlecase }} + + +
+
+ + {{ district.districtName | titlecase }} + + +
+
+ + +
+
+
+ +
+
+
+ . + + + No + {{ + i + 1 + }} + + + + {{ + currentLanguageSet?.bendetails?.beneficiaryID + }} + {{ element?.beneficiaryID }} + + + + {{ + currentLanguageSet?.bendetails?.beneficiaryName + }} + {{ element?.benName | titlecase }} + + + + {{ + currentLanguageSet?.bendetails?.gender + }} + {{ element?.benName | titlecase }} + + + + {{ currentLanguageSet?.inventory?.dOB }} + + {{ element?.benName | titlecase }} + + + + {{ + currentLanguageSet?.inventory?.fatherName + }} + {{ element?.benName | titlecase }} + + + + {{ currentLanguageSet?.bendetails?.district }} + + {{ element?.benName | titlecase }} + + + + {{ + currentLanguageSet?.bendetails?.phoneNo + }} + {{ element?.benName | titlecase }} + + + + {{ + currentLanguageSet?.bendetails?.regDate + }} + {{ element?.benName | titlecase }} + + + + + + + + + + + + + {{ + currentLanguageSet?.inventory?.norecordsfound + }} + + + + + + + {{ filteredBeneficiaryList.indexOf(beneficiary) + 1 }} + + + {{ beneficiary?.beneficiaryID }} + + + {{ beneficiary?.benName | titlecase }} + + + {{ beneficiary.genderName }} + + + {{ beneficiary.age | date: "dd/MM/yyyy" }} + + + {{ beneficiary.fatherName | titlecase }} + + + {{ beneficiary.districtName | titlecase }} / + {{ beneficiary.villageName | titlecase }} + + + {{ beneficiary.phoneNo }} + + + {{ beneficiary.registeredOn | date: "dd/MM/yyyy" }} + + + + + + + +
+ {{ currentLanguageSet?.inventory?.totalCount }} : + {{ filteredBeneficiaryList.length }} +
+ + + + + + +
+
+ +
+
+
+
+
diff --git a/src/app/app-modules/core/components/search/search.component.spec.ts b/src/app/app-modules/core/components/search/search.component.spec.ts new file mode 100644 index 0000000..d442615 --- /dev/null +++ b/src/app/app-modules/core/components/search/search.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SearchComponent } from './search.component'; + +describe('SearchComponent', () => { + let component: SearchComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [SearchComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SearchComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/search/search.component.ts b/src/app/app-modules/core/components/search/search.component.ts new file mode 100644 index 0000000..0467ef6 --- /dev/null +++ b/src/app/app-modules/core/components/search/search.component.ts @@ -0,0 +1,290 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Component, + OnInit, + ViewChild, + ChangeDetectorRef, + AfterViewChecked, + DoCheck, +} from '@angular/core'; +import { ConfirmationService } from '../../services/confirmation.service'; +import { CommonService } from '../../services/common-services.service'; +import { InventoryService } from '../../../inventory/shared/service/inventory.service'; +import { SetLanguageComponent } from '../set-language.component'; +import { LanguageService } from '../../services/language.service'; +import { environment } from 'src/environments/environment'; +import { MatDialogRef } from '@angular/material/dialog'; + +interface Beneficary { + firstName: string; + lastName: string; + gender: string; + stateID: string; + districtID: string | null; +} + +@Component({ + selector: 'app-search', + templateUrl: './search.component.html', + styleUrls: ['./search.component.css'], +}) +export class SearchComponent implements OnInit, DoCheck { + beneficiary!: Beneficary; + genders: any = []; + states: any = []; + districts: any = []; + stateID: any; + districtID: any; + countryId = environment.countryId; + searched = false; + beneficiaryList: any = []; + filteredBeneficiaryList: any = []; + blankTable = [{}, {}, {}, {}, {}]; + displayedColumns: string[] = [ + 'sno', + 'beneficiaryID', + 'benName', + 'genderName', + 'age', + 'fatherName', + 'districtVillage', + 'phoneNo', + 'registeredOn', + ]; + + @ViewChild('newSearchForm') form: any; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private confirmationService: ConfirmationService, + public mdDialogRef: MatDialogRef, + private commonService: CommonService, + public http_service: LanguageService, + private changeDetectorRef: ChangeDetectorRef, + private inventoryService: InventoryService, + ) {} + + ngOnInit() { + this.createBeneficiaryForm(); + this.callForMasterData(); + this.fetchLanguageResponse(); + } + + AfterViewChecked() { + this.changeDetectorRef.detectChanges(); + } + + callForMasterData() { + this.commonService.getRegistrationData().subscribe((res) => { + if (res && res.statusCode == 200 && res.data) { + console.log(res); + this.genders = res.data.m_genders; + this.states = res.data.states; + } else { + this.mdDialogRef.close(false); + } + }); + } + + onStateChange() { + this.beneficiary.districtID = null; + + this.commonService + .getStateDistricts(this.beneficiary.stateID) + .subscribe((res) => { + if (res && res.data && res.statusCode == 200) { + console.log(res); + this.districts = res.data; + } else { + this.mdDialogRef.close(false); + } + }); + } + + createBeneficiaryForm() { + this.beneficiary = { + firstName: '', + lastName: '', + gender: '', + stateID: '', + districtID: '', + }; + } + + resetBeneficiaryForm() { + this.form.reset(); + this.beneficiaryList = []; + this.filteredBeneficiaryList = []; + this.searched = false; + // this.getStatesData() + } + + getSearchResult() { + const dataObj = { + firstName: this.beneficiary.firstName, + lastName: this.beneficiary.lastName, + genderID: this.beneficiary.gender, + providerServiceMapID: localStorage.getItem('providerServiceID'), + i_bendemographics: { + stateID: this.beneficiary.stateID, + districtID: this.beneficiary.districtID, + }, + }; + + this.commonService.searchBeneficiary(dataObj).subscribe( + (beneficiaryList) => { + if ( + !beneficiaryList || + !beneficiaryList.data || + beneficiaryList.data.length <= 0 + ) { + this.beneficiaryList = []; + this.filteredBeneficiaryList = []; + this.searched = true; + } else { + this.beneficiaryList = this.searchRestruct(beneficiaryList.data, {}); + this.filteredBeneficiaryList = this.beneficiaryList; + this.searched = true; + console.log(this.beneficiaryList, this.filteredBeneficiaryList); + } + // console.log(JSON.stringify(beneficiaryList.data, null, 4)); + }, + (error) => { + this.confirmationService.alert(error, 'error'); + }, + ); + } + + /** + * ReStruct the response object of Identity Search to be as per search table requirements + */ + searchRestruct(benList: any, benObject: any) { + const requiredBenData: any = []; + benList.forEach((element: any, i: any) => { + requiredBenData.push({ + beneficiaryID: element.beneficiaryID, + beneficiaryRegID: element.beneficiaryRegID, + benName: `${element.firstName} ${element.lastName || ''}`, + genderName: `${element.m_gender.genderName || 'Not Available'}`, + fatherName: `${element.fatherName || 'Not Available'}`, + districtName: `${element.i_bendemographics.districtName || 'Not Available'}`, + villageName: `${element.i_bendemographics.districtBranchName || 'Not Available'}`, + phoneNo: this.getCorrectPhoneNo(element.benPhoneMaps, benObject), + age: element.dOB, + registeredOn: element.createdDate, + }); + }); + console.log(JSON.stringify(requiredBenData, null, 4), 'yoooo!'); + + return requiredBenData; + } + // getCorrectPhoneNo(phoneMaps: any, benObject: any) { + // let phone; + // if (benObject && !benObject && !benObject.phoneNo) { + // return phoneMaps[0].phoneNo; + // } else if ( + // benObject && + // !benObject && + // !benObject.phoneNo && + // !phoneMaps.length + // ) { + // return phoneMaps[0].phoneNo || 'Not Available'; + // } else if (benObject && benObject.phoneNo && phoneMaps.length > 0) { + // phoneMaps.forEach((element: any) => { + // if (element.phoneNo == benObject.phoneNo) { + // phone = element.phoneNo; + // } + // }); + // if (phone) { + // return phone; + // } else if (phoneMaps.length > 0) { + // return phoneMaps[0].phoneNo; + // } else { + // return 'Not Available'; + // } + // } else if (phoneMaps.length > 0) { + // return phoneMaps[0].phoneNo; + // } else { + // return 'Not Available'; + // } + // } + getCorrectPhoneNo(phoneMaps: any, benObject: any) { + let phone; + if (benObject && !benObject.phoneNo) { + return phoneMaps.length > 0 ? phoneMaps[0].phoneNo : 'Not Available'; + } else if (benObject && benObject.phoneNo && phoneMaps.length > 0) { + phoneMaps.forEach((element: any) => { + if (element.phoneNo == benObject.phoneNo) { + phone = element.phoneNo; + } + }); + return phone || 'Not Available'; + } else if (phoneMaps.length > 0) { + return phoneMaps[0].phoneNo; + } else { + return 'Not Available'; + } + } + + checkVisit(benID: any) { + if (benID) { + this.inventoryService + .getBeneficaryVisitDetail({ + providerServiceMapID: localStorage.getItem('providerServiceID'), + beneficiaryID: benID, + }) + .subscribe((res) => { + if (res && res.statusCode == 200 && res.data) { + if (res.data.benVisitDetail && res.data.benVisitDetail.length) { + this.mdDialogRef.close(benID); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory + .NoVisitRecordFoundForThisBeneficiary, + 'info', + ); + } + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory + .NoVisitRecordFoundForThisBeneficiary, + 'info', + ); + } + }); + } + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.css b/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.css new file mode 100644 index 0000000..8d7ac9a --- /dev/null +++ b/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.css @@ -0,0 +1,24 @@ +.title .exit { + cursor: pointer; +} + +.title { + padding: 10px 24px 10px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; +} + +.title h4 { + display: inline-block; +} + +.width20 { + width: 20%; +} + +.width40 { + width: 40%; +} diff --git a/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.html b/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.html new file mode 100644 index 0000000..bf190d2 --- /dev/null +++ b/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.html @@ -0,0 +1,33 @@ +
+

{{ currentLanguageSet?.inventory?.versionDetails }}

+ +
+
+ +
+ +
+
+
diff --git a/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.spec.ts b/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.spec.ts new file mode 100644 index 0000000..76bf782 --- /dev/null +++ b/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ShowCommitAndVersionDetailsComponent } from './show-commit-and-version-details.component'; + +describe('ShowCommitAndVersionDetailsComponent', () => { + let component: ShowCommitAndVersionDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ShowCommitAndVersionDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ShowCommitAndVersionDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.ts b/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.ts new file mode 100644 index 0000000..8471571 --- /dev/null +++ b/src/app/app-modules/core/components/show-commit-and-version-details/show-commit-and-version-details.component.ts @@ -0,0 +1,57 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { LanguageService } from '../../services/language.service'; +import { SetLanguageComponent } from '../set-language.component'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-show-commit-and-version-details', + templateUrl: './show-commit-and-version-details.component.html', + styleUrls: ['./show-commit-and-version-details.component.css'], +}) +export class ShowCommitAndVersionDetailsComponent implements OnInit, DoCheck { + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + @Inject(MAT_DIALOG_DATA) public input: any, + public http_service: LanguageService, + public dialogRef: MatDialogRef, + ) {} + + ngOnInit() { + this.fetchLanguageResponse(); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/components/spinner/spinner.component.css b/src/app/app-modules/core/components/spinner/spinner.component.css new file mode 100644 index 0000000..6b3b0ab --- /dev/null +++ b/src/app/app-modules/core/components/spinner/spinner.component.css @@ -0,0 +1,35 @@ +.overlay { + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + position: fixed; + z-index: 1001; + /* Sit on top */ + left: 0; + top: 0; + background-color: rgb(0, 0, 0); + /* Black fallback color */ + background-color: rgba(0, 0, 0, 0.3); + /* Black w/opacity */ +} + + +/* Position the content inside the overlay */ + + +/* .overlay-content { */ + /* position: relative; */ + /* top: 42%; 25% fro/m the top */ + /* left: 46%; */ + /* width: 100%; 100% width */ +/* } */ + +.overlay:root { + padding: 0px; +} + +.loader-hidden { + display: none; +} diff --git a/src/app/app-modules/core/components/spinner/spinner.component.html b/src/app/app-modules/core/components/spinner/spinner.component.html new file mode 100644 index 0000000..c167673 --- /dev/null +++ b/src/app/app-modules/core/components/spinner/spinner.component.html @@ -0,0 +1,5 @@ +
+
+ +
+
diff --git a/src/app/app-modules/core/components/spinner/spinner.component.spec.ts b/src/app/app-modules/core/components/spinner/spinner.component.spec.ts new file mode 100644 index 0000000..887a38c --- /dev/null +++ b/src/app/app-modules/core/components/spinner/spinner.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SpinnerComponent } from './spinner.component'; + +describe('SpinnerComponent', () => { + let component: SpinnerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [SpinnerComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SpinnerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + xit('should be created', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/spinner/spinner.component.ts b/src/app/app-modules/core/components/spinner/spinner.component.ts new file mode 100644 index 0000000..310e0e0 --- /dev/null +++ b/src/app/app-modules/core/components/spinner/spinner.component.ts @@ -0,0 +1,49 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { SpinnerState, SpinnerService } from '../../services/spinner.service'; +import { Subscription } from 'rxjs'; + +@Component({ + selector: 'app-spinner', + templateUrl: './spinner.component.html', + styleUrls: ['./spinner.component.css'], +}) +export class SpinnerComponent implements OnDestroy, OnInit { + visible = false; + + private spinnerStateChanged!: Subscription; + + constructor(private spinnerService: SpinnerService) {} + + ngOnInit() { + this.spinnerStateChanged = this.spinnerService.spinnerState.subscribe( + (state: SpinnerState) => { + this.visible = state.show; + }, + ); + } + + ngOnDestroy() { + this.spinnerStateChanged.unsubscribe(); + } +} diff --git a/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.css b/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.css new file mode 100644 index 0000000..b641a58 --- /dev/null +++ b/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.css @@ -0,0 +1,3 @@ +.textarea-full-width { + width: 100%; +} \ No newline at end of file diff --git a/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.html b/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.html new file mode 100644 index 0000000..8b40b2b --- /dev/null +++ b/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.html @@ -0,0 +1,16 @@ +
+ + + {{ message.value.length }} / {{ data.length }} + +
diff --git a/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.spec.ts b/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.spec.ts new file mode 100644 index 0000000..ded39cb --- /dev/null +++ b/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TextareaDialogComponent } from './textarea-dialog.component'; + +describe('TextareaDialogComponent', () => { + let component: TextareaDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [TextareaDialogComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TextareaDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + xit('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.ts b/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.ts new file mode 100644 index 0000000..905d546 --- /dev/null +++ b/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.component.ts @@ -0,0 +1,60 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { LanguageService } from '../../services/language.service'; +import { SetLanguageComponent } from '../set-language.component'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-textarea-dialog', + templateUrl: './textarea-dialog.component.html', + styleUrls: ['./textarea-dialog.component.css'], +}) +export class TextareaDialogComponent implements OnInit, DoCheck { + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + public dialogRef: MatDialogRef, + public http_service: LanguageService, + @Inject(MAT_DIALOG_DATA) public data: any, + ) {} + + ngOnInit() { + this.dialogRef.backdropClick().subscribe((result) => { + this.dialogRef.close(this.data.observations); + }); + this.fetchLanguageResponse(); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.service.ts b/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.service.ts new file mode 100644 index 0000000..116722b --- /dev/null +++ b/src/app/app-modules/core/components/textarea-dialog/textarea-dialog.service.ts @@ -0,0 +1,37 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Injectable } from '@angular/core'; +import { TextareaDialogComponent } from './textarea-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; +import { Observable } from 'rxjs'; +@Injectable() +export class TextareaDialog { + constructor(public dialog: MatDialog) {} + + open(observations: string, length = 500): Observable { + const dialogRef = this.dialog.open(TextareaDialogComponent, { + width: '500px', + data: { observations: observations, length: length }, + }); + return dialogRef.afterClosed(); + } +} diff --git a/src/app/app-modules/core/components/transfer-search/transfer-search.component.css b/src/app/app-modules/core/components/transfer-search/transfer-search.component.css new file mode 100644 index 0000000..a057994 --- /dev/null +++ b/src/app/app-modules/core/components/transfer-search/transfer-search.component.css @@ -0,0 +1,42 @@ +.dialog-container { + height: 100%; + overflow-x: hidden; +} + +.dialog-title { + margin: 0px; + padding: 15px 24px 15px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; +} + +.dialog-title h4 { + display: inline-block; +} + +.dialog-title .exit { + cursor: pointer; +} + +.scrolling-content { + max-height: 75vh; + overflow-y: auto; + overflow-x: hidden; +} + +.input-full-width { + width: 100%; +} + +.m-b-20 { + margin-bottom: 20px; +} + +@media screen and (max-width: 768px) { + .search-btn { + width: 100%; + } +} \ No newline at end of file diff --git a/src/app/app-modules/core/components/transfer-search/transfer-search.component.html b/src/app/app-modules/core/components/transfer-search/transfer-search.component.html new file mode 100644 index 0000000..e507e44 --- /dev/null +++ b/src/app/app-modules/core/components/transfer-search/transfer-search.component.html @@ -0,0 +1,105 @@ +
+

{{ currentLanguageSet?.inventory?.batchSelection }}

+ +
+
+
+
+
+ + + +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+ +
+
+
diff --git a/src/app/app-modules/core/components/transfer-search/transfer-search.component.spec.ts b/src/app/app-modules/core/components/transfer-search/transfer-search.component.spec.ts new file mode 100644 index 0000000..7077ccd --- /dev/null +++ b/src/app/app-modules/core/components/transfer-search/transfer-search.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TransferSearchComponent } from './transfer-search.component'; + +describe('TransferSearchComponent', () => { + let component: TransferSearchComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [TransferSearchComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TransferSearchComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/core/components/transfer-search/transfer-search.component.ts b/src/app/app-modules/core/components/transfer-search/transfer-search.component.ts new file mode 100644 index 0000000..e92758b --- /dev/null +++ b/src/app/app-modules/core/components/transfer-search/transfer-search.component.ts @@ -0,0 +1,96 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { ItemSearchService } from '../../services/item-search.service'; +import { Observable, Subject } from 'rxjs'; +import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; +import { SetLanguageComponent } from '../set-language.component'; +import { LanguageService } from '../../services/language.service'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-transfer-search', + templateUrl: './transfer-search.component.html', + styleUrls: ['./transfer-search.component.css'], +}) +export class TransferSearchComponent implements OnInit, DoCheck { + private searchTerms!: string; + items$!: Observable; + selectedBatchList: any = []; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + @Inject(MAT_DIALOG_DATA) public input: any, + public dialogRef: MatDialogRef, + public http_service: LanguageService, + private itemSearchService: ItemSearchService, + ) {} + + ngOnInit() { + this.search(this.input.searchTerm); + this.fetchLanguageResponse(); + } + + search(term: string): void { + this.items$ = this.itemSearchService.searchDrugItemforTransfer( + term, + this.input.transferTo, + ); + } + + selectBatch(event: any, batch: any) { + if (event.checked) { + this.selectedBatchList.push(batch); + batch.selected = true; + } else { + const index = this.selectedBatchList.indexOf(batch); + this.selectedBatchList.splice(index, 1); + batch.selected = false; + } + } + + disableSelection(batch: any) { + const addedStock = this.input.addedStock; + const temp = addedStock.filter( + (stock: any) => stock.itemStockEntryID == batch.itemStockEntryID, + ); + if (temp.length > 0) return true; + else return false; + } + + submitBatch() { + this.dialogRef.close(this.selectedBatchList); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/core/core.module.ts b/src/app/app-modules/core/core.module.ts index 69c1369..beb8a01 100644 --- a/src/app/app-modules/core/core.module.ts +++ b/src/app/app-modules/core/core.module.ts @@ -31,7 +31,6 @@ import { CommonService } from './services/common-services.service'; import { ConfirmationService } from './services/confirmation.service'; import { MatDialogModule } from '@angular/material/dialog'; import { MatMenuModule } from '@angular/material/menu'; -import { HttpInterceptor } from './services/http-interceptor.service'; import { ItemSearchService } from './services/item-search.service'; import { BatchViewService } from './services/rx-batchview.service'; import { SpinnerService } from './services/spinner.service'; @@ -47,6 +46,43 @@ import { MatCardModule } from '@angular/material/card'; import { MatRadioModule } from '@angular/material/radio'; import { MaterialModule } from './material.module'; import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatListModule } from '@angular/material/list'; +import { MatSelectModule } from '@angular/material/select'; +import { SpinnerComponent } from './components/spinner/spinner.component'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { SearchComponent } from './components/search/search.component'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { ItemSearchDirective } from './directives/item-search.directive'; +import { ItemSearchComponent } from './components/item-search/item-search.component'; +import { DisableFormControlDirective } from './directives/disableFormControl.directive'; +import { HttpInterceptorService } from './services/http-interceptor.service'; +import { AppFooterComponent } from './components/app-footer/app-footer.component'; +import { AppHeaderComponent } from './components/app-header/app-header.component'; +import { myEmailDirective } from './directives/email/myEmail.directive'; +import { myMobileNumberDirective } from './directives/MobileNumber/myMobileNumber.directive'; +import { myNameDirective } from './directives/name/myName.directive'; +import { myPasswordDirective } from './directives/password/myPassword.directive'; +import { ISTDatePipe } from './pipes/ist-date.pipe'; +import { BatchAdjustmentComponent } from './components/batch-adjustment/batch-adjustment.component'; +import { BatchSearchDirective } from './directives/batch-search.directive'; +import { BatchSearchComponent } from './components/batch-search/batch-search.component'; +import { BeneficiaryDetailsComponent } from './components/beneficiary-details/beneficiary-details.component'; +import { IndentItemListComponent } from './components/indent-item-list/indent-item-list.component'; +import { ItemDispenseComponent } from './components/item-dispense/item-dispense.component'; +import { RxBatchViewComponent } from './components/rx-batch-view/rx-batch-view.component'; +import { ShowCommitAndVersionDetailsComponent } from './components/show-commit-and-version-details/show-commit-and-version-details.component'; +import { TextareaDialogComponent } from './components/textarea-dialog/textarea-dialog.component'; +import { TransferSearchComponent } from './components/transfer-search/transfer-search.component'; +import { BatchAdjustmentDirective } from './directives/batch-adjustment.directive'; +import { StringValidatorDirective } from './directives/stringValidator.directive'; +import { NullDefaultValueDirective } from './directives/null-default-value.directive'; +import { ItemDispenseDirective } from './directives/item-dispense.directive'; +import { ItemTransferDirective } from './directives/item-transfer.directive'; +import { IndentDispenseDirective } from './directives/indent-dispense.directive'; +import { IndentRequestDirective } from './directives/indent-request.directive'; +import { MinNumberValidatorDirective } from './directives/minNumberValidator.directive'; +import { NumberValidatorDirective } from './directives/numberValidator.directive'; @NgModule({ imports: [ HttpClientModule, @@ -62,87 +98,92 @@ import { MatDatepickerModule } from '@angular/material/datepicker'; MatInputModule, MatTableModule, MatTooltipModule, + MatPaginatorModule, MatMenuModule, MatIconModule, MatButtonModule, MatCardModule, MatRadioModule, MatDatepickerModule, + MatListModule, + MatSelectModule, + MatProgressBarModule, + MatProgressSpinnerModule, // Ng2GoogleChartsModule, ], declarations: [ CommonDialogComponent, - // TextareaDialogComponent, - // SpinnerComponent, - // AppFooterComponent, - // AppHeaderComponent, - // myEmail, - // myMobileNumber, + TextareaDialogComponent, + SpinnerComponent, + AppFooterComponent, + AppHeaderComponent, + myEmailDirective, + myMobileNumberDirective, SetLanguageComponent, - // myName, - // myPassword, - // StringValidator, - // NullDefaultValueDirective, - // NumberValidator, - // DisableFormControlDirective, - // ItemSearchComponent, - // ItemSearchDirective, - // MinNumberValidator, - // TransferSearchComponent, - // ItemTransferDirective, - // BatchSearchComponent, - // BatchSearchDirective, - // ItemDispenseDirective, - // ItemDispenseComponent, - // SearchComponent, + myNameDirective, + myPasswordDirective, + StringValidatorDirective, + NullDefaultValueDirective, + NumberValidatorDirective, + DisableFormControlDirective, + ItemSearchComponent, + ItemSearchDirective, + MinNumberValidatorDirective, + TransferSearchComponent, + ItemTransferDirective, + BatchSearchComponent, + BatchSearchDirective, + ItemDispenseDirective, + ItemDispenseComponent, + SearchComponent, // SetLanguageComponent, - // ISTDatePipe, - // BatchAdjustmentDirective, - // BatchAdjustmentComponent, - // BeneficiaryDetailsComponent, - // RxBatchViewComponent, - // IndentRequestDirective, - // IndentItemListComponent, - // IndentDispenseDirective, - // ShowCommitAndVersionDetailsComponent + ISTDatePipe, + BatchAdjustmentDirective, + BatchAdjustmentComponent, + BeneficiaryDetailsComponent, + RxBatchViewComponent, + IndentRequestDirective, + IndentItemListComponent, + IndentDispenseDirective, + ShowCommitAndVersionDetailsComponent, ], exports: [ MaterialModule, // Md2Module, CommonDialogComponent, - // TextareaDialogComponent, - // SpinnerComponent, + TextareaDialogComponent, + SpinnerComponent, // SetLanguageComponent, // ReactiveFormsModule, - // AppFooterComponent, - // AppHeaderComponent, + AppFooterComponent, + AppHeaderComponent, // Ng2GoogleChartsModule, - // myEmail, + myEmailDirective, SetLanguageComponent, - // myMobileNumber, - // myName, - // myPassword, + myMobileNumberDirective, + myNameDirective, + myPasswordDirective, // DisableFormControlDirective, - // StringValidator, - // NumberValidator, - // MinNumberValidator, - // NullDefaultValueDirective, - // ItemSearchComponent, - // ItemSearchDirective, - // TransferSearchComponent, - // ItemTransferDirective, - // ItemDispenseDirective, - // BatchSearchComponent, - // BatchSearchDirective, - // ISTDatePipe, - // BatchAdjustmentComponent, - // BatchAdjustmentDirective, - // BeneficiaryDetailsComponent, - // IndentRequestDirective, - // IndentItemListComponent, - // IndentDispenseDirective, - // ShowCommitAndVersionDetailsComponent + StringValidatorDirective, + NumberValidatorDirective, + MinNumberValidatorDirective, + NullDefaultValueDirective, + ItemSearchComponent, + ItemSearchDirective, + TransferSearchComponent, + ItemTransferDirective, + ItemDispenseDirective, + BatchSearchComponent, + BatchSearchDirective, + ISTDatePipe, + BatchAdjustmentComponent, + BatchAdjustmentDirective, + BeneficiaryDetailsComponent, + IndentRequestDirective, + IndentItemListComponent, + IndentDispenseDirective, + ShowCommitAndVersionDetailsComponent, ], // entryComponents: [ // CommonDialogComponent, @@ -165,7 +206,7 @@ export class CoreModule { ngModule: CoreModule, providers: [ ConfirmationService, - HttpInterceptor, + HttpInterceptorService, BatchViewService, // TextareaDialog, AuthGuard, diff --git a/src/app/app-modules/core/directives/MobileNumber/myMobileNumber.directive.ts b/src/app/app-modules/core/directives/MobileNumber/myMobileNumber.directive.ts new file mode 100644 index 0000000..fd2575a --- /dev/null +++ b/src/app/app-modules/core/directives/MobileNumber/myMobileNumber.directive.ts @@ -0,0 +1,88 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Directive, ElementRef, HostListener, Input } from '@angular/core'; + +@Directive({ + selector: '[appMyMobileNumber]', +}) +export class myMobileNumberDirective { + constructor(element: ElementRef) {} + + // private mobileNumberValidator(number:any) + // { + // if (number.match(/^[+]?[0-9]{1,10}$/)) + // { + // if(number.length==10) + // { + // return 1; + // } + // else + // { + // return 0; + // } + // } + // else{ + // return -1; + // } + // } + + // @HostListener('keyup', ['$event']) onKeyUp(ev: any) + // { + + // var result = this.mobileNumberValidator(ev.target.value); + // if(result==1) + // { + // ev.target.nextSibling.nextElementSibling.innerHTML = "Valid Number"; + // ev.target.style.border = "2px solid green"; + // } + // if(result==0) + // { + // ev.target.nextSibling.nextElementSibling.innerHTML = "mobile number should be a 10 digit number"; + // ev.target.style.border = "2px solid yellow"; + // } + // if(result==-1) + // { + // ev.target.nextSibling.nextElementSibling.innerHTML="Enter only numbers"; + // ev.target.style.border = "2px solid red"; + // } + + // } + + @HostListener('keypress', ['$event']) onKeyPress(ev: any) { + const regex = new RegExp(/^[a-zA-Z~!@#$%^&*()_+\-=[]{};':"\\|,.<>\/?]*$/); + const key = String.fromCharCode(!ev.charCode ? ev.which : ev.charCode); + if (regex.test(key)) { + ev.preventDefault(); + } + } + @HostListener('paste', ['$event']) blockPaste(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('copy', ['$event']) blockCopy(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('cut', ['$event']) blockCut(event: KeyboardEvent) { + event.preventDefault(); + } +} diff --git a/src/app/app-modules/core/directives/batch-adjustment.directive.ts b/src/app/app-modules/core/directives/batch-adjustment.directive.ts new file mode 100644 index 0000000..7cbb4ed --- /dev/null +++ b/src/app/app-modules/core/directives/batch-adjustment.directive.ts @@ -0,0 +1,115 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Directive, + HostListener, + Inject, + Input, + ElementRef, +} from '@angular/core'; +import { BatchAdjustmentComponent } from '../components/batch-adjustment/batch-adjustment.component'; +import { FormArray, FormBuilder, Validators, FormGroup } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; + +@Directive({ + selector: '[appBatchAdjustment]', +}) +export class BatchAdjustmentDirective { + @Input() + previousSelected: any; + + @Input() + stockForm!: FormGroup; + + @HostListener('keyup.enter') onKeyDown() { + this.openDialog(); + } + + @HostListener('click') onClick() { + if (this.el.nativeElement.nodeName != 'INPUT') this.openDialog(); + } + + constructor( + private el: ElementRef, + private fb: FormBuilder, + private dialog: MatDialog, + ) {} + + openDialog(): void { + const searchTerm = this.stockForm.value.itemName; + + const dialogRef = this.dialog.open(BatchAdjustmentComponent, { + // width: '80%', + // height: '90%', + panelClass: 'fit-screen', + data: { searchTerm: searchTerm, addedStock: this.previousSelected }, + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result) { + const formArray = this.stockForm.parent as FormArray; + const len = formArray.length; + + console.log(formArray + ' ' + len); + + for (let i = len - 1, j = 0; i < len + result.length - 1; i++, j++) { + (formArray.at(i)).controls['itemStockEntryID'].setValue( + result[j].itemStockEntryID, + ); + (formArray.at(i)).controls['batchID'].setValue( + result[j].batchNo, + ); + (formArray.at(i)).controls['itemID'].setValue( + result[j].item.itemID, + ); + (formArray.at(i)).controls['itemName'].setValue( + result[j].item.itemName, + ); + (formArray.at(i)).controls['quantityInHand'].setValue( + result[j].quantityInHand, + ); + (formArray.at(i)).controls['itemName'].disable(); + // (formArray.at(i)).controls['quantity'].enable(); + (formArray.at(i)).markAsDirty(); + + if (formArray.length < len + result.length - 1) + formArray.push(this.initStockAdjustmentList()); + } + } + }); + } + + initStockAdjustmentList() { + return this.fb.group({ + itemStockEntryID: null, + itemID: null, + itemName: null, + batchID: null, + quantityInHand: null, + adjustmentType: null, + adjustedQuantity: null, + qohAfterAdjustment: null, + reason: null, + deleted: false, + }); + } +} diff --git a/src/app/app-modules/core/directives/batch-search.directive.ts b/src/app/app-modules/core/directives/batch-search.directive.ts new file mode 100644 index 0000000..016a1fd --- /dev/null +++ b/src/app/app-modules/core/directives/batch-search.directive.ts @@ -0,0 +1,115 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Directive, + HostListener, + Inject, + Input, + ElementRef, +} from '@angular/core'; + +import { NgControl } from '@angular/forms'; +import { FormArray, FormBuilder, Validators, FormGroup } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { BatchSearchComponent } from '../components/batch-search/batch-search.component'; + +@Directive({ + selector: '[appBatchSearch]', +}) +export class BatchSearchDirective { + @Input() + previousSelected: any; + + @Input() + stockForm!: FormGroup; + + @HostListener('keyup.enter') onKeyDown() { + const searchTerm = this.stockForm.value.itemName; + + if (searchTerm.length >= 2) this.openDialog(); + } + + @HostListener('click') onClick() { + if (this.el.nativeElement.nodeName != 'INPUT') this.openDialog(); + } + + constructor( + private el: ElementRef, + private fb: FormBuilder, + private dialog: MatDialog, + ) {} + + openDialog(): void { + const searchTerm = this.stockForm.value.itemName; + + const dialogRef = this.dialog.open(BatchSearchComponent, { + // width: '80%', + // height: '90%', + panelClass: 'fit-screen', + data: { searchTerm: searchTerm, addedStock: this.previousSelected }, + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result) { + const formArray = this.stockForm.parent as FormArray; + const len = formArray.length; + + console.log(formArray + ' ' + len); + + for (let i = len - 1, j = 0; i < len + result.length - 1; i++, j++) { + (formArray.at(i)).controls['itemStockEntryID'].setValue( + result[j].itemStockEntryID, + ); + (formArray.at(i)).controls['batchNo'].setValue( + result[j].batchNo, + ); + (formArray.at(i)).controls['itemID'].setValue( + result[j].item.itemID, + ); + (formArray.at(i)).controls['itemName'].setValue( + result[j].item.itemName, + ); + (formArray.at(i)).controls['quantityInHand'].setValue( + result[j].quantityInHand, + ); + (formArray.at(i)).controls['itemName'].disable(); + (formArray.at(i)).controls['quantity'].enable(); + (formArray.at(i)).markAsDirty(); + + if (formArray.length < len + result.length - 1) + formArray.push(this.initDispensedStock()); + } + } + }); + } + + initDispensedStock() { + return this.fb.group({ + itemStockEntryID: null, + batchNo: [null, Validators.required], + itemID: null, + itemName: [null, Validators.required], + quantityInHand: null, + quantity: [null, Validators.required], + }); + } +} diff --git a/src/app/app-modules/core/directives/disableFormControl.directive.ts b/src/app/app-modules/core/directives/disableFormControl.directive.ts new file mode 100644 index 0000000..c434b2c --- /dev/null +++ b/src/app/app-modules/core/directives/disableFormControl.directive.ts @@ -0,0 +1,39 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Directive, Input } from '@angular/core'; +import { NgControl } from '@angular/forms'; + +@Directive({ + selector: '[appDisableFormControl]', +}) +export class DisableFormControlDirective { + // @Input() + // set disableFormControl(condition: boolean) { + // const action = this.ngControl.control.parent.disabled || condition ? 'disable' : 'enable'; + // if (action == 'disable' && !this.ngControl.control.parent.disabled) + // this.ngControl.control.setValue(null); + // // this.ngControl.control.markAsTouched(); + // this.ngControl.control[action](); + // } + // constructor(private ngControl: NgControl) { + // } +} diff --git a/src/app/app-modules/core/directives/email/myEmail.directive.ts b/src/app/app-modules/core/directives/email/myEmail.directive.ts new file mode 100644 index 0000000..d79aff0 --- /dev/null +++ b/src/app/app-modules/core/directives/email/myEmail.directive.ts @@ -0,0 +1,68 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Directive, forwardRef, HostListener } from '@angular/core'; +import { + NG_VALIDATORS, + Validator, + Validators, + ValidatorFn, + AbstractControl, +} from '@angular/forms'; + +@Directive({ + selector: '[appValidateEmail]', + providers: [ + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => myEmailDirective), + multi: true, + }, + ], +}) +export class myEmailDirective implements Validator { + pattern = /^[0-9a-zA-Z_.]+@[a-zA-Z_]+?\.[a-zA-Z.]{2,5}$/; + + constructor() {} + + validate(control: AbstractControl): { [key: string]: any } | null { + const input = control.value; + if (input == '' || input == null) return null; + + const flag = this.pattern.test(input); + return flag + ? null + : { + valid: false, + }; + } + @HostListener('paste', ['$event']) blockPaste(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('copy', ['$event']) blockCopy(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('cut', ['$event']) blockCut(event: KeyboardEvent) { + event.preventDefault(); + } +} diff --git a/src/app/app-modules/core/directives/indent-dispense.directive.ts b/src/app/app-modules/core/directives/indent-dispense.directive.ts new file mode 100644 index 0000000..627233e --- /dev/null +++ b/src/app/app-modules/core/directives/indent-dispense.directive.ts @@ -0,0 +1,75 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Directive, + HostListener, + Inject, + Input, + ElementRef, +} from '@angular/core'; +import { NgControl, FormGroup } from '@angular/forms'; +import { ItemDispenseComponent } from './../components/item-dispense/item-dispense.component'; +import { MatDialog } from '@angular/material/dialog'; + +@Directive({ + selector: '[appIndentDispense]', +}) +export class IndentDispenseDirective { + @Input() + stockForm!: FormGroup; + + @Input() + indentDispenseList: any; + + @HostListener('keyup.enter') onKeyDown() { + this.openDialog(); + } + + @HostListener('click') onClick() { + if (this.el.nativeElement.nodeName != 'INPUT') this.openDialog(); + } + + constructor( + private el: ElementRef, + private dialog: MatDialog, + ) {} + + openDialog(): void { + const searchTerm = this.stockForm.value.itemName; + + console.log('indent dispense directive form', this.stockForm); + + // let dialogRef = this.dialog.open(ItemDispenseComponent, { + // // width: '80%', + // // height: '90%', + // panelClass: 'fit-screen', + // data: { searchTerm: searchTerm, indentDispenseList: this.indentDispenseList } + // }); + + // dialogRef.afterClosed().subscribe(result => { + // if (result) { + // this.stockForm.controls['itemName'].setValue(result.item.itemName); + // this.stockForm.controls['requestedQty'].setValue(result.requestedQty); + // } + // }); + } +} diff --git a/src/app/app-modules/core/directives/indent-request.directive.ts b/src/app/app-modules/core/directives/indent-request.directive.ts new file mode 100644 index 0000000..3e7fe3f --- /dev/null +++ b/src/app/app-modules/core/directives/indent-request.directive.ts @@ -0,0 +1,99 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Directive, + HostListener, + Inject, + Input, + ElementRef, +} from '@angular/core'; +import { NgControl } from '@angular/forms'; +import { IndentItemListComponent } from '../components/indent-item-list/indent-item-list.component'; +import { FormArray, FormBuilder, Validators, FormGroup } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; + +@Directive({ + selector: '[appIndentRequest]', +}) +export class IndentRequestDirective { + @Input() + previousSelected: any; + + @Input() + itemListForm!: FormGroup; + + @HostListener('keyup.enter') onKeyDown() { + this.openDialog(); + } + @HostListener('click') onClick() { + if (this.el.nativeElement.nodeName != 'INPUT') this.openDialog(); + } + constructor( + private el: ElementRef, + private fb: FormBuilder, + private dialog: MatDialog, + ) {} + + openDialog(): void { + const searchTerm = this.itemListForm.value.itemNameView; + const dialogRef = this.dialog.open(IndentItemListComponent, { + width: '80%', + // height: '90%', + panelClass: 'fit-screen', + data: { searchTerm: searchTerm, addedIndent: this.previousSelected }, + }); + dialogRef.afterClosed().subscribe((result) => { + if (result) { + const formArray = this.itemListForm.parent as FormArray; + const len = formArray.length; + for (let i = len - 1, j = 0; i < len + result.length - 1; i++, j++) { + (formArray.at(i)).controls['itemID'].setValue( + result[j].itemID, + ); + (formArray.at(i)).controls['itemName'].setValue( + result[j].itemName, + ); + (formArray.at(i)).controls['qOH'].setValue(result[j].qoh); + (formArray.at(i)).controls['itemNameView'].setValue( + result[j].itemName, + ); + (formArray.at(i)).controls['itemNameView'].disable(); + (formArray.at(i)).markAsDirty(); + + if (formArray.length < len + result.length - 1) + formArray.push(this.initIndentRequestList()); + } + } + }); + } + initIndentRequestList() { + return this.fb.group({ + itemID: null, + itemName: null, + itemNameView: null, + qOH: null, + requiredQty: null, + remarks: null, + deleted: false, + }); + } +} diff --git a/src/app/app-modules/core/directives/item-dispense.directive.ts b/src/app/app-modules/core/directives/item-dispense.directive.ts new file mode 100644 index 0000000..eeb2fb4 --- /dev/null +++ b/src/app/app-modules/core/directives/item-dispense.directive.ts @@ -0,0 +1,80 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Directive, + HostListener, + Inject, + Input, + ElementRef, +} from '@angular/core'; + +import { NgControl, FormGroup } from '@angular/forms'; + +import { ItemDispenseComponent } from './../components/item-dispense/item-dispense.component'; +import { MatDialog } from '@angular/material/dialog'; + +@Directive({ + selector: '[appItemDispense]', +}) +export class ItemDispenseDirective { + @Input() + stockForm!: FormGroup; + + @Input() + dispenseItemList: any; + + @HostListener('keyup.enter') onKeyDown() { + this.openDialog(); + } + + @HostListener('click') onClick() { + if (this.el.nativeElement.nodeName != 'INPUT') this.openDialog(); + } + + constructor( + private el: ElementRef, + private dialog: MatDialog, + ) {} + + openDialog(): void { + const searchTerm = this.stockForm.value.itemName; + + console.log(this.stockForm); + + const dialogRef = this.dialog.open(ItemDispenseComponent, { + // width: '80%', + // height: '90%', + panelClass: 'fit-screen', + data: { searchTerm: searchTerm, dispenseItemList: this.dispenseItemList }, + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result) { + this.stockForm.controls['itemName'].setValue(result.item.itemName); + this.stockForm.controls['quantityInHand'].setValue( + result.quantityInHand, + ); + this.stockForm.controls['itemID'].setValue(result.item.itemID); + } + }); + } +} diff --git a/src/app/app-modules/core/directives/item-search.directive.ts b/src/app/app-modules/core/directives/item-search.directive.ts new file mode 100644 index 0000000..47d5e55 --- /dev/null +++ b/src/app/app-modules/core/directives/item-search.directive.ts @@ -0,0 +1,79 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Directive, + HostListener, + Inject, + Input, + ElementRef, +} from '@angular/core'; +import { FormGroup } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { ItemSearchComponent } from '../components/item-search/item-search.component'; +// import { ItemSearchComponent } from '../components/item-search/item-search.component'; + +@Directive({ + selector: '[appItemSearch]', +}) +export class ItemSearchDirective { + @Input() + stockForm!: FormGroup; + + @HostListener('keyup.enter') onKeyDown() { + this.openDialog(); + } + + @HostListener('click') onClick() { + if (this.el.nativeElement.nodeName != 'INPUT') this.openDialog(); + } + + constructor( + private el: ElementRef, + private dialog: MatDialog, + ) {} + + openDialog(): void { + const searchTerm = this.stockForm.value.itemName ?? ''; + console.log('SEARCH#####', this.stockForm.value); + const dialogRef = this.dialog.open(ItemSearchComponent, { + width: '80%', + height: '90%', + panelClass: 'fit-screen', + data: { searchTerm: searchTerm }, + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result) { + console.log('result', result); + this.stockForm.controls['itemName'].setValue(result.itemName); + this.stockForm.controls['itemName'].disable(); + this.stockForm.controls['itemID'].setValue(result.itemID); + + if (this.stockForm.controls['isMedical']) + this.stockForm.controls['isMedical'].setValue(result.isMedical); + this.stockForm.markAsDirty(); + } else { + // this.stockForm.control.parent.reset(); + } + }); + } +} diff --git a/src/app/app-modules/core/directives/item-transfer.directive.ts b/src/app/app-modules/core/directives/item-transfer.directive.ts new file mode 100644 index 0000000..fa24325 --- /dev/null +++ b/src/app/app-modules/core/directives/item-transfer.directive.ts @@ -0,0 +1,117 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Directive, + HostListener, + Inject, + Input, + ElementRef, +} from '@angular/core'; +import { + NgControl, + FormArray, + FormBuilder, + FormGroup, + Validators, +} from '@angular/forms'; +import { TransferSearchComponent } from '../components/transfer-search/transfer-search.component'; +import { MatDialog } from '@angular/material/dialog'; + +@Directive({ + selector: '[appItemTransfer]', +}) +export class ItemTransferDirective { + @Input() + previousSelected: any; + + @Input() + stockForm!: FormGroup; + + @HostListener('keydown.enter') onKeyDown() { + this.openDialog(); + } + + @HostListener('click') onClick() { + if (this.el.nativeElement.nodeName != 'INPUT') this.openDialog(); + } + + constructor( + private el: ElementRef, + private fb: FormBuilder, + private dialog: MatDialog, + ) {} + + openDialog(): void { + const searchTerm = this.stockForm.value.itemName; + const transferTo = + this.stockForm?.parent?.parent?.value.transferTo.facilityID; + + const dialogRef = this.dialog.open(TransferSearchComponent, { + // width: '80%', + // height: '90%', + panelClass: 'fit-screen', + data: { + searchTerm: searchTerm, + transferTo: transferTo, + addedStock: this.previousSelected, + }, + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result) { + const formArray = this.stockForm.parent as FormArray; + const len = formArray.length; + for (let i = len - 1, j = 0; i < len + result.length - 1; i++, j++) { + (formArray.at(i)).controls['itemStockEntryID'].setValue( + result[j].itemStockEntryID, + ); + (formArray.at(i)).controls['batchNo'].setValue( + result[j].batchNo, + ); + (formArray.at(i)).controls['qoh'].setValue( + result[j].quantityInHand, + ); + + (formArray.at(i)).controls['itemName'].setValue( + result[j].item.itemName, + ); + (formArray.at(i)).controls['itemName'].disable(); + (formArray.at(i)).controls['quantity'].enable(); + (formArray.at(i)).markAsDirty(); + + if (formArray.length < len + result.length - 1) + formArray.push(this.createItem()); + } + } + }); + } + + createItem() { + return this.fb.group({ + batchNo: [null, Validators.required], + itemStockEntryID: [null, Validators.required], + itemName: [null, Validators.required], + qoh: [null, Validators.required], + quantity: [null, Validators.required], + }); + } +} diff --git a/src/app/app-modules/core/directives/minNumberValidator.directive.ts b/src/app/app-modules/core/directives/minNumberValidator.directive.ts new file mode 100644 index 0000000..810d17a --- /dev/null +++ b/src/app/app-modules/core/directives/minNumberValidator.directive.ts @@ -0,0 +1,80 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Directive, + ElementRef, + Attribute, + HostListener, + Input, + Injector, +} from '@angular/core'; +import { AbstractControl, NgControl } from '@angular/forms'; + +@Directive({ + selector: + '[appAllowMin][formControlName],[appAllowMin][formControl],[appAllowMin][ngModel],[allowMin]', +}) +export class MinNumberValidatorDirective { + @Input('allowMin') + public min!: any; + + constructor( + private elementRef: ElementRef, + private injector: Injector, + ) {} + + validate(input: any) { + const min = this.min; + + if (+input >= +min) return true; + else return false; + } + + @HostListener('input', ['$event']) + onInput(event: any) { + const value = event.target.value; + const ngControl: any = this.injector.get(NgControl, null) as NgControl; + + if (!this.validate(value)) { + if (ngControl) ngControl.control.setValue(this.lastValue); + else event.target.value = this.lastValue; + } + this.lastValue = event.target.value; + } + + lastValue = null; + @HostListener('focus', ['$event']) + onFocus(event: any) { + this.lastValue = event.target.value; + } + @HostListener('paste', ['$event']) blockPaste(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('copy', ['$event']) blockCopy(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('cut', ['$event']) blockCut(event: KeyboardEvent) { + event.preventDefault(); + } +} diff --git a/src/app/app-modules/core/directives/name/myName.directive.ts b/src/app/app-modules/core/directives/name/myName.directive.ts new file mode 100644 index 0000000..874553d --- /dev/null +++ b/src/app/app-modules/core/directives/name/myName.directive.ts @@ -0,0 +1,48 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Directive, ElementRef, HostListener, Input } from '@angular/core'; + +@Directive({ + selector: '[appMyName]', +}) +export class myNameDirective { + constructor(element: ElementRef) {} + + @HostListener('keypress', ['$event']) onKeyPress(ev: any) { + const regex = new RegExp(/^[0-9 ~!@#$%^&*()_+\-=[]{};':"\\|,.<>\/?]*$/); + const key = String.fromCharCode(!ev.charCode ? ev.which : ev.charCode); + if (regex.test(key)) { + ev.preventDefault(); + } + } + @HostListener('paste', ['$event']) blockPaste(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('copy', ['$event']) blockCopy(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('cut', ['$event']) blockCut(event: KeyboardEvent) { + event.preventDefault(); + } +} diff --git a/src/app/app-modules/core/directives/null-default-value.directive.ts b/src/app/app-modules/core/directives/null-default-value.directive.ts new file mode 100644 index 0000000..d4a1d3b --- /dev/null +++ b/src/app/app-modules/core/directives/null-default-value.directive.ts @@ -0,0 +1,49 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Directive, ElementRef, Attribute, HostListener } from '@angular/core'; +import { NgControl } from '@angular/forms'; + +@Directive({ + selector: '[appDefaultNull]', +}) +export class NullDefaultValueDirective { + constructor( + private el: ElementRef, + private control: NgControl, + ) {} + + @HostListener('input', ['$event.target']) + onEvent(target: HTMLInputElement) { + this.control.control?.setValue(target.value === '' ? null : target.value); + } + @HostListener('paste', ['$event']) blockPaste(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('copy', ['$event']) blockCopy(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('cut', ['$event']) blockCut(event: KeyboardEvent) { + event.preventDefault(); + } +} diff --git a/src/app/app-modules/core/directives/numberValidator.directive.ts b/src/app/app-modules/core/directives/numberValidator.directive.ts new file mode 100644 index 0000000..79419cc --- /dev/null +++ b/src/app/app-modules/core/directives/numberValidator.directive.ts @@ -0,0 +1,81 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Directive, + ElementRef, + Attribute, + HostListener, + Input, + Injector, +} from '@angular/core'; +import { AbstractControl, NgControl } from '@angular/forms'; + +@Directive({ + selector: + '[appAllowMax][formControlName],[appAllowMax][formControl],[appAllowMax][ngModel],[appAllowMax]', +}) +export class NumberValidatorDirective { + @Input() + public appAllowMax!: number; + + constructor( + private elementRef: ElementRef, + private injector: Injector, + ) {} + + validate(input: any) { + const max = this.appAllowMax; + + if (+input <= +max) return true; + else return false; + } + + @HostListener('input', ['$event']) + onInput(event: any) { + const ngControl: any = this.injector.get(NgControl, null) as NgControl; + const value = event.target.value; + + if (!this.validate(value)) { + if (ngControl) ngControl.control.setValue(this.lastValue); + else event.target.value = this.lastValue; + } + + this.lastValue = event.target.value; + } + + lastValue = null; + @HostListener('focus', ['$event']) + onFocus(event: any) { + this.lastValue = event.target.value; + } + @HostListener('paste', ['$event']) blockPaste(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('copy', ['$event']) blockCopy(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('cut', ['$event']) blockCut(event: KeyboardEvent) { + event.preventDefault(); + } +} diff --git a/src/app/app-modules/core/directives/password/myPassword.directive.ts b/src/app/app-modules/core/directives/password/myPassword.directive.ts new file mode 100644 index 0000000..7f6adf4 --- /dev/null +++ b/src/app/app-modules/core/directives/password/myPassword.directive.ts @@ -0,0 +1,78 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Directive, ElementRef, HostListener, Input } from '@angular/core'; + +@Directive({ + selector: '[appMyPassword]', +}) +export class myPasswordDirective { + constructor(element: ElementRef) {} + + private passwordValidator(password: any) { + if (password.match(/^[a-zA-Z]{1,1}[a-zA-Z0-9 $%#@!&^*()+{}[]-]{7,11}$/)) { + if (password.length >= 8) { + return 1; + } else { + return 0; + } + } else { + return -1; + } + } + + @HostListener('keyup', ['$event']) onKeyUp(ev: any) { + const result = this.passwordValidator(ev.target.value); + if (result == 1) { + ev.target.nextSibling.nextElementSibling.innerHTML = 'Strong Password'; + ev.target.style.border = '2px solid green'; + } + if (result == 0) { + ev.target.nextSibling.nextElementSibling.innerHTML = 'Weak Password'; + ev.target.style.border = '2px solid yellow'; + } + + if (result == -1) { + ev.target.nextSibling.nextElementSibling.innerHTML = + 'password should be 8-12 characters long and must start with an alphabet and can have numbers alphabets and $%#@!&^*()-+{}[]'; + ev.target.style.border = '2px solid red'; + } + } + + @HostListener('keypress', ['$event']) onKeyPress(ev: any) { + const regex = new RegExp(/^[\s]*$/); + const key = String.fromCharCode(!ev.charCode ? ev.which : ev.charCode); + if (regex.test(key)) { + ev.preventDefault(); + } + } + @HostListener('paste', ['$event']) blockPaste(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('copy', ['$event']) blockCopy(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('cut', ['$event']) blockCut(event: KeyboardEvent) { + event.preventDefault(); + } +} diff --git a/src/app/app-modules/core/directives/stringValidator.directive.ts b/src/app/app-modules/core/directives/stringValidator.directive.ts new file mode 100644 index 0000000..7a81fb8 --- /dev/null +++ b/src/app/app-modules/core/directives/stringValidator.directive.ts @@ -0,0 +1,206 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Directive, + ElementRef, + Attribute, + HostListener, + Input, + Injector, +} from '@angular/core'; +import { AbstractControl, ValidatorFn, NgControl } from '@angular/forms'; + +@Directive({ + selector: + '[appAllowText][formControlName],[appAllowText][formControl],[appAllowText][ngModel],[appAllowText]', +}) +export class StringValidatorDirective { + @Input() + allowText!: string; + + alphabet = /^[a-zA-Z]+$/; + alphaspace = /^[a-zA-Z ]+$/; + alphanumeric = /^[a-zA-Z0-9]+$/; + alphanumericspace = /^[a-zA-Z0-9 ]+$/; + alphanumerichyphen = /^[a-zA-Z0-9-/ ]+$/; + numerichyphen = /^[0-9- ]+$/; + number = /^[0-9]+$/; + decimal = /^[0-9.]+$/; + numberslash = /^[0-9/]+$/; + address = /^[a-zA-Z0-9-./,# ]+$/; + + lastValue = null; + result!: boolean; + inputFieldValidator = /^[a-zA-Z0-9 ]+$/; + textAreaValidator = /^[a-zA-Z0-9., ]+$/; + questionnaireValidator = /^[a-zA-Z0-9.,? ]+$/; + addressValidator = /^[a-zA-Z0-9.,/\-# ]+$/; + smsTemplateValidator = /^[a-zA-Z0-9.,$\-:;/() ]+$/; + itemNameSearchValidator = /^[a-zA-Z0-9% ]+$/; + answerValidator = /^[a-zA-Z0-9.,/\- ]+$/; + usernameValidator = /^[a-zA-Z0-9]+$/; + + constructor( + private elementRef: ElementRef, + private injector: Injector, + ) {} + + validate(input: any) { + const patternCode = this.allowText.trim(); + + if (input == null || input == '') return false; + + switch (patternCode) { + case 'alphabet': + this.result = this.alphabet.test(input); + break; + case 'alphaspace': + this.result = this.alphaspace.test(input); + break; + case 'alphanumeric': + this.result = this.alphanumeric.test(input); + break; + case 'alphanumericspace': + this.result = this.alphanumericspace.test(input); + break; + case 'number': + this.result = this.number.test(input); + break; + case 'numberslash': + this.result = this.numberslash.test(input); + break; + case 'alphanumerichyphen': + this.result = this.alphanumerichyphen.test(input); + break; + case 'numerichyphen': + this.result = this.numerichyphen.test(input); + break; + case 'decimal': + this.result = this.decimal.test(input); + break; + case 'address': + this.result = this.address.test(input); + break; + case 'inputFieldValidator': + this.result = this.inputFieldValidator.test(input); + break; + case 'textAreaValidator': + this.result = this.textAreaValidator.test(input); + break; + case 'questionnaireValidator': + this.result = this.questionnaireValidator.test(input); + break; + case 'addressValidator': + this.result = this.addressValidator.test(input); + break; + case 'smsTemplateValidator': + this.result = this.smsTemplateValidator.test(input); + break; + case 'itemNameSearchValidator': + this.result = this.itemNameSearchValidator.test(input); + break; + case 'answerValidator': + this.result = this.answerValidator.test(input); + break; + case 'usernameValidator': + this.result = this.usernameValidator.test(input); + break; + default: + this.result = false; + } + return this.result; + } + + @HostListener('input', ['$event']) + onInput(event: any) { + const ngControl: any = this.injector.get(NgControl, null) as NgControl; + + const val = event.target.value; + const lastVal = this.lastValue; + const maxlength = event.target.maxLength; + + const inserted = this.findDelta(val, lastVal); + // get removed chars + const removed = this.findDelta(lastVal, val); + // determine if user pasted content + const pasted = inserted.length >= 1 || (!inserted && !removed); + + if (maxlength > 0 && val.length > maxlength) { + event.target.value = lastVal; + } else { + if (pasted) { + if (!this.isValidString(val)) { + if (ngControl) ngControl.control.setValue(this.lastValue); + else event.target.value = this.lastValue; + } + } else if (!removed) { + if (!this.isValidChar(inserted)) { + if (ngControl) ngControl.control.setValue(this.lastValue); + else event.target.value = this.lastValue; + } + } + + this.lastValue = event.target.value; + } + } + + @HostListener('focus', ['$event']) + onFocus(event: any) { + const input = event.target.value; + this.lastValue = input; + } + + findDelta(value: any, prevValue: any) { + let delta = ''; + + for (let i = 0; i < value.length; i++) { + const str = + value.substr(0, i) + value.substr(i + value.length - prevValue.length); + + if (str === prevValue) + delta = value.substr(i, value.length - prevValue.length); + } + + return delta; + } + + isValidChar(c: any) { + return this.validate(c); + } + + isValidString(str: any) { + for (let i = 0; i < str.length; i++) + if (!this.isValidChar(str.substr(i, 1))) return false; + return true; + } + @HostListener('paste', ['$event']) blockPaste(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('copy', ['$event']) blockCopy(event: KeyboardEvent) { + event.preventDefault(); + } + + @HostListener('cut', ['$event']) blockCut(event: KeyboardEvent) { + event.preventDefault(); + } +} diff --git a/src/app/app-modules/core/pipes/ist-date.pipe.ts b/src/app/app-modules/core/pipes/ist-date.pipe.ts new file mode 100644 index 0000000..0823e2d --- /dev/null +++ b/src/app/app-modules/core/pipes/ist-date.pipe.ts @@ -0,0 +1,32 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Pipe, PipeTransform } from '@angular/core'; +import { DatePipe } from '@angular/common'; + +@Pipe({ name: 'istDate' }) +export class ISTDatePipe implements PipeTransform { + transform(value: any, format = 'mediumDate'): string | null { + const date = new Date(value).valueOf(); + const transformDate = new Date(date - 19800000); + return new DatePipe('en-US').transform(transformDate, format); + } +} diff --git a/src/app/app-modules/core/services/confirmation.service.ts b/src/app/app-modules/core/services/confirmation.service.ts index 673d39f..b12f7ba 100644 --- a/src/app/app-modules/core/services/confirmation.service.ts +++ b/src/app/app-modules/core/services/confirmation.service.ts @@ -62,14 +62,15 @@ export class ConfirmationService { return dialogRef.afterClosed(); } - public alert(message: string, status = 'info', btnOkText = 'OK'): void { + public alert( + message: string, + status = 'info', + btnOkText = 'OK', + ): MatDialogRef { const config = { width: '420px', }; - const dialogRef: MatDialogRef = this.dialog.open( - CommonDialogComponent, - config, - ); + const dialogRef = this.dialog.open(CommonDialogComponent, config); dialogRef.componentInstance.message = message; dialogRef.componentInstance.status = status.toLowerCase(); dialogRef.componentInstance.btnOkText = btnOkText; @@ -77,6 +78,9 @@ export class ConfirmationService { dialogRef.componentInstance.alert = true; dialogRef.componentInstance.remarks = false; dialogRef.componentInstance.editRemarks = false; + // dialogRef.componentInstance.comments = null; + + return dialogRef; } public remarks( diff --git a/src/app/app-modules/core/services/http-interceptor.service.ts b/src/app/app-modules/core/services/http-interceptor.service.ts index ee28e76..e153213 100644 --- a/src/app/app-modules/core/services/http-interceptor.service.ts +++ b/src/app/app-modules/core/services/http-interceptor.service.ts @@ -20,28 +20,27 @@ * along with this program. If not, see https://www.gnu.org/licenses/. */ import { Injectable } from '@angular/core'; - -import { SpinnerService } from './spinner.service'; -import { ConfirmationService } from './confirmation.service'; -import { Router } from '@angular/router'; - -import { environment } from '../../../../environments/environment'; - -// import 'rxjs/Rx'; -import { SetLanguageComponent } from '../components/set-language.component'; -import { LanguageService } from './language.service'; import { - HttpClient, - HttpErrorResponse, - HttpEvent, - HttpHandler, + HttpInterceptor, HttpRequest, + HttpHandler, + HttpEvent, HttpResponse, + HttpClient, + HttpErrorResponse, } from '@angular/common/http'; -import { Observable, catchError, tap, throwError } from 'rxjs'; +import { catchError, tap } from 'rxjs/operators'; +import { Observable, of } from 'rxjs'; +import { Router } from '@angular/router'; +import { throwError } from 'rxjs/internal/observable/throwError'; +import { SpinnerService } from './spinner.service'; +import { ConfirmationService } from './confirmation.service'; +import { environment } from 'src/environments/environment'; -@Injectable() -export class HttpInterceptor implements HttpInterceptor { +@Injectable({ + providedIn: 'root', +}) +export class HttpInterceptorService implements HttpInterceptor { timerRef: any; currentLanguageSet: any; constructor( @@ -49,6 +48,7 @@ export class HttpInterceptor implements HttpInterceptor { private router: Router, private confirmationService: ConfirmationService, private http: HttpClient, + // private setLanguageService: SetLanguageService ) {} intercept( @@ -69,17 +69,18 @@ export class HttpInterceptor implements HttpInterceptor { return next.handle(modifiedReq).pipe( tap((event: HttpEvent) => { if (req.url !== undefined && !req.url.includes('cti/getAgentState')) - this.spinnerService.show(); - if (event instanceof HttpResponse) { - console.log(event.body); - this.onSuccess(req.url, event.body); - this.spinnerService.show(); - return event.body; - } + if (event instanceof HttpResponse) { + // this.spinnerService.show(); + console.log(event.body); + this.onSuccess(req.url, event.body); + // this.spinnerService.show(); + return event.body; + } }), catchError((error: HttpErrorResponse) => { console.error(error); - this.spinnerService.show(); + + // this.spinnerService.show(); return throwError(error.error); }), ); @@ -96,7 +97,57 @@ export class HttpInterceptor implements HttpInterceptor { localStorage.clear(); setTimeout(() => this.router.navigate(['/login']), 0); this.confirmationService.alert(response.errorMessage, 'error'); + } else { + this.startTimer(); } } - // -----End------ + + startTimer() { + this.timerRef = setTimeout( + () => { + console.log('there', Date()); + + if ( + sessionStorage.getItem('authenticationToken') && + sessionStorage.getItem('isAuthenticated') + ) { + this.confirmationService + .alert( + 'Your session is about to Expire. Do you need more time ? ', + 'sessionTimeOut', + ) + .afterClosed() + .subscribe((result: any) => { + if (result.action == 'continue') { + this.http.post(environment.extendSessionUrl, {}).subscribe( + (res: any) => {}, + (err: any) => {}, + ); + } else if (result.action == 'timeout') { + clearTimeout(this.timerRef); + sessionStorage.clear(); + localStorage.clear(); + this.confirmationService.alert( + this.currentLanguageSet.sessionExpired, + 'error', + ); + this.router.navigate(['/login']); + } else if (result.action == 'cancel') { + setTimeout(() => { + clearTimeout(this.timerRef); + sessionStorage.clear(); + localStorage.clear(); + this.confirmationService.alert( + this.currentLanguageSet.sessionExpired, + 'error', + ); + this.router.navigate(['/login']); + }, result.remainingTime * 1000); + } + }); + } + }, + 27 * 60 * 1000, + ); + } } diff --git a/src/app/app-modules/inventory/dashboard/dashboard.component.css b/src/app/app-modules/inventory/dashboard/dashboard.component.css new file mode 100644 index 0000000..75ef38a --- /dev/null +++ b/src/app/app-modules/inventory/dashboard/dashboard.component.css @@ -0,0 +1,3 @@ +.content { + /* height: stretch; */ +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/dashboard/dashboard.component.html b/src/app/app-modules/inventory/dashboard/dashboard.component.html new file mode 100644 index 0000000..31b120d --- /dev/null +++ b/src/app/app-modules/inventory/dashboard/dashboard.component.html @@ -0,0 +1,5 @@ + +
+ +
+ diff --git a/src/app/app-modules/inventory/dashboard/dashboard.component.spec.ts b/src/app/app-modules/inventory/dashboard/dashboard.component.spec.ts new file mode 100644 index 0000000..ac3b27d --- /dev/null +++ b/src/app/app-modules/inventory/dashboard/dashboard.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DashboardComponent } from './dashboard.component'; + +describe('DashboardComponent', () => { + let component: DashboardComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [DashboardComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/dashboard/dashboard.component.ts b/src/app/app-modules/inventory/dashboard/dashboard.component.ts new file mode 100644 index 0000000..dc2c6a4 --- /dev/null +++ b/src/app/app-modules/inventory/dashboard/dashboard.component.ts @@ -0,0 +1,31 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-dashboard', + templateUrl: './dashboard.component.html', + styleUrls: ['./dashboard.component.css'], +}) +export class DashboardComponent { + constructor() {} +} diff --git a/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.css b/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.css new file mode 100644 index 0000000..7044e5d --- /dev/null +++ b/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.css @@ -0,0 +1,54 @@ +@media print { + body { + background: white; + font-size: 14px; + } + .non-printable { + display: none; + } + .page-break { + page-break-after: always; + } + @page { + margin: 1.3cm; + } +} + +.table-no-border tr, th, .table-no-border tr td, .table-no-border thead tr th, .table-no-border tbody tr th, .table-no-border tbody tr td { + border: none; +} + +#logo { + width: 90px; +} + +.container { + background: white; + padding-top: 10px; +} + +.bg-unset{ + background: unset; +} + +.example-fab.mat-mini-fab { + position: fixed; + right: 20px; + z-index: 3; +} + +.upward { + bottom: 30px; +} + +.print { + bottom: 80px; +} + +.back { + bottom: 130px; +} + +.select { + bottom: 180px; +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.html b/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.html new file mode 100644 index 0000000..1c483f1 --- /dev/null +++ b/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.html @@ -0,0 +1,103 @@ +
+
+
+

+ {{ currentLanguageSet?.inventory?.date }} : {{ today | date: "dd/MM/yyyy" }} +

+
+
+ +
+
+ +
+
+

+ {{ currentLanguageSet?.inventory?.facilityName }} : {{ headerDetail?.facilityName }} +

+
+
+

+ {{ currentLanguageSet?.inventory?.dispenseType }} : + {{ headerDetail?.issueType }} +

+
+
+ + +
+
+

{{ title?.headerTitle }}

+
+
+ + + + + + + + + + + + + + + +
+ {{ column?.columnName }} + + {{ headerDetail[column?.keyName] }} +
{{ column?.columnName }}{{ headerDetail[column?.keyName] }}
+
+
+ +
+
+ + + + + + + +
{{ column.columnName }}{{ data[column.keyName] }}
+
+
+
+ +
+
+ + +
+
diff --git a/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.spec.ts b/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.spec.ts new file mode 100644 index 0000000..752ea03 --- /dev/null +++ b/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DynamicPrintComponent } from './dynamic-print.component'; + +describe('DynamicPrintComponent', () => { + let component: DynamicPrintComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [DynamicPrintComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DynamicPrintComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.ts b/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.ts new file mode 100644 index 0000000..7e217ef --- /dev/null +++ b/src/app/app-modules/inventory/dynamic-print/dynamic-print.component.ts @@ -0,0 +1,93 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, DoCheck, OnInit } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { Location } from '@angular/common'; +import { SetLanguageComponent } from '../../core/components/set-language.component'; +import { LanguageService } from '../../core/services/language.service'; +import { DataStorageService } from '../shared/service/data-storage.service'; + +@Component({ + selector: 'app-dynamic-print', + templateUrl: './dynamic-print.component.html', + styleUrls: ['./dynamic-print.component.css'], +}) +export class DynamicPrintComponent implements OnInit, DoCheck { + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private dataStorageService: DataStorageService, + private router: Router, + private http_service: LanguageService, + private route: ActivatedRoute, + private location: Location, + ) {} + + printableData: any; + columnList: any = []; + fieldData: any = []; + headerColumn: any = []; + headerDetail: any; + facilityDetail: any; + title: any; + today!: Date; + + ngOnInit() { + this.today = new Date(); + this.fetchLanguageResponse(); + const dataStore = this.route.snapshot.params['printablePage']; + console.log('dataStore', dataStore); + + // this.printableData = this.dataStorageService[dataStore]; + console.log('printableData', JSON.stringify(this.printableData, null, 4)); + this.title = this.printableData.title; + this.headerDetail = this.printableData.headerDetail; + this.columnList = this.printableData.columns; + this.fieldData = this.printableData.printableData; + this.headerColumn = this.printableData.headerColumn; + } + + goBack() { + this.location.back(); + } + + downloadList() { + window.print(); + } + + goToTop() { + window.scrollTo(0, 0); + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/inventory-routing.module.ts b/src/app/app-modules/inventory/inventory-routing.module.ts new file mode 100644 index 0000000..f5f6c8c --- /dev/null +++ b/src/app/app-modules/inventory/inventory-routing.module.ts @@ -0,0 +1,219 @@ +/* * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { DashboardComponent } from './dashboard/dashboard.component'; +import { WorkareaComponent } from './workarea/workarea.component'; +import { DynamicPrintComponent } from './dynamic-print/dynamic-print.component'; +import { MedicineDispenseComponent } from './medicine-dispense/medicine-dispense.component'; +import { PhysicalStockEntryComponent } from './physical-stock-entry/physical-stock-entry.component'; +import { StoreStockAdjustmentComponent } from './store-stock-adjustment/store-stock-adjustment.component'; +import { StoreSelfConsumptionComponent } from './store-self-consumption/store-self-consumption.component'; +import { StoreStockTransferComponent } from './store-stock-transfer/store-stock-transfer.component'; +import { PatientReturnComponent } from './patient-return/patient-return.component'; +import { ViewPhysicalStockComponent } from './physical-stock-entry/view-physical-stock/view-physical-stock.component'; +import { ViewStoreStockAdjustmentComponent } from './store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component'; +import { ViewStoreStockAdjustmentDraftComponent } from './store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component'; +import { ViewStoreSelfConsumptionComponent } from './store-self-consumption/view-store-self-consumption/view-store-self-consumption.component'; +import { ViewStoreStockTransferComponent } from './store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component'; +import { ViewMedicineDispenseComponent } from './medicine-dispense/view-medicine-dispense/view-medicine-dispense.component'; +import { PatientReturnPreviousRecordComponent } from './patient-return/patient-return-previous-record/patient-return-previous-record.component'; +// import { DashboardComponent } from './dashboard/dashboard.component'; +// import { WorkareaComponent } from './workarea/workarea.component'; +// import { MedicineDispenseComponent } from './medicine-dispense/medicine-dispense.component'; +// import { StoreSelfConsumptionComponent } from './store-self-consumption/store-self-consumption.component'; +// import { PhysicalStockEntryComponent } from './physical-stock-entry/physical-stock-entry.component'; +// import { StoreStockTransferComponent } from './store-stock-transfer/store-stock-transfer.component'; +// import { ViewStoreSelfConsumptionComponent } from './store-self-consumption/view-store-self-consumption/view-store-self-consumption.component'; +// import { ViewPhysicalStockComponent } from './physical-stock-entry/view-physical-stock/view-physical-stock.component'; +// import { ViewMedicineDispenseComponent } from './medicine-dispense/view-medicine-dispense/view-medicine-dispense.component'; +// import { ViewStoreStockTransferComponent } from './store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component'; +// import { DynamicPrintComponent } from './dynamic-print/dynamic-print.component'; + +// import { StoreStockAdjustmentComponent } from './store-stock-adjustment/store-stock-adjustment.component'; +// import { ViewStoreStockAdjustmentComponent } from './store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component'; +// import { ViewStoreStockAdjustmentDraftComponent } from './store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component' +// import { PatientReturnComponent } from './patient-return/patient-return.component'; +// import { IndentOrderWorklistComponent } from './indent/indent-order-worklist/indent-order-worklist.component'; +// import { IndentRequestComponent } from './indent/indent-order-worklist/sub-store-indent-order-worklist/indent-request/indent-request.component'; +// import { MainStoreIndentOrderWorklistComponent } from './indent/indent-order-worklist/main-store-indent-order-worklist/main-store-indent-order-worklist.component'; +// import { SubStoreIndentOrderWorklistComponent } from './indent/indent-order-worklist/sub-store-indent-order-worklist/sub-store-indent-order-worklist.component'; +// import { IndentDispensesComponent } from './indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/indent-dispenses.component'; +// import { InwardStockReportComponent } from './reports/inward-stock-report/inward-stock-report.component'; +// import { ConsumptionReportComponent } from './reports/consumption-report/consumption-report.component'; +// import { ExpiryReportComponent } from './reports/expiry-report/expiry-report.component'; +// import { BeneficiaryDrugIssueReportComponent } from './reports/beneficiary-drug-issue-report/beneficiary-drug-issue-report.component'; +// import { DailyStockDetailsReportComponent } from './reports/daily-stock-details-report/daily-stock-details-report.component'; +// import { DailyStockSummaryReportComponent } from './reports/daily-stock-summary-report/daily-stock-summary-report.component'; +// import { MonthlyReportComponent } from './reports/monthly-report/monthly-report.component'; +// import { YearlyReportComponent} from './reports/yearly-report/yearly-report.component'; +// import { TransitReportComponent } from './reports/transit-report/transit-report.component'; +// import { ShortExpiryReportComponent } from './reports/short-expiry-report/short-expiry-report.component'; +// import { PatientReturnPreviousRecordComponent } from './patient-return/patient-return-previous-record/patient-return-previous-record.component'; + +const routes: Routes = [ + { + path: '', + component: DashboardComponent, + children: [ + { + path: '', + redirectTo: 'dashboard', + pathMatch: 'full', + }, + { + path: 'dashboard', + component: WorkareaComponent, + }, + { + path: 'medicineDispense', + component: MedicineDispenseComponent, + }, + { + path: 'medicineDispense/View', + component: ViewMedicineDispenseComponent, + }, + { + path: 'storeSelfConsumption', + component: StoreSelfConsumptionComponent, + }, + { + path: 'storeSelfConsumption/View', + component: ViewStoreSelfConsumptionComponent, + }, + { + path: 'physicalStockEntry', + component: PhysicalStockEntryComponent, + }, + { + path: 'physicalStockEntry/View', + component: ViewPhysicalStockComponent, + }, + { + path: 'storeStockTransfer', + component: StoreStockTransferComponent, + }, + { + path: 'storeStockTransfer/View', + component: ViewStoreStockTransferComponent, + }, + { + path: 'storeStockAdjustment', + component: StoreStockAdjustmentComponent, + }, + { + path: 'storeStockAdjustment/update/:draftID', + component: StoreStockAdjustmentComponent, + }, + { + path: 'storeStockAdjustment/view', + component: ViewStoreStockAdjustmentComponent, + }, + { + path: 'storeStockAdjustmentDraft/view', + component: ViewStoreStockAdjustmentDraftComponent, + }, + { + path: 'patientReturn', + component: PatientReturnComponent, + }, + { + path: 'patientReturn/previousRecord', + component: PatientReturnPreviousRecordComponent, + }, + // { + // path : 'indentOrderWorklist', + // component : IndentOrderWorklistComponent + // }, + // { + // path : 'mainStoreIndentOrderWorklist', + // component : MainStoreIndentOrderWorklistComponent + // }, + // { + // path : 'subStoreIndentOrderWorklist', + // component : SubStoreIndentOrderWorklistComponent + // }, + // { + // path : 'mainStoreIndentDispenses/:toFacilityID/:indentID', + // component : IndentDispensesComponent + // }, + // { + // path:'indentRequest', + // component:IndentRequestComponent + // }, + // { + // path:'indentRequest/:indentID/:fromFacilityID', + // component:IndentRequestComponent + // }, + + // { + // path:'inwardStockReport', + // component:InwardStockReportComponent + // }, + // { + // path:'consumptionReport', + // component:ConsumptionReportComponent + // }, + // { + // path:'expiryReport', + // component:ExpiryReportComponent + // }, + // { + // path:'beneficiaryDrugIssueReport', + // component:BeneficiaryDrugIssueReportComponent + // }, + // { + // path:'dailyStockReportDetails', + // component:DailyStockDetailsReportComponent + // }, + // { + // path:'dailyStockReportSummary', + // component:DailyStockSummaryReportComponent + // }, + // { + // path:'monthlyReport', + // component:MonthlyReportComponent + // }, + // { + // path:'yearlyReport', + // component:YearlyReportComponent + // }, + // { + // path:'shortExpiryReport', + // component:ShortExpiryReportComponent + // }, + // { + // path:'transitReport', + // component:TransitReportComponent + // } + ], + }, + { + path: 'dynamicPrint/:printablePage', + component: DynamicPrintComponent, + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class InventoryRoutingModule {} diff --git a/src/app/app-modules/inventory/inventory.module.ts b/src/app/app-modules/inventory/inventory.module.ts new file mode 100644 index 0000000..e4b8975 --- /dev/null +++ b/src/app/app-modules/inventory/inventory.module.ts @@ -0,0 +1,249 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { CoreModule } from '../core/core.module'; +import { MaterialModule } from '../core/material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatTableModule } from '@angular/material/table'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatListModule } from '@angular/material/list'; +import { MatSelectModule } from '@angular/material/select'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatDialogModule } from '@angular/material/dialog'; +import { WorkareaComponent } from './workarea/workarea.component'; +import { DynamicPrintComponent } from './dynamic-print/dynamic-print.component'; +import { DataStorageService } from './shared/service/data-storage.service'; +import { InventoryMasterService } from './shared/service/inventory-master.service'; +import { InventoryService } from './shared/service/inventory.service'; +import { MedicineDispenseComponent } from './medicine-dispense/medicine-dispense.component'; +import { PhysicalStockEntryComponent } from './physical-stock-entry/physical-stock-entry.component'; +import { StoreStockAdjustmentComponent } from './store-stock-adjustment/store-stock-adjustment.component'; +import { StoreSelfConsumptionComponent } from './store-self-consumption/store-self-consumption.component'; +import { StoreStockTransferComponent } from './store-stock-transfer/store-stock-transfer.component'; +import { PatientReturnComponent } from './patient-return/patient-return.component'; +import { BenificiaryDetailsComponent } from './patient-return/benificiary-details/benificiary-details.component'; +import { ItemBatchDetailsForPatientReturnComponent } from './patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component'; +import { PatientReturnBatchDetailsComponent } from './patient-return/patient-return-batch-details/patient-return-batch-details.component'; +import { ViewPhysicalStockComponent } from './physical-stock-entry/view-physical-stock/view-physical-stock.component'; +import { ViewPhysicalStockDetailsComponent } from './physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component'; +import { ViewStockAdjustmentDetailsComponent } from './store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component'; +import { ViewStockAdjustmentDraftDetailsComponent } from './store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component'; +import { InventoryRoutingModule } from './inventory-routing.module'; +import { DashboardComponent } from './dashboard/dashboard.component'; +import { ViewStoreStockAdjustmentComponent } from './store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component'; +import { ViewStoreStockAdjustmentDraftComponent } from './store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component'; +import { ViewStoreSelfConsumptionComponent } from './store-self-consumption/view-store-self-consumption/view-store-self-consumption.component'; +import { ViewStoreSelfConsumptionDetailsComponent } from './store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component'; +import { ViewStoreStockTransferComponent } from './store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component'; +import { ViewStoreStockTransferDetailsComponent } from './store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component'; +import { ManualMedicineDispenseComponent } from './medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component'; +import { SelectBatchComponent } from './medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component'; +import { SystemMedicineDispenseComponent } from './medicine-dispense/system-medicine-dispense/system-medicine-dispense.component'; +import { ShowBatchItemComponent } from './medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component'; +import { ViewMedicineDispenseComponent } from './medicine-dispense/view-medicine-dispense/view-medicine-dispense.component'; +import { ViewMedicineDispenseDetailsComponent } from './medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component'; +import { PatientReturnPreviousRecordComponent } from './patient-return/patient-return-previous-record/patient-return-previous-record.component'; + +// import { DatepickerModule, BsDatepickerModule } from 'ngx-bootstrap/datepicker'; + +/*Components*/ +// import { InventoryRoutingModule } from './inventory-routing.module'; +// import { DashboardComponent } from './dashboard/dashboard.component'; +// import { WorkareaComponent } from './workarea/workarea.component'; +// import { MedicineDispenseComponent } from './medicine-dispense/medicine-dispense.component'; +// import { ManualMedicineDispenseComponent } from './medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component'; +// import { SystemMedicineDispenseComponent } from './medicine-dispense/system-medicine-dispense/system-medicine-dispense.component'; +// import { StoreSelfConsumptionComponent } from './store-self-consumption/store-self-consumption.component'; +// import { PhysicalStockEntryComponent } from './physical-stock-entry/physical-stock-entry.component'; +// import { SelectBatchComponent } from './medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component'; +// import { StoreStockTransferComponent } from './store-stock-transfer/store-stock-transfer.component'; + +/*Services*/ +// import { InventoryService } from './shared/service/inventory.service'; +// import {PrescribedDrugService} from './shared/service/prescribed-drug.service'; +// import { InventoryMasterService } from './shared/service/inventory-master.service'; +// import { DataStorageService } from './shared/service/data-storage.service'; + +// import { +// ViewStoreSelfConsumptionComponent +// } from './store-self-consumption/view-store-self-consumption/view-store-self-consumption.component'; +// import { +// ViewStoreSelfConsumptionDetailsComponent +// } from './store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component'; +// import { ViewPhysicalStockComponent } from './physical-stock-entry/view-physical-stock/view-physical-stock.component'; +// import { +// ViewPhysicalStockDetailsComponent +// } from './physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component'; +// import { ViewMedicineDispenseComponent } from './medicine-dispense/view-medicine-dispense/view-medicine-dispense.component'; +// import { +// ViewMedicineDispenseDetailsComponent +// } from './medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component'; +// import { ViewStoreStockTransferComponent } from './store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component'; +// import { +// ViewStoreStockTransferDetailsComponent +// } from './store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component'; +// import { ShowBatchItemComponent } from './medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component'; +// import { DynamicPrintComponent } from './dynamic-print/dynamic-print.component'; +// import { StoreStockAdjustmentComponent } from './store-stock-adjustment/store-stock-adjustment.component'; +// import { ViewStoreStockAdjustmentComponent } from './store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component'; +// import { ViewStoreStockAdjustmentDraftComponent } from './store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component'; +// import { ViewStockAdjustmentDraftDetailsComponent } from './store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component'; +// import { ViewStockAdjustmentDetailsComponent } from './store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component'; +// import { PatientReturnComponent } from './patient-return/patient-return.component'; +// import { PatientReturnBatchDetailsComponent } from './patient-return/patient-return-batch-details/patient-return-batch-details.component'; +// import { BenificiaryDetailsComponent } from './patient-return/benificiary-details/benificiary-details.component'; +// import { IndentOrderWorklistComponent } from './indent/indent-order-worklist/indent-order-worklist.component'; +// import { IndentRequestComponent } from './indent/indent-order-worklist/sub-store-indent-order-worklist/indent-request/indent-request.component'; +// import { ItemBatchDetailsForPatientReturnComponent } from './patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component'; +// import { MainStoreIndentOrderWorklistComponent } from './indent/indent-order-worklist/main-store-indent-order-worklist/main-store-indent-order-worklist.component'; +// import { SubStoreIndentOrderWorklistComponent } from './indent/indent-order-worklist/sub-store-indent-order-worklist/sub-store-indent-order-worklist.component'; +// import { IndentDispensesComponent } from './indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/indent-dispenses.component'; +// import { SubStoreItemModelComponent } from './indent/indent-order-worklist/sub-store-indent-order-worklist/sub-store-item-model/sub-store-item-model.component'; +// import { MainStoreItemModelComponent } from './indent/indent-order-worklist/main-store-indent-order-worklist/main-store-item-model/main-store-item-model.component'; +// import { SelectBatchForIndentItemComponent } from './indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/manual-indent-dispense/select-batch-for-indent-item/select-batch-for-indent-item.component'; +// import { ManualIndentDispenseComponent } from './indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/manual-indent-dispense/manual-indent-dispense.component'; +// import { SystemIndentDispenseComponent } from './indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/system-indent-dispense/system-indent-dispense.component'; +// import { ShowIndentBatchDetailsComponent } from './indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/system-indent-dispense/show-indent-batch-details/show-indent-batch-details.component'; +// import { UtcDatePipe } from './utc-date.pipe'; +// import { InwardStockReportComponent } from './reports/inward-stock-report/inward-stock-report.component'; +// import { ConsumptionReportComponent } from './reports/consumption-report/consumption-report.component'; +// import { ExpiryReportComponent } from './reports/expiry-report/expiry-report.component'; +// import { BeneficiaryDrugIssueReportComponent } from './reports/beneficiary-drug-issue-report/beneficiary-drug-issue-report.component'; +// import { DailyStockDetailsReportComponent } from './reports/daily-stock-details-report/daily-stock-details-report.component'; +// import { DailyStockSummaryReportComponent } from './reports/daily-stock-summary-report/daily-stock-summary-report.component'; +// import { MonthlyReportComponent } from './reports/monthly-report/monthly-report.component'; +// import { YearlyReportComponent } from './reports/yearly-report/yearly-report.component'; +// import { RejectItemFromMainstoreModelComponent } from './indent/indent-order-worklist/main-store-indent-order-worklist/reject-item-from-mainstore-model/reject-item-from-mainstore-model.component'; +// import { PatientReturnPreviousRecordComponent } from './patient-return/patient-return-previous-record/patient-return-previous-record.component'; +// import { ShortExpiryReportComponent } from './reports/short-expiry-report/short-expiry-report.component'; +// import { TransitReportComponent } from './reports/transit-report/transit-report.component'; + +@NgModule({ + imports: [ + CommonModule, + CoreModule, + InventoryRoutingModule, + ReactiveFormsModule, + FormsModule, + MaterialModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatTableModule, + MatTooltipModule, + MatMenuModule, + MatIconModule, + MatButtonModule, + MatCardModule, + MatRadioModule, + MatDatepickerModule, + MatListModule, + MatSelectModule, + MatProgressBarModule, + MatProgressSpinnerModule, + // BsDatepickerModule.forRoot(), + // DatepickerModule.forRoot() + ], + // entryComponents: [ + // SelectBatchComponent, + // ViewStoreSelfConsumptionDetailsComponent, + // ViewPhysicalStockDetailsComponent, + // ViewMedicineDispenseDetailsComponent, + // ViewStoreStockTransferDetailsComponent, + // ShowBatchItemComponent, + // ShowIndentBatchDetailsComponent, + // ViewStockAdjustmentDetailsComponent, + // ViewStockAdjustmentDraftDetailsComponent, + // PatientReturnBatchDetailsComponent, + // BenificiaryDetailsComponent, + // SubStoreItemModelComponent, + // MainStoreItemModelComponent, + // SelectBatchForIndentItemComponent, + // RejectItemFromMainstoreModelComponent + // ], + declarations: [ + DashboardComponent, + WorkareaComponent, + MedicineDispenseComponent, + ManualMedicineDispenseComponent, + SystemMedicineDispenseComponent, + SelectBatchComponent, + PhysicalStockEntryComponent, + StoreSelfConsumptionComponent, + StoreStockTransferComponent, + ViewStoreSelfConsumptionComponent, + ViewStoreSelfConsumptionDetailsComponent, + ViewPhysicalStockComponent, + ViewPhysicalStockDetailsComponent, + ViewMedicineDispenseComponent, + ViewMedicineDispenseDetailsComponent, + ViewStoreStockTransferComponent, + ViewStoreStockTransferDetailsComponent, + ShowBatchItemComponent, + DynamicPrintComponent, + StoreStockAdjustmentComponent, + ViewStoreStockAdjustmentComponent, + ViewStoreStockAdjustmentDraftComponent, + ViewStockAdjustmentDraftDetailsComponent, + ViewStockAdjustmentDetailsComponent, + PatientReturnComponent, + PatientReturnBatchDetailsComponent, + BenificiaryDetailsComponent, + // IndentOrderWorklistComponent, + // IndentRequestComponent, + ItemBatchDetailsForPatientReturnComponent, + // MainStoreIndentOrderWorklistComponent, + // SubStoreIndentOrderWorklistComponent, + // IndentDispensesComponent, + // SubStoreItemModelComponent, + // MainStoreItemModelComponent, + // SelectBatchForIndentItemComponent, + // ManualIndentDispenseComponent, + // SystemIndentDispenseComponent, + // ShowIndentBatchDetailsComponent, + // UtcDatePipe, + // InwardStockReportComponent, + // ConsumptionReportComponent, + // ExpiryReportComponent, + // BeneficiaryDrugIssueReportComponent, + // DailyStockDetailsReportComponent, + // DailyStockSummaryReportComponent, + // MonthlyReportComponent, + // YearlyReportComponent, + // RejectItemFromMainstoreModelComponent, + PatientReturnPreviousRecordComponent, + // ShortExpiryReportComponent, + // TransitReportComponent, + ], + providers: [InventoryService, InventoryMasterService, DataStorageService], +}) +export class InventoryModule {} diff --git a/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.css b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.css new file mode 100644 index 0000000..56976a7 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.css @@ -0,0 +1,35 @@ +.input-full-width { + width: 100%; +} + +.width-percent-5 { + width: 5% +} + +.width-percent-10 { + width: 10% +} + +.inner_table { + margin-bottom: 0px; +} + +.noPadding { + padding: 0px; +} + +.width-percent-25 { + width: 25%; +} + +.m-r-5 { + margin-right: 5px; +} + +.box { + height: 70px; +} + +.search-btn { + cursor: pointer; +} diff --git a/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.html b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.html new file mode 100644 index 0000000..20ed2b8 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.html @@ -0,0 +1,130 @@ +
+
+
+
+ + + search + +
+
+ + + +
+
+
+ +
+
+

{{ currentLanguageSet?.inventory?.dispensingItem }}

+
+ +
+
+ +
+
+
+ +
+
+ + +
+
+
diff --git a/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.spec.ts b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.spec.ts new file mode 100644 index 0000000..5b2960b --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ManualMedicineDispenseComponent } from './manual-medicine-dispense.component'; + +describe('ManualMedicineDispenseComponent', () => { + let component: ManualMedicineDispenseComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ManualMedicineDispenseComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ManualMedicineDispenseComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.ts b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.ts new file mode 100644 index 0000000..65ffb22 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/manual-medicine-dispense.component.ts @@ -0,0 +1,388 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Component, + OnInit, + Input, + Output, + EventEmitter, + OnChanges, + DoCheck, +} from '@angular/core'; +import { FormBuilder, FormGroup, FormControl, FormArray } from '@angular/forms'; +import { InventoryService } from './../../shared/service/inventory.service'; +import { SelectBatchComponent } from './select-batch/select-batch.component'; +import { ConfirmationService } from './../../../core/services/confirmation.service'; +import { DataStorageService } from './../../shared/service/data-storage.service'; +import { Router } from '@angular/router'; +import * as moment from 'moment'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +@Component({ + selector: 'app-manual-medicine-dispense', + templateUrl: './manual-medicine-dispense.component.html', + styleUrls: ['./manual-medicine-dispense.component.css'], +}) +export class ManualMedicineDispenseComponent implements OnInit, DoCheck { + @Input() + beneficaryDetail: any; + + app: any; + + @Output() resetBeneficiaryDetail: EventEmitter = new EventEmitter(); + + manualItemDispenseForm!: FormGroup; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private fb: FormBuilder, + private dialog: MatDialog, + private router: Router, + public http_service: LanguageService, + private confirmationService: ConfirmationService, + private dataStorageService: DataStorageService, + private inventoryService: InventoryService, + ) {} + + ngOnInit() { + this.app = this.getApp(); + this.manualItemDispenseForm = this.initManualDispenseForm(); + this.subscribeToFormChange(); + this.fetchLanguageResponse(); + } + + subscribeToFormChange() { + this.manualItemDispenseForm.controls['itemID'].valueChanges.subscribe( + (value) => { + if (value) + setTimeout(() => { + this.selectBatch(); + }, 0); + }, + ); + } + getApp() { + console.log(sessionStorage.getItem('host')); + if (sessionStorage.getItem('host')) { + return sessionStorage.getItem('host'); + } else { + return 'STORE'; + } + } + resetDependent() { + this.manualItemDispenseForm.patchValue({ + itemID: null, + quantityInHand: null, + quantityDispensed: null, + }); + } + + initManualDispenseForm(): FormGroup { + return this.fb.group({ + itemName: null, + itemID: null, + quantityInHand: null, + quantityDispensed: null, + batchList: new FormArray([]), + }); + } + + initBatchForm(): FormGroup { + return this.fb.group({ + batchNo: null, + quantityOnBatch: null, + expiryDate: null, + entryDate: null, + quantityOfDispense: null, + }); + } + + get quantityInHand() { + return this.manualItemDispenseForm.controls['quantityInHand'].value; + } + + manualDispenseList: any = []; + selectBatch() { + const batchList = ( + this.manualItemDispenseForm.controls['batchList'] + ); + const batchListLength = batchList.length; + if (batchList && batchListLength > 0) { + for (let j = 0; j <= batchListLength; j++) { + batchList.removeAt(0); + } + this.getItemBatchList(null, this.manualItemDispenseForm.value); + } else { + this.getItemBatchList(null, this.manualItemDispenseForm.value); + } + } + + getItemBatchList(editIndex: any, formValue: any) { + let itemBatchList = []; + const requestObjectGetBatchList = { + facilityID: localStorage.getItem('facilityID'), + itemID: formValue.itemID, + }; + this.inventoryService.getItemBatchList(requestObjectGetBatchList).subscribe( + (response) => { + if (response.statusCode == 200) { + if (response.data.length > 0) { + itemBatchList = response.data; + this.openModalTOSelectBatch(editIndex, formValue, itemBatchList); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.noBatchavailableforthisItem, + ); + } + } else { + this.confirmationService.alert(response.errorMessage, 'error'); + } + }, + (err) => { + this.confirmationService.alert(err, 'error'); + }, + ); + } + + openModalTOSelectBatch(editIndex: any, formValue: any, itemBatchList: any) { + const mdDialogRef: MatDialogRef = this.dialog.open( + SelectBatchComponent, + { + data: { + batchList: itemBatchList, + editBatch: formValue, + editIndex: editIndex, + }, + panelClass: 'fit-screen', + disableClose: false, + }, + ); + mdDialogRef.afterClosed().subscribe((result) => { + if (result) { + if (editIndex != null) { + this.manualDispenseList.splice(editIndex, 1); + this.manualDispenseList.push(result.value); + this.manualItemDispenseForm.reset(); + } else { + this.manualDispenseList.push(result.value); + this.manualItemDispenseForm.reset(); + } + } + }); + } + + removeManualDispenseItem(i: any) { + this.manualDispenseList.splice(i, 1); + } + + editItem(item: any, i: any) { + this.getItemBatchList(i, item); + } + + stockExitList: any = []; + createStockExitList() { + this.manualDispenseList.forEach((dispenseItem: any) => { + dispenseItem.batchList.forEach((batch: any) => { + console.log('batch', batch); + const dispensedItem = { + createdBy: localStorage.getItem('userID'), + itemID: batch.batchNo.itemID, + itemStockEntryID: batch.batchNo.itemStockEntryID, + quantity: batch.quantityOfDispense, + }; + this.stockExitList.push(dispensedItem); + }); + }); + const dispensingItem = Object.assign( + {}, + { issuedBy: this.app }, + this.beneficaryDetail, + { itemStockExit: this.stockExitList }, + { + vanID: localStorage.getItem('vanID'), + parkingPlaceID: localStorage.getItem('parkingPlaceID'), + }, + ); + return dispensingItem; + } + save(print: any) { + this.saveItem(print); + } + saveItem(print: any) { + const dispensingItem = this.createStockExitList(); + console.log('dispensingItem', dispensingItem); + this.inventoryService.saveStockExit(dispensingItem).subscribe( + (response) => { + if (response.statusCode == 200) { + if (print) { + this.saveAndPrintPage(); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.savedsuccessfully, + 'success', + ); + this.manualDispenseList = []; + this.manualItemDispenseForm.reset(); + this.resetBeneficiaryDetails(); + } + } else { + this.confirmationService.alert(response.errorMessage, 'error'); + } + }, + (err) => { + this.confirmationService.alert(err, 'error'); + }, + ); + } + + resetBeneficiaryDetails() { + console.log('event', event); + this.resetBeneficiaryDetail.emit(); + } + + createPrintableData() { + const printableData: any = []; + let i = 0; + this.manualDispenseList.forEach((dispenseItem: any) => { + dispenseItem.batchList.forEach((batch: any) => { + console.log('batch', batch); + i = i + 1; + const dispensedItem = { + sNo: i, + itemName: dispenseItem.itemName, + batchNo: batch.batchNo.batchNo, + expiryDate: moment(batch.expiryDate).format('DD-MM-YYYY'), + qod: batch.quantityOfDispense, + }; + printableData.push(dispensedItem); + }); + }); + const beneficaryDetail = Object.assign( + { + visitedDate: moment(this.beneficaryDetail.visitDate).format( + 'DD-MM-YYYY', + ), + }, + this.beneficaryDetail, + ); + console.log('beneficaryDetail', JSON.stringify(beneficaryDetail, null, 4)); + + const manualDispenseItem = Object.assign( + {}, + { title: this.title }, + { headerColumn: this.headerColumn }, + { headerDetail: beneficaryDetail }, + { columns: this.columns }, + { printableData: printableData }, + ); + return manualDispenseItem; + } + + title = { + modalTitle: 'Manual Dispense', + headerTitle: 'Dispense Detail', + tableTitle: 'Dispensed Item', + }; + + columns = [ + { + keyName: 'sNo', + columnName: 'S No.', + }, + { + keyName: 'itemName', + columnName: 'Item Name', + }, + { + keyName: 'batchNo', + columnName: 'Batch No', + }, + { + keyName: 'expiryDate', + columnName: 'Expiry Date', + }, + { + keyName: 'qod', + columnName: 'Qty dispensed', + }, + ]; + + headerColumn = [ + { + columnName: 'Name :', + keyName: 'patientName', + }, + { + columnName: 'Beneficiary ID :', + keyName: 'beneficiaryID', + }, + { + columnName: 'Gender :', + keyName: 'gender', + }, + { + columnName: 'Age :', + keyName: 'age', + }, + { + columnName: 'Visit ID :', + keyName: 'visitID', + }, + { + columnName: 'Visit Date :', + keyName: 'visitedDate', + }, + { + columnName: 'Doctor Name :', + keyName: 'doctorName', + }, + { + columnName: 'Issued By :', + keyName: 'createdBy', + }, + { + columnName: 'Reference :', + keyName: 'reference', + }, + ]; + + saveAndPrintPage() { + const manualDispenseItem = this.createPrintableData(); + this.dataStorageService.manualDispenseItem = manualDispenseItem; + const uRL = 'manualDispenseItem'; + this.router.navigate(['/inventory/dynamicPrint/', uRL]); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.css b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.css new file mode 100644 index 0000000..c1dca21 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.css @@ -0,0 +1,58 @@ +.input-full-width { + width: 100%; +} + +.m-b-30 { + margin-bottom: 30px; +} + +.mat-form-field { + line-height: unset !important; +} + +.vertical-align-middle { + vertical-align: middle; +} + +.title { + margin: 0px 0px 10px; + padding: 15px 24px 15px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; +} + +.title h4 { + display: inline-block; +} + +.title .exit { + cursor: pointer; +} + +.scrolling-content { + max-height: 75vh; + overflow: auto; +} + +.icon-remove { + margin: 16px; +} + +.actionButton { + float: right; +} + +.width5 { + width: 5%; +} + +.width10 { + width: 10%; +} + +.width15 { + width: 15%; +} diff --git a/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.html b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.html new file mode 100644 index 0000000..bdeff0b --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.html @@ -0,0 +1,117 @@ +
+

{{ title }}

+ +
+ +
+
+
+
+
+ + + +
+
+ +
+
+
+ +
+
+
+ +
+
+ + +
+
+
+
+
diff --git a/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.spec.ts b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.spec.ts new file mode 100644 index 0000000..335bbd5 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SelectBatchComponent } from './select-batch.component'; + +describe('SelectBatchComponent', () => { + let component: SelectBatchComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [SelectBatchComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SelectBatchComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.ts b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.ts new file mode 100644 index 0000000..9a8c65d --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/manual-medicine-dispense/select-batch/select-batch.component.ts @@ -0,0 +1,276 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { FormBuilder, FormGroup, FormControl, FormArray } from '@angular/forms'; +import { ConfirmationService } from '../../../../core/services/confirmation.service'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; + +@Component({ + selector: 'app-select-batch', + templateUrl: './select-batch.component.html', + styleUrls: ['./select-batch.component.css'], +}) +export class SelectBatchComponent implements OnInit, DoCheck { + batchForm!: FormGroup; + today!: Date; + + itemBatchList: any = []; + masterItemBatchList = []; + enableEditMode = false; + editBatchList: any; + selectedBatchList: any = []; + filteredBatchList: any = []; + languageComponent: any; + currentLanguageSet: any; + + constructor( + private confirmationService: ConfirmationService, + @Inject(MAT_DIALOG_DATA) public data: any, + private fb: FormBuilder, + public http_service: LanguageService, + public mdDialogRef: MatDialogRef, + ) {} + title!: string; + + ngOnInit() { + this.fetchLanguageResponse(); + if ( + this.data !== undefined && + this.data !== null && + this.data.batchList !== undefined && + this.data.batchList !== null + ) { + this.masterItemBatchList = this.data.batchList; + this.itemBatchList = this.data.batchList; + } + this.batchForm = this.createBatchForm(); + if (this.data.editIndex != null) { + this.title = this.currentLanguageSet.inventory.editBatchSelection; + } else { + this.title = this.currentLanguageSet.itemDispense.batchSelection; + } + this.title; + console.log('this.data', this.data); + + if (this.data.editBatch != null) { + if (this.data.editBatch.batchList.length > 0) { + this.enableEditMode = true; + this.editBatchList = this.data.editBatch; + this.batchForm.patchValue(this.data.editBatch); + this.addBatch(); + this.handleBatchData(); + } else { + this.addBatch(); + this.editableBatch(this.data.editBatch); + } + } else { + this.editBatchList = []; + this.addBatch(); + } + } + + editableBatch(editBatchList: any) { + this.editBatchList = editBatchList; + this.batchForm.patchValue(editBatchList); + } + + handleBatchData() { + const formBatchList = this.batchForm.controls['batchList']; + const temp = this.data.editBatch.batchList.slice(); + + for (let i = 0; i < temp.length; i++) { + const batchArray = this.masterItemBatchList.filter((item: any) => { + return item.batchNo == temp[i].batchNo.batchNo; + }); + + if (batchArray.length > 0) { + temp[i].batchNo = batchArray[0]; + } + + if (temp[i].batchNo.batchNo) { + const k: any = formBatchList.get('' + i); + k.patchValue(temp[i]); + k.markAsTouched(); + this.getQuantityAndFilterItem(temp[i].batchNo, i); + } + if (i + 1 < temp.length) { + this.addBatch(); + } + } + } + + createBatchForm() { + return this.fb.group({ + item: null, + itemName: null, + itemID: null, + quantityInHand: null, + quantityDispensed: null, + batchList: new FormArray([]), + }); + } + + getQuantityAndFilterItem(selectedBatch: any, i: any, batchForm?: FormGroup) { + const selectedBatchList = this.selectedBatchList[i]; + this.filteredBatchList.map((item: any, t: any) => { + const index = item.indexOf(selectedBatch); + if (index != -1 && t != i) { + item = item.splice(index, 1); + } + }); + this.selectedBatchList[i] = selectedBatch; + + const expiryDate = (this.today = new Date(selectedBatch.expiryDate)); + if (batchForm != undefined) { + batchForm.patchValue({ + quantityOnBatch: selectedBatch.quantityInHand, + expiryDate: expiryDate, + quantityOfDispense: null, + }); + } + const quantityOnBatch = selectedBatch.quantityInHand; + } + + calculateDispenseQuantity() { + const batchList = this.batchForm.controls['batchList']; + const batchListValue = batchList.value; + let totalQuantity = 0; + batchListValue.filter((quantity: any) => { + if (quantity.quantityOfDispense && quantity.quantityOfDispense != null) { + totalQuantity = +totalQuantity + +quantity.quantityOfDispense; + } + }); + this.batchForm.patchValue({ quantityDispensed: totalQuantity }); + } + + addBatch() { + const batchList = this.batchForm.controls['batchList']; + const tempBatch = batchList.value; + if (this.itemBatchList.length > tempBatch.length) { + if (this.itemBatchList) { + const resultBatch = this.itemBatchList.filter((batch: any) => { + const batchArray = tempBatch.filter((item: any) => { + if ( + item.batchNo && + item.batchNo != null && + item.batchNo.batchNo != null + ) { + return item.batchNo.batchNo == batch.batchNo; + } + }); + const batchFlag = batchArray.length == 0 ? true : false; + return batchFlag; + }); + this.filteredBatchList.push(resultBatch.slice()); + } + batchList.push(this.initBatchForm()); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.nofurtherbatchesavailable, + ); + } + } + + initBatchForm(): FormGroup { + return this.fb.group({ + batchNo: null, + quantityOnBatch: null, + expiryDate: null, + quantityOfDispense: null, + }); + } + + removeBatch(i: any, batchForm: any) { + const batchList = this.batchForm.controls['batchList']; + if (batchList.length == 1 && !!batchForm) { + batchForm.patchValue({ + batchNo: null, + quantityOnBatch: null, + expiryDate: null, + entryDate: null, + quantityOfDispense: null, + }); + this.calculateDispenseQuantity(); + } else { + const removedValue = this.selectedBatchList[i]; + this.filteredBatchList.map((item: any, t: any) => { + if (t != i && removedValue) { + item.push(removedValue); + } + }); + this.selectedBatchList.splice(i, 1); + this.filteredBatchList.splice(i, 1); + batchList.removeAt(i); + this.calculateDispenseQuantity(); + } + } + + checkValidity(batchForm: FormGroup) { + const batchList = this.batchForm.controls['batchList']; + const tempBatch = batchForm.value; + if (batchList.length != this.masterItemBatchList.length) { + if (tempBatch.quantityOfDispense) { + return false; + } else { + return true; + } + } else { + return true; + } + } + + checkQuantity(batch: FormGroup) { + const quantity = batch.value.quantityOfDispense; + if (batch.value.quantityOfDispense == 0) { + this.confirmationService.alert( + this.currentLanguageSet.inventory + .pleaseenterquantitygreaterthanzeroandlessthanorequaltoQtyinBatch, + ); + batch.patchValue({ quantityOfDispense: null }); + batch.markAsPristine(); + } else if (batch.value.quantityOnBatch < batch.value.quantityOfDispense) { + this.confirmationService.alert( + this.currentLanguageSet.inventory + .pleaseenterquantitylessthanorequaltoQtyinBatch, + ); + batch.patchValue({ quantityOfDispense: null }); + batch.markAsPristine(); + } + } + saveAndUpdateItem() { + this.mdDialogRef.close(this.batchForm); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.css b/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.css new file mode 100644 index 0000000..28a1f0a --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.css @@ -0,0 +1,46 @@ +.input-full-width { + width: 100%; +} + +.box { + height: 70px; +} + +.inline-block { + display: inline-block; +} + +.mat-card { + padding-left: 0px !important; + padding-right: 0px !important; + padding-top: 15px !important; + padding-bottom: 15px !important; +} + +.m-b-40 { + margin-bottom: 40px; +} + +.mat-form-field { + line-height: unset !important; +} + +.m-l-5 { + margin-left: 5px; +} + +@media screen and (max-width: 768px) { + .button-full-width { + width: 100%; + /* height: 50px; */ + margin-top: 3px; + } + .box{ + height: 60px; + } + +} +.medicineAlign{ + display: flex; + justify-content: space-between; +} diff --git a/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.html b/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.html new file mode 100644 index 0000000..0b85139 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.html @@ -0,0 +1,217 @@ +
+
+
+

+ {{ currentLanguageSet?.inventory?.patientIssueWithoutRx }} +

+
+
+ + +
+ +
+ +
+
+
+ + + +
+
+ + + {{ currentLanguageSet?.itemDispense?.visitcode }} + + + + {{ visit.benVisitCode }} + + + +
+
+ + + + + + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+ + {{ + currentLanguageSet?.inventory?.manualDispense + }} + {{ + currentLanguageSet?.inventory?.systemDispense + }} + +
+
+
+
+ + + +
+
+
+
diff --git a/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.spec.ts b/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.spec.ts new file mode 100644 index 0000000..a67d0e1 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MedicineDispenseComponent } from './medicine-dispense.component'; + +describe('MedicineDispenseComponent', () => { + let component: MedicineDispenseComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [MedicineDispenseComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MedicineDispenseComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.ts b/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.ts new file mode 100644 index 0000000..b541884 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/medicine-dispense.component.ts @@ -0,0 +1,343 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, OnDestroy, DoCheck } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { InventoryService } from './../shared/service/inventory.service'; +import { ConfirmationService } from './../../core/services/confirmation.service'; +import { SetLanguageComponent } from '../../core/components/set-language.component'; +import { LanguageService } from '../../core/services/language.service'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { SearchComponent } from '../../core/components/search/search.component'; + +@Component({ + selector: 'app-medicine-dispense', + templateUrl: './medicine-dispense.component.html', + styleUrls: ['./medicine-dispense.component.css'], +}) +export class MedicineDispenseComponent implements OnInit, OnDestroy, DoCheck { + beneficiaryDetailForm!: FormGroup; + beneficaryDetail: any; + + parentBenID: any; + parentVisitID: any; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + constructor( + private fb: FormBuilder, + private confirmationService: ConfirmationService, + private inventoryService: InventoryService, + public http_service: LanguageService, + private dialog: MatDialog, + ) {} + + ngOnInit() { + this.beneficiaryDetailForm = this.createBeneficiaryForm(); + //Parent App Calling + this.checkParentVisits(); + this.fetchLanguageResponse(); + } + + ngOnDestroy() { + sessionStorage.removeItem('parentBen'); + sessionStorage.removeItem('parentBenVisit'); + } + + createBeneficiaryForm() { + return this.fb.group({ + medicineDispenseType: { value: '', disabled: true }, + beneficiaryID: { value: '', disabled: false }, + visitCode: { value: '', disabled: true }, + visitID: { value: '', disabled: true }, + beneficiaryName: { value: '', disabled: false }, + beneficiaryAge: { value: '', disabled: false }, + genderName: { value: '', disabled: false }, + doctorName: { value: '', disabled: false }, + reference: { value: '', disabled: true }, + visitDate: { value: '', disabled: false }, + }); + } + + checkParentVisits() { + this.parentBenID = + sessionStorage.getItem('parentBen') === 'undefined' + ? undefined + : sessionStorage.getItem('parentBen'); + this.parentVisitID = + sessionStorage.getItem('parentBenVisit') === 'undefined' + ? undefined + : sessionStorage.getItem('parentBenVisit'); + console.log(this.parentBenID, this.parentVisitID); + + if (this.parentBenID) { + this.getParentBenVisits(); + } + } + + getParentBenVisits() { + this.beneficiaryDetailForm.patchValue({ + beneficiaryID: this.parentBenID, + medicineDispenseType: 'System', + }); + + this.inventoryService + .getBeneficaryVisitDetail({ + providerServiceMapID: localStorage.getItem('providerServiceID'), + beneficiaryID: + this.beneficiaryDetailForm.controls['beneficiaryID'].value, + }) + .subscribe( + (response) => { + console.log('response', response); + if (response.statusCode == 200) { + if (response.data.beneficiaryFlowStatus.length > 0) { + this.beneficiaryVisitDetailList = response.data; + console.log(this.beneficiaryVisitDetailList, 'lissss'); + this.beneficiaryDetail = response.data.beneficiaryFlowStatus; + this.loadCurrentVisit(response.data.beneficiaryFlowStatus); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.norecentvisitavailable, + ); + } + } else { + this.confirmationService.alert(response.errorMessage, 'error'); + } + }, + (err) => { + this.confirmationService.alert(err, 'error'); + }, + ); + } + + loadCurrentVisit(resp: any) { + if (this.parentVisitID) { + resp.forEach((element: any) => { + if (element.benVisitID == this.parentVisitID) { + this.beneficiaryDetailForm.patchValue({ + visitCode: element, + }); + this.getVisitDetail(); + } + }); + } + } + + beneficiaryDetail: any; + beneficiaryVisitDetailList: any; + recentBeneficaryVisit: any; + checkBeneficiary() { + if (this.beneficiaryDetailForm.controls['beneficiaryID'].value == null) { + this.nullifyBeneficiaryDetails(); + } + + if (this.beneficiaryDetailForm.controls['beneficiaryID'].value != null) { + if ( + this.beneficiaryDetailForm.controls['beneficiaryID'].value.length != 12 + ) { + this.nullifyBeneficiaryDetails(); + } + if ( + this.beneficiaryDetailForm.controls['beneficiaryID'].value.length == 12 + ) { + this.inventoryService + .getBeneficaryVisitDetail({ + providerServiceMapID: localStorage.getItem('providerServiceID'), + beneficiaryID: + this.beneficiaryDetailForm.controls['beneficiaryID'].value, + }) + .subscribe( + (response) => { + console.log('response', response); + if (response.statusCode == 200) { + if (response.data.benVisitDetail.length > 0) { + this.beneficiaryVisitDetailList = response.data; + this.beneficiaryDetail = response.data.beneficiaryFlowStatus; + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.norecentvisitavailable, + ); + } + } else { + this.confirmationService.alert(response.errorMessage, 'error'); + } + }, + (err) => { + this.confirmationService.alert(err, 'error'); + }, + ); + } + } + // 720088175112 + } + openSearchDialog() { + const matDialogRef: MatDialogRef = this.dialog.open( + SearchComponent, + { + // height: '80%', + // width: '80%', + panelClass: 'fit-screen', + disableClose: false, + }, + ); + + matDialogRef.afterClosed().subscribe((result) => { + if (result) { + console.log('something fishy happening here', result); + this.beneficiaryDetailForm.patchValue({ + beneficiaryID: result, + }); + this.checkBeneficiary(); + } + }); + } + + getVisitDetail() { + // console.log('this.beneficiaryDetailForm.controls['medicineDispenseType'].value', this.beneficiaryDetailForm.controls['medicineDispenseType'].value); + if ( + this.beneficiaryDetailForm.controls['medicineDispenseType'].value != + undefined || + this.beneficiaryDetailForm.controls['medicineDispenseType'].value != null + ) { + this.beneficiaryDetailForm.patchValue({ + beneficiaryName: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .benName, + beneficiaryAge: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .ben_age_val, + genderName: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .genderName, + doctorName: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .agentId, + visitDate: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .visitDate, + visitID: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .benVisitID, + reference: null, + medicineDispenseType: 'System', + }); + this.getBeneficiaryDetail(); + } else { + this.nullifyBeneficiaryDetails(); + } + } + nullifyBeneficiaryDetails() { + this.beneficiaryDetailForm.patchValue({ + medicineDispenseType: null, + visitCode: null, + visitDate: null, + beneficiaryName: null, + beneficiaryAge: null, + genderName: null, + doctorName: null, + reference: null, + }); + } + + getBeneficiaryDetail() { + const facilityDetailfromStorage: any = + localStorage.getItem('facilityDetail'); + const facilityDetail = JSON.parse(facilityDetailfromStorage); + const facilityName = facilityDetail.facilityName; + // console.log(' this.beneficiaryDetailForm.controls['medicineDispenseType'].value', this.beneficiaryDetailForm.controls['medicineDispenseType'].value); + this.beneficaryDetail = { + age: this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .ben_age_val, + beneficiaryID: this.beneficiaryDetailForm.controls['beneficiaryID'].value, + benRegID: this.beneficiaryVisitDetailList.beneficiaryRegID, + createdBy: localStorage.getItem('username'), + providerServiceMapID: localStorage.getItem('providerServiceID'), + doctorName: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .agentId, + facilityID: localStorage.getItem('facilityID'), + gender: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .genderName, + issueType: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value, + patientName: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .benName, + prescriptionID: null, + reference: this.beneficiaryDetailForm.controls['reference'].value, + visitID: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .benVisitID, + visitCode: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .benVisitCode, + facilityName: facilityName, + visitDate: + this.beneficiaryDetailForm.controls['medicineDispenseType'].value + .visitDate, + }; + } + + // get reference() { + // return this.beneficiaryDetailForm.controls['reference'].value; + // } + // get medicineDispenseType() { + // return this.beneficiaryDetailForm.controls['medicineDispenseType'].value; + // } + + // get beneficiaryID() { + // return this.beneficiaryDetailForm.controls['beneficiaryID'].value; + // } + + // get beneficiaryName() { + // return this.beneficiaryDetailForm.controls['beneficiaryName'].value; + // } + + // get beneficiaryAge() { + // return this.beneficiaryDetailForm.controls['beneficiaryAge'].value; + // } + + // get visitDate() { + // return this.beneficiaryDetailForm.controls['visitDate'].value; + // } + + // get visitCode() { + // return this.beneficiaryDetailForm.controls['visitCode'].value; + // } + + resetBeneficiaryDetails(event: any) { + console.log('event', event); + this.beneficiaryDetailForm.reset(); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.css b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.css new file mode 100644 index 0000000..a2a645e --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.css @@ -0,0 +1,38 @@ +.input-full-width { + width: 100%; +} + +.m-t-30 { + margin-top: 30px; +} + +.container-fluid { + padding: 24px !important; +} + +.display{ + padding-bottom: 20px; +} + + +.title { + margin: 0px 0px 10px; + padding: 15px 24px 15px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; +} + +.title h4 { + display: inline-block; +} + +.title .exit { + cursor: pointer; +} + +.actionButton { + float: right; +} diff --git a/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.html b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.html new file mode 100644 index 0000000..b5b87a5 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.html @@ -0,0 +1,67 @@ +
+

{{ currentLanguageSet?.inventory?.issuedBatch }}

+ +
+ +
+ +
+
+ +
+
+
+ +
+
+ + +
+
+
diff --git a/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.spec.ts b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.spec.ts new file mode 100644 index 0000000..b0c87ef --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ShowBatchItemComponent } from './show-batch-item.component'; + +describe('ShowBatchItemComponent', () => { + let component: ShowBatchItemComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ShowBatchItemComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ShowBatchItemComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.ts b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.ts new file mode 100644 index 0000000..a190560 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/show-batch-item/show-batch-item.component.ts @@ -0,0 +1,129 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { InventoryService } from './../../../shared/service/inventory.service'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-show-batch-item', + templateUrl: './show-batch-item.component.html', + styleUrls: ['./show-batch-item.component.css'], +}) +export class ShowBatchItemComponent implements OnInit, DoCheck { + app: any; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private inventoryService: InventoryService, + public http_service: LanguageService, + @Inject(MAT_DIALOG_DATA) public data: any, + public mdDialogRef: MatDialogRef, + ) {} + issuedBatchList: any = []; + beneficaryDetail: any; + ngOnInit() { + this.app = this.getApp(); + + this.issuedBatchList = this.data.batchList; + this.beneficaryDetail = this.data.beneficaryDetail; + console.log('issuedBatchList', this.issuedBatchList); + this.fetchLanguageResponse(); + } + + getApp() { + console.log(sessionStorage.getItem('host')); + if (sessionStorage.getItem('host')) { + return sessionStorage.getItem('host'); + } else { + return 'STORE'; + } + } + createStockExitList() { + const stockExitList: any = []; + this.issuedBatchList.forEach((dispenseItem: any) => { + dispenseItem.itemBatchList.forEach((batch: any) => { + const dispensedItem = { + createdBy: localStorage.getItem('userID'), + itemID: dispenseItem.itemID, + itemStockEntryID: batch.itemStockEntryID, + quantity: batch.quantity, + }; + stockExitList.push(dispensedItem); + }); + }); + const dispensingItem = Object.assign( + {}, + { issuedBy: this.app }, + this.beneficaryDetail, + { itemStockExit: stockExitList }, + { + vanID: localStorage.getItem('vanID'), + parkingPlaceID: localStorage.getItem('parkingPlaceID'), + }, + ); + return dispensingItem; + } + + saveAndUpdateItem() { + const dispensingItem = this.createStockExitList(); + console.log('dispenseItem', dispensingItem); + this.inventoryService + .saveStockExit(dispensingItem) + .subscribe((response) => { + this.closeBatchModal(response, this.issuedBatchList, null); + }); + } + + saveUpdateAndPrintItem() { + const dispensingItem = this.createStockExitList(); + console.log('dispenseItem', dispensingItem); + this.inventoryService + .saveStockExit(dispensingItem) + .subscribe((response) => { + this.closeBatchModal(response, this.issuedBatchList, true); + }); + } + + closeBatchModal(result: any, issuedBatchList: any, print: any) { + const modalresult = Object.assign({ + result: result, + issuedBatchList: issuedBatchList, + print: print, + }); + this.mdDialogRef.close(modalresult); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.css b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.css new file mode 100644 index 0000000..1e230e9 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.css @@ -0,0 +1,31 @@ +.input-full-width { + width: 100%; +} + +.search-btn { + cursor: pointer; +} + +.vertical-align-middle { + vertical-align: middle; +} + +.icon-remove { + margin: 16px; +} + +.mat-form-field { + line-height: unset !important; +} + +.width5 { + width: 5%; +} + +.width10 { + width: 10%; +} + +.width15 { + width: 15%; +} diff --git a/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.html b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.html new file mode 100644 index 0000000..f6f79cf --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.html @@ -0,0 +1,222 @@ +
+
+
+
+
+ + + + + {{ + currentLanguageSet?.inventory?.index + }} + {{ + i + 1 + }} + + + + + {{ currentLanguageSet?.inventory?.item }} + + + + + search + + + + + + {{ + currentLanguageSet?.inventory?.qtyinHand + }} + + + + + + + + + {{ + currentLanguageSet?.inventory?.qtyRequired + }} + + + + + + + + + {{ + currentLanguageSet?.inventory?.actions + }} + + delete + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
diff --git a/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.spec.ts b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.spec.ts new file mode 100644 index 0000000..5c0d1bc --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SystemMedicineDispenseComponent } from './system-medicine-dispense.component'; + +describe('SystemMedicineDispenseComponent', () => { + let component: SystemMedicineDispenseComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [SystemMedicineDispenseComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SystemMedicineDispenseComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.ts b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.ts new file mode 100644 index 0000000..68f331b --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/system-medicine-dispense/system-medicine-dispense.component.ts @@ -0,0 +1,390 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Component, + OnInit, + Input, + Output, + EventEmitter, + DoCheck, +} from '@angular/core'; +import { + FormBuilder, + FormGroup, + FormControl, + FormArray, + AbstractControl, +} from '@angular/forms'; +import { InventoryService } from './../../shared/service/inventory.service'; +import { ConfirmationService } from './../../../core/services/confirmation.service'; +import { DataStorageService } from './../../shared/service/data-storage.service'; + +import { ShowBatchItemComponent } from './show-batch-item/show-batch-item.component'; +import * as moment from 'moment'; +import { Router } from '@angular/router'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { MatTableDataSource } from '@angular/material/table'; + +export interface PeriodicElement { + itemName: string; + index: number; +} + +@Component({ + selector: 'app-system-medicine-dispense', + templateUrl: './system-medicine-dispense.component.html', + styleUrls: ['./system-medicine-dispense.component.css'], +}) +export class SystemMedicineDispenseComponent implements OnInit, DoCheck { + @Input() + beneficaryDetail: any; + + @Output() resetBeneficiaryDetail: EventEmitter = new EventEmitter(); + + systemDispenseForm!: FormGroup; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + displayedColumns: string[] = ['itemName']; + dataSource!: MatTableDataSource; + constructor( + private inventoryService: InventoryService, + private confirmationService: ConfirmationService, + private dataStorageService: DataStorageService, + private router: Router, + public http_service: LanguageService, + private dialog: MatDialog, + private fb: FormBuilder, + ) {} + + ngOnInit() { + this.systemDispenseForm = this.createSystemDispenseForm(); + this.fetchLanguageResponse(); + } + + systemMedicineDataSource(): AbstractControl[] { + return (this.systemDispenseForm.get('systemItemDispenseList') as FormArray) + .controls; + } + + initSystemDispenseMode() { + const systemItemDispenseList = ( + this.systemDispenseForm.controls['systemItemDispenseList'] + ); + systemItemDispenseList.push(this.initSystemDispense()); + } + removeItem(i: any, itemForm: FormGroup) { + const systemItemDispenseList = ( + this.systemDispenseForm.controls['systemItemDispenseList'] + ); + console.log('systemItemDispenseList.length', systemItemDispenseList.length); + if (systemItemDispenseList.length == 1 && !!itemForm) { + this.systemDispenseForm.reset(); + console.log('here'); + // itemForm.patchValue({ + // itemName: null, + // itemID: null, + // quantityInHand: null, + // quantityRequired: null + // }) + } else { + systemItemDispenseList.removeAt(i); + } + } + + checkValidity(systemDispenseForm: FormGroup) { + const tempBatch = systemDispenseForm.value; + if (tempBatch.quantityRequired) { + return false; + } else { + return true; + } + } + createSystemDispenseForm() { + return this.fb.group({ + systemItemDispenseList: new FormArray([this.initSystemDispense()]), + }); + } + + initSystemDispense(): FormGroup { + return this.fb.group({ + itemName: null, + itemID: null, + quantityInHand: null, + quantityRequired: null, + }); + } + + resetDependent(systemItemDispense: FormGroup) { + systemItemDispense.patchValue({ + itemID: null, + quantityInHand: null, + quantityRequired: null, + }); + } + + createItemList() { + const systemDispenseValue = this.systemDispenseForm.value; + console.log('systemDispenseValue', systemDispenseValue); + const itemList: any = []; + systemDispenseValue.systemItemDispenseList.forEach((item: any) => { + const itemObj = { + itemID: item.itemID, + quantity: item.quantityRequired, + }; + itemList.push(itemObj); + }); + return itemList; + } + + allocateBatch() { + const itemList = this.createItemList(); + console.log('itemList', JSON.stringify(itemList, null, 4)); + this.inventoryService.allocateBatch(itemList).subscribe( + (response) => { + if (response.statusCode == 200) { + if (response.data.length > 0) { + const itemBatchList = response.data; + this.openModalToShowBatchList(itemBatchList); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.itembatchlistisempty, + 'error', + ); + } + } else { + this.confirmationService.alert(response.errorMessage, 'error'); + } + }, + (err) => { + this.confirmationService.alert(err, 'error'); + }, + ); + } + + openModalToShowBatchList(itemBatchList: any) { + const mdDialogRef: MatDialogRef = this.dialog.open( + ShowBatchItemComponent, + { + data: { + batchList: itemBatchList, + beneficaryDetail: this.beneficaryDetail, + }, + width: 0.8 * window.innerWidth + 'px', + panelClass: 'dialog-width', + disableClose: false, + }, + ); + mdDialogRef.afterClosed().subscribe( + (result) => { + console.log('result', result); + if (result) { + console.log('resuklt', result); + if (result.result) { + console.log('result.result', result.result); + if (result.result.statusCode == 200) { + console.log('result.result.statusCode', result.result.statusCode); + if (result.print != null && result.print == true) { + const printableData = this.createPrintableData( + result.issuedBatchList, + ); + this.dataStorageService.systemItemDispense = printableData; + console.log( + 'printableData', + JSON.stringify(printableData, null, 4), + ); + const uRL = 'systemItemDispense'; + this.router.navigate(['/inventory/dynamicPrint/', uRL]); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.savedsuccessfully, + 'success', + ); + this.resetBeneficiaryDetails(); + } + } else { + this.confirmationService.alert( + result.result.errorMessage, + 'error', + ); + } + } + } + }, + (err) => { + this.confirmationService.alert(err, 'error'); + }, + ); + } + + resetForm() { + console.log('here in '); + const systemItemDispenseList = ( + this.systemDispenseForm.controls['systemItemDispenseList'] + ); + const systemItemDispenseListLength = systemItemDispenseList.value.length; + console.log('systemItemDispenseListLength', systemItemDispenseListLength); + for (let i = 0; i < systemItemDispenseListLength; i++) { + systemItemDispenseList.removeAt(0); + } + this.resetBeneficiaryDetails(); + } + + resetBeneficiaryDetails() { + console.log('event', event); + this.resetBeneficiaryDetail.emit(); + } + + createPrintableData(issuedBatchList: any) { + const printableData: any = []; + let i = 0; + issuedBatchList.forEach((dispenseItem: any) => { + dispenseItem.itemBatchList.forEach((batch: any) => { + console.log('batch', batch); + i = i + 1; + const dispensedItem = { + sNo: i, + itemName: dispenseItem.itemName, + batchNo: batch.batchNo, + expiryDate: moment(batch.expiryDate).format('DD-MM-YYYY'), + qod: batch.quantity, + }; + printableData.push(dispensedItem); + }); + }); + console.log(JSON.stringify(this.beneficaryDetail, null, 4)); + const beneficaryDetail = Object.assign( + { + visitedDate: moment(this.beneficaryDetail.visitDate).format( + 'DD-MM-YYYY', + ), + }, + this.beneficaryDetail, + ); + + const systemDispenseItem = Object.assign( + {}, + { title: this.title }, + { headerColumn: this.headerColumn }, + { headerDetail: beneficaryDetail }, + { columns: this.columns }, + { printableData: printableData }, + ); + return systemDispenseItem; + } + + validateRequestedQuantity(stock: FormGroup) { + const quantityInHand = stock.value.quantityInHand; + const requestedQuantity = stock.value.quantityRequired; + + if (requestedQuantity <= 0) { + this.confirmationService.alert( + this.currentLanguageSet.inventory.quantitycannotbenegativeorzero, + ); + stock.controls['quantityRequired'].setValue(null); + } else if (requestedQuantity > quantityInHand) { + this.confirmationService.alert( + this.currentLanguageSet.inventory.insufficientquantityinthisbatch, + ); + stock.controls['quantityRequired'].setValue(null); + } + } + + title = { + modalTitle: 'System Dispense', + headerTitle: 'Dispense Detail', + tableTitle: 'Dispensed Item', + }; + columns = [ + { + keyName: 'sNo', + columnName: 'S No.', + }, + { + keyName: 'itemName', + columnName: 'Item Name', + }, + { + keyName: 'batchNo', + columnName: 'Batch No', + }, + { + keyName: 'expiryDate', + columnName: 'Expiry Date', + }, + { + keyName: 'qod', + columnName: 'Qty dispensed', + }, + ]; + headerColumn = [ + { + columnName: 'Name :', + keyName: 'patientName', + }, + { + columnName: 'Beneficiary ID :', + keyName: 'beneficiaryID', + }, + { + columnName: 'Gender :', + keyName: 'gender', + }, + { + columnName: 'Age :', + keyName: 'age', + }, + { + columnName: 'Visit ID :', + keyName: 'visitID', + }, + { + columnName: 'Visit Date :', + keyName: 'visitedDate', + }, + { + columnName: 'Doctor Name :', + keyName: 'doctorName', + }, + { + columnName: 'Issued By :', + keyName: 'createdBy', + }, + { + columnName: 'Reference :', + keyName: 'reference', + }, + ]; + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.css b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.css new file mode 100644 index 0000000..2c7098b --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.css @@ -0,0 +1,39 @@ +#head { + background: #0277bd; + color: white; + height: 51px; + width: 100%; + padding: 20px; + overflow-x: hidden; + overflow-y: hidden; +} + +#dialog_head { + margin: 0; + padding: 0; +} + +h5 { + display: inline-block; +} + +#cross { + cursor: pointer; +} + +#dialog_row { + padding: 15px; +} + +.h5_bold { + font-weight: bold; +} + +.m-b-15 { + margin-bottom: 15px; +} + +.scrolling-content { + max-height: 75vh; + overflow: auto; +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.html b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.html new file mode 100644 index 0000000..6eb554e --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.html @@ -0,0 +1,119 @@ + + +
+
+
+
+ +
+
+ +
+
+ + + search + +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
diff --git a/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.spec.ts b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.spec.ts new file mode 100644 index 0000000..83f3b45 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewMedicineDispenseDetailsComponent } from './view-medicine-dispense-details.component'; + +describe('ViewMedicineDispenseDetailsComponent', () => { + let component: ViewMedicineDispenseDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewMedicineDispenseDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewMedicineDispenseDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.ts b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.ts new file mode 100644 index 0000000..32967aa --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense-details/view-medicine-dispense-details.component.ts @@ -0,0 +1,209 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, OnDestroy, DoCheck } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import * as moment from 'moment'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; + +@Component({ + selector: 'app-view-medicine-dispense-details', + templateUrl: './view-medicine-dispense-details.component.html', + styleUrls: ['./view-medicine-dispense-details.component.css'], +}) +export class ViewMedicineDispenseDetailsComponent + implements OnInit, OnDestroy, DoCheck +{ + _filterTerm = ''; + _detailedList: any = []; + _filteredDetailedList: any = []; + blankTable = [1, 2, 3, 4, 5]; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + public dialogRef: MatDialogRef, + public http_service: LanguageService, + @Inject(MAT_DIALOG_DATA) public data: any, + ) {} + + ngOnInit() { + this.populateDispenseRecords(this.data); + this.fetchLanguageResponse(); + } + + ngOnDestroy(): void { + //Called once, before the instance is destroyed. + //Add 'implements OnDestroy' to the class. + this.data = ''; + } + populateDispenseRecords(data: any) { + if (data && data.dispenseItem && data.dispense) { + this._detailedList = data.dispenseItem; + this._filteredDetailedList = data.dispenseItem; + } + } + + filterDetails(filterTerm: string) { + console.log(filterTerm); + if (!filterTerm) this._filteredDetailedList = this._detailedList; + else { + this._filteredDetailedList = []; + this._detailedList.forEach((item: any) => { + for (const key in item) { + if (key == 'batchNo' || key == 'itemName' || key == 'quantity') { + const value: string = '' + item[key]; + if (value.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0) { + this._filteredDetailedList.push(item); + break; + } + } + } + }); + } + } + + print() { + const printableData = this.createPrintableData(); + console.log('printableData', JSON.stringify(printableData, null, 4)); + this.closeModal(printableData); + } + closeModal(printableData: any) { + this.dialogRef.close(printableData); + } + + createPrintableData() { + const facilityDetailStrorage: any = localStorage.getItem('facilityDetail'); + const facilityDetail = JSON.parse(facilityDetailStrorage); + const facilityName = facilityDetail.facilityName; + const printableData: any = []; + let i = 0; + this.data.dispenseItem.forEach((dispenseItem: any) => { + i = i + 1; + const dispensedItem = { + sNo: i, + itemName: dispenseItem.itemName, + batchNo: dispenseItem.batchNo, + expiryDate: moment(dispenseItem.expiryDate).format('DD-MM-YYYY'), + qod: dispenseItem.quantity, + }; + printableData.push(dispensedItem); + }); + + const beneficiaryDetails = Object.assign( + { + facilityName: facilityName, + visitedDate: moment(this.data.dispense.visitDate).format('DD-MM-YYYY'), + }, + this.data.dispense, + ); + const previousDispense = Object.assign( + {}, + { title: this.title }, + { headerColumn: this.headerColumn }, + { headerDetail: beneficiaryDetails }, + { columns: this.columns }, + { printableData: printableData }, + ); + return previousDispense; + } + + title = { + modalTitle: 'Previous Dispense', + headerTitle: 'Dispense Detail', + tableTitle: 'Dispensed Item', + }; + + columns = [ + { + keyName: 'sNo', + columnName: 'S No.', + }, + { + keyName: 'itemName', + columnName: 'Item Name', + }, + { + keyName: 'batchNo', + columnName: 'Batch No', + }, + { + keyName: 'expiryDate', + columnName: 'Expiry Date', + }, + { + keyName: 'qod', + columnName: 'Qty dispensed', + }, + ]; + + headerColumn = [ + { + columnName: 'Name :', + keyName: 'patientName', + }, + { + columnName: 'Beneficiary ID :', + keyName: 'beneficiaryID', + }, + { + columnName: 'Gender :', + keyName: 'gender', + }, + { + columnName: 'Age :', + keyName: 'age', + }, + { + columnName: 'Visit Code :', + keyName: 'visitCode', + }, + { + columnName: 'Visit Date :', + keyName: 'visitedDate', + }, + { + columnName: 'Doctor Name :', + keyName: 'doctorName', + }, + { + columnName: 'Issued By :', + keyName: 'createdBy', + }, + { + columnName: 'Reference :', + keyName: 'reference', + }, + ]; + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.css b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.css new file mode 100644 index 0000000..f23c398 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.css @@ -0,0 +1,50 @@ +#head { + background: #0277bd; + color: white; + height: 51px; + width: 100%; + padding: 20px; +} + +#dialog_head { + margin: 0; + padding: 0; +} + +#cross { + cursor: pointer; +} + +#dialog_row { + padding: 24px; +} + +.h5_bold { + font-weight: bold; +} + +.input-full-width { + width: 100%; +} + +.box { + height: 60px; +} + +.back-btn-container { + margin: -26px 15px 15px; +} + +.previous-btn { + margin: 5px 0px; +} + +.m-b-40 { + margin-bottom: 40px !important; +} + +@media screen and (max-width: 768px) { + .previous-btn { + width: 100%; + } +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.html b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.html new file mode 100644 index 0000000..68c45c2 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.html @@ -0,0 +1,308 @@ +
+
+
+

+ {{ currentLanguageSet?.inventory?.previousPatientIssueWithoutRx }} +

+
+
+ + + + + + +
+
+ + + + + + + {{ currentLanguageSet?.inventory?.toDateCannotBeBeforeFromDate }} +
+
+ +
+
+ +
+
+ + +
+
+ + + search + +
+
+ + + + + + {{ + _filteredDispenseList.data.indexOf(element) + 1 + }} + + + + + {{ + currentLanguageSet?.inventory?.issueID + }} + {{ element?.patientIssueID }} + + + + + {{ + currentLanguageSet?.inventory?.patientName + }} + {{ element?.patientName }} + + + + + {{ + currentLanguageSet?.inventory?.reference + }} + {{ element?.reference }} + + + + + {{ + currentLanguageSet?.inventory?.issueType + }} + {{ element?.issueType }} + + + + + {{ + currentLanguageSet?.inventory?.createdBy + }} + {{ element?.createdBy }} + + + + + {{ + currentLanguageSet?.inventory?.createdDate + }} + {{ + element?.createdDate | istDate: "dd/MM/yyyy" + }} + + + + + + +
+ + + {{ + currentLanguageSet?.inventory?.norecordsfound + }} + + +
+
+
+
+ +
+ +
+
+
+
+
+
diff --git a/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.spec.ts b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.spec.ts new file mode 100644 index 0000000..92efa7a --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewMedicineDispenseComponent } from './view-medicine-dispense.component'; + +describe('ViewMedicineDispenseComponent', () => { + let component: ViewMedicineDispenseComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewMedicineDispenseComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewMedicineDispenseComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.ts b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.ts new file mode 100644 index 0000000..8bc7964 --- /dev/null +++ b/src/app/app-modules/inventory/medicine-dispense/view-medicine-dispense/view-medicine-dispense.component.ts @@ -0,0 +1,216 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Component, + OnInit, + HostListener, + ViewChild, + DoCheck, +} from '@angular/core'; +import { ViewMedicineDispenseDetailsComponent } from './view-medicine-dispense-details/view-medicine-dispense-details.component'; +import * as moment from 'moment'; +import { Location } from '@angular/common'; +import { InventoryService } from '../../shared/service/inventory.service'; +import { DataStorageService } from './../../shared/service/data-storage.service'; +import { Router } from '@angular/router'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { MatTableDataSource } from '@angular/material/table'; + +@Component({ + selector: 'app-view-medicine-dispense', + templateUrl: './view-medicine-dispense.component.html', + styleUrls: ['./view-medicine-dispense.component.css'], +}) +export class ViewMedicineDispenseComponent implements OnInit, DoCheck { + _minDate: any; + _today: any; + + _dateRange: Date[] = []; + _dateRangePrevious: Date[] = []; + + _dispenseList: any = []; + _filteredDispenseList = new MatTableDataSource(); + // _filteredDispenseList: any = []; + blankTable = [1, 2, 3, 4, 5]; + filterTerm: any; + searched = false; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private location: Location, + private inventoryService: InventoryService, + private dialog: MatDialog, + public http_service: LanguageService, + private router: Router, + private dataStorageService: DataStorageService, + ) {} + + ngOnInit() { + this.setDateDefault(); + this.fetchLanguageResponse(); + this.getPastDispense(); + } + + setDateDefault() { + this._today = new Date(); + this._minDate = new Date(); + this._dateRange[0] = this._today; + this._dateRange[1] = this._today; + this._minDate.setFullYear(this._today.getFullYear() - 1); + // const date = new Date(); // Now + // date.setDate(date.getDate() - 30); + // this._dateRange = [date, new Date()] + console.log(this._dateRange, 'dateRange'); + } + + getPastDispense() { + const obj = this.getViewServiceObject(); + this.inventoryService.viewMedicineDispenseEntry(obj).subscribe((res) => { + this.searched = true; + this.loadDispense(res); + }); + } + + preventTyping(e: any) { + if (e.keyCode === 9) { + return true; + } else { + return false; + } + } + + getViewServiceObject() { + const startDate: Date = new Date(this._dateRange[0]); + startDate.setHours(0); + startDate.setMinutes(0); + startDate.setSeconds(0); + startDate.setMilliseconds(0); + + const endDate: Date = new Date(this._dateRange[1]); + endDate.setHours(23); + endDate.setMinutes(59); + endDate.setSeconds(59); + endDate.setMilliseconds(0); + + return { + facilityID: localStorage.getItem('facilityID'), + fromDate: new Date( + startDate.valueOf() - 1 * startDate.getTimezoneOffset() * 60 * 1000, + ), + toDate: new Date( + endDate.valueOf() - 1 * endDate.getTimezoneOffset() * 60 * 1000, + ), + }; + } + + updateDate() { + // if (this._dateRange[0] != this._dateRangePrevious[0] || this._dateRange[1] != this._dateRangePrevious[1]) { + this._dateRangePrevious = this._dateRange; + // console.log(JSON.stringify(this._dateRange, null, 4), 'callservice'); + this.getPastDispense(); + + // } + } + + loadDispense(dispenseObject: any) { + console.log(dispenseObject); + // if (dispenseObject) { + // dispenseObject.forEach(element => { + // element.createdDate = moment(element.createdDate).utc().format('DD/MM/YYYY HH:mm') || 'Not Available' + + // }); + // } + this._dispenseList = dispenseObject.data; + this._filteredDispenseList.data = dispenseObject.data; + this.filterTerm = ''; + } + + filterConsumptionList(searchTerm: string) { + if (!searchTerm) this._filteredDispenseList.data = this._dispenseList; + else { + this._filteredDispenseList.data = []; + this._dispenseList.forEach((item: any) => { + for (const key in item) { + if ( + key == 'patientIssueID' || + key == 'patientName' || + key == 'reference' || + key == 'issueType' || + key == 'createdBy' + ) { + const value: string = '' + item[key]; + if (value.toLowerCase().indexOf(searchTerm.toLowerCase()) >= 0) { + this._filteredDispenseList.data.push(item); + break; + } + } + } + }); + } + } + + loadDispenseDetails(dispense: any) { + if (dispense && dispense.patientIssueID) { + this.inventoryService + .getParticularMedicineDispenseEntry(dispense.patientIssueID) + .subscribe((res) => this.popOutDispense(dispense, res)); + } + } + + popOutDispense(dispense: any, dispenseResponse: any) { + if (dispenseResponse) { + const mdDialogRef: MatDialogRef = + this.dialog.open(ViewMedicineDispenseDetailsComponent, { + // height: '90%', + width: '80%', + panelClass: 'fit-screen', + data: { dispense: dispense, dispenseItem: dispenseResponse }, + disableClose: false, + }); + mdDialogRef.afterClosed().subscribe((result: any) => { + if (result) { + this.dataStorageService.previousVisitData = result; + const uRL = 'previousVisitData'; + this.router.navigate(['/inventory/dynamicPrint/', uRL]); + } + }); + } + } + goBack() { + this.location.back(); + } + + // AV40085804 29/09/2021 Integrating Multilingual Functionality -----Start----- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + // -----End------ +} diff --git a/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.css b/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.css new file mode 100644 index 0000000..d080b7f --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.css @@ -0,0 +1,37 @@ +.input-full-width { + width: 100%; + } + .box { + height: 70px; + } + .m-t-30 { + margin-top: 30px; + } + + .container-fluid { + padding: 24px !important; + } + + .title { + margin: 0px 0px 10px; + padding: 15px 24px 15px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; + } + + .title h4 { + display: inline-block; + } + + .title .exit { + cursor: pointer; + } + + @media screen and (max-width: 768px) { + .search-btn { + width: 100%; + } + } \ No newline at end of file diff --git a/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.html b/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.html new file mode 100644 index 0000000..efe6c3e --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.html @@ -0,0 +1,61 @@ +
+

{{ currentLanguageSet?.inventory?.benificiaryDetails }}

+ +
+ +
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+
+
+
diff --git a/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.spec.ts b/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.spec.ts new file mode 100644 index 0000000..fdba674 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BenificiaryDetailsComponent } from './benificiary-details.component'; + +describe('BenificiaryDetailsComponent', () => { + let component: BenificiaryDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [BenificiaryDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BenificiaryDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.ts b/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.ts new file mode 100644 index 0000000..4031697 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/benificiary-details/benificiary-details.component.ts @@ -0,0 +1,67 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { InventoryService } from './../../../inventory/shared/service/inventory.service'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-benificiary-details', + templateUrl: './benificiary-details.component.html', + styleUrls: ['./benificiary-details.component.css'], +}) +export class BenificiaryDetailsComponent implements OnInit, DoCheck { + beneficiaryDetailsList: any = []; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private inventoryService: InventoryService, + private http_service: LanguageService, + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + ) {} + + ngOnInit() { + console.log('Data', this.data); + this.beneficiaryDetailsList = this.data.beneficiaryDetailsList; + this.fetchLanguageResponse(); + console.log('this.ben', this.beneficiaryDetailsList); + } + + loadbeneficiaryDetails(beneficiary: any) { + this.dialogRef.close(beneficiary); + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.css b/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.css new file mode 100644 index 0000000..fc25b2c --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.css @@ -0,0 +1,83 @@ +.input-full-width { + width: 100%; +} + +.searchBox { + background: #fff; + min-height: 40px; + overflow: hidden; + border-radius: 2px; + border-width: 0px; + box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.08); + } + + .search_icon { + font-weight: bold; + } + + .search_button { + padding: 0; + width: 40px; + min-height: 40px; + background: none; + border: none; + transform: scale(1); + transition: all 1s; + outline: none; + } + + .search_button:active { + outline: none; + border: none; + } + + .search_textbox { + width: 100%; + height: 40px; + border: none; + padding-left: 10px; + } + + #search_type { + margin-bottom: -1px; + } + + .search_button:hover { + transform: scale(1.5); + transition: all 1s; + outline: none; + border: none; + } + +.width-percent-5 { + width: 5% +} + +.width-percent-10 { + width: 10% +} + +.inner_table { + margin-bottom: 0px; +} + +.noPadding { + padding: 0px; +} + +.width-percent-25 { + width: 25%; +} + +.m-r-5 { + margin-right: 5px; +} + +.box { + height: 70px; +} + +.search-btn { + cursor: pointer; +} + diff --git a/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.html b/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.html new file mode 100644 index 0000000..d6883b8 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.html @@ -0,0 +1,91 @@ +
+
+ + + {{ item.itemName }} + + +
+
+
+
+
+

{{ currentLanguageSet?.inventory?.dispensingItem }}

+
+ +
+
+ +
+
+
+
+
+ + +
+
+
diff --git a/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.spec.ts b/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.spec.ts new file mode 100644 index 0000000..57bd03e --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.spec.ts @@ -0,0 +1,47 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ItemBatchDetailsForPatientReturnComponent } from './item-batch-details-for-patient-return.component'; + +describe('ItemBatchDetailsForPatientReturnComponent', () => { + let component: ItemBatchDetailsForPatientReturnComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ItemBatchDetailsForPatientReturnComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent( + ItemBatchDetailsForPatientReturnComponent, + ); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.ts b/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.ts new file mode 100644 index 0000000..2fd3bb6 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/item-batch-details-for-patient-return/item-batch-details-for-patient-return.component.ts @@ -0,0 +1,259 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Component, + OnInit, + Input, + EventEmitter, + Output, + DoCheck, +} from '@angular/core'; +import { + NgForm, + FormBuilder, + FormArray, + Validators, + FormGroup, +} from '@angular/forms'; +import { InventoryService } from '../../../inventory/shared/service/inventory.service'; +import { ConfirmationService } from '../../../core/services/confirmation.service'; +import { SearchComponent } from '../../../core/components/search/search.component'; +import { Router } from '@angular/router'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { PatientReturnBatchDetailsComponent } from '../patient-return-batch-details/patient-return-batch-details.component'; + +@Component({ + selector: 'app-item-batch-details-for-patient-return', + templateUrl: './item-batch-details-for-patient-return.component.html', + styleUrls: ['./item-batch-details-for-patient-return.component.css'], +}) +export class ItemBatchDetailsForPatientReturnComponent + implements OnInit, DoCheck +{ + @Input() + itemMasterList: any; + + @Input() + benRegId: any; + + @Output() + resetBenDetails: EventEmitter = new EventEmitter(); + + itemReturnForm!: FormGroup; + + batchList: any; + selectedItemList: any = []; + filterItemList: any = []; + + selectedBatchList: any = []; + patientReturnList: any = []; + + searched = false; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + hide = false; + constructor( + private fb: FormBuilder, + private dialog: MatDialog, + private http_service: LanguageService, + private inventoryService: InventoryService, + private confirmationService: ConfirmationService, + private router: Router, + ) {} + + ngOnInit() { + this.itemReturnForm = this.createItemReturnForm(); + this.fetchLanguageResponse(); + if (this.itemMasterList.length > 0) { + this.filterItemList = this.itemMasterList; + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.itemnotIssuedforthebeneficiary, + ); + } + console.log('itemListttttt......', this.itemMasterList, this.benRegId); + } + + createItemReturnForm() { + return this.fb.group({ + itemName: null, + batchList: new FormArray([]), + }); + } + + get itemName() { + return this.itemReturnForm.controls['itemName'].value; + } + + getBatchDetail(formvalue: any, editIndex: any) { + let batchReq; + let data: any; + if (editIndex == null) { + batchReq = { + benRegID: this.benRegId, + itemID: formvalue.itemID, + facilityID: localStorage.getItem('facilityID'), + }; + data = this.itemReturnForm.value; + console.log('Data if editIndex is null', data); + } else { + batchReq = { + benRegID: this.benRegId, + itemID: formvalue.itemName.itemID, + facilityID: localStorage.getItem('facilityID'), + }; + data = formvalue; + console.log('Data if editIndex is not null', data); + } + this.inventoryService.getBatchDetails(batchReq).subscribe((response) => { + console.log('Response of item batch list', response); + if (response.statusCode == 200) { + this.batchList = response.data; + this.popOutBenAndItemDetails(this.batchList, data, editIndex); + } + console.log('Batchlist::', JSON.stringify(this.batchList, null, 4)); + }); + } + + popOutBenAndItemDetails(batchList: any, formvalue: any, editIndex: any) { + console.warn(batchList); + const itemName = formvalue.itemName; + console.log('Itemmmmm', itemName); + const matDialogRef: MatDialogRef = + this.dialog.open(PatientReturnBatchDetailsComponent, { + // height: '90%', + // width: '80%', + panelClass: 'fit-screen', + data: { + batchList: batchList, + editIndex: editIndex, + editBatch: formvalue, + }, + disableClose: false, + }); + matDialogRef.afterClosed().subscribe((selectedBatchList: any) => { + if (selectedBatchList) { + if (editIndex != null) { + this.selectedBatchList.splice(editIndex, 1); + this.selectedBatchList.push(selectedBatchList.value); + this.itemReturnForm.patchValue({ + itemName: null, + }); + } else { + this.selectedBatchList.push(selectedBatchList.value); + this.itemReturnForm.patchValue({ + itemName: null, + }); + const filterItemMasterList = this.filterItemList; + this.filterItem(itemName, filterItemMasterList); + } + } else { + this.itemReturnForm.patchValue({ + itemName: null, + }); + } + }); + } + + removeAddedItem(i: any) { + const removedItem = this.selectedBatchList[i]; + this.filterItemList.push(removedItem.itemName); + this.selectedBatchList.splice(i, 1); + } + + filterItem(itemName: any, filterItemMasterList: any) { + this.selectedItemList.push(itemName); + console.log('selectedItemList', this.selectedItemList); + this.filterItemList = []; + this.filterItemList = filterItemMasterList.filter((item: any) => { + if (itemName && itemName.itemName && itemName.itemName != null) { + return itemName.itemName != item.itemName; + } + }); + } + openSearchDialog() { + const mdDialogRef: MatDialogRef = this.dialog.open( + SearchComponent, + { + // height: '80%', + // width: '80%', + panelClass: 'fit-screen', + disableClose: false, + }, + ); + } + editItem(item: any, i: any) { + this.getBatchDetail(item, i); + } + + manipulateFinalData() { + const finalData: any = []; + this.selectedBatchList.forEach((item: any) => { + item.batchList.forEach((batch: any) => { + const returnQuantity = batch.returnQuantity; + const createdBy = localStorage.getItem('userName'); + const batchNo = Object.assign(batch.batchNo, { + returnQuantity, + createdBy, + }); + finalData.push(batchNo); + }); + }); + console.log('finalData', finalData); + this.savePatientReturnBatch(finalData); + } + + savePatientReturnBatch(finalData: any) { + this.inventoryService + .updateQuantityReturned(finalData) + .subscribe((response) => { + if (response.statusCode == 200) { + this.confirmationService.alert(response.data.response, 'success'); + this.resetFieldsAfterSubmit(); + this.resetBenDetails.emit(false); + } + }); + } + + resetFieldsAfterSubmit() { + this.itemReturnForm.reset(); + this.selectedBatchList = []; + } + resetOnClear() { + this.resetFieldsAfterSubmit(); + this.resetBenDetails.emit(false); + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.css b/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.css new file mode 100644 index 0000000..bfd9064 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.css @@ -0,0 +1,38 @@ +.input-full-width { + width: 100%; +} + +.m-t-30 { + margin-top: 30px; +} + +.container-fluid { + padding: 24px !important; +} + +.display{ + padding-bottom: 20px; +} + + +.title { + margin: 0px 0px 10px; + padding: 15px 24px 15px; + color: white; + font-size: 18px; + line-height: 32px; + font-weight: 400; + background: #0277bd; +} + +.title h4 { + display: inline-block; +} + +.title .exit { + cursor: pointer; +} + +.actionButton { + float: right; +} diff --git a/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.html b/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.html new file mode 100644 index 0000000..48a3b07 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.html @@ -0,0 +1,120 @@ +
+

{{ title }}

+ +
+
+
+
+
+
+
+ + + {{ item.itemName }} + + +
+
+
+ +
+
+
+ +
+
+
+
+
+
+ + +
+
+
+
+
diff --git a/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.spec.ts b/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.spec.ts new file mode 100644 index 0000000..a8cd356 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PatientReturnBatchDetailsComponent } from './patient-return-batch-details.component'; + +describe('PatientReturnBatchDetailsComponent', () => { + let component: PatientReturnBatchDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [PatientReturnBatchDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PatientReturnBatchDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.ts b/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.ts new file mode 100644 index 0000000..4a552ad --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return-batch-details/patient-return-batch-details.component.ts @@ -0,0 +1,305 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { FormGroup, FormBuilder, FormArray } from '@angular/forms'; +import { InventoryService } from './../../../inventory/shared/service/inventory.service'; +import { ConfirmationService } from './../../../core/services/confirmation.service'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; + +@Component({ + selector: 'app-patient-return-batch-details', + templateUrl: './patient-return-batch-details.component.html', + styleUrls: ['./patient-return-batch-details.component.css'], +}) +export class PatientReturnBatchDetailsComponent implements OnInit, DoCheck { + batchForm!: FormGroup; + today!: Date; + + itemBatchList: any = []; + masterItemBatchList = []; + enableEditMode = false; + editBatchList: any; + selectedBatchList: any = []; + filteredBatchList: any = []; + + title!: string; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + private formBuilder: FormBuilder, + private http_service: LanguageService, + private inventoryService: InventoryService, + private confirmationService: ConfirmationService, + ) {} + filterItemList: any = []; + ngOnInit() { + this.fetchLanguageResponse(); + this.batchForm = this.createBatchForm(); + console.log('Data', this.data); + this.filterItemList.push(this.data.editBatch.itemName); + this.initAfterNg(); + } + + initAfterNg() { + if (this.data !== undefined) { + this.masterItemBatchList = this.data.batchList; + this.itemBatchList = this.data.batchList; + if (this.data.editIndex != null) { + this.title = this.currentLanguageSet.inventory.editBatchSelection; + } else { + this.title = this.currentLanguageSet.itemDispense.batchSelection; + const item = this.data.editBatch; + console.log('Item', JSON.stringify(item, null, 4)); + // this.setItem(item); + } + this.title; + console.log('this.data', this.data); + if (this.data.editBatch != null) { + if ( + this.data.editBatch.batchList && + this.data.editBatch.batchList.length > 0 + ) { + this.enableEditMode = true; + this.editBatchList = this.data.editBatch; + this.batchForm.patchValue(this.data.editBatch); + this.addBatch(); + this.handleBatchData(); + } else { + this.addBatch(); + this.editableBatch(this.data.editBatch); + } + } else { + this.editBatchList = []; + this.addBatch(); + } + } + } + + setItem(editBatch: any) { + console.log('editBatch', editBatch.itemName.itemName); + const item = editBatch.itemName.itemName; + this.batchForm.patchValue({ + itemName: editBatch.itemName.itemName, + itemDetails: editBatch.itemName, + }); + } + + createBatchForm() { + return this.formBuilder.group({ + itemName: null, + itemDetails: null, + batchList: this.formBuilder.array([]), + }); + } + + editableBatch(editBatchList: any) { + this.editBatchList = editBatchList; + this.batchForm.patchValue(editBatchList); + } + + handleBatchData() { + const formBatchList = this.batchForm.controls['batchList']; + const temp = this.data.editBatch.batchList.slice(); + + for (let i = 0; i < temp.length; i++) { + const batchArray = this.masterItemBatchList.filter((item: any) => { + return item.batchNo == temp[i].batchNo.batchNo; + }); + + if (batchArray.length > 0) { + temp[i].batchNo = batchArray[0]; + } + + if (temp[i].batchNo.batchNo) { + const k = formBatchList.get('' + i); + if (k) { + k.patchValue(temp[i]); + k.markAsTouched(); + this.getQuantityAndFilterItem(temp[i].batchNo, i); + } else { + throw new Error('Form control at index ${i} is null'); + } + } + if (i + 1 < temp.length) { + this.addBatch(); + } + } + } + + initBatchForm(): FormGroup { + return this.formBuilder.group({ + batchNo: null, + issuedQuantity: null, + dateOfIssue: null, + returnQuantity: null, + }); + } + + getQuantityAndFilterItem(selectedBatch: any, i: any, batchForm?: FormGroup) { + console.log('selectedBatch', selectedBatch); + + const selectedBatchList = this.selectedBatchList[i]; + this.filteredBatchList.map((item: any, t: any) => { + console.log('item, t', item, t); + + const index = item.indexOf(selectedBatch); + console.log('index', index); + + if (index != -1 && t != i) { + console.log('item', item); + + item = item.splice(index, 1); + } + }); + console.log('filteredBatchList', this.filteredBatchList); + + this.selectedBatchList[i] = selectedBatch; + + const dateOfIssue = (this.today = new Date(selectedBatch.dateofIssue)); + if (batchForm != undefined) { + batchForm.patchValue({ + issuedQuantity: selectedBatch.issuedQuantity, + dateOfIssue: dateOfIssue, + returnQuantity: null, + }); + } + // const quantityOnBatch = selectedBatch.quantityInHand; + } + + // calculateDispenseQuantity() { + // const batchList = this.batchForm.controls['batchList']; + // const batchListValue = batchList.value; + // let totalQuantity = 0; + // batchListValue.filter((quantity) => { + // if (quantity.returnQuantity && quantity.returnQuantity != null) { + // totalQuantity = +(totalQuantity) + (+quantity.returnQuantity); + // } + // }) + // this.batchForm.patchValue({ quantityDispensed: totalQuantity }); + // } + addBatch() { + const batchList = this.batchForm.controls['batchList']; + const tempBatch = batchList.value; + if (this.itemBatchList.length > tempBatch.length) { + if (this.itemBatchList) { + const resultBatch = this.itemBatchList.filter((batch: any) => { + const batchArray = tempBatch.filter((item: any) => { + if ( + item.batchNo && + item.batchNo != null && + item.batchNo.batchNo != null + ) { + return item.batchNo.batchNo == batch.batchNo; + } + }); + const batchFlag = batchArray.length == 0 ? true : false; + return batchFlag; + }); + this.filteredBatchList.push(resultBatch.slice()); + } + batchList.push(this.initBatchForm()); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.nofurtherbatchesavailable, + ); + } + } + + removeBatch(i: any, batchForm: any) { + const batchList = this.batchForm.controls['batchList']; + if (batchList.length == 1 && !!batchForm) { + batchForm.patchValue({ + batchNo: null, + issuedQuantity: null, + dateOfIssue: null, + returnQuantity: null, + }); + // this.calculateDispenseQuantity(); + } else { + const removedBatch = this.selectedBatchList[i]; + this.filteredBatchList.map((item: any, t: any) => { + if (t != i && removedBatch) { + item.push(removedBatch); + } + }); + this.selectedBatchList.splice(i, 1); + this.filteredBatchList.splice(i, 1); + batchList.removeAt(i); + // this.calculateDispenseQuantity(); + } + } + + checkValidity(batchForm: FormGroup) { + const batchList = this.batchForm.controls['batchList']; + const tempBatch = batchForm.value; + if (batchList.length != this.masterItemBatchList.length) { + if (tempBatch.returnQuantity) { + return false; + } else { + return true; + } + } else { + return true; + } + } + + checkQuantity(batch?: FormGroup) { + if (batch) { + const quantity = batch.value.returnQuantity; + if (batch.value.returnQuantity == 0) { + this.confirmationService.alert( + this.currentLanguageSet.inventory + .pleaseenterquantitygreaterthanzeroandlessthanorequaltoQtyinBatch, + ); + batch.patchValue({ returnQuantity: null }); + batch.markAsPristine(); + } else if (batch.value.issuedQuantity < batch.value.returnQuantity) { + this.confirmationService.alert( + this.currentLanguageSet.inventory + .pleaseenterquantitylessthanorequaltoQtyinBatch, + ); + batch.patchValue({ returnQuantity: null }); + batch.markAsPristine(); + } + } + } + saveAndUpdateItem() { + this.dialogRef.close(this.batchForm); + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.css b/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.css new file mode 100644 index 0000000..9fce1b0 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.css @@ -0,0 +1,33 @@ +.mdIcon { + vertical-align: text-bottom; +} + +.input-full-width { + width: 100%; +} + +.box { + height: 60px; +} + +.back-btn-container { + margin: -26px 15px 15px; +} + +.previous-btn { + margin: 5px 0px; +} + +.m-b-40 { + margin-bottom: 40px !important; +} + +.vertical-align-middle { + vertical-align: middle; +} + +@media screen and (max-width: 768px) { + .previous-btn { + width: 100%; + } +} diff --git a/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.html b/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.html new file mode 100644 index 0000000..2c8b324 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.html @@ -0,0 +1,163 @@ +
+
+
+

{{ currentLanguageSet?.inventory?.previousPatientReturn }}

+
+
+ + + + + + +
+
+ + + + + + + {{ currentLanguageSet?.inventory?.toDateCannotBeBeforeFromDate }} +
+
+ +
+
+ +
+
+ + +
+
+ + + search + +
+
+
+ +
+
+
+
+ +
+ +
+
+
+
+
+
diff --git a/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.spec.ts b/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.spec.ts new file mode 100644 index 0000000..7c13dd4 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PatientReturnPreviousRecordComponent } from './patient-return-previous-record.component'; + +describe('PatientReturnPreviousRecordComponent', () => { + let component: PatientReturnPreviousRecordComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [PatientReturnPreviousRecordComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PatientReturnPreviousRecordComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.ts b/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.ts new file mode 100644 index 0000000..f4202a8 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return-previous-record/patient-return-previous-record.component.ts @@ -0,0 +1,154 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, DoCheck, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { DataStorageService } from '../../shared/service/data-storage.service'; +import { InventoryService } from '../../shared/service/inventory.service'; +import { Location } from '@angular/common'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { MatDialog } from '@angular/material/dialog'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; + +@Component({ + selector: 'app-patient-return-previous-record', + templateUrl: './patient-return-previous-record.component.html', + styleUrls: ['./patient-return-previous-record.component.css'], +}) +export class PatientReturnPreviousRecordComponent implements OnInit, DoCheck { + today: any; + fromDate: any; + toDate: any; + patientReturnList: any = []; + + filterTerm: any; + filteredPatientReturnList: any = []; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private location: Location, + private dialog: MatDialog, + private router: Router, + private http_service: LanguageService, + private dataStorageService: DataStorageService, + private inventoryService: InventoryService, + ) {} + + ngOnInit() { + this.initializeDate(); + this.fetchLanguageResponse(); + } + + initializeDate() { + this.fromDate = new Date(); + this.fromDate.setHours(0, 0, 0, 0); + this.toDate = new Date(); + + this.fromDate.setHours(0); + this.fromDate.setMinutes(0); + this.fromDate.setSeconds(0); + this.fromDate.setMilliseconds(0); + + this.toDate.setHours(23); + this.toDate.setMinutes(59); + this.toDate.setSeconds(59); + this.toDate.setMilliseconds(0); + + this.today = new Date(); + this.viewRecords(); + } + + viewRecords() { + const startDate: Date = new Date(this.fromDate); + startDate.setHours(0); + startDate.setMinutes(0); + startDate.setSeconds(0); + startDate.setMilliseconds(0); + + const endDate: Date = new Date(this.toDate); + endDate.setHours(23); + endDate.setMinutes(59); + endDate.setSeconds(59); + endDate.setMilliseconds(0); + + const temp = { + fromDate: new Date( + startDate.valueOf() - 1 * startDate.getTimezoneOffset() * 60 * 1000, + ), + toDate: new Date( + endDate.valueOf() - 1 * endDate.getTimezoneOffset() * 60 * 1000, + ), + facilityID: localStorage.getItem('facilityID') + ? +localStorage.getItem('facilityID')! + : undefined, + }; + + this.inventoryService.getPatientReturnList(temp).subscribe((response) => { + console.log('res..', response); + this.patientReturnList = response.data.slice(); + console.log('patientReturnList', this.patientReturnList); + this.filteredPatientReturnList = response.data.slice(); + console.log('filteredPatientReturnList', this.filteredPatientReturnList); + }); + } + + goBack() { + this.location.back(); + } + + filterPatientReturnList(filterTerm: any) { + if (!filterTerm) + this.filteredPatientReturnList = this.patientReturnList.slice(); + else { + this.filteredPatientReturnList = []; + this.patientReturnList.forEach((item: any) => { + for (const key in item) { + if ( + key == 'itemName' || + key == 'batchNo' || + key == 'dateofIssue' || + key == 'patientName' || + key == 'returnDate' + ) { + const value: string = '' + item[key]; + if (value.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0) { + this.filteredPatientReturnList.push(item); + break; + } + } + } + }); + } + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/patient-return/patient-return.component.css b/src/app/app-modules/inventory/patient-return/patient-return.component.css new file mode 100644 index 0000000..fc25b2c --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return.component.css @@ -0,0 +1,83 @@ +.input-full-width { + width: 100%; +} + +.searchBox { + background: #fff; + min-height: 40px; + overflow: hidden; + border-radius: 2px; + border-width: 0px; + box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.08); + } + + .search_icon { + font-weight: bold; + } + + .search_button { + padding: 0; + width: 40px; + min-height: 40px; + background: none; + border: none; + transform: scale(1); + transition: all 1s; + outline: none; + } + + .search_button:active { + outline: none; + border: none; + } + + .search_textbox { + width: 100%; + height: 40px; + border: none; + padding-left: 10px; + } + + #search_type { + margin-bottom: -1px; + } + + .search_button:hover { + transform: scale(1.5); + transition: all 1s; + outline: none; + border: none; + } + +.width-percent-5 { + width: 5% +} + +.width-percent-10 { + width: 10% +} + +.inner_table { + margin-bottom: 0px; +} + +.noPadding { + padding: 0px; +} + +.width-percent-25 { + width: 25%; +} + +.m-r-5 { + margin-right: 5px; +} + +.box { + height: 70px; +} + +.search-btn { + cursor: pointer; +} + diff --git a/src/app/app-modules/inventory/patient-return/patient-return.component.html b/src/app/app-modules/inventory/patient-return/patient-return.component.html new file mode 100644 index 0000000..0bb84d3 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return.component.html @@ -0,0 +1,111 @@ +
+
+
+
+

+ {{ currentLanguageSet?.inventory?.patientReturns }} +

+
+
+ +
+
+ +
+
+ + + search + +
+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+
+ diff --git a/src/app/app-modules/inventory/patient-return/patient-return.component.spec.ts b/src/app/app-modules/inventory/patient-return/patient-return.component.spec.ts new file mode 100644 index 0000000..5aae1e3 --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PatientReturnComponent } from './patient-return.component'; + +describe('PatientReturnComponent', () => { + let component: PatientReturnComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [PatientReturnComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PatientReturnComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/patient-return/patient-return.component.ts b/src/app/app-modules/inventory/patient-return/patient-return.component.ts new file mode 100644 index 0000000..aed0edf --- /dev/null +++ b/src/app/app-modules/inventory/patient-return/patient-return.component.ts @@ -0,0 +1,222 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, DoCheck, OnInit } from '@angular/core'; +import { + FormBuilder, + Validators, + FormGroup, + FormControl, +} from '@angular/forms'; +import { InventoryService } from './../../inventory/shared/service/inventory.service'; +import { ConfirmationService } from './../../core/services/confirmation.service'; +import { SetLanguageComponent } from '../../core/components/set-language.component'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { LanguageService } from '../../core/services/language.service'; +import { BenificiaryDetailsComponent } from './benificiary-details/benificiary-details.component'; + +@Component({ + selector: 'app-patient-return', + templateUrl: './patient-return.component.html', + styleUrls: ['./patient-return.component.css'], +}) +export class PatientReturnComponent implements OnInit, DoCheck { + patientReturnForm!: FormGroup; + beneficiaryDetailsList: any = []; + + itemMasterList: any = []; + benSelected = false; + + selectedItemList = []; + filterItemList = []; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private fb: FormBuilder, + private dialog: MatDialog, + private http_service: LanguageService, + private inventoryService: InventoryService, + private confirmationService: ConfirmationService, + ) {} + + ngOnInit() { + this.patientReturnForm = this.createPatientReturnForm(); + this.fetchLanguageResponse(); + } + + createPatientReturnForm() { + return this.fb.group({ + beneficiaryIDOrPhoneNumber: null, + beneficiaryID: [{ value: null, disabled: true }], + benRegId: null, + name: [{ value: null, disabled: true }], + age: [{ value: null, disabled: true }], + gender: [{ value: null, disabled: true }], + }); + } + + get beneficiaryIDOrPhoneNumber() { + return this.patientReturnForm.controls['beneficiaryIDOrPhoneNumber'].value; + } + + get beneficiaryID() { + return this.patientReturnForm.controls['beneficiaryID'].value; + } + + get name() { + return this.patientReturnForm.controls['name'].value; + } + + get age() { + return this.patientReturnForm.controls['age'].value; + } + + get gender() { + return this.patientReturnForm.controls['gender'].value; + } + + get benRegId() { + return this.patientReturnForm.controls['benRegId'].value; + } + + initpatientReturnList() { + return this.fb.group({ + itemName: null, + batchID: null, + issueQuantity: null, + dateOfIssue: null, + returnQuantity: null, + }); + } + + identityQuickSearch(beneficiaryIDOrPhoneNumber: string) { + if (beneficiaryIDOrPhoneNumber.length == 10) { + this.phoneNumberSearch(beneficiaryIDOrPhoneNumber); + } else if (beneficiaryIDOrPhoneNumber.length == 12) { + this.beneficiarySearch(beneficiaryIDOrPhoneNumber); + } + } + + openBenDetailsModal() { + const mdDialogRef: MatDialogRef = + this.dialog.open(BenificiaryDetailsComponent, { + // height: '90%', + width: '80%', + panelClass: 'fit-screen', + data: { + beneficiaryDetailsList: this.beneficiaryDetailsList, + }, + disableClose: false, + }); + mdDialogRef.afterClosed().subscribe((benificiary) => { + if (benificiary) { + this.patchData(benificiary); + this.itemSearch(benificiary); + } + }); + } + + phoneNumberSearch(phoneNumber: any) { + this.inventoryService + .getBeneficiaryByPhoneNumber({ + phoneNo: phoneNumber, + }) + .subscribe((response) => { + console.log('response', response); + this.reponseDataCheck(response); + }); + } + + reponseDataCheck(response: any) { + if (response.statusCode == 200) { + if (response.data.length > 0) { + this.beneficiaryDetailsList = response.data; + this.openBenDetailsModal(); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.nobeneficiarydetailsavailable, + ); + } + } + } + beneficiarySearch(beneficiaryID: any) { + this.inventoryService + .getBeneficiaryByBeneficiaryID({ + beneficiaryID: beneficiaryID, + }) + .subscribe((response) => { + console.log('response', response); + this.reponseDataCheck(response); + }); + } + openSearchDialog() {} + patchData(benDetails: any) { + this.patientReturnForm.patchValue({ + beneficiaryID: benDetails.beneficiaryID, + benRegId: benDetails.beneficiaryRegID, + name: benDetails.firstName + ? benDetails.firstName + : '' + benDetails.lastName + ? benDetails.lastName + : '', + age: benDetails.age, + gender: benDetails.m_gender.genderName, + }); + } + + itemSearch(beneficiary: any) { + console.log('Beneficiary details..', beneficiary); + if (beneficiary != undefined) { + this.inventoryService + .getItemList({ + benRegID: beneficiary.beneficiaryRegID, + facilityID: localStorage.getItem('facilityID'), + }) + .subscribe((response) => { + console.log(this.itemMasterList); + + this.itemMasterList = response.data; + this.benSelected = true; + + this.filterItemList = response.data; + }); + } + } + + resetBenDetails(event: any) { + console.log('event', event); + this.benSelected = false; + this.patientReturnForm.reset(); + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.css b/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.css new file mode 100644 index 0000000..ebd92bf --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.css @@ -0,0 +1,47 @@ +.input-full-width { + width: 100%; +} + +.m-b-40 { + margin-bottom: 200px; +} + +.m-r-5 { + margin-right: 5px; +} + +.icon-remove { + margin: 16px; +} + +.width5 { + width: 5%; +} + +.width25 { + width: 25%; +} + +.width20 { + width: 20%; +} + +.vertical-align-middle { + vertical-align: middle; +} + +.input-datepicker { + padding: 5px 8px; +} + +.search-btn { + cursor: pointer; +} + +@media screen and (max-width: 768px) { + .button-full-width { + width: 100%; + /* height: 50px; */ + margin-top: 3px; + } +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.html b/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.html new file mode 100644 index 0000000..9ed4138 --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.html @@ -0,0 +1,283 @@ +
+
+
+
+

+ {{ currentLanguageSet?.inventory?.physicalStockEntry }} +

+
+
+ +
+
+ +
+
+ + + + + + {{ currentLanguageSet?.inventory?.pleaseenterReferenceNumber }} + + +
+ +
+ + + + + +
+
+ +
+
+ +
+ + + + {{ + currentLanguageSet?.inventory?.index + }} + {{ + i + 1 + }} + + + + {{ + currentLanguageSet?.inventory?.itemName + }} + + + + search + + + + + + {{ + currentLanguageSet?.inventory?.qtyInLowestUnit + }} + + + + + + + + + {{ + currentLanguageSet?.inventory?.unitCostPrice + }} + + + + + + + + + {{ + currentLanguageSet?.itemDispense?.batchNo + }} + + + + + + + + + {{ + currentLanguageSet?.itemDispense?.expiryDate + }} + + + + + + + + + + + + {{ + currentLanguageSet?.inventory?.actions + }} + + delete + + + + + + + + +
+ +
+
+
+
+
+ +
+
+ + +
+
+
+
diff --git a/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.spec.ts b/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.spec.ts new file mode 100644 index 0000000..3d7bc7b --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PhysicalStockEntryComponent } from './physical-stock-entry.component'; + +describe('PhysicalStockEntryComponent', () => { + let component: PhysicalStockEntryComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [PhysicalStockEntryComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PhysicalStockEntryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.ts b/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.ts new file mode 100644 index 0000000..75ce848 --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/physical-stock-entry.component.ts @@ -0,0 +1,262 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, OnChanges, DoCheck } from '@angular/core'; +import { InventoryService } from '../shared/service/inventory.service'; +import { Observable } from 'rxjs'; +import { + NgForm, + FormBuilder, + FormArray, + Validators, + FormGroup, + FormControl, + AbstractControl, +} from '@angular/forms'; +import { map, startWith } from 'rxjs/operators'; +import { ConfirmationService } from '../../core/services/confirmation.service'; +import { animate, style, transition, trigger } from '@angular/animations'; +import { SetLanguageComponent } from '../../core/components/set-language.component'; +import { LanguageService } from '../../core/services/language.service'; +import { MatTableDataSource } from '@angular/material/table'; + +@Component({ + selector: 'app-physical-stock-entry', + templateUrl: './physical-stock-entry.component.html', + styleUrls: ['./physical-stock-entry.component.css'], + animations: [ + trigger('enterAnimation', [ + transition(':enter', [ + style({ opacity: 0 }), + animate('200ms', style({ opacity: 1 })), + ]), + transition(':leave', [ + style({ opacity: 1 }), + animate('200ms', style({ opacity: 0 })), + ]), + ]), + ], +}) +export class PhysicalStockEntryComponent implements OnInit, OnChanges, DoCheck { + physicalStockEntryForm!: FormGroup; + otherDetails: any; + physicalStockList: any = []; + today!: Date; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + displayedColumns: string[] = [ + 'index', + 'itemName', + 'quantity', + 'totalCostPrice', + 'batchNo', + 'expiryDate', + 'actions', + ]; + stockEntryDate = new FormControl(new Date()); + dataSource!: MatTableDataSource; + constructor( + private inventoryService: InventoryService, + private http_service: LanguageService, + private dialogService: ConfirmationService, + private fb: FormBuilder, + ) {} + + ngOnInit() { + this.otherDetails = { + createdBy: localStorage.getItem('username'), + providerServiceMapID: localStorage.getItem('providerServiceID'), + userId: localStorage.getItem('userID'), + facilityID: localStorage.getItem('facilityID'), + vanID: localStorage.getItem('vanID'), + parkingPlaceID: localStorage.getItem('parkingPlaceID'), + }; + + this.today = new Date(); + this.fetchLanguageResponse(); + this.physicalStockEntryForm = this.createPhysicalStockEntryForm(); + } + + ngOnChanges() { + console.log('form', this.physicalStockEntryForm); + } + + createPhysicalStockEntryForm() { + return this.fb.group({ + referenceNumber: null, + stockEntryDate: null, + physicalStock: new FormArray([this.initPhysicalStock()]), + }); + } + + get isMedical() { + return this.physicalStockEntryForm.controls['isMedical'].value; + } + + initPhysicalStock() { + return this.fb.group({ + batchNo: [null, Validators.required], + expiryDate: null, + itemID: [null, Validators.required], + itemName: [null, Validators.required], + quantity: [null, Validators.required], + totalCostPrice: [null, Validators.required], + isMedical: null, + }); + } + + physicalStockTableData(): AbstractControl[] { + return (this.physicalStockEntryForm.get('physicalStock') as FormArray) + .controls; + } + + // this.dataSource = new MatTableDataSource(this.physicalStockTableData()); + + addStock() { + const stockForm = this.physicalStockEntryForm.controls[ + 'physicalStock' + ] as FormArray; + stockForm.push(this.initPhysicalStock()); + } + + removeStock(index: any, stock?: FormGroup) { + const stockForm = this.physicalStockEntryForm.controls[ + 'physicalStock' + ] as FormArray; + if (stockForm.length > 1) { + stockForm.removeAt(index); + } else { + stockForm.reset(); + stockForm.enable(); + } + } + + savePhysicalStock() { + const physicalStockEntry = JSON.parse( + JSON.stringify(this.physicalStockEntryForm.value), + ); + + physicalStockEntry.physicalStock.map((item: any) => { + item.createdBy = this.otherDetails.createdBy; + item.facilityID = this.otherDetails.facilityID; + }); + + const temp = Object.assign({}, physicalStockEntry, this.otherDetails, { + refNo: physicalStockEntry.referenceNumber, + status: 'Active', + itemStockEntry: physicalStockEntry.physicalStock, + physicalStock: undefined, + referenceNumber: undefined, + }); + + // console.log("Physical Entry Stock ", JSON.stringify(temp, null, 4)); + + this.inventoryService.savePhysicalStock(temp).subscribe( + (response) => { + if ( + response.statusCode == 200 && + response.data && + response.data.phyEntryID + ) { + this.dialogService.alert( + this.currentLanguageSet.inventory.savedsuccessfully, + 'success', + ); + this.reset(); + } else this.dialogService.alert(response.status, 'error'); + }, + (err) => { + this.dialogService.alert(err, 'error'); + }, + ); + } + + reset() { + // this.removeAllPhysicalStock(this.physicalStockEntryForm.controls['physicalStock'] as FormArray); + // this.physicalStockEntryForm.reset(); + this.physicalStockEntryForm = this.createPhysicalStockEntryForm(); + + this.today = new Date(); + } + + preventTyping(e: any) { + if (e.keyCode === 9) { + return true; + } else { + return false; + } + } + + removeAllPhysicalStock(physicalStockArray: FormArray) { + // let len = physicalStockArray.length; + + while (physicalStockArray.length > 1) { + physicalStockArray.removeAt(0); + } + // physicalStockArray.enable(); + } + + checkForDuplicateBatch(stockForm: FormGroup, index: any) { + // const index = (this.physicalStockEntryForm.get('physicalStock') as FormArray).controls.indexOf(stockForm) + const stockList = + this.physicalStockEntryForm.controls['physicalStock'].value; + const itemID = stockForm.value.itemID; + const batchNo = stockForm.value.batchNo; + + const temp = stockList.filter((stock: any, i: any) => { + if (i != index) + return ( + itemID && + stock.itemID == itemID && + batchNo && + stock.batchNo == batchNo + ); + else return false; + }); + + if (temp.length > 0) { + this.dialogService.alert( + this.currentLanguageSet.inventory.batchalreadypresent, + 'warn', + ); + stockForm.controls['batchNo'].reset(); + } + } + + getPhysicalStockControls() { + const physicalStockArray = this.physicalStockEntryForm.get( + 'physicalStock', + ) as FormArray; + return physicalStockArray.controls; + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.css b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.css new file mode 100644 index 0000000..a198ae3 --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.css @@ -0,0 +1,34 @@ +#head { + background: #0277bd; + color: white; + height: 51px; + width: 100%; + padding: 20px; +} + +#dialog_head { + margin: 0; + padding: 0; +} + +#cross { + cursor: pointer; +} + +#dialog_row { + padding: 15px; +} + +.h5_bold { + font-weight: bold; + display: inline-block; +} + +.m-b-15{ + margin-bottom: 15px; +} + +.scrolling-content { + max-height: 75vh; + overflow: auto; +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.html b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.html new file mode 100644 index 0000000..adba32b --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.html @@ -0,0 +1,148 @@ + + +
+
+ + +
+
+ + + search + +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
diff --git a/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.spec.ts b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.spec.ts new file mode 100644 index 0000000..4745df8 --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewPhysicalStockDetailsComponent } from './view-physical-stock-details.component'; + +describe('ViewPhysicalStockDetailsComponent', () => { + let component: ViewPhysicalStockDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewPhysicalStockDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewPhysicalStockDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.ts b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.ts new file mode 100644 index 0000000..bb8cc74 --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock-details/view-physical-stock-details.component.ts @@ -0,0 +1,119 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, OnDestroy, DoCheck } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; + +@Component({ + selector: 'app-view-physical-stock-details', + templateUrl: './view-physical-stock-details.component.html', + styleUrls: ['./view-physical-stock-details.component.css'], +}) +export class ViewPhysicalStockDetailsComponent + implements OnInit, OnDestroy, DoCheck +{ + _filterTerm = ''; + _detailedList: any = []; + _filteredDetailedList: any = []; + blankTable = [1, 2, 3, 4, 5]; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private http_service: LanguageService, + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + ) {} + + ngOnInit() { + this.populateStockEntryItems(this.data); + this.fetchLanguageResponse(); + } + + ngOnDestroy(): void { + //Called once, before the instance is destroyed. + //Add 'implements OnDestroy' to the class. + this.data = ''; + } + populateStockEntryItems(data: any) { + console.log(data); + if (data && data.entryDetails && data.stockEntry) { + const entries = data.entryDetails; + // entries.forEach(element => { + // element.createdDate = moment(element.createdDate).format('DD-MM-YYYY HH:mm A') || 'Not Available' + // }); + this._detailedList = entries; + this._filteredDetailedList = entries; + } + } + + filterDetails(filterTerm: string) { + console.log(filterTerm); + if (!filterTerm) this._filteredDetailedList = this._detailedList; + else { + this._filteredDetailedList = []; + this._detailedList.forEach((item: any) => { + for (const key in item) { + if (key != 'item') { + if (key == 'batchNo' || key == 'quantity') { + const value: string = '' + item[key]; + if (value.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0) { + this._filteredDetailedList.push(item); + break; + } + } + } + + if (key == 'item') { + const value: string = '' + item.item.itemName; + if (value.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0) { + this._filteredDetailedList.push(item); + break; + } + } + } + }); + } + } + + print() { + this.closeViewModal(); + } + + closeViewModal() { + const modalresult = Object.assign({ print: true }); + this.dialogRef.close(modalresult); + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.css b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.css new file mode 100644 index 0000000..452fdef --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.css @@ -0,0 +1,25 @@ +.input-full-width { + width: 100%; +} + +.box { + height: 60px; +} + +.back-btn-container { + margin: -26px 15px 15px; +} + +.previous-btn { + margin: 5px 0px; +} + +.m-b-40 { + margin-bottom: 40px !important; +} + +@media screen and (max-width: 768px) { + .previous-btn { + width: 100%; + } +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.html b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.html new file mode 100644 index 0000000..b2710b8 --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.html @@ -0,0 +1,399 @@ +
+
+
+

{{ currentLanguageSet?.inventory?.previousPhysicalStoreEntry }}

+
+ +
+ + + + + + + +
+ +
+ + + + + + + {{ currentLanguageSet?.inventory?.toDateCannotBeBeforeFromDate }} + +
+ + +
+ +
+
+ +
+
+ + +
+
+ + + search + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{ currentLanguageSet?.inventory?.entryID }} + + {{ i + 1 }} + + {{ currentLanguageSet?.inventory?.refNo }} + + {{ row?.refNo }} + + {{ currentLanguageSet?.bendetails?.status }} + + {{ row?.status }} + + {{ currentLanguageSet?.inventory?.createdBy }} + + {{ row?.createdBy }} + + {{ currentLanguageSet?.inventory?.createdDate }} + + {{ row?.createdDate | istDate: "dd/MM/yyyy" }} +
+
+ + + {{ + currentLanguageSet?.inventory?.norecordsfound + }} + + +
+ +
+
+
+
+ +
+ +
+
+
+
+
+
diff --git a/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.spec.ts b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.spec.ts new file mode 100644 index 0000000..0f2c1d9 --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewPhysicalStockComponent } from './view-physical-stock.component'; + +describe('ViewPhysicalStockComponent', () => { + let component: ViewPhysicalStockComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewPhysicalStockComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewPhysicalStockComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.ts b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.ts new file mode 100644 index 0000000..e96c459 --- /dev/null +++ b/src/app/app-modules/inventory/physical-stock-entry/view-physical-stock/view-physical-stock.component.ts @@ -0,0 +1,331 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Component, + OnInit, + HostListener, + ViewChild, + DoCheck, +} from '@angular/core'; +import { ViewPhysicalStockDetailsComponent } from './view-physical-stock-details/view-physical-stock-details.component'; +import { Location } from '@angular/common'; +import { InventoryService } from '../../shared/service/inventory.service'; +import { DataStorageService } from './../../shared/service/data-storage.service'; +import * as moment from 'moment'; +import { Router } from '@angular/router'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { MatTableDataSource } from '@angular/material/table'; + +@Component({ + selector: 'app-view-physical-stock', + templateUrl: './view-physical-stock.component.html', + styleUrls: ['./view-physical-stock.component.css'], +}) +export class ViewPhysicalStockComponent implements OnInit, DoCheck { + _minDate: any; + _today: any; + + _dateRange: Date[] = []; + _dateRangePrevious: Date[] = []; + + _stockEntryList: any = []; + _filteredStockEntryList = new MatTableDataSource(); + // _filteredStockEntryList: MatTableDataSource = new MatTableDataSource(); + blankTable = [1, 2, 3, 4, 5]; + filterTerm: any; + + searched = false; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + displayedColumns: string[] = [ + 'entryID', + 'refNo', + 'status', + 'createdBy', + 'createdDate', + ]; + + constructor( + private location: Location, + private http_service: LanguageService, + private inventoryService: InventoryService, + private dataStorageService: DataStorageService, + private dialog: MatDialog, + private router: Router, + ) {} + + ngOnInit() { + this.setDateDefault(); + this.fetchLanguageResponse(); + this.getPastEntries(); + } + + setDateDefault() { + this._today = new Date(); + this._minDate = new Date(); + this._minDate.setFullYear(this._today.getFullYear() - 1); + this._dateRange[0] = this._today; + this._dateRange[1] = this._today; + + console.log(this._dateRange, 'dateRange'); + } + + getPastEntries() { + const obj = this.getViewServiceObject(); + this.inventoryService.viewPhysicalStockEntry(obj).subscribe((res) => { + this.loadEntries(res); + this.searched = true; + }); + } + + getViewServiceObject() { + const startDate: Date = new Date(this._dateRange[0]); + startDate.setHours(0); + startDate.setMinutes(0); + startDate.setSeconds(0); + startDate.setMilliseconds(0); + + const endDate: Date = new Date(this._dateRange[1]); + endDate.setHours(23); + endDate.setMinutes(59); + endDate.setSeconds(59); + endDate.setMilliseconds(0); + + return { + facilityID: localStorage.getItem('facilityID'), + fromDate: new Date( + startDate.valueOf() - 1 * startDate.getTimezoneOffset() * 60 * 1000, + ), + toDate: new Date( + endDate.valueOf() - 1 * endDate.getTimezoneOffset() * 60 * 1000, + ), + }; + } + + updateDate() { + this.getPastEntries(); + } + + loadEntries(entriesObject: any) { + console.log(entriesObject); + console.log('ENTRIES' + entriesObject.data); + this._stockEntryList = entriesObject.data; + this._filteredStockEntryList.data = entriesObject.data; + console.log('P1' + this._filteredStockEntryList); + this.filterTerm = ''; + } + + filterConsumptionList(searchTerm: string) { + if (!searchTerm) this._filteredStockEntryList.data = this._stockEntryList; + else { + this._filteredStockEntryList.data = []; + this._stockEntryList.forEach((item: any) => { + for (const key in item) { + if ( + key == 'phyEntryID' || + key == 'refNo' || + key == 'status' || + key == 'createdBy' + ) { + const value: string = '' + item[key]; + if (value.toLowerCase().indexOf(searchTerm.toLowerCase()) >= 0) { + console.log('ITEM', +item); + this._filteredStockEntryList.data.push(item); + console.log('P2' + this._filteredStockEntryList.data); + break; + } + } + } + }); + } + } + + // filterConsumptionList(searchTerm: string) { + // if (!searchTerm) { + // this._filteredStockEntryList.data = this._stockEntryList; + // } else { + // this._filteredStockEntryList.data = this._stockEntryList.filter((item: any) => { + // for (const key in item) { + // if (key == 'phyEntryID' || key == 'refNo' || key == 'status' || key == 'createdBy') { + // const value: string = '' + item[key]; + // if (value.toLowerCase().indexOf(searchTerm.toLowerCase()) >= 0) { + // return true; + // } + // } + // } + // return false; + // }); + // } + // } + + loadEntryDetails(entry: any) { + if (entry && entry.phyEntryID) { + this.inventoryService + .getParticularStockEntry(entry.phyEntryID) + .subscribe((res) => this.popOutEntryDetails(entry, res)); + } + } + + popOutEntryDetails(entry: any, stockEntryResponse: any) { + console.warn(entry, stockEntryResponse); + if (stockEntryResponse) { + const matDialogRef: MatDialogRef = + this.dialog.open(ViewPhysicalStockDetailsComponent, { + // height: '90%', + width: '80%', + panelClass: 'fit-screen', + data: { stockEntry: entry, entryDetails: stockEntryResponse }, + disableClose: false, + }); + matDialogRef.afterClosed().subscribe((result) => { + if (result) { + if (result.print != null && result.print == true) { + if (result.print) { + const printableData = this.createPrintableData( + entry, + stockEntryResponse, + ); + this.dataStorageService.physicalStock = printableData; + const uRL = 'physicalStock'; + this.router.navigate(['/inventory/dynamicPrint/', uRL]); + } + } + } + }); + } + } + createPrintableData(entry: any, stockEntryResponse: any) { + const facilityDetl: any = localStorage.getItem('facilityDetail'); + const facilityDetail = JSON.parse(facilityDetl); + const facilityName = facilityDetail.facilityName; + const printableData: any = []; + let i = 0; + console.log( + 'stockEntryResponse', + JSON.stringify(stockEntryResponse, null, 4), + ); + stockEntryResponse.forEach((batch: any) => { + i = i + 1; + const consumedBatch = { + sNo: i, + itemName: batch.item.itemName, + batchNo: batch.batchNo, + expiryDate: moment(batch.expiryDate).format('DD-MM-YYYY'), + qod: batch.quantity, + }; + printableData.push(consumedBatch); + }); + console.log('consumptionDetails', JSON.stringify(entry, null, 4)); + const entryDetails = Object.assign( + { + facilityName: facilityName, + createDate: moment(entry.createdDate).format('DD-MM-YYYY'), + }, + entry, + ); + console.log('consumptionResponse', JSON.stringify(printableData, null, 4)); + const stockEntered = Object.assign( + {}, + { title: this.title }, + { headerColumn: this.headerColumn }, + { headerDetail: entryDetails }, + { columns: this.columns }, + { printableData: printableData }, + ); + return stockEntered; + } + goBack() { + this.location.back(); + } + + preventTyping(e: any) { + if (e.keyCode === 9) { + return true; + } else { + return false; + } + } + + title = { + modalTitle: '', + headerTitle: 'Stock Entry Detail', + tableTitle: '', + }; + columns = [ + { + keyName: 'sNo', + columnName: 'S No.', + }, + { + keyName: 'itemName', + columnName: 'Item Name', + }, + { + keyName: 'batchNo', + columnName: 'Batch No', + }, + { + keyName: 'expiryDate', + columnName: 'Expiry Date', + }, + { + keyName: 'qod', + columnName: 'Quantity', + }, + ]; + headerColumn = [ + { + columnName: 'Stock Entry ID :', + keyName: 'phyEntryID', + }, + { + columnName: 'Facility ID :', + keyName: 'facilityID', + }, + { + columnName: 'Reference No :', + keyName: 'refNo', + }, + { + columnName: 'Created By :', + keyName: 'createdBy', + }, + { + columnName: 'Created Date :', + keyName: 'createDate', + }, + ]; + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/shared/service/data-storage.service.spec.ts b/src/app/app-modules/inventory/shared/service/data-storage.service.spec.ts new file mode 100644 index 0000000..a3930e5 --- /dev/null +++ b/src/app/app-modules/inventory/shared/service/data-storage.service.spec.ts @@ -0,0 +1,39 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { TestBed, inject } from '@angular/core/testing'; + +import { DataStorageService } from './data-storage.service'; + +describe('DataStorageService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [DataStorageService], + }); + }); + + it('should be created', inject( + [DataStorageService], + (service: DataStorageService) => { + expect(service).toBeTruthy(); + }, + )); +}); diff --git a/src/app/app-modules/inventory/shared/service/data-storage.service.ts b/src/app/app-modules/inventory/shared/service/data-storage.service.ts new file mode 100644 index 0000000..f08c9f2 --- /dev/null +++ b/src/app/app-modules/inventory/shared/service/data-storage.service.ts @@ -0,0 +1,34 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Injectable } from '@angular/core'; + +@Injectable() +export class DataStorageService { + manualDispenseItem: any = {}; + systemItemDispense: any = {}; + previousVisitData: any = {}; + selfConsumption: any = {}; + physicalStock: any = {}; + stockTransfer: any = {}; + adjustment: any = {}; + indentDetails: any = {}; +} diff --git a/src/app/app-modules/inventory/shared/service/indent-dispense.service.ts b/src/app/app-modules/inventory/shared/service/indent-dispense.service.ts new file mode 100644 index 0000000..39453ed --- /dev/null +++ b/src/app/app-modules/inventory/shared/service/indent-dispense.service.ts @@ -0,0 +1,42 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +// import { Injectable } from '@angular/core'; +// import { Subject } from 'rxjs'; + +// @Injectable() +// export class IndentDispenseService { + +// private mainStoreRequest = new Subject(); +// private indentDispenseAllocation = new Subject(); + +// mainStoreRequest$ = this.mainStoreRequest.asObservable(); +// indentDispenseAllocation$ = this.indentDispenseAllocation.asObservable(); + +// // Service message commands +// mainStoreIndentRequest(indentRequest: string) { +// this.mainStoreRequest.next(indentRequest); +// } + +// indentAllocateBasedOnBatch(indentAllocate: string) { +// this.indentDispenseAllocation.next(indentAllocate); +// } +// } diff --git a/src/app/app-modules/inventory/shared/service/inventory-master.service.spec.ts b/src/app/app-modules/inventory/shared/service/inventory-master.service.spec.ts new file mode 100644 index 0000000..d64ea29 --- /dev/null +++ b/src/app/app-modules/inventory/shared/service/inventory-master.service.spec.ts @@ -0,0 +1,39 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { TestBed, inject } from '@angular/core/testing'; + +import { InventoryMasterService } from './inventory-master.service'; + +describe('InventoryMasterService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [InventoryMasterService], + }); + }); + + it('should be created', inject( + [InventoryMasterService], + (service: InventoryMasterService) => { + expect(service).toBeTruthy(); + }, + )); +}); diff --git a/src/app/app-modules/inventory/shared/service/inventory-master.service.ts b/src/app/app-modules/inventory/shared/service/inventory-master.service.ts new file mode 100644 index 0000000..beef263 --- /dev/null +++ b/src/app/app-modules/inventory/shared/service/inventory-master.service.ts @@ -0,0 +1,25 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Injectable } from '@angular/core'; + +@Injectable() +export class InventoryMasterService {} diff --git a/src/app/app-modules/inventory/shared/service/inventory.service.spec.ts b/src/app/app-modules/inventory/shared/service/inventory.service.spec.ts new file mode 100644 index 0000000..26858f1 --- /dev/null +++ b/src/app/app-modules/inventory/shared/service/inventory.service.spec.ts @@ -0,0 +1,39 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { TestBed, inject } from '@angular/core/testing'; + +import { InventoryService } from './inventory.service'; + +describe('InventoryService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [InventoryService], + }); + }); + + it('should be created', inject( + [InventoryService], + (service: InventoryService) => { + expect(service).toBeTruthy(); + }, + )); +}); diff --git a/src/app/app-modules/inventory/shared/service/inventory.service.ts b/src/app/app-modules/inventory/shared/service/inventory.service.ts new file mode 100644 index 0000000..19a58ad --- /dev/null +++ b/src/app/app-modules/inventory/shared/service/inventory.service.ts @@ -0,0 +1,378 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Router } from '@angular/router'; +import { Observable, throwError } from 'rxjs'; +import { environment } from 'src/environments/environment'; + +@Injectable() +export class InventoryService { + constructor(private http: HttpClient) {} + + getAvailableItemInStore() { + const storeID = localStorage.getItem('facilityID'); + console.log('this.itemInStore', storeID); + return this.http.post( + environment.getAvailableItemInStoreUrl + storeID, + {}, + ); + } + getBeneficaryVisitDetail(beneficiaryID: any) { + return this.http.post( + environment.getBeneficaryVisitDetailsurl, + beneficiaryID, + ); + } + + saveStockExit(dispensingItem: any) { + return this.http.post(environment.saveStockExitUrl, dispensingItem); + } + + allocateBatch(itemList: any) { + return this.http.post( + environment.allocateBatchStockUrl + localStorage.getItem('facilityID'), + itemList, + ); + } + + getItemBatchList(itemDetail: any) { + return this.http.post(environment.getItemBatchListUrl, itemDetail); + } + + getStoreItemsCall(facID: any) { + return this.http.post(environment.getStoreItems + facID, {}); + } + + getItemBatchForStoreIDCall(itemID: any, facID: any) { + return this.http.post(environment.getItemBatchForStoreID, { + facilityID: facID, + itemID: itemID, + }); + } + + getItem(obj: any) { + return this.http.post(environment.getItem_Url, obj); + } + + /** + * Related To Store Consumption + * */ + storeSelfConsumption(obj: any) { + return this.http.post(environment.storeSelfConsumption, obj); + } + viewSelfConsumption(obj: any) { + return this.http.post(environment.viewSelfConsumption, obj); + } + + getParticularConsumption(consumptionID: any) { + return this.http.post(environment.getParticularConsumptionURL, { + consumptionID: consumptionID, + }); + } + + /** + * Related To Store Consumption -- ENDS + * */ + + /** + * Related to Physical Stock Entry + */ + savePhysicalStock(obj: any) { + return this.http.post(environment.savePhysicalStock_Url, obj); + } + + viewPhysicalStockEntry(obj: any) { + return this.http.post(environment.viewPhysicalStockURL, obj); + } + + getParticularStockEntry(entryID: any) { + return this.http.post(environment.getParticularStockURL, { + phyEntryID: entryID, + }); + } + + /** + * Related to Physical Stock Entry -- ENDS + */ + + /** + * Related to Medicine Dispense + */ + viewMedicineDispenseEntry(obj: any) { + return this.http.post(environment.viewMedicineDispenceURL, obj); + } + + getParticularMedicineDispenseEntry(patientIssueID: any) { + return this.http.post(environment.getParticularMedicineDispenseURL, { + patientIssueID: patientIssueID, + }); + } + /** + * Related to Medicine Dispense -- ENDS + */ + + /** + * Related to Stock Transfer + */ + + saveStockTransfer(obj: any) { + return this.http.post(environment.saveStoreTransferUrl, obj); + } + + viewStockTransferEntry(obj: any) { + return this.http.post(environment.viewStockTransferURL, obj); + } + + getParticularStockTransferEntry(stockTransferID: any) { + return this.http.post(environment.getParticularStockTransferURL, { + stockTransferID: stockTransferID, + }); + } + + /** + * Related to Stock Transfer -- ENDS + */ + + getAllStore(serviceProviderId: any) { + return this.http.post( + environment.getFacilityUrl + serviceProviderId, + {}, + ); + } + + saveStockAdjustmentDraft(stockAdjustment: any) { + return this.http.post( + environment.saveStockAdjustmentDraftUrl, + stockAdjustment, + ); + } + + saveStockAdjustment(stockAdjustment: any) { + return this.http.post( + environment.saveStockAdjustmentUrl, + stockAdjustment, + ); + } + + getStockAdjustmentDraftList(fetchDetails: any) { + return this.http.post( + environment.getStockAjustmentDraftList, + fetchDetails, + ); + } + + getStockAdjustmentList(fetchDetails: any) { + return this.http.post(environment.getStockAjustmentList, fetchDetails); + } + + getStockAdjustmentDraftDetails(stockAdjustmentDraftID: any) { + return this.http.post(environment.getStockAjustmentDraftDetails, { + stockAdjustmentDraftID, + }); + } + + getStockAdjustmentDetails(stockAdjustmentID: any) { + return this.http.post(environment.getStockAjustmentDetails, { + stockAdjustmentID, + }); + } + + /** + * Related to Patient Return -- STARTS + */ + + getBeneficiaryByPhoneNumber(obj: any) { + return this.http.post(environment.getBeneficiaryByPhoneNumberUrl, obj); + } + + getBeneficiaryByBeneficiaryID(obj: any) { + return this.http.post( + environment.getBeneficiaryByBeneficiaryIDUrl, + obj, + ); + } + + getItemList(obj: any) { + return this.http.post(environment.getItemListUrl, obj); + } + + getBatchDetails(obj: any) { + return this.http.post(environment.getBatchListUrl, obj); + } + + updateQuantityReturned(obj: any) { + return this.http.post(environment.getUpdateQuantityReturnedUrl, obj); + } + + getPatientReturnList(obj: any) { + return this.http.post(environment.getPatientReturnListUrl, obj); + } + /** + * + * Errrrorororororoor + * + */ + handleError(error: Response | any) { + return throwError(error.json()); + } + + /* + * Related to Indent Request + */ + saveIndentRequest(tempObj: any) { + return this.http.post(environment.saveIndentRequestUrl, tempObj); + } + showMainstoreOrderWorklist(facilityID: any) { + return this.http.post( + environment.showMainStoreIndentRequestUrl, + facilityID, + ); + } + + viewItemListForMainStore(itemList: any) { + return this.http.post( + environment.viewItemListForMainStoreUrl, + itemList, + ); + } + viewBatchlistForIndentItem(batchlistObj: any) { + return this.http.post(environment.getItemBatchListUrl, batchlistObj); + } + rejectIndentOrder(rejectIndent: any) { + return this.http.post( + environment.getSaveDispenseListUrl, + rejectIndent, + ); + } + /** + * Related to indent dispense + */ + saveDispenseList(itemListObj: any) { + return this.http.post(environment.getSaveDispenseListUrl, itemListObj); + } + /* + * Related to sub store + */ + showSubStoreOrderWorklist(facilityID: any) { + return this.http.post( + environment.showSubStoreIndentRequestUrl, + facilityID, + ); + } + cancelIndentRequest(cancelIndent: any) { + return this.http.post( + environment.cancelIndentRequestUrl, + cancelIndent, + ); + } + viewItemListForSubStore(itemList: any) { + return this.http.post( + environment.viewItemListForSubStoreUrl, + itemList, + ); + } + receiveIndentOrder(acceptOrderObj: any) { + return this.http.post( + environment.receiveIndentOrderUrl, + acceptOrderObj, + ); + } + updateIndentRequest(updateTempObj: any) { + return this.http.post(environment.updateIndentOrderUrl, updateTempObj); + } + + /** + * Reports + */ + getInwardStockReports(inwardStockReportObj: any) { + return this.http.post( + environment.inwardStockReportUrl, + inwardStockReportObj, + ); + } + + getConsumptionReports(consumptionReportObj: any) { + return this.http.post( + environment.consumptionReportUrl, + consumptionReportObj, + ); + } + + getExpiryReports(expiryReportObj: any) { + return this.http.post(environment.expiryReportUrl, expiryReportObj); + } + + getBeneficiaryDrugIssueReports(beneficiaryDrugIssueReportObj: any) { + return this.http.post( + environment.beneficiaryDrugIssueReportUrl, + beneficiaryDrugIssueReportObj, + ); + } + + getDailyStockDetailsReports(dailyStockDetailsReportObj: any) { + return this.http.post( + environment.dailyStockDetailsReportUrl, + dailyStockDetailsReportObj, + ); + } + + getDailyStockSummaryReports(dailyStockSummaryReportObj: any) { + return this.http.post( + environment.dailyStockSummaryReportUrl, + dailyStockSummaryReportObj, + ); + } + + getMonthlyReports(monthlyReportObj: any) { + return this.http.post(environment.monthlyReportUrl, monthlyReportObj); + } + + getYearlyReports(yearlyReportObj: any) { + return this.http.post(environment.yearlyReportUrl, yearlyReportObj); + } + + getShortExpiryReports(shortExpiryReportObj: any) { + return this.http.post( + environment.shortExpiryReportUrl, + shortExpiryReportObj, + ); + } + + getTransitReports(transitReportReqObj: any) { + return this.http.post( + environment.transitReportUrl, + transitReportReqObj, + ); + } + + addEAushadhiItemsToAmrit(facilityID: any) { + return this.http.post( + environment.eAushadhiStockAdditionUrl, + facilityID, + ); + } + + showLastUpdatedStockLogs(facilityID: any) { + return this.http.post(environment.lastUpdatedStockLogUrl, facilityID); + } +} diff --git a/src/app/app-modules/inventory/shared/service/prescribed-drug.service.spec.ts b/src/app/app-modules/inventory/shared/service/prescribed-drug.service.spec.ts new file mode 100644 index 0000000..7e8dedc --- /dev/null +++ b/src/app/app-modules/inventory/shared/service/prescribed-drug.service.spec.ts @@ -0,0 +1,39 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { TestBed, inject } from '@angular/core/testing'; + +import { PrescribedDrugService } from './prescribed-drug.service'; + +describe('PrescribedDrugService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [PrescribedDrugService], + }); + }); + + it('should be created', inject( + [PrescribedDrugService], + (service: PrescribedDrugService) => { + expect(service).toBeTruthy(); + }, + )); +}); diff --git a/src/app/app-modules/inventory/shared/service/prescribed-drug.service.ts b/src/app/app-modules/inventory/shared/service/prescribed-drug.service.ts new file mode 100644 index 0000000..618b809 --- /dev/null +++ b/src/app/app-modules/inventory/shared/service/prescribed-drug.service.ts @@ -0,0 +1,69 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { environment } from 'src/environments/environment'; + +@Injectable() +export class PrescribedDrugService { + dummify = { + prescribed: { + prescriptionID: '1A22eddt5', + prescribedDate: '08/08/2018', + consultantName: 'Balu Lal', + status: false, + prescribedDrugs: [ + { + drugID: '123431', + drugName: 'SomeMed CapsoTableSyruped', + batchNumber: '245u67ujt', + qoh: 209, + quantityPrescribed: 203, + quantiyIssued: 209, + }, + { + drugID: '123431', + drugName: 'SomeMed CapsoTableSyruped', + batchNumber: '245u67ujt', + qoh: 209, + quantityPrescribed: 203, + quantiyIssued: 209, + }, + { + drugID: '123431', + drugName: 'SomeMed CapsoTableSyruped', + batchNumber: '245u67ujt', + qoh: 209, + quantityPrescribed: 203, + quantiyIssued: 209, + }, + ], + }, + }; + + constructor(private http: HttpClient) {} + + getPrescription(reqObj: any) { + // return Observable.of(this.dummify); + return this.http.post(environment.getPrescriptions, reqObj); + } +} diff --git a/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.css b/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.css new file mode 100644 index 0000000..e896df5 --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.css @@ -0,0 +1,51 @@ +.input-full-width { + width: 100%; +} + +.m-b-40 { + margin-bottom: 40px; +} + +.m-r-5 { + margin-right: 5px; +} + +.icon-remove { + margin: 16px; +} + +.vertical-align-middle { + vertical-align: middle; +} + +.input-datepicker { + padding: 5px 8px; +} + +.search-btn { + cursor: pointer; +} + +@media screen and (max-width: 768px) { + .button-full-width { + width: 100%; + /* height: 50px; */ + margin-top: 3px; + } +} + +.width5 { + width: 5%; +} + +.width10 { + width: 10%; +} + +.width15 { + width: 15%; +} + +.width20 { + width: 20%; +} diff --git a/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.html b/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.html new file mode 100644 index 0000000..98ee83e --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.html @@ -0,0 +1,299 @@ +
+
+
+
+

{{ currentLanguageSet?.inventory?.storeConsumption }}

+
+ +
+ +
+
+ +
+
+ + + + + + {{ currentLanguageSet?.inventory?.pleaseenterReferenceNumber }} + + +
+
+ + + +
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
# + {{ i + 1 }} + + {{ currentLanguageSet?.inventory?.itemName }} + + + + search + + + {{ currentLanguageSet?.itemDispense?.batchNo }} + + + + + + {{ currentLanguageSet?.inventory?.qOH }} + + + + + + {{ currentLanguageSet?.inventory?.quantity }} + + + + + + delete + + +
+
+
+
+
+ +
+
+ + +
+
+
+
diff --git a/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.spec.ts b/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.spec.ts new file mode 100644 index 0000000..05cac2a --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { StoreSelfConsumptionComponent } from './store-self-consumption.component'; + +describe('StoreSelfConsumptionComponent', () => { + let component: StoreSelfConsumptionComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [StoreSelfConsumptionComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StoreSelfConsumptionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.ts b/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.ts new file mode 100644 index 0000000..48dd628 --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/store-self-consumption.component.ts @@ -0,0 +1,233 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, DoCheck, OnInit } from '@angular/core'; +import { ConfirmationService } from '../../core/services/confirmation.service'; +import { InventoryService } from '../shared/service/inventory.service'; +import { Router } from '@angular/router'; +import { FormBuilder, FormArray, FormGroup, Validators } from '@angular/forms'; +import { LanguageService } from '../../core/services/language.service'; +import { SetLanguageComponent } from '../../core/components/set-language.component'; +import { MatTableDataSource } from '@angular/material/table'; + +export interface PeriodicElement { + itemName: string; + index: number; + batchNo: number; + quantityInHand: string; + quantity: string; + delete: string; + addButton: string; +} + +@Component({ + selector: 'app-store-self-consumption', + templateUrl: './store-self-consumption.component.html', + styleUrls: ['./store-self-consumption.component.css'], +}) +export class StoreSelfConsumptionComponent implements OnInit, DoCheck { + storeSelfConsumptionForm!: FormGroup; + facilityID: any; + providerServiceMapID: any; + createdBy: any; + currentLanguageSet: any; + languageComponent: any; + displayedColumns: string[] = [ + 'index', + 'itemName', + 'batchNo', + 'quantityInHand', + 'quantity', + 'delete', + 'addButton', + ]; + + constructor( + private fb: FormBuilder, + private router: Router, + private http_service: LanguageService, + private inventoryService: InventoryService, + private alertService: ConfirmationService, + ) {} + dataSource = new MatTableDataSource([{}]); + ngOnInit() { + this.createdBy = localStorage.getItem('username'); + this.facilityID = localStorage.getItem('facilityID'); + this.fetchLanguageResponse(); + this.providerServiceMapID = localStorage.getItem('providerServiceID'); + + if (this.facilityID == null || this.facilityID <= 0) { + this.router.navigate(['/inventory']); + } + + this.storeSelfConsumptionForm = this.createStoreSelfConsumptionForm(); + } + + createStoreSelfConsumptionForm() { + return this.fb.group({ + referenceNumber: null, + dispenseReason: null, + dispensedStock: new FormArray([this.initDispensedStock()]), + }); + } + + initDispensedStock() { + return this.fb.group({ + itemStockEntryID: null, + batchNo: [null, Validators.required], + itemID: [null, Validators.required], + itemName: [null, Validators.required], + quantityInHand: null, + quantity: [null, Validators.required], + }); + } + + addDispensedStock() { + const stockForm = this.storeSelfConsumptionForm.controls[ + 'dispensedStock' + ] as FormArray; + // if (stock) { + stockForm.push(this.initDispensedStock()); + this.dataSource.data = stockForm.controls; + // } else { + // this.alertService.alert('Please enter the values first', 'info'); + // } + } + + checkValidity(stock?: FormGroup) { + if (stock) { + const tempValid = stock.value; + // console.log('tempValid', tempValid) + if (tempValid.quantity) { + return false; + } else { + return true; + } + } + } + + removeDispensedStock(index: any, stock?: FormGroup) { + const stockForm = this.storeSelfConsumptionForm.controls[ + 'dispensedStock' + ] as FormArray; + if (stockForm.length > 1) { + stockForm.removeAt(index); + this.dataSource.data = stockForm.controls; + } else { + if (stock) { + stock.reset(); + stock.controls['itemName'].enable(); + } + } + } + + saveSelfConsumptionStock() { + const temp = JSON.parse( + JSON.stringify(this.storeSelfConsumptionForm.value), + ); + const itemStockExit = temp.dispensedStock.map((item: any) => { + item = { + ...item, + createdBy: this.createdBy, + facilityID: this.facilityID, + }; + return item; + }); + const requestBody = { + issueType: 'Manual', + refNo: temp.referenceNumber, + reason: temp.dispenseReason, + itemStockExit: itemStockExit, + facilityID: this.facilityID, + providerServiceMapID: this.providerServiceMapID, + createdBy: this.createdBy, + dispensedStock: undefined, + vanID: localStorage.getItem('vanID'), + parkingPlaceID: localStorage.getItem('parkingPlaceID'), + }; + + // console.log("Self Stock Consumption", JSON.stringify(requestBody, null, 4)); + + this.inventoryService.storeSelfConsumption(requestBody).subscribe( + (response) => { + if (response.statusCode == 200) { + this.alertService.alert( + this.currentLanguageSet.inventory.savedsuccessfully, + 'success', + ); + this.reset(); + } else this.alertService.alert(response.status, 'error'); + }, + (err) => { + this.alertService.alert(err, 'error'); + }, + ); + } + + reset() { + this.removeAllDispensedStock( + this.storeSelfConsumptionForm.controls['dispensedStock'] as FormArray, + ); + // let i = this.storeSelfConsumptionForm.controls['dispensedStock'] as FormArray; + // i = null; + // i = new FormArray([this.initDispensedStock()]); + this.storeSelfConsumptionForm.reset(); + // this.storeSelfConsumptionForm = this.createStoreSelfConsumptionForm(); + } + + validateRequestedQuantity(stock: FormGroup) { + const quantityInHand = stock.value.quantityInHand; + const requestedQuantity = stock.value.quantity; + + if (requestedQuantity <= 0) { + this.alertService.alert( + this.currentLanguageSet.inventory.quantitycannotbenegativeorzero, + ); + stock.controls['quantity'].setValue(null); + } else if (requestedQuantity > quantityInHand) { + this.alertService.alert( + this.currentLanguageSet.inventory.insufficientquantityinthisbatch, + ); + stock.controls['quantity'].setValue(null); + } + } + + removeAllDispensedStock(dispensedStockArray: FormArray) { + // let len = dispensedStockArray.length; + // for (let i = 0; i < len - 1; i++) { + while (dispensedStockArray.length > 1) { + dispensedStockArray.removeAt(0); + } + dispensedStockArray.enable(); + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.css b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.css new file mode 100644 index 0000000..50a1d15 --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.css @@ -0,0 +1,34 @@ +#head { + background: #0277bd; + color: white; + height: 51px; + width: 100%; + padding: 20px; +} + +#dialog_head { + margin: 0; + padding: 0; +} + +#cross { + cursor: pointer; +} + +#dialog_row { + padding: 15px; +} + +.h5_bold { + font-weight: bold; + display: inline-block; +} + +.m-b-15 { + margin-bottom: 15px; +} + +.scrolling-content { + max-height: 75vh; + overflow: auto; +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.html b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.html new file mode 100644 index 0000000..bf47a8f --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.html @@ -0,0 +1,120 @@ + + +
+
+ + +
+
+ + + search + +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
diff --git a/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.spec.ts b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.spec.ts new file mode 100644 index 0000000..6ee8df8 --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewStoreSelfConsumptionDetailsComponent } from './view-store-self-consumption-details.component'; + +describe('ViewStoreSelfConsumptionDetailsComponent', () => { + let component: ViewStoreSelfConsumptionDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewStoreSelfConsumptionDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewStoreSelfConsumptionDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.ts b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.ts new file mode 100644 index 0000000..1f9c037 --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption-details/view-store-self-consumption-details.component.ts @@ -0,0 +1,103 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, OnDestroy, DoCheck } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; + +@Component({ + selector: 'app-view-store-self-consumption-details', + templateUrl: './view-store-self-consumption-details.component.html', + styleUrls: ['./view-store-self-consumption-details.component.css'], +}) +export class ViewStoreSelfConsumptionDetailsComponent + implements OnInit, OnDestroy, DoCheck +{ + _filterTerm = ''; + _detailedList: any = []; + _filteredDetailedList: any = []; + blankTable = [1, 2, 3, 4, 5]; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private http_service: LanguageService, + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + ) {} + + ngOnInit() { + this.populateConsumedItems(this.data); + this.fetchLanguageResponse(); + } + + ngOnDestroy(): void { + //Called once, before the instance is destroyed. + //Add 'implements OnDestroy' to the class. + this.data = ''; + } + populateConsumedItems(data: any) { + if (data && data.consumptionItem && data.consumptionDetails) { + this._detailedList = data.consumptionItem; + this._filteredDetailedList = data.consumptionItem; + } + } + + filterDetails(filterTerm: string) { + console.log(filterTerm); + if (!filterTerm) this._filteredDetailedList = this._detailedList; + else { + this._filteredDetailedList = []; + this._detailedList.forEach((item: any) => { + for (const key in item) { + if (key == 'batchNo' || key == 'itemName' || key == 'quantity') { + const value: string = '' + item[key]; + if (value.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0) { + this._filteredDetailedList.push(item); + break; + } + } + } + }); + } + } + print() { + this.closeViewModal(); + } + + closeViewModal() { + const modalresult = Object.assign({ print: true }); + this.dialogRef.close(modalresult); + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.css b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.css new file mode 100644 index 0000000..e76b2d5 --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.css @@ -0,0 +1,29 @@ +.mdIcon { + vertical-align: text-bottom; +} + +.input-full-width { + width: 100%; +} + +.box { + height: 60px; +} + +.back-btn-container { + margin: -26px 15px 15px; +} + +.previous-btn { + margin: 5px 0px; +} + +.m-b-40 { + margin-bottom: 40px !important; +} + +@media screen and (max-width: 768px) { + .previous-btn { + width: 100%; + } +} diff --git a/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.html b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.html new file mode 100644 index 0000000..4274aec --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.html @@ -0,0 +1,172 @@ +
+
+
+

{{ currentLanguageSet?.inventory?.previousStoreConsumption }}

+
+
+ + + + + + +
+
+ + + + + + + {{ currentLanguageSet?.inventory?.toDateCannotBeBeforeFromDate }} +
+
+ +
+
+ +
+
+ + +
+
+ + + search + +
+
+ +
+
+
+ +
+ +
+
+
+
+
+
diff --git a/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.spec.ts b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.spec.ts new file mode 100644 index 0000000..0aef067 --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewStoreSelfConsumptionComponent } from './view-store-self-consumption.component'; + +describe('ViewStoreSelfConsumptionComponent', () => { + let component: ViewStoreSelfConsumptionComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewStoreSelfConsumptionComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewStoreSelfConsumptionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.ts b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.ts new file mode 100644 index 0000000..d8df304 --- /dev/null +++ b/src/app/app-modules/inventory/store-self-consumption/view-store-self-consumption/view-store-self-consumption.component.ts @@ -0,0 +1,322 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Component, + OnInit, + HostListener, + ViewChild, + DoCheck, +} from '@angular/core'; +import { Location } from '@angular/common'; +import { InventoryService } from '../../shared/service/inventory.service'; +import { DataStorageService } from './../../shared/service/data-storage.service'; +import * as moment from 'moment'; +import { Router } from '@angular/router'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { ViewStoreSelfConsumptionDetailsComponent } from './view-store-self-consumption-details/view-store-self-consumption-details.component'; + +@Component({ + selector: 'app-view-store-self-consumption', + templateUrl: './view-store-self-consumption.component.html', + styleUrls: ['./view-store-self-consumption.component.css'], +}) +export class ViewStoreSelfConsumptionComponent implements OnInit, DoCheck { + _minDate: any; + _today: any; + + _dateRange: Date[] = []; + _dateRangePrevious: Date[] = []; + + _consumptionList: any = []; + _filteredConsumptionList: any = []; + blankTable = [1, 2, 3, 4, 5]; + filterTerm: any; + searched = false; + currentLanguageSet: any; + languageComponent!: SetLanguageComponent; + + constructor( + private location: Location, + private inventoryService: InventoryService, + private dataStorageService: DataStorageService, + private http_service: LanguageService, + private dialog: MatDialog, + private router: Router, + ) {} + + ngOnInit() { + this.setDateDefault(); + this.fetchLanguageResponse(); + this.getPastConsumptions(); + } + + setDateDefault() { + this._today = new Date(); + this._minDate = new Date(); + this._minDate.setFullYear(this._today.getFullYear() - 1); + this._dateRange[0] = this._today; + this._dateRange[1] = this._today; + + // const dateFrom = new Date(); + // dateFrom.setDate(dateFrom.getDate() - 30); + + // const dateTo = new Date(); + // dateTo.setDate(dateTo.getDate() + 1); + + // this._dateRange = [dateFrom, dateTo]; + console.log(this._dateRange, 'dateRange'); + } + + getPastConsumptions() { + const obj = this.getViewServiceObject(); + this.inventoryService.viewSelfConsumption(obj).subscribe((res) => { + this.searched = true; + this.loadConsumption(res); + }); + } + preventTyping(e: any) { + if (e.keyCode === 9) { + return true; + } else { + return false; + } + } + + getViewServiceObject() { + const startDate: Date = new Date(this._dateRange[0]); + startDate.setHours(0); + startDate.setMinutes(0); + startDate.setSeconds(0); + startDate.setMilliseconds(0); + + const endDate: Date = new Date(this._dateRange[1]); + endDate.setHours(23); + endDate.setMinutes(59); + endDate.setSeconds(59); + endDate.setMilliseconds(0); + + return { + facilityID: localStorage.getItem('facilityID'), + fromDate: new Date( + startDate.valueOf() - 1 * startDate.getTimezoneOffset() * 60 * 1000, + ), + toDate: new Date( + endDate.valueOf() - 1 * endDate.getTimezoneOffset() * 60 * 1000, + ), + }; + } + + updateDate() { + // if (this._dateRange !== this._dateRangePrevious) { + // this._dateRangePrevious = this._dateRange; + // console.log(JSON.stringify(this._dateRange, null, 4), 'callservice'); + this.getPastConsumptions(); + + // } + } + + loadConsumption(consumptionObject: any) { + console.log(consumptionObject); + // if (consumptionObject) { + // consumptionObject.forEach(element => { + // element.createdDate = moment(element.createdDate).format('DD-MM-YYYY HH:mm A ') || 'Not Available' + + // }); + // } + this._consumptionList = consumptionObject; + this._filteredConsumptionList = consumptionObject; + this.filterTerm = ''; + } + + filterConsumptionList(searchTerm: string) { + if (!searchTerm) this._filteredConsumptionList = this._consumptionList; + else { + this._filteredConsumptionList = []; + this._consumptionList.forEach((item: any) => { + for (const key in item) { + if ( + key == 'consumptionID' || + key == 'refNo' || + key == 'reason' || + key == 'createdBy' + ) { + const value: string = '' + item[key]; + if (value.toLowerCase().indexOf(searchTerm.toLowerCase()) >= 0) { + this._filteredConsumptionList.push(item); + break; + } + } + } + }); + } + } + + loadConsumptionDetails(consumption: any) { + if (consumption && consumption.consumptionID) { + this.inventoryService + .getParticularConsumption(consumption.consumptionID) + .subscribe((res) => this.popOutConsumption(consumption, res)); + } + } + + popOutConsumption(consumptionDetails: any, consumptionResponse: any) { + if (consumptionResponse) { + const mdDialogRef: MatDialogRef = + this.dialog.open(ViewStoreSelfConsumptionDetailsComponent, { + // height: '90%', + width: '80%', + panelClass: 'fit-screen', + data: { + consumptionDetails: consumptionDetails, + consumptionItem: consumptionResponse, + }, + disableClose: false, + }); + mdDialogRef.afterClosed().subscribe((result) => { + if (result) { + if (result.print != null && result.print == true) { + if (result.print) { + const printableData = this.createPrintableData( + consumptionDetails, + consumptionResponse, + ); + this.dataStorageService.selfConsumption = printableData; + const uRL = 'selfConsumption'; + this.router.navigate(['/inventory/dynamicPrint/', uRL]); + } + } + } + }); + } + } + + createPrintableData(consumptionDetails: any, consumptionResponse: any) { + const facilityDetailStorage: any = localStorage.getItem('facilityDetail'); + const facilityDetail = JSON.parse(facilityDetailStorage); + const facilityName = facilityDetail.facilityName; + const printableData: any = []; + let i = 0; + consumptionResponse.forEach((batch: any) => { + i = i + 1; + const consumedBatch = { + sNo: i, + itemName: batch.itemName, + batchNo: batch.batchNo, + expiryDate: moment(batch.expiryDate).format('DD-MM-YYYY'), + qod: batch.quantity, + }; + printableData.push(consumedBatch); + }); + console.log( + 'consumptionDetails', + JSON.stringify(consumptionDetails, null, 4), + ); + const consumptionDetail = Object.assign( + { + facilityName: facilityName, + createDate: moment(consumptionDetails.createdDate).format('DD-MM-YYYY'), + }, + consumptionDetails, + ); + console.log('consumptionResponse', JSON.stringify(printableData, null, 4)); + const consumedItem = Object.assign( + {}, + { title: this.title }, + { headerColumn: this.headerColumn }, + { headerDetail: consumptionDetail }, + { columns: this.columns }, + { printableData: printableData }, + ); + return consumedItem; + } + + goBack() { + this.location.back(); + } + title = { + modalTitle: '', + headerTitle: 'Consumed Detail', + tableTitle: '', + }; + columns = [ + { + keyName: 'sNo', + columnName: 'S No.', + }, + { + keyName: 'itemName', + columnName: 'Item Name', + }, + { + keyName: 'batchNo', + columnName: 'Batch No', + }, + { + keyName: 'expiryDate', + columnName: 'Expiry Date', + }, + { + keyName: 'qod', + columnName: 'Qty dispensed', + }, + ]; + headerColumn = [ + { + columnName: 'Consumption ID :', + keyName: 'consumptionID', + }, + { + columnName: 'Facility ID :', + keyName: 'facilityID', + }, + { + columnName: 'Reference No :', + keyName: 'refNo', + }, + { + columnName: 'Reason :', + keyName: 'reason', + }, + { + columnName: 'Created By :', + keyName: 'createdBy', + }, + { + columnName: 'Created Date :', + keyName: 'createDate', + }, + ]; + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.css b/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.css new file mode 100644 index 0000000..6e1906f --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.css @@ -0,0 +1,74 @@ +.input-full-width { + width: 100%; +} + +.mat-form-field { + line-height: unset; +} + +.m-b-40 { + margin-bottom: 40px; +} + +.m-r-5 { + margin-right: 5px; +} + +.icon-remove { + margin: 16px; +} + +.vertical-align-middle { + vertical-align: middle; +} + +.input-datepicker { + padding: 5px 8px; +} + +.search-btn { + cursor: pointer; +} + +.button-full-width { + margin-left: 5px; +} + +@media screen and (max-width: 768px) { + .button-full-width { + width: 100%; + margin-top: 5px; + /* height: 50px; */ + } +} + + +.mat-select-placeholder { + white-space: nowrap; + text-overflow: ellipsis; +} + +.mat-form-field-placeholder { + white-space: nowrap; + text-overflow: ellipsis; +} + +.box { + height: 60px; +} + +.width5 { + width: 5%; +} + +.width10 { + width: 10%; +} + +.width15 { + width: 15%; +} + +.width20 { + width: 20%; +} diff --git a/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.html b/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.html new file mode 100644 index 0000000..1008898 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.html @@ -0,0 +1,419 @@ +
+
+
+

{{ currentLanguageSet?.inventory?.storeAdjustment }}

+
+ +
+ + + +
+
+
+ E-aushadhi stock last updated on - + {{ + lastUpdatedStockDate + ? (lastUpdatedStockDate | date: "dd/MM/yyyy HH:mm") + : "NA" + }} +
+
+
+
+
+
+ + + + + +
+ +
+ + + +
+
+ +
+
+ +
+ + + + + {{ + currentLanguageSet?.inventory?.index + }} + {{ + i + 1 + }} + + + + + {{ + currentLanguageSet?.inventory?.itemName + }} + + + + search + + + + + + + {{ + currentLanguageSet?.itemDispense?.batchID + }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{ currentLanguageSet?.inventory?.quantityOnHand }} + + {{ item?.quantityInHand }} + + {{ currentLanguageSet?.inventory?.adjustmentType }} + + {{ item?.adjustmentType }} + + {{ currentLanguageSet?.inventory?.adjustmentQuantity }} + + + + + + + + + + {{ currentLanguageSet?.inventory?.qOHAfterAdjustment }} + + {{ item?.qohAfterAdjustment }} + + {{ currentLanguageSet?.inventory?.reason }} + + + + + + {{ currentLanguageSet?.inventory?.action }} + + delete +
+ +
+
+
+
+
+ +
+
+ + + + +
+
+
+
diff --git a/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.spec.ts b/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.spec.ts new file mode 100644 index 0000000..7757403 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { StoreStockAdjustmentComponent } from './store-stock-adjustment.component'; + +describe('StoreStockAdjustmentComponent', () => { + let component: StoreStockAdjustmentComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [StoreStockAdjustmentComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StoreStockAdjustmentComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.ts b/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.ts new file mode 100644 index 0000000..9f53258 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/store-stock-adjustment.component.ts @@ -0,0 +1,443 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, DoCheck, OnInit } from '@angular/core'; +import { + FormBuilder, + FormGroup, + FormArray, + AbstractControl, +} from '@angular/forms'; +import { Router, ActivatedRoute } from '@angular/router'; +import { Location } from '@angular/common'; +import { SetLanguageComponent } from '../../core/components/set-language.component'; +import { LanguageService } from '../../core/services/language.service'; +import { ConfirmationService } from '../../core/services/confirmation.service'; +import { InventoryService } from '../shared/service/inventory.service'; +import { MatTableDataSource } from '@angular/material/table'; + +@Component({ + selector: 'app-store-stock-adjustment', + templateUrl: './store-stock-adjustment.component.html', + styleUrls: ['./store-stock-adjustment.component.css'], +}) +export class StoreStockAdjustmentComponent implements OnInit, DoCheck { + storeStockAdjustmentForm!: FormGroup; + adjustmentTypeList = ['Issue', 'Receipt']; + draftID: any; + + editMode = false; + currentLanguageSet: any; + languageComponent!: SetLanguageComponent; + isMainStore = false; + lastUpdatedStockDate: any; + // dataSource: MatTableDataSource = new MatTableDataSource([]); + dataSource!: MatTableDataSource; + + displayedColumns: string[] = [ + 'itemName', + 'batchID', + 'quantityOnHand', + 'adjustmentType', + 'adjustmentQuantity', + 'qOHAfterAdjustment', + 'reason', + ]; + + constructor( + private fb: FormBuilder, + private router: Router, + private location: Location, + private http_service: LanguageService, + private route: ActivatedRoute, + private confirmationService: ConfirmationService, + private inventoryService: InventoryService, + ) {} + + ngOnInit() { + this.storeStockAdjustmentForm = this.createStoreStockAdjustmentForm(); + this.draftID = this.route.snapshot.paramMap.get('draftID'); + this.fetchLanguageResponse(); + + if (this.draftID) { + this.editMode = true; + this.getStockAdjustmentDraftDetails(this.draftID); + } else { + this.editMode = false; + } + + const isMainStore: any = localStorage.getItem('facilityDetail'); + this.isMainStore = JSON.parse(isMainStore).isMainFacility; + this.showLastUpdatedStockLog(); + } + + createStoreStockAdjustmentForm() { + return this.fb.group({ + refNo: null, + adjustmentDate: { value: new Date(), disabled: true }, + stockAdjustmentDraftID: null, + draftDesc: null, + stockAdjustmentList: this.fb.array([this.initStockAdjustmentList()]), + }); + } + + initStockAdjustmentList() { + return this.fb.group({ + itemStockEntryID: null, + itemID: null, + itemName: null, + batchID: null, + quantityInHand: null, + adjustmentType: null, + adjustedQuantity: null, + qohAfterAdjustment: null, + reason: null, + deleted: false, + stockAdjustmentDraftID: null, + sADraftItemMapID: null, + }); + } + + stroreStockTableData(): AbstractControl[] { + return ( + this.storeStockAdjustmentForm.get('stockAdjustmentList') as FormArray + ).controls; + } + // addToStockAdjustmentList() { + // const stockAdjustmentFormArray = this.storeStockAdjustmentForm.get('stockAdjustmentList') as FormArray; + // stockAdjustmentFormArray.push(this.initStockAdjustmentList()); + // this.dataSource.data = stockAdjustmentFormArray.value; + // } + + addToStockAdjustmentList() { + const stockAdjustmentFormArray = this.storeStockAdjustmentForm.controls[ + 'stockAdjustmentList' + ] as FormArray; + stockAdjustmentFormArray.push(this.initStockAdjustmentList()); + } + + removeFromStockAdjustmentList(index: any, stockForm?: FormGroup) { + const stockAdjustmentFormArray = this.storeStockAdjustmentForm.controls[ + 'stockAdjustmentList' + ] as FormArray; + + if (stockAdjustmentFormArray.length > 1) { + stockAdjustmentFormArray.removeAt(index); + } else { + if (stockForm) { + stockForm.reset(); + stockForm.controls['itemName'].enable(); + } + } + } + // removeFromStockAdjustmentList(index: any) { + // const stockAdjustmentFormArray = this.storeStockAdjustmentForm.get('stockAdjustmentList') as FormArray; + // stockAdjustmentFormArray.removeAt(index); + // this.dataSource.data = stockAdjustmentFormArray.value; + // } + + submitStockAdjustmentDraft(storeStockAdjustmentForm: FormGroup) { + const storeStockAdjustment = JSON.parse( + JSON.stringify(storeStockAdjustmentForm.value), + ); + + const otherDetails = { + createdBy: localStorage.getItem('username'), + modifiedBy: localStorage.getItem('username'), + providerServiceMapID: localStorage.getItem('providerServiceID'), + facilityID: localStorage.getItem('facilityID'), + vanID: localStorage.getItem('vanID'), + parkingPlaceID: localStorage.getItem('parkingPlaceID'), + }; + + const stockAdjustmentItemDraft = + storeStockAdjustment.stockAdjustmentList.map((item: any) => { + item.isAdded = item.adjustmentType == 'Receipt' ? true : false; + item.adjustedQuantity = item.adjustedQuantity + ? +item.adjustedQuantity + : 0; + item.adjustmentType = undefined; + item = Object.assign({}, item, otherDetails); + return item; + }); + + const temp = Object.assign({}, storeStockAdjustment, otherDetails, { + stockAdjustmentItemDraft: stockAdjustmentItemDraft, + stockAdjustmentList: undefined, + }); + + this.confirmationService + .provideDraftDescription( + this.currentLanguageSet.inventory.draftDescription, + temp.draftDesc, + ) + .subscribe((draftDesc) => { + temp.draftDesc = draftDesc; + + this.inventoryService + .saveStockAdjustmentDraft(temp) + .subscribe((response) => { + if (temp.stockAdjustmentDraftID) { + this.confirmationService.alert( + this.currentLanguageSet.inventory.updatedSuccessfully, + 'success', + ); + // this.getStockAdjustmentDraftDetails(this.draftID); + this.storeStockAdjustmentForm.reset({ + adjustmentDate: new Date(), + }); + this.location.back(); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.savedsuccessfully, + 'success', + ); + this.storeStockAdjustmentForm.reset(); + this.storeStockAdjustmentForm.reset({ + adjustmentDate: new Date(), + }); + this.resetStockAdjustmentFormArray(); + } + }); + }); + } + + submitStockAdjustmentFinal(storeStockAdjustmentForm: FormGroup) { + const storeStockAdjustment = JSON.parse( + JSON.stringify(storeStockAdjustmentForm.value), + ); + + const otherDetails = { + createdBy: localStorage.getItem('username'), + providerServiceMapID: localStorage.getItem('providerServiceID'), + facilityID: localStorage.getItem('facilityID'), + vanID: localStorage.getItem('vanID'), + parkingPlaceID: localStorage.getItem('parkingPlaceID'), + }; + + const stockAdjustmentItemDraft = + storeStockAdjustment.stockAdjustmentList.map((item: any) => { + item.isAdded = item.adjustmentType == 'Receipt' ? true : false; + item.adjustedQuantity = item.adjustedQuantity + ? +item.adjustedQuantity + : 0; + item.adjustmentType = undefined; + item = Object.assign({}, item, otherDetails); + return item; + }); + + const temp = Object.assign({}, storeStockAdjustment, otherDetails, { + stockAdjustmentItem: stockAdjustmentItemDraft, + stockAdjustmentList: undefined, + }); + + this.inventoryService.saveStockAdjustment(temp).subscribe((response) => { + if (temp.stockAdjustmentDraftID) { + this.confirmationService.alert( + this.currentLanguageSet.inventory.savedsuccessfully, + 'success', + ); + // this.getStockAdjustmentDraftDetails(this.draftID); + this.storeStockAdjustmentForm.reset({ adjustmentDate: new Date() }); + this.location.back(); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.savedsuccessfully, + 'success', + ); + this.storeStockAdjustmentForm.reset(); + this.storeStockAdjustmentForm.reset({ adjustmentDate: new Date() }); + this.resetStockAdjustmentFormArray(); + } + }); + } + + // getStockAdjustmentDraftDetails(draftID: any) { + // const temp = parseInt(draftID); + // this.inventoryService + // .getStockAdjustmentDraftDetails(temp) + // .subscribe((response) => { + // const stockAdjusmentList = response.stockAdjustmentItemDraftEdit; + // const stockAdjustmentFormArray = this.storeStockAdjustmentForm.controls[ + // 'stockAdjustmentList' + // ] as FormArray; + + // for (let i = 0; i < stockAdjusmentList.length; i++) { + // stockAdjusmentList[i].adjustmentType = stockAdjusmentList[i].isAdded + // ? 'Receipt' + // : 'Issue'; + // stockAdjusmentList[i].stockAdjustmentDraftID = + // response.stockAdjustmentDraftID; + // stockAdjustmentFormArray.at(i).patchValue(stockAdjusmentList[i]); + // (stockAdjustmentFormArray.at(i)).controls[ + // 'itemName' + // ].disable(); + // this.calculateQOHAfterAdjustment( + // stockAdjustmentFormArray.at(i) as FormGroup, + // ); + // if (stockAdjustmentFormArray.length < stockAdjusmentList.length) + // this.addToStockAdjustmentList(); + // } + + // this.storeStockAdjustmentForm.patchValue({ + // adjustmentDate: new Date(response.createdDate), + // refNo: response.refNo, + // stockAdjustmentDraftID: response.stockAdjustmentDraftID, + // draftDesc: response.draftDesc, + // }); + // }); + // } + + getStockAdjustmentDraftDetails(draftID: any) { + const temp = parseInt(draftID); + this.inventoryService + .getStockAdjustmentDraftDetails(temp) + .subscribe((response) => { + const stockAdjustmentList = response.stockAdjustmentItemDraftEdit; + + // Clear the existing data in the MatTableDataSource + this.dataSource.data = []; + + for (let i = 0; i < stockAdjustmentList.length; i++) { + stockAdjustmentList[i].adjustmentType = stockAdjustmentList[i].isAdded + ? 'Receipt' + : 'Issue'; + stockAdjustmentList[i].stockAdjustmentDraftID = + response.stockAdjustmentDraftID; + this.dataSource.data.push(stockAdjustmentList[i]); + } + + // Assign the modified data to MatTableDataSource + this.dataSource.data = this.dataSource.data.slice(); + + this.storeStockAdjustmentForm.patchValue({ + adjustmentDate: new Date(response.createdDate), + refNo: response.refNo, + stockAdjustmentDraftID: response.stockAdjustmentDraftID, + draftDesc: response.draftDesc, + }); + }); + } + + calculateQOHAfterAdjustment(stockForm: FormGroup) { + const qoh = parseInt(stockForm.value.quantityInHand) || 0; + const adjustedQuantity = parseInt(stockForm.value.adjustedQuantity) || 0; + const adjustmentType = stockForm.value.adjustmentType; + + if (adjustmentType == 'Receipt') { + if (qoh >= 0 && adjustedQuantity >= 0) + stockForm.patchValue({ qohAfterAdjustment: qoh + adjustedQuantity }); + } else if (adjustmentType == 'Issue') { + if (qoh > 0 && adjustedQuantity >= 0 && adjustedQuantity <= qoh) + stockForm.patchValue({ qohAfterAdjustment: qoh - adjustedQuantity }); + } + } + + // resetStockAdjustmentFormArray() { + // const stockAdjustmentFormArray = this.storeStockAdjustmentForm.controls[ + // 'stockAdjustmentList' + // ] as FormArray; + // stockAdjustmentFormArray.controls.length = 0; + // this.addToStockAdjustmentList(); + // } + resetStockAdjustmentFormArray() { + const stockAdjustmentFormArray = this.storeStockAdjustmentForm.get( + 'stockAdjustmentList', + ) as FormArray; + stockAdjustmentFormArray.controls.length = 0; + this.addToStockAdjustmentList(); + } + + // resetStoreStockAdjustmentForm() { + // this.resetStockAdjustmentFormArray(); + // this.storeStockAdjustmentForm.reset({ adjustmentDate: new Date() }); + // } + + resetStoreStockAdjustmentForm() { + this.resetStockAdjustmentFormArray(); + this.storeStockAdjustmentForm.reset({ adjustmentDate: new Date() }); + } + + goBack() { + this.location.back(); + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- + + addEAushadhiStock() { + const reqObj = { + facilityID: localStorage.getItem('facilityID'), + }; + this.inventoryService.addEAushadhiItemsToAmrit(reqObj).subscribe( + (response) => { + if ( + response != null && + response !== undefined && + response.statusCode === 200 + ) { + this.confirmationService.alert(response.data.response, 'success'); + this.showLastUpdatedStockLog(); + } else { + this.confirmationService.alert(response.errorMessage, 'error'); + } + }, + (err) => { + this.confirmationService.alert(err, 'error'); + }, + ); + } + showLastUpdatedStockLog() { + const reqObj = { + facilityID: localStorage.getItem('facilityID'), + }; + this.inventoryService.showLastUpdatedStockLogs(reqObj).subscribe( + (logResponse) => { + console.log('response stock', logResponse); + if ( + logResponse != null && + logResponse !== undefined && + logResponse.statusCode === 200 + ) { + if (logResponse.data.lastSuccessDate) + this.lastUpdatedStockDate = new Date( + logResponse.data.lastSuccessDate, + ); + else this.lastUpdatedStockDate = null; + } else { + this.confirmationService.alert(logResponse.errorMessage, 'error'); + } + }, + (err) => { + this.confirmationService.alert(err, 'error'); + }, + ); + } +} diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.css b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.css new file mode 100644 index 0000000..0e0856d --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.css @@ -0,0 +1,34 @@ +#head { + background: #0277bd; + color: white; + height: 51px; + width: 100%; + padding: 20px; +} + +#dialog_head { + margin: 0; + padding: 0; +} + +#cross { + cursor: pointer; +} + +#dialog_row { + padding: 15px; +} + +.h5_bold { + font-weight: bold; + display: inline-block; +} + +.m-b-15 { + margin-bottom: 15px; +} + +.scrolling-content { + max-height: 75vh; + overflow: auto; +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.html b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.html new file mode 100644 index 0000000..4831955 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.html @@ -0,0 +1,121 @@ + + +
+
+ + +
+
+ + + search + +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.spec.ts b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.spec.ts new file mode 100644 index 0000000..cdd3f7c --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewStockAdjustmentDetailsComponent } from './view-stock-adjustment-details.component'; + +describe('ViewStockAdjustmentDetailsComponent', () => { + let component: ViewStockAdjustmentDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewStockAdjustmentDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewStockAdjustmentDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.ts b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.ts new file mode 100644 index 0000000..9c199a4 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-details/view-stock-adjustment-details.component.ts @@ -0,0 +1,119 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { InventoryService } from '../../shared/service/inventory.service'; + +@Component({ + selector: 'app-view-stock-adjustment-details', + templateUrl: './view-stock-adjustment-details.component.html', + styleUrls: ['./view-stock-adjustment-details.component.css'], +}) +export class ViewStockAdjustmentDetailsComponent implements OnInit, DoCheck { + filterTerm!: string; + + stock: any; + adjustmentList: any = []; + filteredAdjustmentList: any = []; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private http_service: LanguageService, + @Inject(MAT_DIALOG_DATA) public input: any, + public dialogRef: MatDialogRef, + private inventoryService: InventoryService, + ) {} + + ngOnInit() { + this.fetchLanguageResponse(); + if (this.input && this.input.adjustmentID) { + this.getStockAdjustmentDetails(this.input.adjustmentID); + } + } + + getStockAdjustmentDetails(adjustmentID: any) { + const temp = parseInt(adjustmentID); + this.inventoryService + .getStockAdjustmentDetails(temp) + .subscribe((response) => { + this.stock = response; + this.adjustmentList = response.stockAdjustmentItemDraftEdit.slice(); + this.filteredAdjustmentList = + response.stockAdjustmentItemDraftEdit.slice(); + }); + } + + filterDetails(filterTerm: any) { + if (!filterTerm) this.filteredAdjustmentList = this.adjustmentList.slice(); + else { + this.filteredAdjustmentList = []; + this.adjustmentList.forEach((item: any) => { + for (const key in item) { + if ( + key == 'itemName' || + key == 'batchID' || + key == 'reason' || + key == 'quantityInHand' || + key == 'adjustedQuantity' || + key == 'isAdded' + ) { + const value: string = '' + item[key]; + if (key == 'isAdded') { + if ( + 'receipt'.indexOf(filterTerm.toLowerCase()) >= 0 && + item[key] + ) { + this.filteredAdjustmentList.push(item); + break; + } else if ( + 'issue'.indexOf(filterTerm.toLowerCase()) >= 0 && + !item[key] + ) { + this.filteredAdjustmentList.push(item); + break; + } + } + if (value.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0) { + this.filteredAdjustmentList.push(item); + break; + } + } + } + }); + } + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.css b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.css new file mode 100644 index 0000000..ec9f52f --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.css @@ -0,0 +1,38 @@ +#head { + background: #0277bd; + color: white; + height: 51px; + width: 100%; + padding: 20px; +} + +#dialog_head { + margin: 0; + padding: 0; +} + +#cross { + cursor: pointer; +} + +#dialog_row { + padding: 15px; +} + +.h5_bold { + font-weight: bold; + display: inline-block; +} + +.m-b-15 { + margin-bottom: 15px; +} + +.scrolling-content { + max-height: 75vh; + overflow: auto; +} + +.box { + /* height: 60px; */ +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.html b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.html new file mode 100644 index 0000000..5cd1bd0 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.html @@ -0,0 +1,125 @@ + + +
+
+ + +
+
+ + + search + +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.spec.ts b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.spec.ts new file mode 100644 index 0000000..d5826e7 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewStockAdjustmentDraftDetailsComponent } from './view-stock-adjustment-draft-details.component'; + +describe('ViewStockAdjustmentDraftDetailsComponent', () => { + let component: ViewStockAdjustmentDraftDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewStockAdjustmentDraftDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewStockAdjustmentDraftDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.ts b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.ts new file mode 100644 index 0000000..cb6321e --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component.ts @@ -0,0 +1,121 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, DoCheck } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { InventoryService } from '../../shared/service/inventory.service'; + +@Component({ + selector: 'app-view-stock-adjustment-draft-details', + templateUrl: './view-stock-adjustment-draft-details.component.html', + styleUrls: ['./view-stock-adjustment-draft-details.component.css'], +}) +export class ViewStockAdjustmentDraftDetailsComponent + implements OnInit, DoCheck +{ + filterTerm!: string; + + stock: any; + adjustmentList: any = []; + filteredAdjustmentList: any = []; + currentLanguageSet: any; + languageComponent!: SetLanguageComponent; + + constructor( + private http_service: LanguageService, + @Inject(MAT_DIALOG_DATA) public input: any, + public dialogRef: MatDialogRef, + private inventoryService: InventoryService, + ) {} + + ngOnInit() { + this.fetchLanguageResponse(); + if (this.input && this.input.adjustmentID) { + this.getStockAdjustmentDetails(this.input.adjustmentID); + } + } + + getStockAdjustmentDetails(adjustmentID: any) { + const temp = parseInt(adjustmentID); + this.inventoryService + .getStockAdjustmentDraftDetails(temp) + .subscribe((response) => { + this.stock = response; + this.adjustmentList = response.stockAdjustmentItemDraftEdit.slice(); + this.filteredAdjustmentList = + response.stockAdjustmentItemDraftEdit.slice(); + }); + } + + filterDetails(filterTerm: any) { + if (!filterTerm) this.filteredAdjustmentList = this.adjustmentList.slice(); + else { + this.filteredAdjustmentList = []; + this.adjustmentList.forEach((item: any) => { + for (const key in item) { + if ( + key == 'itemName' || + key == 'batchID' || + key == 'reason' || + key == 'quantityInHand' || + key == 'adjustedQuantity' || + key == 'isAdded' + ) { + const value: string = '' + item[key]; + if (key == 'isAdded') { + if ( + 'receipt'.indexOf(filterTerm.toLowerCase()) >= 0 && + item[key] + ) { + this.filteredAdjustmentList.push(item); + break; + } else if ( + 'issue'.indexOf(filterTerm.toLowerCase()) >= 0 && + !item[key] + ) { + this.filteredAdjustmentList.push(item); + break; + } + } + if (value.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0) { + this.filteredAdjustmentList.push(item); + break; + } + } + } + }); + } + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.css b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.css new file mode 100644 index 0000000..44f97a7 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.css @@ -0,0 +1,30 @@ +.mdIcon { + vertical-align: text-bottom; +} + +.input-full-width { + width: 100%; +} + +.box { + height: 60px; +} + +.back-btn-container { + margin: -26px 15px 15px; +} + +.previous-btn { + margin: 5px 0px; +} + +.m-b-40 { + margin-bottom: 40px !important; +} + +@media screen and (max-width: 768px) { + .previous-btn { + width: 100%; + } +} + diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.html b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.html new file mode 100644 index 0000000..1f40685 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.html @@ -0,0 +1,163 @@ +
+
+
+

{{ currentLanguageSet?.inventory?.previousStoreAdjustmentDraft }}

+
+
+ + + + + + +
+
+ + + + + + + {{ currentLanguageSet?.inventory?.toDateCannotBeBeforeFromDate }} +
+
+ +
+
+ +
+
+ + +
+
+ + + search + +
+
+
+ +
+
+
+
+ +
+ +
+
+
+
+
+
diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.spec.ts b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.spec.ts new file mode 100644 index 0000000..9052727 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewStoreStockAdjustmentDraftComponent } from './view-store-stock-adjustment-draft.component'; + +describe('ViewStoreStockAdjustmentDraftComponent', () => { + let component: ViewStoreStockAdjustmentDraftComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewStoreStockAdjustmentDraftComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewStoreStockAdjustmentDraftComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.ts b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.ts new file mode 100644 index 0000000..bbc27ec --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment-draft/view-store-stock-adjustment-draft.component.ts @@ -0,0 +1,268 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, DoCheck, OnInit } from '@angular/core'; +import { Location } from '@angular/common'; +import { Router } from '@angular/router'; +import * as moment from 'moment'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { MatDialog } from '@angular/material/dialog'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { DataStorageService } from '../../shared/service/data-storage.service'; +import { InventoryService } from '../../shared/service/inventory.service'; +import { ViewStockAdjustmentDraftDetailsComponent } from '../view-stock-adjustment-draft-details/view-stock-adjustment-draft-details.component'; + +@Component({ + selector: 'app-view-store-stock-adjustment-draft', + templateUrl: './view-store-stock-adjustment-draft.component.html', + styleUrls: ['./view-store-stock-adjustment-draft.component.css'], +}) +export class ViewStoreStockAdjustmentDraftComponent implements OnInit, DoCheck { + today: any; + fromDate: any; + toDate: any; + stockAdjustmentList: any = []; + + filterTerm: any; + filteredStockAdjustmentList: any = []; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private location: Location, + private router: Router, + private dialog: MatDialog, + private http_service: LanguageService, + private dataStorageService: DataStorageService, + private inventoryService: InventoryService, + ) {} + + ngOnInit() { + this.fromDate = new Date(); + this.fromDate.setHours(0, 0, 0, 0); + this.toDate = new Date(); + + this.today = new Date(); + this.viewRecords(); + this.fetchLanguageResponse(); + } + + viewRecords() { + const startDate: Date = new Date(this.fromDate); + startDate.setHours(0); + startDate.setMinutes(0); + startDate.setSeconds(0); + startDate.setMilliseconds(0); + + const endDate: Date = new Date(this.toDate); + endDate.setHours(23); + endDate.setMinutes(59); + endDate.setSeconds(59); + endDate.setMilliseconds(0); + + const temp = { + fromDate: new Date( + startDate.valueOf() - 1 * startDate.getTimezoneOffset() * 60 * 1000, + ), + toDate: new Date( + endDate.valueOf() - 1 * endDate.getTimezoneOffset() * 60 * 1000, + ), + facilityID: localStorage.getItem('facilityID') + ? +localStorage.getItem('facilityID')! + : undefined, + }; + + this.inventoryService + .getStockAdjustmentDraftList(temp) + .subscribe((response) => { + this.stockAdjustmentList = response.slice(); + this.filteredStockAdjustmentList = response.slice(); + }); + } + + filterStockAdjustmentList(filterTerm: any) { + if (!filterTerm) + this.filteredStockAdjustmentList = this.stockAdjustmentList.slice(); + else { + this.filteredStockAdjustmentList = []; + this.stockAdjustmentList.forEach((item: any) => { + for (const key in item) { + if ( + key == 'stockAdjustmentDraftID' || + key == 'refNo' || + key == 'draftDesc' || + key == 'createdBy' + ) { + const value: string = '' + item[key]; + if (value.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0) { + this.filteredStockAdjustmentList.push(item); + break; + } + } + } + }); + } + } + + viewStockAdjustmentDraftDetails(draftID: any) { + this.dialog + .open(ViewStockAdjustmentDraftDetailsComponent, { + width: '80%', + panelClass: 'fit-screen', + data: { + adjustmentID: draftID, + }, + }) + .afterClosed() + .subscribe((response) => { + if (response) { + console.log(response); + const printableData = this.createPrintableData(response); + this.dataStorageService.adjustment = printableData; + const URL = 'adjustment'; + this.router.navigate(['/inventory/dynamicPrint/', URL]); + } + }); + } + + goBack() { + this.location.back(); + } + + goToUpdateAdjustmentDraft(draftID: any) { + this.router.navigate(['inventory/storeStockAdjustment/update', draftID]); + } + createPrintableData(adjustmentDetials: any) { + const facilityDetailStrorage: any = localStorage.getItem('facilityDetail'); + const facilityDetail = JSON.parse(facilityDetailStrorage); + const facilityName = facilityDetail.facilityName; + const adjustedItemList: any = []; + let i = 0; + + adjustmentDetials.stockAdjustmentItemDraftEdit.forEach((stock: any) => { + i = i + 1; + const temp = { + sNo: i, + itemName: stock.itemName, + batchID: stock.batchID, + quantityInHand: stock.quantityInHand, + adjustedQuantity: stock.adjustedQuantity, + adjustmentType: + stock.isAdded != undefined && stock.isAdded ? 'Receipt' : 'Issue', + reason: stock.reason, + }; + adjustedItemList.push(temp); + }); + + const headerDetails = Object.assign( + { + facilityName: facilityName, + createDate: moment(adjustmentDetials.createdDate).format('DD-MM-YYYY'), + }, + adjustmentDetials, + ); + const printableData = Object.assign( + {}, + { title: this.title }, + { headerColumn: this.headerColumn }, + { headerDetail: headerDetails }, + { columns: this.columns }, + { printableData: adjustedItemList }, + ); + return printableData; + } + + title = { + modalTitle: '', + headerTitle: 'Adjustment Detail', + tableTitle: '', + }; + + columns = [ + { + keyName: 'sNo', + columnName: 'S No.', + }, + { + keyName: 'itemName', + columnName: 'Item Name', + }, + { + keyName: 'batchID', + columnName: 'Batch No', + }, + { + keyName: 'quantityInHand', + columnName: 'Quantity on Hand', + }, + { + keyName: 'adjustedQuantity', + columnName: 'Adjusted Quantity', + }, + { + keyName: 'adjustmentType', + columnName: 'Adjustment Type', + }, + { + columnName: 'Reason', + keyName: 'reason', + }, + ]; + + headerColumn = [ + { + columnName: 'Adjustment Draft ID :', + keyName: 'stockAdjustmentDraftID', + }, + { + columnName: 'Facility ID :', + keyName: 'facilityID', + }, + { + columnName: 'Reference No :', + keyName: 'refNo', + }, + { + columnName: 'Draft Description :', + keyName: 'draftDesc', + }, + { + columnName: 'Created By :', + keyName: 'createdBy', + }, + { + columnName: 'Created Date :', + keyName: 'createDate', + }, + ]; + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.css b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.css new file mode 100644 index 0000000..3c5daa4 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.css @@ -0,0 +1,33 @@ +.filterTest { + vertical-align: text-bottom; +} + +.input-full-width { + width: 100%; +} + +.box { + height: 60px; +} + +.back-btn-container { + margin: -26px 15px 15px; +} + +.previous-btn { + margin: 5px 0px; +} + +.m-b-40 { + margin-bottom: 40px !important; +} + +.vertical-align-middle { + vertical-align: middle; +} + +@media screen and (max-width: 768px) { + .previous-btn { + width: 100%; + } +} diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.html b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.html new file mode 100644 index 0000000..fe40bb4 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.html @@ -0,0 +1,163 @@ +
+
+
+

{{ currentLanguageSet?.inventory?.previousStoreAdjustment }}

+
+
+ + + + + +
+
+ + + + + + + {{ currentLanguageSet?.inventory?.toDateCannotBeBeforeFromDate }} +
+
+ +
+
+ +
+
+ + +
+
+ + + search + +
+
+
+ +
+
+
+
+ +
+ +
+
+
+
+
+
diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.spec.ts b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.spec.ts new file mode 100644 index 0000000..d7efc54 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewStoreStockAdjustmentComponent } from './view-store-stock-adjustment.component'; + +describe('ViewStoreStockAdjustmentComponent', () => { + let component: ViewStoreStockAdjustmentComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewStoreStockAdjustmentComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewStoreStockAdjustmentComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.ts b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.ts new file mode 100644 index 0000000..6e2f8f6 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-adjustment/view-store-stock-adjustment/view-store-stock-adjustment.component.ts @@ -0,0 +1,270 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, DoCheck, OnInit } from '@angular/core'; +import { Location } from '@angular/common'; +import { Router } from '@angular/router'; +import * as moment from 'moment'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { MatDialog } from '@angular/material/dialog'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +import { DataStorageService } from '../../shared/service/data-storage.service'; +import { ViewStockAdjustmentDetailsComponent } from '../view-stock-adjustment-details/view-stock-adjustment-details.component'; +import { InventoryService } from '../../shared/service/inventory.service'; + +@Component({ + selector: 'app-view-store-stock-adjustment', + templateUrl: './view-store-stock-adjustment.component.html', + styleUrls: ['./view-store-stock-adjustment.component.css'], +}) +export class ViewStoreStockAdjustmentComponent implements OnInit, DoCheck { + today: any; + fromDate: any; + toDate: any; + stockAdjustmentList: any = []; + _minDate: any; + filterTerm: any; + filteredStockAdjustmentList: any = []; + currentLanguageSet: any; + languageComponent!: SetLanguageComponent; + + constructor( + private location: Location, + private dialog: MatDialog, + private http_service: LanguageService, + private router: Router, + private dataStorageService: DataStorageService, + private inventoryService: InventoryService, + ) {} + + ngOnInit() { + this.fromDate = new Date(); + this.fromDate.setHours(0, 0, 0, 0); + this.toDate = new Date(); + + this.today = new Date(); + this.viewRecords(); + this.fetchLanguageResponse(); + } + + viewRecords() { + const startDate: Date = new Date(this.fromDate); + startDate.setHours(0); + startDate.setMinutes(0); + startDate.setSeconds(0); + startDate.setMilliseconds(0); + + const endDate: Date = new Date(this.toDate); + endDate.setHours(23); + endDate.setMinutes(59); + endDate.setSeconds(59); + endDate.setMilliseconds(0); + + const temp = { + fromDate: new Date( + startDate.valueOf() - 1 * startDate.getTimezoneOffset() * 60 * 1000, + ), + toDate: new Date( + endDate.valueOf() - 1 * endDate.getTimezoneOffset() * 60 * 1000, + ), + facilityID: localStorage.getItem('facilityID') + ? +localStorage.getItem('facilityID')! + : undefined, + }; + + this.inventoryService + .getStockAdjustmentList(temp) + .subscribe((response: any) => { + this.stockAdjustmentList = response.slice(); + this.filteredStockAdjustmentList = response.slice(); + }); + } + + filterStockAdjustmentList(filterTerm: any) { + if (!filterTerm) + this.filteredStockAdjustmentList = this.stockAdjustmentList.slice(); + else { + this.filteredStockAdjustmentList = []; + this.stockAdjustmentList.forEach((item: any) => { + for (const key in item) { + if ( + key == 'stockAdjustmentDraftID' || + key == 'refNo' || + key == 'reason' || + key == 'createdBy' + ) { + const value: string = '' + item[key]; + if (value.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0) { + this.filteredStockAdjustmentList.push(item); + break; + } + } + } + }); + } + } + + viewStockAdjustmentDetails(adjustmentID: any) { + this.dialog + .open(ViewStockAdjustmentDetailsComponent, { + width: '80%', + panelClass: 'fit-screen', + data: { + adjustmentID: adjustmentID, + }, + }) + .afterClosed() + .subscribe((response) => { + if (response) { + const printableData = this.createPrintableData(response); + this.dataStorageService.adjustment = printableData; + const URL = 'adjustment'; + this.router.navigate(['/inventory/dynamicPrint/', URL]); + } + }); + } + + goBack() { + this.location.back(); + } + + goToUpdateAdjustmentDraft(draftID: any) { + this.router.navigate(['inventory/storeStockAdjustment/update', draftID]); + } + + createPrintableData(adjustmentDetials: any) { + const facilityDetailStorage: any = localStorage.getItem('facilityDetail'); + const facilityDetail = JSON.parse(facilityDetailStorage); + const facilityName = facilityDetail.facilityName; + const adjustedItemList: any = []; + let i = 0; + + adjustmentDetials.stockAdjustmentItemDraftEdit.forEach((stock: any) => { + i = i + 1; + const temp = { + sNo: i, + itemName: stock.itemName, + batchID: stock.batchID, + quantityInHand: stock.quantityInHand, + adjustedQuantity: stock.adjustedQuantity, + adjustmentType: + stock.isAdded != undefined && stock.isAdded ? 'Receipt' : 'Issue', + reason: stock.reason, + }; + adjustedItemList.push(temp); + }); + + const headerDetails = Object.assign( + { + facilityName: facilityName, + createDate: moment(adjustmentDetials.createdDate).format('DD-MM-YYYY'), + }, + adjustmentDetials, + ); + const printableData = Object.assign( + {}, + { title: this.title }, + { headerColumn: this.headerColumn }, + { headerDetail: headerDetails }, + { columns: this.columns }, + { printableData: adjustedItemList }, + ); + return printableData; + } + + setDateDefault() { + this.today = new Date(); + this._minDate = new Date(); + this._minDate.setFullYear(this.today.getFullYear() - 1); + } + + title = { + modalTitle: '', + headerTitle: 'Adjustment Detail', + tableTitle: '', + }; + + columns = [ + { + keyName: 'sNo', + columnName: 'S No.', + }, + { + keyName: 'itemName', + columnName: 'Item Name', + }, + { + keyName: 'batchID', + columnName: 'Batch No', + }, + { + keyName: 'quantityInHand', + columnName: 'Quantity on Hand', + }, + { + keyName: 'adjustedQuantity', + columnName: 'Adjusted Quantity', + }, + { + keyName: 'adjustmentType', + columnName: 'Adjustment Type', + }, + { + columnName: 'Reason', + keyName: 'reason', + }, + ]; + + headerColumn = [ + { + columnName: 'Adjustment ID :', + keyName: 'stockAdjustmentID', + }, + { + columnName: 'Facility ID :', + keyName: 'facilityID', + }, + { + columnName: 'Reference No :', + keyName: 'refNo', + }, + { + columnName: 'Created By :', + keyName: 'createdBy', + }, + { + columnName: 'Created Date :', + keyName: 'createDate', + }, + ]; + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.css b/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.css new file mode 100644 index 0000000..6b3ca8f --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.css @@ -0,0 +1,50 @@ +.input-full-width { + width: 100%; +} + +.mat-form-field { + line-height: unset; +} + +.vertical-align-middle { + vertical-align: middle; +} + +.search-btn { + cursor: pointer; +} + +.m-b-40 { + margin-bottom: 40px; +} + +.m-r-5 { + margin-right: 5px; +} + +.icon-remove { + margin: 16px; +} + +@media screen and (max-width: 768px) { + .button-full-width { + width: 100%; + /* height: 50px; */ + margin-top: 3px; + } +} +.width5 { + width: 5%; +} + +.width10 { + width: 10%; +} + +.width15 { + width: 15%; +} + +.width20 { + width: 20%; +} diff --git a/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.html b/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.html new file mode 100644 index 0000000..68f063b --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.html @@ -0,0 +1,148 @@ +
+
+
+

{{ currentLanguageSet?.inventory?.stockTransfer }}

+
+
+ +
+
+ +
+
+
+ + + +
+
+ + + +
+
+ + + {{ store.facilityName }} + + +
+
+ +
+
+ +
+ +
+
+
+
+ +
+
+ + +
+
+
+
diff --git a/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.spec.ts b/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.spec.ts new file mode 100644 index 0000000..6cbca35 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { StoreStockTransferComponent } from './store-stock-transfer.component'; + +describe('StoreStockTransferComponent', () => { + let component: StoreStockTransferComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [StoreStockTransferComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StoreStockTransferComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.ts b/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.ts new file mode 100644 index 0000000..c34d85a --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/store-stock-transfer.component.ts @@ -0,0 +1,289 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Router } from '@angular/router'; +import { InventoryService } from '../shared/service/inventory.service'; +import { FormBuilder, FormArray, Validators, FormGroup } from '@angular/forms'; +import { ConfirmationService } from '../../core/services/confirmation.service'; +import { Component, DoCheck, OnInit } from '@angular/core'; +import { animate, style, transition, trigger } from '@angular/animations'; +import { SetLanguageComponent } from '../../core/components/set-language.component'; +import { LanguageService } from '../../core/services/language.service'; +import * as moment from 'moment'; +@Component({ + selector: 'app-store-stock-transfer', + templateUrl: './store-stock-transfer.component.html', + styleUrls: ['./store-stock-transfer.component.css'], + animations: [ + trigger('enterAnimation', [ + transition(':enter', [ + style({ opacity: 0 }), + animate('200ms', style({ opacity: 1 })), + ]), + transition(':leave', [ + style({ opacity: 1 }), + animate('200ms', style({ opacity: 0 })), + ]), + ]), + ], +}) +export class StoreStockTransferComponent implements OnInit, DoCheck { + stockTransferForm!: FormGroup; + arrayHead!: FormArray; + facilityID: any; + stores: any = []; + filterStore: any = []; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private inventoryService: InventoryService, + private alertService: ConfirmationService, + private fb: FormBuilder, + private router: Router, + private http_service: LanguageService, + private confirmationService: ConfirmationService, + ) { + this.checkFacility(); + } + + ngOnInit() { + this.getAllStore(); + this.stockTransferForm = this.createStockTransferForm(); + this.setArrayHead(); + this.updateTodaysData(); + this.fetchLanguageResponse(); + } + + checkFacility() { + this.facilityID = localStorage.getItem('facilityID'); + if (this.facilityID == null || this.facilityID <= 0) { + this.router.navigate(['/inventory']); + } + } + + getAllStore() { + const serviceProviderId = localStorage.getItem('providerServiceID'); + this.inventoryService.getAllStore(serviceProviderId).subscribe((data) => { + this.stores = data.filter((item: any) => item.deleted == false); + this.filterStore = this.filterSubStore(this.stores, this.facilityID); + }); + } + + filterSubStore(storeList: any, facilityID: any) { + const source = storeList.filter( + (item: any) => item.facilityID == facilityID, + ); + + const children = []; + const queue = []; + queue.push(source[0]); + + while (queue.length > 0) { + const front = queue.shift(); + children.push(front); + storeList.forEach((item: any) => { + if (item.mainFacilityID && item.mainFacilityID == front.facilityID) + queue.push(item); + }); + } + + const index = children.indexOf(source[0]); + children.splice(index, 1); + + const parent = storeList.filter( + (item: any) => + source[0].mainFacilityID && item.facilityID == source[0].mainFacilityID, + ); + const sibling = storeList.filter( + (item: any) => + source[0].mainFacilityID && + item.mainFacilityID == source[0].mainFacilityID, + ); + + const index2 = sibling.indexOf(source[0]); + sibling.splice(index2, 1); + + const final = new Set(parent.concat(sibling).concat(children)); + return Array.from(final); + } + + createStockTransferForm() { + return this.fb.group({ + dated: { value: null, disabled: true }, + referenceNumber: [null, Validators.required], + transferTo: [null, Validators.required], + createdBy: [null, Validators.required], + providerServiceMapID: [null, Validators.required], + itemArray: new FormArray([this.createItem()]), + }); + } + + createItem() { + return this.fb.group({ + batchNo: [null, Validators.required], + itemStockEntryID: [null, Validators.required], + itemName: [null, Validators.required], + qoh: [null, Validators.required], + quantity: [null, Validators.required], + }); + } + + setArrayHead() { + this.arrayHead = this.stockTransferForm.controls['itemArray'] as FormArray; + } + + updateTodaysData() { + this.stockTransferForm.patchValue({ + dated: moment(new Date()).format('DD/MM/YYYY'), + createdBy: localStorage.getItem('username'), + providerServiceMapID: localStorage.getItem('providerServiceID'), + }); + } + + addTransfer() { + if (this.arrayHead.valid) { + this.arrayHead.push(this.createItem()); + } else { + this.confirmationService.alert( + this.currentLanguageSet.inventory.pleaseenterthevaluesfirst, + 'info', + ); + } + } + + removeTransfer(index: any, length: any) { + const stockArray = this.stockTransferForm.controls[ + 'itemArray' + ] as FormArray; + if (stockArray.length > 1) { + stockArray.removeAt(index); + } + + if (index === 0 && length === 1) this.addTransfer(); + } + + matcher(control: any, form: any) { + const isSubmitted = form && form.submitted; + return !!( + control && + control.invalid && + (control.dirty || control.touched || isSubmitted) + ); + } + + resetForm() { + this.resetItemArray(); + this.stockTransferForm.reset(); + this.updateTodaysData(); + } + + resetItemArray() { + this.stockTransferForm.removeControl('itemArray'); + this.stockTransferForm.addControl( + 'itemArray', + new FormArray([this.createItem()]), + ); + this.setArrayHead(); + } + + checkReferences() { + if ( + this.stockTransferForm.value.referenceNumber && + this.stockTransferForm.value.transferTo + ) { + return true; + } else { + this.resetItemArray(); + return false; + } + } + + checkQuantityAvailable(index: any) { + if ( + this.arrayHead.at(index).value.quantity > + this.arrayHead.at(index).value.qoh + ) { + this.confirmationService.alert( + this.currentLanguageSet.inventory.transferquantitycannotbegreater, + 'info', + ); + this.arrayHead.at(index).patchValue({ + quantity: null, + }); + } + } + + submitTransfers() { + console.log(this.stockTransferForm.value); + this.inventoryService + .saveStockTransfer(this.serviceDataMapper(this.stockTransferForm.value)) + .subscribe((res) => { + if (res && res.response) { + this.confirmationService.alert( + this.currentLanguageSet.inventory.savedsuccessfully, + 'success', + ); + this.resetForm(); + } + }); + } + + serviceDataMapper(formValues: any) { + return { + createdBy: formValues.createdBy, + refNo: formValues.referenceNumber, + providerServiceMapID: formValues.providerServiceMapID, + transferFromFacilityID: this.facilityID, + vanID: localStorage.getItem('vanID'), + parkingPlaceID: localStorage.getItem('parkingPlaceID'), + transferToFacilityID: formValues.transferTo.facilityID, + itemStockExit: this.mapItemsForService( + formValues.itemArray, + formValues.createdBy, + ), + }; + } + + mapItemsForService(itemArray: any, createdBy: any) { + const itemStockExit: any = []; + itemArray.forEach((element: any) => { + itemStockExit.push({ + createdBy: createdBy, + itemStockEntryID: element.itemStockEntryID, + quantity: element.quantity, + }); + }); + return itemStockExit; + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.css b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.css new file mode 100644 index 0000000..50a1d15 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.css @@ -0,0 +1,34 @@ +#head { + background: #0277bd; + color: white; + height: 51px; + width: 100%; + padding: 20px; +} + +#dialog_head { + margin: 0; + padding: 0; +} + +#cross { + cursor: pointer; +} + +#dialog_row { + padding: 15px; +} + +.h5_bold { + font-weight: bold; + display: inline-block; +} + +.m-b-15 { + margin-bottom: 15px; +} + +.scrolling-content { + max-height: 75vh; + overflow: auto; +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.html b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.html new file mode 100644 index 0000000..fbcd09d --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.html @@ -0,0 +1,121 @@ + + +
+
+ + +
+
+ + + search + +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
diff --git a/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.spec.ts b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.spec.ts new file mode 100644 index 0000000..ecb4627 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewStoreStockTransferDetailsComponent } from './view-store-stock-transfer-details.component'; + +describe('ViewStoreStockTransferDetailsComponent', () => { + let component: ViewStoreStockTransferDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewStoreStockTransferDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewStoreStockTransferDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.ts b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.ts new file mode 100644 index 0000000..f4c0191 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer-details/view-store-stock-transfer-details.component.ts @@ -0,0 +1,104 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit, Inject, OnDestroy, DoCheck } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; + +@Component({ + selector: 'app-view-store-stock-transfer-details', + templateUrl: './view-store-stock-transfer-details.component.html', + styleUrls: ['./view-store-stock-transfer-details.component.css'], +}) +export class ViewStoreStockTransferDetailsComponent + implements OnInit, OnDestroy, DoCheck +{ + _filterTerm = ''; + _detailedList = []; + _filteredDetailedList = []; + blankTable = [1, 2, 3, 4, 5]; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private http_service: LanguageService, + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + ) {} + + ngOnInit() { + this.populateStockEntryItems(this.data); + this.fetchLanguageResponse(); + } + + ngOnDestroy(): void { + //Called once, before the instance is destroyed. + //Add 'implements OnDestroy' to the class. + this.data = ''; + } + populateStockEntryItems(data: any) { + if (data && data.entryDetails && data.stockEntry) { + this._detailedList = data.entryDetails; + this._filteredDetailedList = data.entryDetails; + } + } + + filterDetails(filterTerm: string) { + console.log(filterTerm); + if (!filterTerm) this._filteredDetailedList = this._detailedList; + else { + this._filteredDetailedList = []; + this._detailedList.forEach((item) => { + for (const key in item) { + if (key == 'batchNo' || key == 'itemName' || key == 'quantity') { + const value: string = '' + item[key]; + if (value.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0) { + this._filteredDetailedList.push(item); + break; + } + } + } + }); + } + } + + print() { + this.closeViewModal(); + } + + closeViewModal() { + const modalresult = Object.assign({ print: true }); + this.dialogRef.close(modalresult); + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.css b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.css new file mode 100644 index 0000000..00a596b --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.css @@ -0,0 +1,81 @@ +.transfer { + position: relative; + padding-left: 20px; +} + +.transfer.transfer-in::before { + content: ""; + position: absolute; + left: 0; + top: 0; + bottom: 1px; + width: 4px; + background: #0b69b2; +} + +.transfer.transfer-out::before { + content: ""; + position: absolute; + left: 0; + top: 0; + bottom: 1px; + width: 4px; + background: #ff9900; +} + +ul { + list-style: none; + padding: 0px; +} + +ul li { + display: inline-block; + padding: 0 8px; +} + +ul li div, ul li p { + display: inline-block; +} + +ul li div { + height: 15px; + width: 15px; +} + +.transfer-in-marker { + background: #0b69b2; +} + +.transfer-out-marker { + background: #ff9900; +} + +.totalCount, .description { + padding-top: 15px; +} + +.input-full-width { + width: 100%; +} + +.box { + height: 60px; +} + +.back-btn-container { + margin: -26px 15px 15px; +} + +.previous-btn { + margin: 5px 0px; +} + +.m-b-40 { + margin-bottom: 40px !important; +} + +@media screen and (max-width: 768px) { + .previous-btn { + width: 100%; + } +} \ No newline at end of file diff --git a/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.html b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.html new file mode 100644 index 0000000..d49665a --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.html @@ -0,0 +1,193 @@ +
+
+
+

{{ currentLanguageSet?.inventory?.previousStockTransfer }}

+
+ +
+ + + + + + +
+ +
+ + + + + + + {{ currentLanguageSet?.inventory?.toDateCannotBeBeforeFromDate }} +
+ +
+ +
+
+ +
+
+ + +
+
+ + + search + +
+
+
+ +
+
+
+
+ +
+ +
+
+
+
+
+
diff --git a/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.spec.ts b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.spec.ts new file mode 100644 index 0000000..f456cbc --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewStoreStockTransferComponent } from './view-store-stock-transfer.component'; + +describe('ViewStoreStockTranferComponent', () => { + let component: ViewStoreStockTransferComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ViewStoreStockTransferComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewStoreStockTransferComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.ts b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.ts new file mode 100644 index 0000000..1ea6ac0 --- /dev/null +++ b/src/app/app-modules/inventory/store-stock-transfer/view-store-stock-transfer/view-store-stock-transfer.component.ts @@ -0,0 +1,340 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Component, + OnInit, + HostListener, + ViewChild, + DoCheck, +} from '@angular/core'; +import { ViewStoreStockTransferDetailsComponent } from './view-store-stock-transfer-details/view-store-stock-transfer-details.component'; +import { Location } from '@angular/common'; +import { InventoryService } from '../../shared/service/inventory.service'; +import { DataStorageService } from './../../shared/service/data-storage.service'; +import * as moment from 'moment'; +import { Router } from '@angular/router'; +import { SetLanguageComponent } from 'src/app/app-modules/core/components/set-language.component'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { LanguageService } from 'src/app/app-modules/core/services/language.service'; +@Component({ + selector: 'app-view-store-stock-transfer', + templateUrl: './view-store-stock-transfer.component.html', + styleUrls: ['./view-store-stock-transfer.component.css'], +}) +export class ViewStoreStockTransferComponent implements OnInit, DoCheck { + _minDate: any; + _today: any; + + _dateRange: Date[] = []; + _dateRangePrevious: Date[] = []; + + _stockEntryList = []; + _filteredStockEntryList = []; + blankTable = [1, 2, 3, 4, 5]; + filterTerm: any; + ourStore: any; + searched = false; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + + constructor( + private location: Location, + private inventoryService: InventoryService, + private dataStorageService: DataStorageService, + private dialog: MatDialog, + private http_service: LanguageService, + private router: Router, + ) {} + + ngOnInit() { + this.setDateDefault(); + this.fetchLanguageResponse(); + + this.getPastEntries(); + this.ourStore = localStorage.getItem('facilityID'); + } + + setDateDefault() { + this._today = new Date(); + this._minDate = new Date(); + this._minDate.setFullYear(this._today.getFullYear() - 1); + this._dateRange[0] = this._today; + this._dateRange[1] = this._today; + + // const date = new Date(); // Now + // date.setDate(date.getDate() - 30); + // this._dateRange = [date, new Date()] + console.log(this._dateRange, 'dateRange'); + } + + getPastEntries() { + const obj = this.getViewServiceObject(); + this.inventoryService.viewStockTransferEntry(obj).subscribe((res) => { + this.searched = true; + this.loadEntries(res); + }); + } + + getViewServiceObject() { + const startDate: Date = new Date(this._dateRange[0]); + startDate.setHours(0); + startDate.setMinutes(0); + startDate.setSeconds(0); + startDate.setMilliseconds(0); + + const endDate: Date = new Date(this._dateRange[1]); + endDate.setHours(23); + endDate.setMinutes(59); + endDate.setSeconds(59); + endDate.setMilliseconds(0); + + return { + facilityID: localStorage.getItem('facilityID'), + fromDate: new Date( + startDate.valueOf() - 1 * startDate.getTimezoneOffset() * 60 * 1000, + ), + toDate: new Date( + endDate.valueOf() - 1 * endDate.getTimezoneOffset() * 60 * 1000, + ), + }; + } + preventTyping(e: any) { + if (e.keyCode === 9) { + return true; + } else { + return false; + } + } + + updateDate() { + // if (this._dateRange !== this._dateRangePrevious) { + // this._dateRangePrevious = this._dateRange; + // console.log(JSON.stringify(this._dateRange, null, 4), 'callservice'); + this.getPastEntries(); + + // } + } + + loadEntries(entriesObject: any) { + console.log(entriesObject); + const newObject: any = []; + if (entriesObject) { + entriesObject.forEach((element: any) => { + newObject.push({ + refNo: element.refNo, + stockTransferID: element.stockTransferID, + transferFromID: element.transferFromFacilityID, + transferToID: element.transferToFacilityID, + transferFromFacility: element.transferFromFacility.facilityName, + transferToFacility: element.transferToFacility.facilityName, + createdBy: element.createdBy, + createdDate: element.createdDate || 'Not Available', + }); + }); + } + this._stockEntryList = newObject; + this._filteredStockEntryList = newObject; + this.filterTerm = ''; + } + + filterConsumptionList(searchTerm: string) { + if (!searchTerm) this._filteredStockEntryList = this._stockEntryList; + else { + this._filteredStockEntryList = []; + this._stockEntryList.forEach((item) => { + for (const key in item) { + if ( + key == 'refNo' || + key == 'stockTransferID' || + key == 'transferFromFacility' || + key == 'transferToFacility' || + key == 'createdBy' + ) { + const value: string = '' + item[key]; + if (value.toLowerCase().indexOf(searchTerm.toLowerCase()) >= 0) { + this._filteredStockEntryList.push(item); + break; + } + } + } + }); + } + } + + loadEntryDetails(entry: any) { + if (entry && entry.stockTransferID) { + this.inventoryService + .getParticularStockTransferEntry(entry.stockTransferID) + .subscribe((res) => this.popOutEntryDetails(entry, res)); + } + } + + popOutEntryDetails(entry: any, stockEntryResponse: any) { + console.warn(entry, stockEntryResponse); + if (stockEntryResponse) { + const mdDialogRef: MatDialogRef = + this.dialog.open(ViewStoreStockTransferDetailsComponent, { + // height: '90%', + width: '80%', + panelClass: 'fit-screen', + data: { stockEntry: entry, entryDetails: stockEntryResponse }, + disableClose: false, + }); + mdDialogRef.afterClosed().subscribe((result) => { + if (result) { + if (result.print != null && result.print == true) { + if (result.print) { + const printableData = this.createPrintableData( + entry, + stockEntryResponse, + ); + this.dataStorageService.stockTransfer = printableData; + const uRL = 'stockTransfer'; + this.router.navigate(['/inventory/dynamicPrint/', uRL]); + } + } + } + }); + } + } + + createPrintableData(entry: any, stockEntryResponse: any) { + const facilityDetailStorage: any = localStorage.getItem('facilityDetail'); + const facilityDetail = JSON.parse(facilityDetailStorage); + const facilityName = facilityDetail.facilityName; + const printableData: any = []; + let i = 0; + console.log( + 'stockEntryResponse', + JSON.stringify(stockEntryResponse, null, 4), + ); + stockEntryResponse.forEach((batch: any) => { + i = i + 1; + const consumedBatch = { + sNo: i, + itemName: batch.itemName, + batchNo: batch.batchNo, + expiryDate: moment(batch.expiryDate).format('DD-MM-YYYY'), + qod: batch.quantity, + }; + printableData.push(consumedBatch); + }); + console.log('consumptionDetails', JSON.stringify(entry, null, 4)); + const entryDetails = Object.assign( + { + facilityName: facilityName, + createDate: moment(entry.createdDate).format('DD-MM-YYYY'), + }, + entry, + ); + console.log('consumptionResponse', JSON.stringify(printableData, null, 4)); + const stockEntered = Object.assign( + {}, + { title: this.title }, + { headerColumn: this.headerColumn }, + { headerDetail: entryDetails }, + { columns: this.columns }, + { printableData: printableData }, + ); + return stockEntered; + } + + goBack() { + this.location.back(); + } + + title = { + modalTitle: '', + headerTitle: 'Stock Transfer Detail', + tableTitle: '', + }; + columns = [ + { + keyName: 'sNo', + columnName: 'S No.', + }, + { + keyName: 'itemName', + columnName: 'Item Name', + }, + { + keyName: 'batchNo', + columnName: 'Batch No', + }, + { + keyName: 'expiryDate', + columnName: 'Expiry Date', + }, + { + keyName: 'qod', + columnName: 'Quantity', + }, + ]; + headerColumn = [ + { + columnName: 'Stock Transfer ID :', + keyName: 'stockTransferID', + }, + { + columnName: 'Reference No :', + keyName: 'refNo', + }, + { + columnName: 'Transfer From ID :', + keyName: 'transferFromID', + }, + + { + columnName: 'Transfer From Facility :', + keyName: 'transferFromFacility', + }, + { + columnName: 'Transfer To ID :', + keyName: 'transferToID', + }, + { + columnName: 'Transfer To Facility :', + keyName: 'transferToFacility', + }, + + { + columnName: 'Created By :', + keyName: 'createdBy', + }, + { + columnName: 'Created Date :', + keyName: 'createDate', + }, + ]; + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/app-modules/inventory/workarea/workarea.component.css b/src/app/app-modules/inventory/workarea/workarea.component.css new file mode 100644 index 0000000..85965f9 --- /dev/null +++ b/src/app/app-modules/inventory/workarea/workarea.component.css @@ -0,0 +1,13 @@ +h3 { + font-size: 150px; + font-weight: bold; + background-color: #565656; + color: transparent; + text-align: center; + vertical-align: bottom; + opacity: 0.3; + text-shadow: 2px 2px 3px rgba(255,255,255,0.5); + -webkit-background-clip: text; + -moz-background-clip: text; + background-clip: text; +} diff --git a/src/app/app-modules/inventory/workarea/workarea.component.html b/src/app/app-modules/inventory/workarea/workarea.component.html new file mode 100644 index 0000000..d2fb3d6 --- /dev/null +++ b/src/app/app-modules/inventory/workarea/workarea.component.html @@ -0,0 +1 @@ + diff --git a/src/app/app-modules/inventory/workarea/workarea.component.spec.ts b/src/app/app-modules/inventory/workarea/workarea.component.spec.ts new file mode 100644 index 0000000..4baf7b3 --- /dev/null +++ b/src/app/app-modules/inventory/workarea/workarea.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { WorkareaComponent } from './workarea.component'; + +describe('WorkareaComponent', () => { + let component: WorkareaComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [WorkareaComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(WorkareaComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-modules/inventory/workarea/workarea.component.ts b/src/app/app-modules/inventory/workarea/workarea.component.ts new file mode 100644 index 0000000..967d333 --- /dev/null +++ b/src/app/app-modules/inventory/workarea/workarea.component.ts @@ -0,0 +1,44 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { + Component, + OnInit, + ChangeDetectorRef, + AfterViewChecked, +} from '@angular/core'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'app-workarea', + templateUrl: './workarea.component.html', + styleUrls: ['./workarea.component.css'], +}) +export class WorkareaComponent implements AfterViewChecked { + constructor( + private changeDetectorRef: ChangeDetectorRef, + private router: Router, + ) {} + + ngAfterViewChecked() { + this.changeDetectorRef.detectChanges(); + } +} diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 4277a41..659942a 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -22,6 +22,10 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { LoginComponent } from './login/login.component'; +import { ServiceComponent } from 'src/service/service.component'; +import { AuthGuard } from './app-modules/core/services/auth-guard.service'; +import { FacilitySelectionComponent } from './facility-selection/facility-selection.component'; +import { LoadStoreDetailsComponent } from './load-store-details/load-store-details.component'; // import { ServiceComponent } from './service/service.component'; @@ -61,25 +65,28 @@ const routes: Routes = [ // component: SetPasswordComponent, // // canActivate: [AuthGuard], // }, - // { - // path: 'service', - // component: ServiceComponent, - // canActivate: [AuthGuard], - // }, - // { - // path: 'facility', - // component: FacilitySelectionComponent, - // canActivate: [AuthGuard], - // }, - // { - // path:'loadStores', - // component:LoadStoreDetailsComponent, - // }, - // { - // path: 'inventory', - // canActivate: [AuthGuard], - // loadChildren: './app-modules/inventory/inventory.module#InventoryModule' - // }, + { + path: 'service', + component: ServiceComponent, + canActivate: [AuthGuard], + }, + { + path: 'facility', + component: FacilitySelectionComponent, + canActivate: [AuthGuard], + }, + { + path: 'loadStores', + component: LoadStoreDetailsComponent, + }, + { + path: 'inventory', + canActivate: [AuthGuard], + loadChildren: () => + import('./app-modules/inventory/inventory.module').then( + (x) => x.InventoryModule, + ), + }, // { // path: 'rx', // canActivate: [AuthGuard], diff --git a/src/app/app.component.html b/src/app/app.component.html index be1126a..7fcdc4a 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 4c96e09..bb39e63 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -27,7 +27,6 @@ import { RouteReuseStrategy } from '@angular/router'; import { CustomRouteReuseStrategy } from './custom-route-reuse-strategy'; import { MatDialogModule } from '@angular/material/dialog'; -import { FormsModule } from '@angular/forms'; // import { HttpModule } from '@angular/http'; // import { Md2Module } from 'md2'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -63,17 +62,30 @@ import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatRadioModule } from '@angular/material/radio'; import { MatDatepickerModule } from '@angular/material/datepicker'; +import { ServiceComponent } from 'src/service/service.component'; +import { MatListModule } from '@angular/material/list'; +import { FacilitySelectionComponent } from './facility-selection/facility-selection.component'; +import { FaciltyService } from './facility-selection/facilty.service'; +import { MatSelectModule } from '@angular/material/select'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { LoadStoreDetailsComponent } from './load-store-details/load-store-details.component'; +import { MaterialModule } from './app-modules/core/material.module'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { HttpInterceptorService } from './app-modules/core/services/http-interceptor.service'; +import { HTTP_INTERCEPTORS } from '@angular/common/http'; @NgModule({ declarations: [ AppComponent, LoginComponent, - // ServiceComponent, + ServiceComponent, // ResetPasswordComponent, // SetPasswordComponent, // SetSecurityQuestionsComponent, - // FacilitySelectionComponent, + FacilitySelectionComponent, // RedirInComponent, - // LoadStoreDetailsComponent, + LoadStoreDetailsComponent, ], imports: [ BrowserModule, @@ -84,6 +96,7 @@ import { MatDatepickerModule } from '@angular/material/datepicker'; AppRoutingModule, MatDialogModule, MatFormFieldModule, + MatPaginatorModule, MatInputModule, MatTableModule, MatTooltipModule, @@ -93,6 +106,12 @@ import { MatDatepickerModule } from '@angular/material/datepicker'; MatCardModule, MatRadioModule, MatDatepickerModule, + MatListModule, + MatSelectModule, + ReactiveFormsModule, + MatProgressBarModule, + MatProgressSpinnerModule, + MaterialModule, CoreModule.forRoot(), // Ng2GoogleChartsModule ], @@ -100,8 +119,13 @@ import { MatDatepickerModule } from '@angular/material/datepicker'; AuthenticationService, LanguageService, AuthService, - // FaciltyService, - { provide: RouteReuseStrategy, useClass: CustomRouteReuseStrategy }, + FaciltyService, + HttpInterceptorService, + { + provide: HTTP_INTERCEPTORS, + useClass: HttpInterceptorService, + multi: true, + }, ], bootstrap: [AppComponent], }) diff --git a/src/app/facility-selection/facility-selection.component.css b/src/app/facility-selection/facility-selection.component.css new file mode 100644 index 0000000..6624c0d --- /dev/null +++ b/src/app/facility-selection/facility-selection.component.css @@ -0,0 +1,15 @@ +.radio-btn { + margin-left: 8px; +} + +.m-t-25 { + margin-top: 25px; +} + +.m-t-10 { + margin-top: 10px; +} + +.submit{ + top: 10px; +} diff --git a/src/app/facility-selection/facility-selection.component.html b/src/app/facility-selection/facility-selection.component.html new file mode 100644 index 0000000..dd79e0c --- /dev/null +++ b/src/app/facility-selection/facility-selection.component.html @@ -0,0 +1,118 @@ + + +
+
+
+
+ + + Logo + + +
+
+ + {{ + currentLanguageSet?.inventory?.typeofStores + }} + {{ + currentLanguageSet?.inventory?.mainStore + }} + {{ + currentLanguageSet?.inventory?.subStore + }} + +
+
+ + + {{ facility.facilityName }} + + +
+
+ + + {{ subFacility.facilityName }} + + +
+
+
+
+ + +
+
+
+
+
+
+
+
+ + diff --git a/src/app/facility-selection/facility-selection.component.spec.ts b/src/app/facility-selection/facility-selection.component.spec.ts new file mode 100644 index 0000000..7bdcfe8 --- /dev/null +++ b/src/app/facility-selection/facility-selection.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FacilitySelectionComponent } from './facility-selection.component'; + +describe('FacilitySelectionComponent', () => { + let component: FacilitySelectionComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [FacilitySelectionComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FacilitySelectionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/facility-selection/facility-selection.component.ts b/src/app/facility-selection/facility-selection.component.ts new file mode 100644 index 0000000..4b68b28 --- /dev/null +++ b/src/app/facility-selection/facility-selection.component.ts @@ -0,0 +1,171 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, DoCheck, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { FormBuilder, FormGroup } from '@angular/forms'; + +import { FaciltyService } from './facilty.service'; +import { ConfirmationService } from '../app-modules/core/services'; +import { SetLanguageComponent } from '../app-modules/core/components/set-language.component'; +import { LanguageService } from '../app-modules/core/services/language.service'; + +@Component({ + selector: 'app-facility-selection', + templateUrl: './facility-selection.component.html', + styleUrls: ['./facility-selection.component.css'], +}) +export class FacilitySelectionComponent implements OnInit, DoCheck { + serviceProviderId: any; + designation: any; + stores: any = []; + enableContinue = false; + facilities: any = []; + subFacilities: any = []; + languageComponent!: SetLanguageComponent; + currentLanguageSet: any; + isMainStoreBool: any; + + constructor( + private fb: FormBuilder, + private router: Router, + private faciltyService: FaciltyService, + private http_service: LanguageService, + private confirmationService: ConfirmationService, + ) {} + + facilityForm = this.fb.group({ + isMainStore: '', + facility: '', + subFacility: '', + }); + + ngOnInit() { + localStorage.removeItem('facilityDetail'); + localStorage.removeItem('facilityID'); + this.fetchLanguageResponse(); + this.serviceProviderId = localStorage.getItem('providerServiceID'); + this.getAllStores(); + } + + getAllStores() { + this.faciltyService + .getAllStores(this.serviceProviderId) + .subscribe((data: any) => { + this.stores = data.data; + }); + } + + checkStores() { + this.subFacilities = []; + this.facilities = []; + this.facilityForm.patchValue({ + facility: null, + subFacility: null, + }); + this.getFacility(); + } + + toContinue() { + const isMainStore: any = this.facilityForm.controls['isMainStore'].value; + const facility: any = this.facilityForm.controls['facility'].value; + const subFacility: any = this.facilityForm.controls['subFacility'].value; + if ( + this.facilityForm.controls.isMainStore.value && + this.facilityForm.controls.facility.value + ) { + this.enableContinue = true; + localStorage.setItem('facilityID', facility.facilityID); + localStorage.setItem('facilityDetail', JSON.stringify(facility)); + } else if (isMainStore == 'false' && facility && subFacility) { + this.enableContinue = true; + localStorage.setItem('facilityID', subFacility.facilityID); + localStorage.setItem('facilityDetail', JSON.stringify(subFacility)); + this.getFacilityMappedVanID(subFacility.facilityID); + } else { + this.enableContinue = false; + } + } + + getFacility() { + this.facilities = this.stores.filter((facility: any) => { + if (facility.isMainFacility == true && facility.deleted == false) { + return facility; + } + }); + } + + getSubFacility() { + const facility: any = this.facilityForm.controls['facility'].value; + this.facilityForm.patchValue({ subFacility: null }); + this.subFacilities = []; + this.subFacilities = this.stores.filter((subFacility: any) => { + if ( + !subFacility.deleted && + subFacility.mainFacilityID && + subFacility.mainFacilityID == facility.facilityID + ) { + return subFacility; + } + }); + } + + vanID: any; + parkingPlaceID: any; + + getFacilityMappedVanID(facilityID: any) { + this.faciltyService.getVanByStoreID(facilityID).subscribe((res: any) => { + if (res.statusCode == 200 && res.data) { + this.vanID = res.data.vanID; + this.parkingPlaceID = res.data.parkingPlaceID; + } + }); + } + proceedFurther() { + this.designation = 'Pharmacist'; + if (this.vanID && this.parkingPlaceID) { + localStorage.setItem('vanID', this.vanID); + localStorage.setItem('parkingPlaceID', this.parkingPlaceID); + } + this.routeToDesignation(this.designation); + } + + routeToDesignation(designation: any) { + switch (designation) { + case 'Pharmacist': + this.router.navigate(['/loadStores']); + break; + default: + } + } + + //AN40085822 29/9/2021 Integrating Multilingual Functionality --Start-- + ngDoCheck() { + this.fetchLanguageResponse(); + } + + fetchLanguageResponse() { + this.languageComponent = new SetLanguageComponent(this.http_service); + this.languageComponent.setLanguage(); + this.currentLanguageSet = this.languageComponent.currentLanguageObject; + } + //--End-- +} diff --git a/src/app/facility-selection/facilty-resolve.service.ts b/src/app/facility-selection/facilty-resolve.service.ts new file mode 100644 index 0000000..4124efb --- /dev/null +++ b/src/app/facility-selection/facilty-resolve.service.ts @@ -0,0 +1,25 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Injectable } from '@angular/core'; + +@Injectable() +export class FaciltyResolveService {} diff --git a/src/app/facility-selection/facilty.service.ts b/src/app/facility-selection/facilty.service.ts new file mode 100644 index 0000000..2beb46c --- /dev/null +++ b/src/app/facility-selection/facilty.service.ts @@ -0,0 +1,43 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { environment } from 'src/environments/environment'; + +@Injectable() +export class FaciltyService { + constructor(private http: HttpClient) {} + + stores: any; + getAllStores(serviceProviderId: any) { + return this.http.post( + environment.getFacilityUrl + serviceProviderId, + {}, + ); + } + + getVanByStoreID(storeID: any) { + return this.http.post(environment.getVanByStoreIDUrl + '/' + storeID, { + storeID, + }); + } +} diff --git a/src/app/load-store-details/load-store-details.component.css b/src/app/load-store-details/load-store-details.component.css new file mode 100644 index 0000000..6d250a4 --- /dev/null +++ b/src/app/load-store-details/load-store-details.component.css @@ -0,0 +1,35 @@ +.overlay { + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + position: fixed; + z-index: 1001; + /* Sit on top */ + left: 0; + top: 0; + background-color: rgb(0, 0, 0); + /* Black fallback color */ + background-color: rgba(0, 0, 0, 0.3); + /* Black w/opacity */ +} + + +/* Position the content inside the overlay */ + + +/*.overlay-content { + position: relative; + top: 42%; 25% from the top + left: 46%; + width: 100%; 100% width +}*/ + +.overlay:root { + padding: 0px; +} + +.loader-hidden { + display: none; +} \ No newline at end of file diff --git a/src/app/load-store-details/load-store-details.component.html b/src/app/load-store-details/load-store-details.component.html new file mode 100644 index 0000000..2e8ae41 --- /dev/null +++ b/src/app/load-store-details/load-store-details.component.html @@ -0,0 +1,5 @@ +
+
+ +
+
diff --git a/src/app/load-store-details/load-store-details.component.spec.ts b/src/app/load-store-details/load-store-details.component.spec.ts new file mode 100644 index 0000000..f363db0 --- /dev/null +++ b/src/app/load-store-details/load-store-details.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LoadStoreDetailsComponent } from './load-store-details.component'; + +describe('LoadStoreDetailsComponent', () => { + let component: LoadStoreDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [LoadStoreDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LoadStoreDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/load-store-details/load-store-details.component.ts b/src/app/load-store-details/load-store-details.component.ts new file mode 100644 index 0000000..07e4b68 --- /dev/null +++ b/src/app/load-store-details/load-store-details.component.ts @@ -0,0 +1,35 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +@Component({ + selector: 'app-load-store-details', + templateUrl: './load-store-details.component.html', + styleUrls: ['./load-store-details.component.css'], +}) +export class LoadStoreDetailsComponent implements OnInit { + constructor(private router: Router) {} + showProgressBar = true; + ngOnInit() { + this.router.navigate(['/inventory']); + } +} diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index 665132d..cc6cb53 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -8,7 +8,7 @@
-
+
account_box
-
+
Forgot Password? @@ -80,4 +80,4 @@
- + diff --git a/src/environments/environment.ts b/src/environments/environment.ts index c34df18..38b6650 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -24,19 +24,19 @@ // `ng build --env=prod` then `environment.prod.ts` will be used instead. // The list of which env maps to which file can be found in `.angular-cli.json`. -const commonIP = 'http://10.208.122.69:8080/'; -const inventoryIP = 'http://10.208.122.69:8080/'; -const mmuIP = 'http://10.208.122.69:8080/'; -const FHIRIP = 'http://10.208.122.69:8080/'; +const commonIP = 'https://amritwprdev.piramalswasthya.org/'; +const inventoryIP = 'https://amritwprdev.piramalswasthya.org/'; +const mmuIP = 'https://amritwprdev.piramalswasthya.org/'; +const FHIRIP = 'https://amritwprdev.piramalswasthya.org/'; // const COMMON_API_OPEN = `http://${IP}:8080/apiman-gateway/IEMR/Common/open/`; // const COMMON_API = `http://${IP}:8080/apiman-gateway/IEMR/Common/1.0/`; // const INVENTORY_API = `http://${IP}:8080/apiman-gateway/IEMR/Inventory/1.0/`; // const MMU_API = `http://${IP}:8080/apiman-gateway/IEMR/MMU/1.0/`; -const COMMON_API_OPEN = `${commonIP}commonapi-v1.1/`; -const COMMON_API = `${commonIP}commonapi-v1.1/`; -const INVENTORY_API = `${inventoryIP}Inventoryapi-v1.0/`; -const MMU_API = `${mmuIP}mmuapi-v1.0/`; +const COMMON_API_OPEN = `${commonIP}commonapi-v0.1/`; +const COMMON_API = `${commonIP}commonapi-v0.1/`; +const INVENTORY_API = `${inventoryIP}Inventoryapi-v0.1/`; +const MMU_API = `${mmuIP}mmuapi-v0.1/`; const FHIR_API = `${FHIRIP}/fhirapi-v1.0/`; // const FHIR_API = `http://localhost:8080/fhirapi-v1.0/`; diff --git a/src/index.html b/src/index.html index 2e15a6f..2f24b15 100644 --- a/src/index.html +++ b/src/index.html @@ -6,6 +6,11 @@ baseTag.href = document.location.href; document.head.appendChild(baseTag); + InventoryUiNext @@ -14,6 +19,14 @@ + + diff --git a/src/service/service.component.css b/src/service/service.component.css new file mode 100644 index 0000000..f999cf8 --- /dev/null +++ b/src/service/service.component.css @@ -0,0 +1,52 @@ +.circle { + position: relative; + padding: 0; + width: 300px; + height: 100px; + z-index: 1; + cursor: pointer; + background: #3175c0; + color: white; +} + +.width310px { + width: 310px; + cursor: pointer; +} + +.line-height-72 { + line-height: 72px !important; +} + +.f-s-48 { + font-size: 48px; +} + +.f-s-20 { + font-size: 20px; +} + +.f-c-w { + color: white +} + +.p-l-15 { + padding-left: 15px; +} + +.p-t-15 { + padding-top: 15px; +} + +#store { + font-size: 7em; + color: white; + height: 98px; + width: 136px; +} + +.container-fluid { + display: flex; + align-items: center; + justify-content: center; +} \ No newline at end of file diff --git a/src/service/service.component.html b/src/service/service.component.html new file mode 100644 index 0000000..0c801e5 --- /dev/null +++ b/src/service/service.component.html @@ -0,0 +1,29 @@ + + +
+
+
+ + +
+ store +
+ + +
+
+
+ + diff --git a/src/service/service.component.spec.ts b/src/service/service.component.spec.ts new file mode 100644 index 0000000..0bb3919 --- /dev/null +++ b/src/service/service.component.spec.ts @@ -0,0 +1,45 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ServiceComponent } from './service.component'; + +describe('ServiceComponent', () => { + let component: ServiceComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ServiceComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ServiceComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + xit('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/service/service.component.ts b/src/service/service.component.ts new file mode 100644 index 0000000..a24c865 --- /dev/null +++ b/src/service/service.component.ts @@ -0,0 +1,52 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'app-service', + templateUrl: './service.component.html', + styleUrls: ['./service.component.css'], +}) +export class ServiceComponent implements OnInit { + servicesList: any = []; + + constructor(private router: Router) {} + + ngOnInit() { + const servicesListStore = localStorage.getItem('services'); + if (servicesListStore !== null) { + this.servicesList = JSON.parse(servicesListStore); + } + } + handleKeyselectService(event: KeyboardEvent, service: any): void { + if (event.key == 'Enter' || event.key == 'Spacebar' || event.key == ' ') { + this.selectService(service); + } + } + + selectService(service: any): void { + localStorage.setItem('providerServiceID', service.providerServiceID); + sessionStorage.setItem('apimanClientKey', service.apimanClientKey); + this.router.navigate(['/facility']); + } +} From 59fc2ba45d507976422a17161f6ce3b02b8fc70d Mon Sep 17 00:00:00 2001 From: Parth Kothari Date: Tue, 27 Feb 2024 18:11:29 +0530 Subject: [PATCH 002/139] Inventory Changes --- angular.json | 2 +- package-lock.json | 1293 +++++++++++++++-- package.json | 3 + .../app-footer/app-footer.component.css | 2 +- .../app-footer/app-footer.component.html | 2 +- .../app-header/app-header.component.css | 37 +- .../app-header/app-header.component.html | 85 +- .../app-header/app-header.component.ts | 16 - .../batch-adjustment.component.css | 9 + .../batch-adjustment.component.html | 217 ++- .../batch-adjustment.component.ts | 16 +- .../batch-search/batch-search.component.css | 8 + .../batch-search/batch-search.component.html | 218 ++- .../batch-search/batch-search.component.ts | 16 +- .../beneficiary-details.component.html | 137 +- .../beneficiary-details.component.ts | 3 + .../common-dialog/common-dialog.component.ts | 5 +- .../indent-item-list.component.css | 4 + .../indent-item-list.component.html | 128 +- .../indent-item-list.component.ts | 18 +- .../item-dispense/item-dispense.component.css | 8 + .../item-dispense.component.html | 167 ++- .../item-dispense/item-dispense.component.ts | 19 +- .../item-search/item-search.component.css | 8 + .../item-search/item-search.component.html | 81 +- .../item-search/item-search.component.ts | 19 +- .../rx-batch-view.component.html | 179 ++- .../rx-batch-view/rx-batch-view.component.ts | 24 +- .../components/search/search.component.css | 5 + .../components/search/search.component.html | 211 +-- .../components/search/search.component.ts | 45 +- ...-commit-and-version-details.component.html | 16 +- .../components/spinner/spinner.component.html | 6 +- .../components/spinner/spinner.component.ts | 21 +- .../transfer-search.component.css | 6 + .../transfer-search.component.html | 169 ++- .../transfer-search.component.ts | 28 +- src/app/app-modules/core/core.module.ts | 39 +- .../directives/batch-adjustment.directive.ts | 2 + .../directives/indent-request.directive.ts | 5 +- .../core/directives/item-search.directive.ts | 3 +- .../minNumberValidator.directive.ts | 2 +- src/app/app-modules/core/material.module.ts | 87 +- .../app-modules/core/services/auth.service.ts | 13 +- .../core/services/http-interceptor.service.ts | 6 +- .../core/services/rx-batchview.service.ts | 25 +- .../core/services/spinner.service.ts | 10 +- .../dynamic-print.component.html | 9 +- .../dynamic-print/dynamic-print.component.ts | 2 - .../indent-order-worklist.component.css | 1 + .../indent-order-worklist.component.html | 3 + .../indent-order-worklist.component.spec.ts | 45 + .../indent-order-worklist.component.ts | 65 + .../indent-dispenses.component.css | 35 + .../indent-dispenses.component.html | 35 + .../indent-dispenses.component.spec.ts | 45 + .../indent-dispenses.component.ts | 53 + .../manual-indent-dispense.component.css | 11 + .../manual-indent-dispense.component.html | 273 ++++ .../manual-indent-dispense.component.spec.ts | 45 + .../manual-indent-dispense.component.ts | 366 +++++ ...select-batch-for-indent-item.component.css | 58 + ...elect-batch-for-indent-item.component.html | 267 ++++ ...ct-batch-for-indent-item.component.spec.ts | 45 + .../select-batch-for-indent-item.component.ts | 394 +++++ .../show-indent-batch-details.component.css | 37 + .../show-indent-batch-details.component.html | 93 ++ ...how-indent-batch-details.component.spec.ts | 45 + .../show-indent-batch-details.component.ts | 84 ++ .../system-indent-dispense.component.css | 19 + .../system-indent-dispense.component.html | 203 +++ .../system-indent-dispense.component.spec.ts | 45 + .../system-indent-dispense.component.ts | 337 +++++ ...-store-indent-order-worklist.component.css | 11 + ...store-indent-order-worklist.component.html | 160 ++ ...re-indent-order-worklist.component.spec.ts | 45 + ...n-store-indent-order-worklist.component.ts | 162 +++ .../main-store-item-model.component.css | 39 + .../main-store-item-model.component.html | 116 ++ .../main-store-item-model.component.spec.ts | 45 + .../main-store-item-model.component.ts | 78 + ...ct-item-from-mainstore-model.component.css | 17 + ...t-item-from-mainstore-model.component.html | 33 + ...tem-from-mainstore-model.component.spec.ts | 45 + ...ect-item-from-mainstore-model.component.ts | 122 ++ .../indent-request.component.css | 19 + .../indent-request.component.html | 299 ++++ .../indent-request.component.spec.ts | 45 + .../indent-request.component.ts | 373 +++++ ...-store-indent-order-worklist.component.css | 11 + ...store-indent-order-worklist.component.html | 196 +++ ...re-indent-order-worklist.component.spec.ts | 45 + ...b-store-indent-order-worklist.component.ts | 137 ++ .../sub-store-item-model.component.css | 44 + .../sub-store-item-model.component.html | 110 ++ .../sub-store-item-model.component.spec.ts | 45 + .../sub-store-item-model.component.ts | 83 ++ .../inventory/inventory-routing.module.ts | 175 +-- .../app-modules/inventory/inventory.module.ts | 164 +-- .../manual-medicine-dispense.component.css | 5 + .../manual-medicine-dispense.component.html | 154 +- .../manual-medicine-dispense.component.ts | 49 +- .../select-batch/select-batch.component.css | 5 + .../select-batch/select-batch.component.html | 258 +++- .../select-batch/select-batch.component.ts | 23 +- .../medicine-dispense.component.css | 6 + .../medicine-dispense.component.html | 37 +- .../medicine-dispense.component.ts | 113 +- .../show-batch-item.component.css | 5 + .../show-batch-item.component.html | 136 +- .../show-batch-item.component.ts | 33 +- .../system-medicine-dispense.component.html | 123 +- .../system-medicine-dispense.component.ts | 109 +- ...ew-medicine-dispense-details.component.css | 4 + ...w-medicine-dispense-details.component.html | 196 ++- ...iew-medicine-dispense-details.component.ts | 37 +- .../view-medicine-dispense.component.css | 6 + .../view-medicine-dispense.component.html | 94 +- .../benificiary-details.component.css | 5 + .../benificiary-details.component.html | 109 +- .../benificiary-details.component.ts | 14 +- ...h-details-for-patient-return.component.css | 5 + ...-details-for-patient-return.component.html | 167 ++- ...ch-details-for-patient-return.component.ts | 38 +- ...patient-return-batch-details.component.css | 5 + ...atient-return-batch-details.component.html | 203 ++- .../patient-return-batch-details.component.ts | 24 +- ...tient-return-previous-record.component.css | 7 + ...ient-return-previous-record.component.html | 206 ++- ...atient-return-previous-record.component.ts | 17 +- .../patient-return.component.css | 5 + .../patient-return.component.html | 33 +- .../physical-stock-entry.component.css | 5 + .../physical-stock-entry.component.html | 361 ++--- .../physical-stock-entry.component.ts | 122 +- .../view-physical-stock-details.component.css | 5 + ...view-physical-stock-details.component.html | 250 ++-- .../view-physical-stock-details.component.ts | 43 +- .../view-physical-stock.component.css | 1 + .../view-physical-stock.component.html | 214 +-- .../view-physical-stock.component.ts | 30 +- ...eneficiary-drug-issue-report.component.css | 5 + ...neficiary-drug-issue-report.component.html | 62 + ...iciary-drug-issue-report.component.spec.ts | 45 + ...beneficiary-drug-issue-report.component.ts | 304 ++++ .../consumption-report.component.css | 1 + .../consumption-report.component.html | 81 ++ .../consumption-report.component.spec.ts | 45 + .../consumption-report.component.ts | 324 +++++ .../daily-stock-details-report.component.css | 1 + .../daily-stock-details-report.component.html | 82 ++ ...ily-stock-details-report.component.spec.ts | 45 + .../daily-stock-details-report.component.ts | 324 +++++ .../daily-stock-summary-report.component.css | 1 + .../daily-stock-summary-report.component.html | 82 ++ ...ily-stock-summary-report.component.spec.ts | 45 + .../daily-stock-summary-report.component.ts | 324 +++++ .../expiry-report/expiry-report.component.css | 1 + .../expiry-report.component.html | 69 + .../expiry-report.component.spec.ts | 45 + .../expiry-report/expiry-report.component.ts | 289 ++++ .../inward-stock-report.component.css | 1 + .../inward-stock-report.component.html | 81 ++ .../inward-stock-report.component.spec.ts | 45 + .../inward-stock-report.component.ts | 319 ++++ .../monthly-report.component.css | 51 + .../monthly-report.component.html | 64 + .../monthly-report.component.spec.ts | 45 + .../monthly-report.component.ts | 319 ++++ .../short-expiry-report.component.css | 1 + .../short-expiry-report.component.html | 44 + .../short-expiry-report.component.spec.ts | 45 + .../short-expiry-report.component.ts | 261 ++++ .../transit-report.component.css | 1 + .../transit-report.component.html | 69 + .../transit-report.component.spec.ts | 45 + .../transit-report.component.ts | 291 ++++ .../yearly-report/yearly-report.component.css | 56 + .../yearly-report.component.html | 57 + .../yearly-report.component.spec.ts | 45 + .../yearly-report/yearly-report.component.ts | 289 ++++ .../store-self-consumption.component.css | 7 + .../store-self-consumption.component.html | 161 +- .../store-self-consumption.component.ts | 106 +- ...ore-self-consumption-details.component.css | 4 + ...re-self-consumption-details.component.html | 197 ++- ...tore-self-consumption-details.component.ts | 51 +- .../view-store-self-consumption.component.css | 7 + ...view-store-self-consumption.component.html | 182 ++- .../view-store-self-consumption.component.ts | 45 +- .../store-stock-adjustment.component.css | 5 + .../store-stock-adjustment.component.html | 295 ++-- .../store-stock-adjustment.component.ts | 163 +-- ...ew-stock-adjustment-details.component.html | 189 ++- ...view-stock-adjustment-details.component.ts | 54 +- ...ck-adjustment-draft-details.component.html | 193 ++- ...tock-adjustment-draft-details.component.ts | 49 +- ...store-stock-adjustment-draft.component.css | 6 + ...tore-stock-adjustment-draft.component.html | 194 ++- ...-store-stock-adjustment-draft.component.ts | 34 +- .../view-store-stock-adjustment.component.css | 14 + ...view-store-stock-adjustment.component.html | 165 ++- .../view-store-stock-adjustment.component.ts | 32 +- .../store-stock-transfer.component.css | 6 + .../store-stock-transfer.component.html | 165 ++- .../store-stock-transfer.component.ts | 36 +- ...tore-stock-transfer-details.component.html | 227 ++- ...-store-stock-transfer-details.component.ts | 32 +- .../view-store-stock-transfer.component.css | 7 + .../view-store-stock-transfer.component.html | 262 +++- .../view-store-stock-transfer.component.ts | 31 +- .../app-modules/inventory/utc-date.pipe.ts | 46 + .../rx-dashboard/rx-dashboard.component.css | 82 ++ .../rx-dashboard/rx-dashboard.component.html | 83 ++ .../rx-dashboard.component.spec.ts | 45 + .../rx/rx-dashboard/rx-dashboard.component.ts | 218 +++ .../rx-item-dispense.component.css | 78 + .../rx-item-dispense.component.html | 328 +++++ .../rx-item-dispense.component.spec.ts | 45 + .../rx-item-dispense.component.ts | 291 ++++ src/app/app-modules/rx/rx-routing.module.ts | 37 + src/app/app-modules/rx/rx.module.ts | 85 ++ .../service/prescribed-drug.service.spec.ts | 39 + .../shared/service/prescribed-drug.service.ts | 92 ++ .../app-modules/rx/shared/utility/index.ts | 22 + .../shared/utility/prescribed-drug.utility.ts | 87 ++ src/app/app-routing.module.ts | 55 +- src/app/app.module.ts | 37 +- .../facility-selection.component.css | 14 + .../facility-selection.component.html | 17 +- src/app/redir-in/redir-in.component.css | 16 + src/app/redir-in/redir-in.component.html | 5 + src/app/redir-in/redir-in.component.spec.ts | 45 + src/app/redir-in/redir-in.component.ts | 338 +++++ .../reset-password.component.css | 39 + .../reset-password.component.html | 134 ++ .../reset-password.component.spec.ts | 45 + .../reset-password.component.ts | 169 +++ .../set-password/set-password.component.css | 31 + .../set-password/set-password.component.html | 98 ++ .../set-password.component.spec.ts | 45 + .../set-password/set-password.component.ts | 156 ++ .../set-security-questions.component.css | 23 + .../set-security-questions.component.html | 218 +++ .../set-security-questions.component.spec.ts | 45 + .../set-security-questions.component.ts | 333 +++++ ...ent.prod.ts => environment.development.ts} | 0 src/environments/environment.ts | 16 +- src/index.html | 20 +- src/styles.css | 45 +- tsconfig.app.json | 2 +- 251 files changed, 19097 insertions(+), 3569 deletions(-) create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/indent-order-worklist.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/indent-order-worklist.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/indent-order-worklist.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/indent-order-worklist.component.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/indent-dispenses.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/indent-dispenses.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/indent-dispenses.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/indent-dispenses.component.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/manual-indent-dispense/manual-indent-dispense.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/manual-indent-dispense/manual-indent-dispense.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/manual-indent-dispense/manual-indent-dispense.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/manual-indent-dispense/manual-indent-dispense.component.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/manual-indent-dispense/select-batch-for-indent-item/select-batch-for-indent-item.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/manual-indent-dispense/select-batch-for-indent-item/select-batch-for-indent-item.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/manual-indent-dispense/select-batch-for-indent-item/select-batch-for-indent-item.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/manual-indent-dispense/select-batch-for-indent-item/select-batch-for-indent-item.component.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/system-indent-dispense/show-indent-batch-details/show-indent-batch-details.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/system-indent-dispense/show-indent-batch-details/show-indent-batch-details.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/system-indent-dispense/show-indent-batch-details/show-indent-batch-details.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/system-indent-dispense/show-indent-batch-details/show-indent-batch-details.component.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/system-indent-dispense/system-indent-dispense.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/system-indent-dispense/system-indent-dispense.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/system-indent-dispense/system-indent-dispense.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/indent-dispenses/system-indent-dispense/system-indent-dispense.component.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/main-store-indent-order-worklist.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/main-store-indent-order-worklist.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/main-store-indent-order-worklist.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/main-store-indent-order-worklist.component.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/main-store-item-model/main-store-item-model.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/main-store-item-model/main-store-item-model.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/main-store-item-model/main-store-item-model.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/main-store-item-model/main-store-item-model.component.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/reject-item-from-mainstore-model/reject-item-from-mainstore-model.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/reject-item-from-mainstore-model/reject-item-from-mainstore-model.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/reject-item-from-mainstore-model/reject-item-from-mainstore-model.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/main-store-indent-order-worklist/reject-item-from-mainstore-model/reject-item-from-mainstore-model.component.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/indent-request/indent-request.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/indent-request/indent-request.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/indent-request/indent-request.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/indent-request/indent-request.component.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/sub-store-indent-order-worklist.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/sub-store-indent-order-worklist.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/sub-store-indent-order-worklist.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/sub-store-indent-order-worklist.component.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/sub-store-item-model/sub-store-item-model.component.css create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/sub-store-item-model/sub-store-item-model.component.html create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/sub-store-item-model/sub-store-item-model.component.spec.ts create mode 100644 src/app/app-modules/inventory/indent/indent-order-worklist/sub-store-indent-order-worklist/sub-store-item-model/sub-store-item-model.component.ts create mode 100644 src/app/app-modules/inventory/reports/beneficiary-drug-issue-report/beneficiary-drug-issue-report.component.css create mode 100644 src/app/app-modules/inventory/reports/beneficiary-drug-issue-report/beneficiary-drug-issue-report.component.html create mode 100644 src/app/app-modules/inventory/reports/beneficiary-drug-issue-report/beneficiary-drug-issue-report.component.spec.ts create mode 100644 src/app/app-modules/inventory/reports/beneficiary-drug-issue-report/beneficiary-drug-issue-report.component.ts create mode 100644 src/app/app-modules/inventory/reports/consumption-report/consumption-report.component.css create mode 100644 src/app/app-modules/inventory/reports/consumption-report/consumption-report.component.html create mode 100644 src/app/app-modules/inventory/reports/consumption-report/consumption-report.component.spec.ts create mode 100644 src/app/app-modules/inventory/reports/consumption-report/consumption-report.component.ts create mode 100644 src/app/app-modules/inventory/reports/daily-stock-details-report/daily-stock-details-report.component.css create mode 100644 src/app/app-modules/inventory/reports/daily-stock-details-report/daily-stock-details-report.component.html create mode 100644 src/app/app-modules/inventory/reports/daily-stock-details-report/daily-stock-details-report.component.spec.ts create mode 100644 src/app/app-modules/inventory/reports/daily-stock-details-report/daily-stock-details-report.component.ts create mode 100644 src/app/app-modules/inventory/reports/daily-stock-summary-report/daily-stock-summary-report.component.css create mode 100644 src/app/app-modules/inventory/reports/daily-stock-summary-report/daily-stock-summary-report.component.html create mode 100644 src/app/app-modules/inventory/reports/daily-stock-summary-report/daily-stock-summary-report.component.spec.ts create mode 100644 src/app/app-modules/inventory/reports/daily-stock-summary-report/daily-stock-summary-report.component.ts create mode 100644 src/app/app-modules/inventory/reports/expiry-report/expiry-report.component.css create mode 100644 src/app/app-modules/inventory/reports/expiry-report/expiry-report.component.html create mode 100644 src/app/app-modules/inventory/reports/expiry-report/expiry-report.component.spec.ts create mode 100644 src/app/app-modules/inventory/reports/expiry-report/expiry-report.component.ts create mode 100644 src/app/app-modules/inventory/reports/inward-stock-report/inward-stock-report.component.css create mode 100644 src/app/app-modules/inventory/reports/inward-stock-report/inward-stock-report.component.html create mode 100644 src/app/app-modules/inventory/reports/inward-stock-report/inward-stock-report.component.spec.ts create mode 100644 src/app/app-modules/inventory/reports/inward-stock-report/inward-stock-report.component.ts create mode 100644 src/app/app-modules/inventory/reports/monthly-report/monthly-report.component.css create mode 100644 src/app/app-modules/inventory/reports/monthly-report/monthly-report.component.html create mode 100644 src/app/app-modules/inventory/reports/monthly-report/monthly-report.component.spec.ts create mode 100644 src/app/app-modules/inventory/reports/monthly-report/monthly-report.component.ts create mode 100644 src/app/app-modules/inventory/reports/short-expiry-report/short-expiry-report.component.css create mode 100644 src/app/app-modules/inventory/reports/short-expiry-report/short-expiry-report.component.html create mode 100644 src/app/app-modules/inventory/reports/short-expiry-report/short-expiry-report.component.spec.ts create mode 100644 src/app/app-modules/inventory/reports/short-expiry-report/short-expiry-report.component.ts create mode 100644 src/app/app-modules/inventory/reports/transit-report/transit-report.component.css create mode 100644 src/app/app-modules/inventory/reports/transit-report/transit-report.component.html create mode 100644 src/app/app-modules/inventory/reports/transit-report/transit-report.component.spec.ts create mode 100644 src/app/app-modules/inventory/reports/transit-report/transit-report.component.ts create mode 100644 src/app/app-modules/inventory/reports/yearly-report/yearly-report.component.css create mode 100644 src/app/app-modules/inventory/reports/yearly-report/yearly-report.component.html create mode 100644 src/app/app-modules/inventory/reports/yearly-report/yearly-report.component.spec.ts create mode 100644 src/app/app-modules/inventory/reports/yearly-report/yearly-report.component.ts create mode 100644 src/app/app-modules/inventory/utc-date.pipe.ts create mode 100644 src/app/app-modules/rx/rx-dashboard/rx-dashboard.component.css create mode 100644 src/app/app-modules/rx/rx-dashboard/rx-dashboard.component.html create mode 100644 src/app/app-modules/rx/rx-dashboard/rx-dashboard.component.spec.ts create mode 100644 src/app/app-modules/rx/rx-dashboard/rx-dashboard.component.ts create mode 100644 src/app/app-modules/rx/rx-item-dispense/rx-item-dispense.component.css create mode 100644 src/app/app-modules/rx/rx-item-dispense/rx-item-dispense.component.html create mode 100644 src/app/app-modules/rx/rx-item-dispense/rx-item-dispense.component.spec.ts create mode 100644 src/app/app-modules/rx/rx-item-dispense/rx-item-dispense.component.ts create mode 100644 src/app/app-modules/rx/rx-routing.module.ts create mode 100644 src/app/app-modules/rx/rx.module.ts create mode 100644 src/app/app-modules/rx/shared/service/prescribed-drug.service.spec.ts create mode 100644 src/app/app-modules/rx/shared/service/prescribed-drug.service.ts create mode 100644 src/app/app-modules/rx/shared/utility/index.ts create mode 100644 src/app/app-modules/rx/shared/utility/prescribed-drug.utility.ts create mode 100644 src/app/redir-in/redir-in.component.css create mode 100644 src/app/redir-in/redir-in.component.html create mode 100644 src/app/redir-in/redir-in.component.spec.ts create mode 100644 src/app/redir-in/redir-in.component.ts create mode 100644 src/app/reset-password/reset-password.component.css create mode 100644 src/app/reset-password/reset-password.component.html create mode 100644 src/app/reset-password/reset-password.component.spec.ts create mode 100644 src/app/reset-password/reset-password.component.ts create mode 100644 src/app/set-password/set-password.component.css create mode 100644 src/app/set-password/set-password.component.html create mode 100644 src/app/set-password/set-password.component.spec.ts create mode 100644 src/app/set-password/set-password.component.ts create mode 100644 src/app/set-security-questions/set-security-questions.component.css create mode 100644 src/app/set-security-questions/set-security-questions.component.html create mode 100644 src/app/set-security-questions/set-security-questions.component.spec.ts create mode 100644 src/app/set-security-questions/set-security-questions.component.ts rename src/environments/{environment.prod.ts => environment.development.ts} (100%) diff --git a/angular.json b/angular.json index 2283cc0..a3fe163 100644 --- a/angular.json +++ b/angular.json @@ -52,7 +52,7 @@ }, "development": { "buildOptimizer": false, - "optimization": false, + "optimization": true, "vendorChunk": true, "extractLicenses": false, "sourceMap": true, diff --git a/package-lock.json b/package-lock.json index af606bc..2714381 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,10 +18,13 @@ "@angular/platform-browser": "^16.2.0", "@angular/platform-browser-dynamic": "^16.2.0", "@angular/router": "^16.2.0", + "@types/file-saver": "^2.0.7", "angular": "^1.6.10", "angular-moment": "^1.3.0", "bootstrap": "^5.3.2", "crypto-js": "^4.2.0", + "exceljs": "^4.4.0", + "file-saver": "^2.0.5", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.13.0" @@ -3187,6 +3190,43 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + } + }, + "node_modules/@fast-csv/format/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + }, + "node_modules/@fast-csv/parse": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@fast-csv/parse/-/parse-4.3.6.tgz", + "integrity": "sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.groupby": "^4.6.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0", + "lodash.isundefined": "^3.0.1", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/@fast-csv/parse/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + }, "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", @@ -5007,6 +5047,11 @@ "@types/send": "*" } }, + "node_modules/@types/file-saver": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz", + "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==" + }, "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", @@ -5942,6 +5987,70 @@ "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "dev": true }, + "node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/archiver-utils/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/are-we-there-yet": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", @@ -5991,8 +6100,7 @@ "node_modules/async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" }, "node_modules/asynckit": { "version": "0.4.0", @@ -6151,14 +6259,12 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -6189,6 +6295,14 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "engines": { + "node": ">=0.6" + } + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -6198,6 +6312,18 @@ "node": "*" } }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -6211,13 +6337,17 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -6295,7 +6425,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6355,7 +6484,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "funding": [ { "type": "github", @@ -6375,12 +6503,36 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "engines": { + "node": ">=0.2.0" + } + }, "node_modules/builtins": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", @@ -6538,6 +6690,17 @@ } ] }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -6811,6 +6974,20 @@ "node": ">=4.0.0" } }, + "node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -6874,8 +7051,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/connect": { "version": "3.7.0", @@ -7028,8 +7204,7 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cors": { "version": "2.8.5", @@ -7088,6 +7263,29 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/critters": { "version": "0.0.20", "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.20.tgz", @@ -7326,6 +7524,11 @@ "node": ">=4.0" } }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -7603,6 +7806,41 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -7687,7 +7925,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "dependencies": { "once": "^1.4.0" } @@ -8416,6 +8653,36 @@ "node": ">=0.8.x" } }, + "node_modules/exceljs": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/exceljs/-/exceljs-4.4.0.tgz", + "integrity": "sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg==", + "dependencies": { + "archiver": "^5.0.0", + "dayjs": "^1.8.34", + "fast-csv": "^4.3.1", + "jszip": "^3.10.1", + "readable-stream": "^3.6.0", + "saxes": "^5.0.1", + "tmp": "^0.2.0", + "unzipper": "^0.10.11", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/exceljs/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -8597,6 +8864,18 @@ "node": ">=4" } }, + "node_modules/fast-csv": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz", + "integrity": "sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==", + "dependencies": { + "@fast-csv/format": "4.3.5", + "@fast-csv/parse": "4.3.6" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -8685,6 +8964,11 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -8926,8 +9210,7 @@ "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "node_modules/fs-extra": { "version": "8.1.0", @@ -8973,8 +9256,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -8990,6 +9272,31 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -9088,7 +9395,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -9165,8 +9471,7 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/graphemer": { "version": "1.4.0", @@ -9578,7 +9883,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -9652,6 +9956,11 @@ "node": ">=0.10.0" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "node_modules/immutable": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", @@ -9711,7 +10020,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -9720,8 +10028,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "4.1.1", @@ -9829,9 +10136,9 @@ } }, "node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", "dev": true }, "node_modules/ipaddr.js": { @@ -10026,8 +10333,7 @@ "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "node_modules/isbinaryfile": { "version": "4.0.10", @@ -10457,6 +10763,44 @@ "node >= 0.2.0" ] }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/karma": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.2.tgz", @@ -10652,6 +10996,44 @@ "shell-quote": "^1.8.1" } }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/less": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", @@ -10775,6 +11157,14 @@ } } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lilconfig": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", @@ -10972,6 +11362,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==" + }, "node_modules/listr2": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.0.tgz", @@ -11116,12 +11511,77 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==" + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==" + }, + "node_modules/lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, + "node_modules/lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -11879,7 +12339,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -11891,7 +12350,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -12123,7 +12581,6 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, "dependencies": { "minimist": "^1.2.6" }, @@ -12369,7 +12826,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -12978,7 +13434,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -13242,8 +13697,7 @@ "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, "node_modules/parent-module": { "version": "1.0.1", @@ -13362,7 +13816,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -13967,8 +14420,7 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/promise-inflight": { "version": "1.0.1", @@ -14224,7 +14676,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -14234,6 +14685,33 @@ "node": ">= 6" } }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -14466,7 +14944,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -14537,7 +15014,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -14629,7 +15105,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, "dependencies": { "xmlchars": "^2.2.0" }, @@ -14888,6 +15363,11 @@ "node": ">= 0.4" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -15407,7 +15887,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -15607,7 +16086,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -15890,6 +16368,14 @@ "node": ">=8" } }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", + "engines": { + "node": "*" + } + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -16216,6 +16702,50 @@ "node": ">= 0.8" } }, + "node_modules/unzipper": { + "version": "0.10.14", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", + "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==", + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/unzipper/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/unzipper/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -16268,8 +16798,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utils-merge": { "version": "1.0.1", @@ -16284,7 +16813,6 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, "bin": { "uuid": "dist/bin/uuid" } @@ -16945,8 +17473,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/ws": { "version": "7.5.9", @@ -16978,8 +17505,7 @@ "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, "node_modules/y18n": { "version": "5.0.8", @@ -17044,6 +17570,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/zone.js": { "version": "0.13.3", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.3.tgz", @@ -19136,6 +19695,47 @@ "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true }, + "@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "requires": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + } + } + }, + "@fast-csv/parse": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@fast-csv/parse/-/parse-4.3.6.tgz", + "integrity": "sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==", + "requires": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.groupby": "^4.6.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0", + "lodash.isundefined": "^3.0.1", + "lodash.uniq": "^4.5.0" + }, + "dependencies": { + "@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + } + } + }, "@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", @@ -20662,6 +21262,11 @@ "@types/send": "*" } }, + "@types/file-saver": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz", + "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==" + }, "@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", @@ -21385,6 +21990,66 @@ "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "dev": true }, + "archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "requires": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + } + }, + "archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "requires": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "are-we-there-yet": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", @@ -21428,8 +22093,7 @@ "async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" }, "asynckit": { "version": "0.4.0", @@ -21548,14 +22212,12 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "base64id": { "version": "2.0.0", @@ -21569,12 +22231,26 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, + "big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==" + }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "requires": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -21585,13 +22261,17 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, + "bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + }, "body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -21655,7 +22335,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -21692,18 +22371,32 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==" + }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==" + }, "builtins": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", @@ -21813,6 +22506,14 @@ "integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==", "dev": true }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "requires": { + "traverse": ">=0.3.0 <0.4" + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -22011,6 +22712,17 @@ "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", "dev": true }, + "compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + } + }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -22067,8 +22779,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "connect": { "version": "3.7.0", @@ -22190,8 +22901,7 @@ "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "cors": { "version": "2.8.5", @@ -22232,6 +22942,20 @@ } } }, + "crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" + }, + "crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "requires": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + } + }, "critters": { "version": "0.0.20", "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.20.tgz", @@ -22412,6 +23136,11 @@ "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", "dev": true }, + "dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -22621,6 +23350,43 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "requires": { + "readable-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -22692,7 +23458,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -23198,6 +23963,32 @@ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true }, + "exceljs": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/exceljs/-/exceljs-4.4.0.tgz", + "integrity": "sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg==", + "requires": { + "archiver": "^5.0.0", + "dayjs": "^1.8.34", + "fast-csv": "^4.3.1", + "jszip": "^3.10.1", + "readable-stream": "^3.6.0", + "saxes": "^5.0.1", + "tmp": "^0.2.0", + "unzipper": "^0.10.11", + "uuid": "^8.3.0" + }, + "dependencies": { + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + } + } + }, "execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -23353,6 +24144,15 @@ "tmp": "^0.0.33" } }, + "fast-csv": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz", + "integrity": "sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==", + "requires": { + "@fast-csv/format": "4.3.5", + "@fast-csv/parse": "4.3.6" + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -23426,6 +24226,11 @@ "flat-cache": "^3.0.4" } }, + "file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" + }, "filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -23604,8 +24409,7 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-extra": { "version": "8.1.0", @@ -23644,8 +24448,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.3", @@ -23654,6 +24457,27 @@ "dev": true, "optional": true }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -23722,7 +24546,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -23778,8 +24601,7 @@ "graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "graphemer": { "version": "1.4.0", @@ -24096,8 +24918,7 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { "version": "5.3.0", @@ -24141,6 +24962,11 @@ "dev": true, "optional": true }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "immutable": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", @@ -24187,7 +25013,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -24196,8 +25021,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "4.1.1", @@ -24280,9 +25104,9 @@ } }, "ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", "dev": true }, "ipaddr.js": { @@ -24417,8 +25241,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isbinaryfile": { "version": "4.0.10", @@ -24743,6 +25566,46 @@ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "dev": true }, + "jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "requires": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "karma": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.2.tgz", @@ -24903,6 +25766,43 @@ "shell-quote": "^1.8.1" } }, + "lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "requires": { + "readable-stream": "^2.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "less": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", @@ -24983,6 +25883,14 @@ "webpack-sources": "^3.0.0" } }, + "lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "requires": { + "immediate": "~3.0.5" + } + }, "lilconfig": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", @@ -25104,6 +26012,11 @@ } } }, + "listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==" + }, "listr2": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.0.tgz", @@ -25208,12 +26121,77 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==" + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==" + }, + "lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, + "lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==" + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -25758,7 +26736,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -25766,8 +26743,7 @@ "minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" }, "minipass": { "version": "5.0.0", @@ -25966,7 +26942,6 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, "requires": { "minimist": "^1.2.6" } @@ -26146,8 +27121,7 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-range": { "version": "0.1.2", @@ -26611,7 +27585,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "requires": { "wrappy": "1" } @@ -26804,8 +27777,7 @@ "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, "parent-module": { "version": "1.0.1", @@ -26897,8 +27869,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -27283,8 +28254,7 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "promise-inflight": { "version": "1.0.1", @@ -27478,13 +28448,38 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, + "readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "requires": { + "minimatch": "^5.1.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -27672,7 +28667,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -27712,8 +28706,7 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safer-buffer": { "version": "2.1.2", @@ -27757,7 +28750,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, "requires": { "xmlchars": "^2.2.0" } @@ -27975,6 +28967,11 @@ "has-property-descriptors": "^1.0.0" } }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -28375,7 +29372,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "requires": { "safe-buffer": "~5.2.0" } @@ -28550,7 +29546,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, "requires": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -28722,6 +29717,11 @@ "punycode": "^2.1.1" } }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==" + }, "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -28954,6 +29954,52 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, + "unzipper": { + "version": "0.10.14", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", + "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==", + "requires": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -28986,8 +30032,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "utils-merge": { "version": "1.0.1", @@ -28998,8 +30043,7 @@ "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-compile-cache": { "version": "2.3.0", @@ -29441,8 +30485,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "ws": { "version": "7.5.9", @@ -29460,8 +30503,7 @@ "xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, "y18n": { "version": "5.0.8", @@ -29508,6 +30550,35 @@ "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", "dev": true }, + "zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "requires": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "requires": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + } + } + } + }, "zone.js": { "version": "0.13.3", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.3.tgz", diff --git a/package.json b/package.json index 13214d8..41acdc7 100644 --- a/package.json +++ b/package.json @@ -27,10 +27,13 @@ "@angular/platform-browser": "^16.2.0", "@angular/platform-browser-dynamic": "^16.2.0", "@angular/router": "^16.2.0", + "@types/file-saver": "^2.0.7", "angular": "^1.6.10", "angular-moment": "^1.3.0", "bootstrap": "^5.3.2", "crypto-js": "^4.2.0", + "exceljs": "^4.4.0", + "file-saver": "^2.0.5", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.13.0" diff --git a/src/app/app-modules/core/components/app-footer/app-footer.component.css b/src/app/app-modules/core/components/app-footer/app-footer.component.css index 3cf8484..6303735 100644 --- a/src/app/app-modules/core/components/app-footer/app-footer.component.css +++ b/src/app/app-modules/core/components/app-footer/app-footer.component.css @@ -1,6 +1,6 @@ footer { background: rgb(37, 55, 70); - height: 25px; + height: 30px; padding: 3px; color: white; } diff --git a/src/app/app-modules/core/components/app-footer/app-footer.component.html b/src/app/app-modules/core/components/app-footer/app-footer.component.html index ac1c414..5f4fa4d 100644 --- a/src/app/app-modules/core/components/app-footer/app-footer.component.html +++ b/src/app/app-modules/core/components/app-footer/app-footer.component.html @@ -1,5 +1,5 @@