diff --git a/ui/src/app/modules/billing/pages/exemption-home/exemption-home.component.html b/ui/src/app/modules/billing/pages/exemption-home/exemption-home.component.html index 5f8bbe27b..57434a22a 100644 --- a/ui/src/app/modules/billing/pages/exemption-home/exemption-home.component.html +++ b/ui/src/app/modules/billing/pages/exemption-home/exemption-home.component.html @@ -1,26 +1,39 @@ -
+
- - Exemption + + + + + - -
- + + +
+
-
-

- No Exemption Requests at the moment -

+ + +
+

No Exemption Requests at the moment

-
\ No newline at end of file +
diff --git a/ui/src/app/modules/billing/pages/exemption-home/exemption-home.component.ts b/ui/src/app/modules/billing/pages/exemption-home/exemption-home.component.ts index 9ec8be233..0cce85aa4 100644 --- a/ui/src/app/modules/billing/pages/exemption-home/exemption-home.component.ts +++ b/ui/src/app/modules/billing/pages/exemption-home/exemption-home.component.ts @@ -1,26 +1,18 @@ -import { Component, EventEmitter, OnInit, Output } from "@angular/core"; +import { Component, OnDestroy, OnInit } from "@angular/core"; import { MatTableDataSource } from "@angular/material/table"; import { Router } from "@angular/router"; import { select, Store } from "@ngrx/store"; -import { Observable, of } from "rxjs"; -import { catchError, tap } from "rxjs/operators"; +import { Observable, of, Subject } from "rxjs"; +import { catchError, takeUntil, tap } from "rxjs/operators"; import { SystemSettingsService } from "src/app/core/services/system-settings.service"; import { TableColumn } from "src/app/shared/models/table-column.model"; import { TableConfig } from "src/app/shared/models/table-config.model"; import { Api } from "src/app/shared/resources/openmrs"; -import { - Visit, - VisitExt, -} from "src/app/shared/resources/visits/models/visit.model"; - +import { Visit, VisitExt } from "src/app/shared/resources/visits/models/visit.model"; import { VisitsService } from "../../../../shared/resources/visits/services"; import { AppState } from "src/app/store/reducers"; import { getCurrentLocation } from "src/app/store/selectors"; -import { - clearCurrentPatient, - go, - loadCurrentPatient, -} from "src/app/store/actions"; +import { clearCurrentPatient, go } from "src/app/store/actions"; import { clearActiveVisit } from "src/app/store/actions/visit.actions"; @Component({ @@ -28,23 +20,28 @@ import { clearActiveVisit } from "src/app/store/actions/visit.actions"; templateUrl: "./exemption-home.component.html", styleUrls: ["./exemption-home.component.scss"], }) -export class ExemptionHomeComponent implements OnInit { - visitsWithBiling$: Observable>; +export class ExemptionHomeComponent implements OnInit, OnDestroy { + visitsWithBilling$: Observable>; + visits$: Observable>; billingColumns: TableColumn[]; - loadingVisits: boolean; - loadingVisitsError: string; tableConfig: TableConfig; orderType$: Observable; currentLocation$: Observable; + orderType: any; - orderByDirection: any; - orderBy: any; - filterBy: any; + orderByDirection: string = "ASC"; + orderBy: string = "ENCOUNTER"; + filterBy: string = ""; currentLocation: any; - loadingPatients: boolean; - visits$: any; - visitsLength: number; - loading: boolean; + visitsLength: number = 0; + + loading: boolean = false; + loadingVisits: boolean = false; + loadingVisitsError: string; + + private exemptionTypes = ["Full", "Partial"]; + private additionalCriteria = ["Student", "Loan", "Other"]; + private unsubscribe$: Subject = new Subject(); constructor( private api: Api, @@ -54,111 +51,144 @@ export class ExemptionHomeComponent implements OnInit { private store: Store ) {} - ngOnInit() { + ngOnInit(): void { + this.initializeTableConfig(); + this.setupSubscriptions(); + this.getExemptionVisits(); + } + + ngOnDestroy(): void { + this.unsubscribe$.next(); + this.unsubscribe$.complete(); + } + + private getRandomItem(array: T[]): T { + return array[Math.floor(Math.random() * array.length)]; + } + + + private addMockDataToVisit(visit: any): any { + return { + ...visit, + exemptionType: this.getRandomItem(this.exemptionTypes), + exemptionCriteria: this.determineExemptionCriteria(visit.patientAge), + }; + } + + private initializeTableConfig(): void { this.billingColumns = [ - { - id: "index", - label: "#", - }, - { - id: "patientName", - label: "Name", - }, - { - id: "patientGender", - label: "Gender", - }, - { - id: "locationName", - label: "Location", - }, - { - id: "patientAge", - label: "Age", - }, + { id: "index", label: "#" }, + { id: "patientName", label: "Name" }, + { id: "patientGender", label: "Gender" }, + { id: "locationName", label: "Location" }, + { id: "patientAge", label: "Age" }, + { id: "exemptionType", label: "Exemption Type" }, + { id: "exemptionCriteria", label: "Exemption Criteria" }, ]; + this.tableConfig = new TableConfig({ noDataLabel: "No bills at the moment", + }); - this.loadingVisits = true; - this.visitsWithBiling$ = Visit.getVisitWithBillingOrders(this.api).pipe( - tap(() => { - this.loadingVisits = false; - }), + } + + private setupSubscriptions(): void { + this.currentLocation$ = this.store.pipe(select(getCurrentLocation(false))); + this.currentLocation$ + .pipe(takeUntil(this.unsubscribe$)) + .subscribe({ + next: (location) => (this.currentLocation = location), + error: (error) => console.error("Error getting current location:", error), + }); + + this.visitsWithBilling$ = Visit.getVisitWithBillingOrders(this.api).pipe( + tap(() => (this.loadingVisits = false)), catchError((error) => { this.loadingVisits = false; this.loadingVisitsError = error; return of(new MatTableDataSource([])); }) ); - - this.currentLocation$ = this.store.pipe(select(getCurrentLocation(false))); - - //Get current location - this.currentLocation$.subscribe({ - next: (currentLocation) => { - this.currentLocation = currentLocation; - }, - error: (error) => { - console.log( - "Error occured while trying to get current location: ", - error - ); - }, - }); - - this.getExemptionVisits(); } - getVisits(orderType) { - return this.visitService - .getAllVisits( - null, - false, - false, - null, - 0, - 10, - orderType?.value, - null, - null, - this.orderBy ? this.orderBy : "ENCOUNTER", - this.orderByDirection ? this.orderByDirection : "ASC", - this.filterBy ? this.filterBy : "" - ) - .pipe( - tap(() => { - this.loadingVisits = false; - }) - ); + private determineExemptionCriteria(age: number): string { + if (age < 5) { + return "Under 5"; // Children under 5 + } else if (age >= 60) { + return "Elderly"; // Seniors aged 60 and above + } else if (age >= 18 && age <= 25) { + return "Student"; // Students (assumed age range: 18-25) + } else { + return this.getRandomItem(this.additionalCriteria); // Default additional criteria + } + } + + private transformVisitData(visit: any, index: number): any { + const patientAge = visit.patient?.age || visit.patientAge || 0; // Ensure age is a number + + return { + ...visit, + index: index + 1, + exemptionType: visit.exemptionType || this.getRandomItem(this.exemptionTypes), + exemptionCriteria: visit.exemptionCriteria || this.determineExemptionCriteria(patientAge), // Use refined criteria + patientName: visit.patient?.name || visit.patientName || "Unknown", + patientGender: visit.patient?.gender || visit.patientGender || "Unknown", + patientAge: patientAge, // Explicitly use extracted age + locationName: visit.location?.name || visit.locationName || "Unknown", + }; } + - getExemptionVisits() { - //Get order type + getExemptionVisits(): void { + this.loading = true; this.orderType$ = this.systemSettingsService .getSystemSettingsMatchingAKey("icare.billing.exemption.orderType") .pipe( - tap((orderType) => { - return orderType[0]; - }), catchError((error) => { - console.log("Error occured while trying to get orderType: ", error); - return of(new MatTableDataSource([])); + console.error("Error getting orderType:", error); + return of([]); }) ); - this.orderType$.subscribe({ + this.orderType$.pipe(takeUntil(this.unsubscribe$)).subscribe({ next: (orderType) => { this.orderType = orderType[0]; - - this.getVisits(this.orderType).subscribe({ - next: (visits) => { - this.visits$ = of( - new MatTableDataSource(visits.map((visit) => new VisitExt(visit))) - ); - this.visitsLength = visits.length; - }, - }); + this.visitService + .getAllVisits( + null, + false, + false, + null, + 0, + 10, + this.orderType?.value, + null, + null, + this.orderBy, + this.orderByDirection, + this.filterBy + ) + .pipe(takeUntil(this.unsubscribe$)) + .subscribe({ + next: (visits) => { + const transformedVisits = visits.map((visit, index) => + this.transformVisitData(visit, index) + ); + this.visits$ = of(new MatTableDataSource(transformedVisits)); + this.visitsLength = transformedVisits.length; + this.loading = false; + }, + error: (error) => { + console.error("Error fetching visits:", error); + this.visits$ = of(new MatTableDataSource([])); + this.visitsLength = 0; + this.loading = false; + }, + }); + }, + error: (error) => { + console.error("Error in orderType subscription:", error); + this.loading = false; }, }); } @@ -167,8 +197,6 @@ export class ExemptionHomeComponent implements OnInit { this.store.dispatch(clearCurrentPatient()); this.store.dispatch(clearActiveVisit()); this.loading = true; - this.store.dispatch( - go({ path: [`/billing/${visit?.patientUuid}/exempt`] }) - ); + this.store.dispatch(go({ path: [`/billing/${visit?.patientUuid}/exempt`] })); } }