+
+
Group Search
border-radius: 10px;
color: #31708f;
font-weight: 700;
+ margin-bottom: 1rem;
"
>
Create New Group
@@ -51,10 +52,33 @@ Group Search
color: #31708f;
font-weight: 700;
margin-left: 15px;
+ margin-bottom: 1rem;
"
>
- View All Groups In This Facility
-
+ View All DC Groups In This Facility
+
+
+
+
+ View All OTZ Clubs In This Facility
+
diff --git a/src/app/group-manager/group-manager-search/group-manager-search.component.ts b/src/app/group-manager/group-manager-search/group-manager-search.component.ts
index 964abbbc9..4a1dc146e 100644
--- a/src/app/group-manager/group-manager-search/group-manager-search.component.ts
+++ b/src/app/group-manager/group-manager-search/group-manager-search.component.ts
@@ -1,4 +1,11 @@
-import { Component, OnInit, OnDestroy, TemplateRef } from '@angular/core';
+import {
+ Component,
+ OnInit,
+ OnDestroy,
+ TemplateRef,
+ ViewChild,
+ AfterViewInit
+} from '@angular/core';
import { CommunityGroupService } from '../../openmrs-api/community-group-resource.service';
import { ToastrFunctionService } from 'src/app/shared/services/toastr-function.service';
import * as _ from 'lodash';
@@ -17,6 +24,7 @@ import { Group } from '../../models/group.model';
import { GridOptions, RowNode } from 'ag-grid';
import { ProgramResourceService } from 'src/app/openmrs-api/program-resource.service';
import { IndividualConfig, ToastrService } from 'ngx-toastr';
+import { CohortOtzModuleResourceService } from 'src/app/etl-api/cohort-otz-module-resource.service';
@Component({
selector: 'group-manager-search',
templateUrl: './group-manager-search.component.html',
@@ -40,11 +48,14 @@ export class GroupManagerSearchComponent implements OnInit, OnDestroy {
public routeLoading = false;
fetchingGroups: boolean;
previousLocationUuid: string;
- columnDefs = this.generateColumns();
rowData: any;
+ columnDefs = this.generateColumns();
public gridOptions: GridOptions = this.getGridOptions();
public filterText = '';
hideGroupsInCurrentFacility: boolean;
+ public isOTZprogram = false;
+ public filterOTZ = '';
+ cohortUuids = new Map();
constructor(
private groupService: CommunityGroupService,
@@ -52,7 +63,8 @@ export class GroupManagerSearchComponent implements OnInit, OnDestroy {
private bsModalService: BsModalService,
private route: ActivatedRoute,
private programResourceService: ProgramResourceService,
- private toastrService: ToastrFunctionService
+ private toastrService: ToastrFunctionService,
+ private cohortOtzModuleResourceService: CohortOtzModuleResourceService
) {}
ngOnInit(): void {
@@ -89,27 +101,88 @@ export class GroupManagerSearchComponent implements OnInit, OnDestroy {
}
public showGroupsInFacilty() {
- this.rowData = [];
this.fetchingGroups = true;
+ this.filterText = '';
const locationUuid = this.router.url.split('/')[2];
- if (locationUuid !== this.previousLocationUuid) {
+
+ if (locationUuid === this.previousLocationUuid && this.isOTZprogram) {
+ this.rowData = [];
+ this.groupsInCurrentFacility = [];
+ this.isOTZprogram = false;
+ this.showDcGroupsInFacility(locationUuid);
+ } else if (locationUuid !== this.previousLocationUuid) {
this.fetchingGroups = true;
- const sub = this.groupService
- .getGroupsByLocationUuid(locationUuid)
- .subscribe((res) => {
- this.groupsInCurrentFacility = res.map((result) => new Group(result));
- this.hideGroupsInCurrentFacility = false;
- this.fetchingGroups = false;
- this.previousLocationUuid = locationUuid;
- this.rowData = this.groupsInCurrentFacility;
- console.log(this.rowData, 'rowData');
- });
- this.subscription.add(sub);
+ this.showDcGroupsInFacility(locationUuid);
} else {
this.rowData = this.groupsInCurrentFacility;
}
}
+ public showDcGroupsInFacility(locationUuid) {
+ const sub = this.groupService
+ .getGroupsByLocationUuid(locationUuid)
+ .subscribe((res) => {
+ this.groupsInCurrentFacility = res.map((result) => new Group(result));
+ this.hideGroupsInCurrentFacility = false;
+ this.fetchingGroups = false;
+ this.previousLocationUuid = locationUuid;
+ this.rowData = this.groupsInCurrentFacility;
+ this.filterText = 'HIV DIFFERENTIATED CARE PROGRAM';
+ if (this.gridOptions.api) {
+ this.gridOptions.api.onFilterChanged();
+ }
+ });
+ this.columnDefs = this.generateColumns();
+ this.subscription.add(sub);
+ }
+ public showOTZGroupsInFacilty() {
+ this.rowData = [];
+ this.fetchingGroups = true;
+ this.isOTZprogram = true;
+ const locationUuid = this.router.url.split('/')[2];
+ this.fetchingGroups = true;
+ this.getCohortSuppresionRate(locationUuid);
+ const sub = this.groupService
+ .getGroupsByLocationUuid(locationUuid)
+ .subscribe((res) => {
+ this.groupsInCurrentFacility = res.map((result) => {
+ const groupInstance = new Group(result);
+ groupInstance.viralSuppression =
+ this.cohortUuids.has(groupInstance.openmrsModel.uuid) &&
+ this.cohortUuids
+ .get(groupInstance.openmrsModel.uuid)
+ .suppression_rate_percentage.toFixed(2) + '%';
+ return groupInstance;
+ });
+ this.hideGroupsInCurrentFacility = false;
+ this.fetchingGroups = false;
+ // this.isOTZprogram = false;
+ this.rowData = this.groupsInCurrentFacility;
+ this.filterText = 'OTZ PROGRAM';
+ if (this.gridOptions.api) {
+ this.gridOptions.api.onFilterChanged();
+ }
+ });
+
+ this.columnDefs = this.generateColumns();
+ this.subscription.add(sub);
+ }
+
+ public generateCohortUuids(cohortData) {
+ cohortData.forEach((cohort) => {
+ this.cohortUuids.set(cohort.uuid, cohort);
+ });
+ return this.cohortUuids;
+ }
+
+ public getCohortSuppresionRate(locationUuid: string) {
+ return this.cohortOtzModuleResourceService
+ .getCohortSuppressionStatus(locationUuid)
+ .subscribe((data: any) => {
+ this.generateCohortUuids(data.result);
+ });
+ }
+
public navigateToGroupDetails(group, newGroup?) {
if (this.modalRef) {
this.modalRef.hide();
@@ -162,7 +235,8 @@ export class GroupManagerSearchComponent implements OnInit, OnDestroy {
return (
_.includes(node.data.display.toLowerCase(), filterCaseLowercase) ||
_.includes(node.data.facility.toLowerCase(), filterCaseLowercase) ||
- _.includes(node.data.status.toLowerCase(), filterCaseLowercase)
+ _.includes(node.data.status.toLowerCase(), filterCaseLowercase) ||
+ _.includes(node.data.program, this.filterText)
);
}
@@ -241,6 +315,50 @@ export class GroupManagerSearchComponent implements OnInit, OnDestroy {
caseSensitive: false
}
},
+ ...(this.isOTZprogram
+ ? [
+ {
+ headerName: 'Viral Suppression',
+ field: 'viralSuppression',
+ sortable: true,
+ filter: 'agTextColumnFilter',
+ width: 200,
+ filterParams: {
+ caseSensitive: false
+ }
+ },
+ {
+ headerName: 'Last Meeting Date',
+ field: 'lastMeetingDate',
+ sortable: true,
+ filter: 'agTextColumnFilter',
+ width: 200,
+ filterParams: {
+ caseSensitive: false
+ }
+ },
+ {
+ headerName: 'OTZ Champion',
+ field: 'otzChampion',
+ sortable: true,
+ filter: 'agTextColumnFilter',
+ width: 200,
+ filterParams: {
+ caseSensitive: false
+ }
+ },
+ {
+ headerName: 'Group Activity',
+ field: 'groupActivity',
+ sortable: true,
+ filter: 'agTextColumnFilter',
+ width: 200,
+ filterParams: {
+ caseSensitive: false
+ }
+ }
+ ]
+ : []),
{
headerName: 'Actions',
field: 'endDate',
diff --git a/src/app/group-manager/group-manager.module.ts b/src/app/group-manager/group-manager.module.ts
index b06933f05..144b1cad0 100644
--- a/src/app/group-manager/group-manager.module.ts
+++ b/src/app/group-manager/group-manager.module.ts
@@ -13,6 +13,7 @@ import { SuccessModalComponent } from './modals/success-modal.component';
import { GroupEditorComponent } from './group-editor/group-editor-component';
import { GroupSearchInputComponent } from './group-manager-search/group-search-input/group-search-input.component';
import { PatientSearchModule } from '../patient-search/patient-search.module';
+import { CohortOtzModuleResourceService } from '../etl-api/cohort-otz-module-resource.service';
@NgModule({
declarations: [
@@ -34,7 +35,7 @@ import { PatientSearchModule } from '../patient-search/patient-search.module';
PatientSearchModule
],
exports: [GroupSearchInputComponent, GroupEditorComponent],
- providers: [DatePipe],
+ providers: [DatePipe, CohortOtzModuleResourceService],
entryComponents: [
DatePickerModalComponent,
SuccessModalComponent,
diff --git a/src/app/group-manager/modals/group-transfer-modal.component.ts b/src/app/group-manager/modals/group-transfer-modal.component.ts
index 1d97862b0..7d4fcf1a3 100644
--- a/src/app/group-manager/modals/group-transfer-modal.component.ts
+++ b/src/app/group-manager/modals/group-transfer-modal.component.ts
@@ -21,9 +21,11 @@ import { Patient } from '../../models/patient.model';
{{ patient.person.display }} is enrolled in
- {{ groupToUnenroll.cohort.name }} under DC program. Would you like to
- unenroll from {{ groupToUnenroll.cohort.name }} and
- enroll in {{ groupToEnroll.name }} {{ groupToEnroll.startDate | date: 'yyyy-MM-dd' }}. Would you like to unenroll from
+ {{ groupToUnenroll.cohort.name }} and enroll in
+ {{ groupToEnroll.name }} ?
@@ -42,7 +44,9 @@ export class GroupTransferModalComponent implements OnInit {
constructor(public modalRef: BsModalRef) {}
- ngOnInit() {}
+ ngOnInit() {
+ console.log('groupToEnroll', this.groupToUnenroll);
+ }
confirm() {
this.modalRef.hide();
diff --git a/src/app/hiv-care-lib/dqa-reports/chart-abstraction-patientlist/chart-abstraction-patientlist.component.ts b/src/app/hiv-care-lib/dqa-reports/chart-abstraction-patientlist/chart-abstraction-patientlist.component.ts
index c413c900e..86c445237 100644
--- a/src/app/hiv-care-lib/dqa-reports/chart-abstraction-patientlist/chart-abstraction-patientlist.component.ts
+++ b/src/app/hiv-care-lib/dqa-reports/chart-abstraction-patientlist/chart-abstraction-patientlist.component.ts
@@ -42,7 +42,7 @@ export class ChartAbstractionPatientlistComponent implements OnInit {
startDate: this.params.startDate,
endDate: this.params.endDate,
patientType: this.params.patientType,
- limit: this.params.limit ? this.params.limit : 10,
+ limit: this.params.limit ? this.params.limit : 'all',
offset: 0
};
this.getPatientList(requestParams);
@@ -71,32 +71,48 @@ export class ChartAbstractionPatientlistComponent implements OnInit {
hide = false;
}
const extraColumns = {
- birthdate: 'DOB',
- sex_gender: 'Gender',
- drugs_given: 'Current Regimen',
+ NUPI: 'NUPI',
+ sex_gender: 'Sex',
+ birthdate: 'Date of Birth (DD/MM/YYYY)',
+ hiv_start_date: 'Date Confirmed HIV Positive (DD/MM/YYYY)',
+ arv_first_regimen_start_date: 'Date of ART Initiation (DD/MM/YYYY)',
+ arv_start_date: 'Date of Current ART Initiation (DD/MM/YYYY)',
+ drugs_given: 'Current ART Regimen',
+ cur_arv_med_basis: 'Current ART Regimen',
drugs_duration: 'Drug dosage given (duration)',
- weight: 'Weight',
- height: 'Height',
- muac: 'MUAC',
- BMI: 'BMI',
+ height: 'Height at Last visit',
+ weight: 'Weight at Last visit',
+ BMI: 'BMI at Last visit',
+ muac: 'MUAC at Last visit',
+ tb_screened_this_visit: 'Was TB Screening done at last visit',
+ tb_screening_result: 'TB Screening outcomes',
+ last_ipt_start_date: 'IPT start date (DD/MM/YYYY)',
+ tpt_status: 'IPT status',
+ ipt_completion_date: 'IPT outcome date (DD/MM/YYYY)',
+ viral_load_validity: 'Does the client have a Valid Viral load result',
+ vl_suppression: 'Is the client virally suppressed',
+ cd4_1: 'Baseline screening for CD4',
+ has_cd4_1: 'Does this client have Baseline screening for CD4',
+ is_crag_screened: 'Does this client have Baseline screening for CrAG',
+ last_clinical_encounter: 'Last clinical encounter date (DD/MM/YYYY)',
sysBP: 'Systolic BP',
dysBP: 'Diastolic BP',
nutrition: 'Nutrition Assessment Done',
DSD: 'DSD Model',
- hiv_start_date: 'Date Confirmed HIV Positive',
- arv_start_date: 'Date of ART Initiation',
- cd4_1: 'Baseline CD4 Test Result',
- vl_1: 'Latest Valid VL',
- tpt_status: 'TPT Status',
+ // cd4_1: 'Baseline CD4 Test Result',
+ // vl_1: 'Latest Valid VL',
+ vl_1: 'Does the client have a Valid viral load result',
ovcid_id: 'OVCID',
- last_ipt_start_date: 'TPT initiated',
- ipt_stop_date: 'TPT Stop Date',
- ipt_completion_date: 'TPT Completion Date',
- last_clinical_encounter: 'Last Clinical Encounter',
- last_appointment_date: 'Date of Last Appointment',
- next_appointment: 'Date of Next Appointment ',
+ ipt_stop_date: 'IPT Stop Date (DD/MM/YYYY)',
+ // last_clinical_encounter: 'Last Clinical Encounter',
+ // last_appointment_date: 'Date of Last Appointment',
+ next_appointment: 'Next appointment date (DD/MM/YYYY)',
+ // next_appointment: 'Date of Next Appointment ',
visit_type: 'Visit Type',
- tb_screened_this_visit: 'TB screening'
+ status: 'Status',
+ // is_crag_screened: 'Baseline CrAG Screened',
+ cur_who_stage: 'Current Who Stage',
+ category: 'Category'
};
for (const indicator in extraColumns) {
if (indicator) {
@@ -107,64 +123,79 @@ export class ChartAbstractionPatientlistComponent implements OnInit {
}
}
this.overrideColumns.push(
+ { field: 'ccc_number', hide: true, pinned: true },
{
field: 'birthdate',
- cellRenderer: (column) => {
- if (column.value != null) {
- return moment(column.value).format('YYYY-MM-DD');
- }
- },
+ // cellRenderer: (column) => {
+ // if (column.value != null) {
+ // // return moment(column.value).format('YYYY-MM-DD');
+ // return moment(column.value).format('DD-MMM-YYYY');
+ // }
+ // return 'missing';
+ // },
pinned: false
},
{
- field: 'last_appointment_date',
- cellRenderer: (column) => {
- if (column.value != null) {
- return moment(column.value).format('DD-MM-YYYY');
- }
- }
+ field: 'last_appointment_date'
+ // cellRenderer: (column) => {
+ // if (column.value != null) {
+ // return moment(column.value).format('DD-MM-YYYY');
+ // }
+ // }
+ },
+ {
+ field: 'arv_first_regimen_start_date'
+ // cellRenderer: (column) => {
+ // if (column.value != null) {
+ // if (moment(column.value).isBefore('1900-01-01', 'year')){
+ // return column.value;
+ // }
+ // return ''
+ // }
+ // }
},
{
field: 'arv_start_date',
- cellRenderer: (column) => {
- if (column.value != null) {
- return moment(column.value).format('DD-MM-YYYY');
- }
- }
+ // cellRenderer: (column) => {
+ // if (column.value != null) {
+ // return moment(column.value).format('DD-MM-YYYY');
+ // }
+ // },
+ hide: true
},
{
- field: 'hiv_start_date',
- cellRenderer: (column) => {
- if (column.value != null) {
- return moment(column.value).format('DD-MM-YYYY');
- }
- }
+ field: 'hiv_start_date'
+ // cellRenderer: (column) => {
+ // if (column.value != null) {
+ // return moment(column.value).format('DD-MM-YYYY');
+ // }
+ // }
},
{
- field: 'last_clinical_encounter',
- cellRenderer: (column) => {
- if (column.value != null) {
- return moment(column.value).format('DD-MM-YYYY');
- }
- }
+ field: 'last_clinical_encounter'
+ // cellRenderer: (column) => {
+ // if (column.value != null) {
+ // return moment(column.value).format('DD-MM-YYYY');
+ // }
+ // }
},
{
- field: 'next_appointment',
- cellRenderer: (column) => {
- if (column.value != null) {
- return moment(column.value).format('DD-MM-YYYY');
- }
- }
+ field: 'next_appointment'
+ // cellRenderer: (column) => {
+ // if (column.value != null) {
+ // return moment(column.value).format('DD-MM-YYYY');
+ // }
+ // }
},
{
- field: 'tb_screened_this_visit',
- width: 150,
- cellRenderer: (column) => {
- if (column.value === 0) {
- return 'NO';
- }
- return 'YES';
- }
+ field: 'tb_screened_this_visit'
+ // width: 150,
+ // cellRenderer: (column) => {
+ // if (column.value === 0) {
+ // return 'No';
+ // }
+ // return 'Yes';
+ // }
},
{
field: 'vl_1',
@@ -173,7 +204,8 @@ export class ChartAbstractionPatientlistComponent implements OnInit {
return 'LDL';
}
return column.value;
- }
+ },
+ hide: true
},
{
field: 'nutrition',
@@ -187,42 +219,36 @@ export class ChartAbstractionPatientlistComponent implements OnInit {
},
{
field: 'last_ipt_start_date',
- cellRenderer: (column) => {
- if (column.value != null) {
- return moment(column.value).format('DD-MM-YYYY');
- }
- },
- hide: true
+ // cellRenderer: (column) => {
+ // if (column.value != null) {
+ // return moment(column.value).format('DD-MM-YYYY');
+ // }
+ // },
+ hide: false
},
{
field: 'ipt_completion_date',
- cellRenderer: (column) => {
- if (column.value != null) {
- return moment(column.value).format('DD-MM-YYYY');
- }
- },
- hide: true
+ // cellRenderer: (column) => {
+ // if (column.value != null) {
+ // return moment(column.value).format('DD-MM-YYYY');
+ // }
+ // },
+ hide: false
},
{
field: 'ipt_stop_date',
- cellRenderer: (column) => {
- if (column.value != null) {
- return moment(column.value).format('DD-MM-YYYY');
- }
- },
- hide: true
- },
- {
- field: 'arv_start_date',
- cellRenderer: (column) => {
- if (column.value != null) {
- return moment(column.value).format('DD-MM-YYYY');
- }
- }
+ // cellRenderer: (column) => {
+ // if (column.value != null) {
+ // return moment(column.value).format('DD-MM-YYYY');
+ // }
+ // },
+ hide: true,
+ suppressToolPanel: true
},
{
field: 'drugs_given',
- width: 280
+ width: 280,
+ hide: true
},
{
field: 'height',
@@ -238,7 +264,9 @@ export class ChartAbstractionPatientlistComponent implements OnInit {
},
{
field: 'visit_type',
- width: 150
+ width: 150,
+ hide: true,
+ suppressToolPanel: true
},
{
field: 'muac',
@@ -247,15 +275,28 @@ export class ChartAbstractionPatientlistComponent implements OnInit {
{
field: 'person_id',
width: 200,
- pinned: true
+ pinned: true,
+ suppressToolPanel: true
},
{
field: 'NUPI',
+ width: 150
+ // pinned: true
+ },
+ {
+ field: 'upi_number',
width: 150,
- pinned: true
+ hide: true,
+ pinned: true,
+ suppressToolPanel: true
},
{
field: 'drugs_given',
+ width: 280,
+ hide: true
+ },
+ {
+ field: 'cur_arv_med_basis',
width: 280
},
{
@@ -264,26 +305,33 @@ export class ChartAbstractionPatientlistComponent implements OnInit {
},
{
field: 'drugs_duration',
- width: 150
+ width: 150,
+ hide: true,
+ suppressToolPanel: true
},
{
field: 'person_name',
width: 150,
- hide: true
+ hide: true,
+ suppressToolPanel: true
},
{
field: 'gender',
width: 150,
- hide: true
+ hide: true,
+ suppressToolPanel: true
},
{
field: 'identifiers',
width: 150,
- hide: true
+ hide: true,
+ suppressToolPanel: true
},
{
field: 'age',
- width: 150
+ width: 150,
+ hide: true,
+ suppressToolPanel: true
},
{
field: 'sex_gender',
@@ -292,11 +340,69 @@ export class ChartAbstractionPatientlistComponent implements OnInit {
{
field: '#',
width: 150,
- hide: true
+ hide: true,
+ suppressToolPanel: true
},
{
field: 'visit_type',
width: 150,
+ hide: true,
+ suppressToolPanel: true
+ },
+ {
+ field: 'sysBP',
+ width: 150,
+ hide: true,
+ suppressToolPanel: true
+ },
+ {
+ field: 'dysBP',
+ width: 150,
+ hide: true,
+ suppressToolPanel: true
+ },
+ {
+ field: 'nutrition',
+ width: 150,
+ hide: true,
+ suppressToolPanel: true
+ },
+ {
+ field: 'DSD',
+ width: 150,
+ hide: true,
+ suppressToolPanel: true
+ },
+ {
+ field: 'ovcid_id',
+ width: 150,
+ hide: true,
+ suppressToolPanel: true
+ },
+ {
+ field: 'cur_who_stage',
+ width: 150,
+ hide: true,
+ suppressToolPanel: true
+ },
+ {
+ field: 'vl_suppression',
+ width: 150,
+ hide: false
+ },
+ {
+ field: 'is_crag_screened',
+ width: 150,
+ hide: false
+ },
+ {
+ field: 'status',
+ width: 150,
+ hide: true
+ },
+ {
+ field: 'cd4_1',
+ width: 150,
hide: true
}
);
diff --git a/src/app/hiv-care-lib/family-testing/family-testing-contact-list.component.ts b/src/app/hiv-care-lib/family-testing/family-testing-contact-list.component.ts
index df5208b7f..10716efd4 100644
--- a/src/app/hiv-care-lib/family-testing/family-testing-contact-list.component.ts
+++ b/src/app/hiv-care-lib/family-testing/family-testing-contact-list.component.ts
@@ -277,7 +277,7 @@ export class FamilyTestingContactComponent implements OnInit {
}
public onAddContactClick() {
- const defaulterTracingFormV1Uuid = 'bf6d0d9a-e6af-48fd-9245-6d1939adb37d';
+ const defaulterTracingFormV1Uuid = 'f3ba9242-9bbb-4284-a0c0-56ac6f0cec65';
const url = `/patient-dashboard/patient/${this.patientUuid}/general/general/formentry/${defaulterTracingFormV1Uuid}`;
this.router.navigate([url], {});
}
diff --git a/src/app/models/group.model.ts b/src/app/models/group.model.ts
index 5c205a6c8..eaecc745a 100644
--- a/src/app/models/group.model.ts
+++ b/src/app/models/group.model.ts
@@ -4,6 +4,7 @@ import * as _ from 'lodash';
const program_visits_config = require('../program-visit-encounter-search/program-visits-config.json');
export class Group extends BaseModel {
+ private _viralSuppression: string;
constructor(openmrsModel?: any) {
super(openmrsModel);
this._openmrsModel.display = this._openmrsModel.name;
@@ -38,6 +39,17 @@ export class Group extends BaseModel {
@serializable()
public get status() {
+ const lastMeetingDate = this.getLatestMeetingDate(
+ this._openmrsModel.cohortVisits
+ );
+ // if last meeting date is more than 3 months ago, group is inactive
+ if (lastMeetingDate) {
+ const today = new Date();
+ const threeMonthsAgo = new Date(today.setMonth(today.getMonth() - 3));
+ if (lastMeetingDate < threeMonthsAgo) {
+ return 'Inactive';
+ }
+ }
return this._openmrsModel.endDate ? 'Disbanded' : 'Active';
}
@@ -62,6 +74,34 @@ export class Group extends BaseModel {
return this.getGroupMembersCount(this._openmrsModel.cohortMembers);
}
+ @serializable()
+ public get otzChampion() {
+ const attrType = this.getCurrentLeader(this._openmrsModel.cohortLeaders);
+ if (attrType) {
+ return attrType.person.display.replace(/\d+|-/g, '');
+ }
+ return null;
+ }
+
+ @serializable()
+ public get groupActivity() {
+ const attrType = 'groupActivity';
+ return this.getAttribute(attrType, this._openmrsModel.attributes);
+ }
+
+ public get viralSuppression() {
+ return this._viralSuppression || 'Unkown %';
+ }
+
+ public set viralSuppression(value: string) {
+ this._viralSuppression = value;
+ }
+
+ @serializable()
+ public get lastMeetingDate() {
+ return this.getLatestMeetingDate(this._openmrsModel.cohortVisits);
+ }
+
public getAttribute(attributeType, attributes) {
const attr = _.filter(
attributes,
@@ -73,10 +113,37 @@ export class Group extends BaseModel {
return null;
}
+ public getLatestMeetingDate(startDates) {
+ if (startDates.length > 0) {
+ const latestStartDateString = startDates.reduce(
+ (maxDate, currentDateObject) => {
+ const currentStartDate = new Date(currentDateObject.startDate);
+ const maxStartDate = maxDate ? new Date(maxDate.startDate) : null;
+
+ if (!maxStartDate || currentStartDate > maxStartDate) {
+ return currentDateObject;
+ } else {
+ return maxDate;
+ }
+ },
+ null
+ ).startDate;
+ return new Date(latestStartDateString);
+ }
+ }
+
public getGroupMembersCount(cohortMembers) {
const active_members = cohortMembers.filter(
(current) => current.endDate == null
);
return active_members ? active_members.length : 0;
}
+
+ public getCurrentLeader(allLeaders: any[]) {
+ const currentLeader = _.filter(
+ allLeaders,
+ (leader) => leader.endDate == null
+ )[0];
+ return currentLeader;
+ }
}
diff --git a/src/app/openmrs-api/community-group-resource.service.ts b/src/app/openmrs-api/community-group-resource.service.ts
index 1c3f759a2..01e928abf 100644
--- a/src/app/openmrs-api/community-group-resource.service.ts
+++ b/src/app/openmrs-api/community-group-resource.service.ts
@@ -12,7 +12,7 @@ export class CommunityGroupService {
public cachedResults: BehaviorSubject
= new BehaviorSubject([]);
public v = 'full';
public _v =
- 'custom:(uuid,name,description,startDate,endDate,location:(display),attributes,cohortMembers:(uuid,endDate))';
+ 'custom:(uuid,name,description,cohortLeaders,startDate,endDate,location:(display),cohortVisits:(startDate),attributes,cohortMembers:(uuid,endDate))';
constructor(
private http: HttpClient,
diff --git a/src/app/openmrs-api/encounter-resource.service.ts b/src/app/openmrs-api/encounter-resource.service.ts
index ce1b9f197..a9f6f8181 100644
--- a/src/app/openmrs-api/encounter-resource.service.ts
+++ b/src/app/openmrs-api/encounter-resource.service.ts
@@ -11,6 +11,7 @@ export class EncounterResourceService {
'patient:(uuid,uuid),form:(uuid,name),' +
'visit:(uuid,display,auditInfo,startDatetime,stopDatetime,location:(uuid,display)' +
',visitType:(uuid,name)),' +
+ 'obs:(uuid,obsDatetime,concept:(uuid,uuid,name:(display),datatype),value:ref,groupMembers),' +
'location:ref,encounterType:ref,encounterProviders:(uuid,display,provider:(uuid,display)))';
constructor(
diff --git a/src/app/patient-dashboard/common/formentry/formentry.component.html b/src/app/patient-dashboard/common/formentry/formentry.component.html
index fc281b3f1..f8725d48d 100644
--- a/src/app/patient-dashboard/common/formentry/formentry.component.html
+++ b/src/app/patient-dashboard/common/formentry/formentry.component.html
@@ -142,13 +142,20 @@
minWidth="300"
closeresponsive="true"
>
-
+
Form submitted successfully.
+
+
+
+
+
+ Patient has been enrolled to OTZ program.
+
Differentiated Care Referral
@@ -261,6 +268,14 @@
>
Group Manager
+
+ Group Manager
+
{
console.error('error', err);
@@ -1282,6 +1297,30 @@ export class FormentryComponent implements OnInit, OnDestroy {
);
}
+ private enrollPatientToOtzProgram() {
+ const formattedDate = new Date(this.extractEncounterDate())
+ .toISOString()
+ .slice(0, 10);
+ const payload = {
+ programUuid: '203571d6-a4f2-4953-9e8b-e1105e2340f5',
+ patient: this.patient,
+ dateEnrolled: formattedDate,
+ dateCompleted: '',
+ location: this.encounterLocation.value,
+ enrollmentUuid: ''
+ };
+
+ this.programManagerService.enrollPatient(payload).subscribe(
+ (enrollment) => {
+ console.log('response', enrollment);
+ this.isBusyIndicator(false);
+ },
+ (error) => {
+ console.log('error', error);
+ }
+ );
+ }
+
private checkDuplicate(payloadTypes) {
this.patientService.currentlyLoadedPatientUuid
.pipe(
diff --git a/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.css b/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.css
new file mode 100644
index 000000000..4afd9ba5d
--- /dev/null
+++ b/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.css
@@ -0,0 +1,260 @@
+.btn-success.text-white {
+ color: white !important;
+}
+
+@media screen and (min-width: 600px) {
+ .program-header {
+ width: 70%;
+ }
+}
+
+.program-header-wrapper {
+ /* background-color: #203864; */
+ color: #ccc;
+}
+
+.program .program-header,
+.program .program-footer {
+ margin: 0 20px 0 20px;
+ font-size: 1.72rem;
+ border: none;
+ padding: 0 0;
+ font-family: Lato, 'Helvetica Neue', Arial, Helvetica, sans-serif;
+ font-weight: 700;
+ line-height: 36px;
+ text-transform: none;
+ color: #fff;
+ opacity: 0.9;
+}
+
+.program.non-enrolled .program-body {
+ padding: 12px;
+}
+
+.program.non-enrolled .program-header-wrapper {
+ color: inherit;
+}
+
+.program-container-fluid {
+ padding-right: 15px;
+ padding-left: 15px;
+}
+
+.program .program-body {
+ padding-top: 12px;
+ padding-bottom: 12px;
+}
+
+.program.non-enrolled .program-body {
+ border-top: 1px solid rgba(34, 36, 38, 0.15);
+}
+
+.program .program-footer {
+ /* background-color: whitesmoke; */
+ color: #fff;
+ margin: 0;
+ padding: 5px 12px;
+ /* border: 1px solid rgba(34, 36, 38, 0.15); */
+ border-top: 0;
+}
+
+.program-footer a.btn {
+ color: #fff !important;
+ display: inline-block;
+ margin-right: 10px;
+ padding: 6px 9px;
+}
+
+.program-footer a.btn:last-child {
+ margin-right: 0;
+}
+
+a.btn.btn-info {
+ margin-bottom: 0;
+ margin-left: 0;
+}
+
+.component-title {
+ font-size: 22px;
+ text-transform: capitalize;
+ padding-bottom: 8px;
+ border-bottom: 1px solid rgba(34, 36, 38, 0.15);
+ margin-bottom: 20px;
+ padding-left: 2.5rem;
+}
+
+.program hr {
+ margin: 1rem 0;
+ line-height: 1;
+ height: 0;
+ font-weight: 700;
+ font-size: 1rem;
+ clear: both;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ color: rgba(0, 0, 0, 0.85);
+ user-select: none;
+ border-top: 1px solid rgba(34, 36, 38, 0.15);
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.program .enrolled {
+ margin-bottom: 20px;
+}
+
+.clear {
+ clear: both;
+}
+
+h3 {
+ padding-top: 0;
+}
+
+.program-header-wrapper {
+ background-color: #203864;
+ color: #ccc;
+ border: 2px solid rgba(34, 36, 38, 0.15);
+ border-radius: 4px;
+ margin-bottom: 8px;
+}
+
+.program.non-enrolled .program-body {
+ padding: 12px;
+}
+
+.program.non-enrolled .program-header-wrapper {
+ background-color: darkred;
+ color: #ccc;
+}
+
+.program .program-body {
+ padding-top: 12px;
+ padding-bottom: 12px;
+ border-left: 1px solid rgba(34, 36, 38, 0.15);
+ border-right: 1px solid rgba(34, 36, 38, 0.15);
+ border-bottom: 1px solid rgba(34, 36, 38, 0.15);
+}
+
+.program .program-footer {
+ /* background-color: whitesmoke; */
+ color: #fff;
+ margin: 0;
+ padding: 5px;
+ /* border: 1px solid rgba(34, 36, 38, 0.15); */
+ border-top: 0;
+}
+
+.program-container-fluid {
+ padding: 0 10px 0 10px;
+}
+
+.program hr {
+ margin: 1rem 0;
+ line-height: 1;
+ height: 0;
+ font-weight: 700;
+ font-size: 1rem;
+ clear: both;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ color: rgba(0, 0, 0, 0.85);
+ user-select: none;
+ border-top: 1px solid rgba(34, 36, 38, 0.15);
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.program .enrolled {
+ margin-bottom: 20px;
+}
+
+.clear {
+ clear: both;
+}
+
+.fa-pencil:before {
+ margin-right: 5px;
+}
+
+label.buttons {
+ height: 22px;
+ display: block;
+}
+
+.enroll-button {
+ margin-top: -2px;
+}
+
+.buttons button {
+ float: left;
+}
+
+.otz-header {
+ display: flex;
+ justify-content: space-between;
+}
+
+ul li {
+ list-style: none !important;
+ padding-top: 24px;
+ font-weight: 400;
+ font-size: 18px;
+ font-style: bold;
+}
+
+.otz-nav-header li {
+ list-style: none !important;
+ padding: 6px 22px;
+ margin: 0 2px;
+ border: 1px solid #1081c2;
+ border-radius: 4px;
+ font-size: 18px;
+ color: rgb(0, 140, 255);
+ cursor: pointer;
+}
+
+.otz-nav-header {
+ display: flex;
+ justify-content: space-between;
+ margin-left: -40px;
+}
+
+.otz-content-wrapper {
+ margin-left: -38px;
+}
+
+.thead-blue {
+ background-color: #086becee;
+ color: #fff;
+}
+
+.theader-appoint {
+ padding: 8px 4px;
+ font-size: 18px;
+ margin: 0 2px;
+}
+
+.ldl-col {
+ color: green;
+}
+
+.low-risk-col {
+ color: orangered;
+}
+
+.high-risk-col {
+ color: orange;
+}
+
+.treatment-col {
+ color: red;
+}
+
+.disc-form {
+ color: black;
+ background-color: MediumSeaGreen;
+ padding: 8px;
+ border-radius: 4px;
+ width: 50%;
+ font-size: 20px;
+ font-weight: bold;
+}
diff --git a/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.html b/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.html
new file mode 100644
index 000000000..f9364cfb6
--- /dev/null
+++ b/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.html
@@ -0,0 +1,216 @@
+
+
+
Patient not eligible for OTZ Program (age 10 and 24)
+
+
+
+
+ Reason for Discontinuation:
+ {{ reasonForDiscontinuation }}
+
+
+
+
+
+
+
+
+
+
+ Last Encounter Date:
+ {{ patientData?.encounter_datetime }}
+
+
+ ARV Regimen: {{ patientData?.arv_first_regimen }}
+
+
+ RTC Date: {{ patientData?.rtc_date }}
+
+ Module:
+
+ Last Viral Load:
+ {{ patientData?.vl_1 | zeroVl }}
+
+
+ Last Viral Load Date:
+
+
+ {{ patientData?.vl_1_date | date: 'dd-MM-yyyy' }}
+
+
+
+
+ Viral Load Categorization:
+
+
+ {{ viralLoadCategory }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ patientData?.prev_rtc_date | date: 'dd-MM-yyyy' }}
+
+ {{ patientData?.encounter_type_name }}
+ {{ patientData?.rtc_date | date: 'dd-MM-yyyy' }}
+
+ {{ patientData?.med_pickup_rtc_date | date: 'dd-MM-yyyy' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ patientData?.encounter_datetime }}
+ {{ patientData?.cur_arv_adherence }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.test_datetime | date: 'dd-MM-yyyy' }}
+
+ {{ item.hiv_viral_load }}
+ 50 && item.hiv_viral_load <= 200,
+ 'high-risk-col':
+ item.hiv_viral_load > 200 && item.hiv_viral_load <= 500,
+ 'treatment-col': item.hiv_viral_load > 500
+ }"
+ >
+ {{
+ item.hiv_viral_load <= 50
+ ? 'LDL'
+ : item.hiv_viral_load <= 200
+ ? 'Low Risk Low Level Viremia'
+ : item.hiv_viral_load <= 500
+ ? 'High Risk Low Level Viremia'
+ : 'Suspected Treatment Failure'
+ }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.spec.ts b/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.spec.ts
new file mode 100644
index 000000000..16e1099be
--- /dev/null
+++ b/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.spec.ts
@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { OtzSnapshotComponent } from './otz-snapshot.component';
+
+describe('OtzSnapshotComponent', () => {
+ let component: OtzSnapshotComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [OtzSnapshotComponent]
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OtzSnapshotComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.ts b/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.ts
new file mode 100644
index 000000000..3974c4851
--- /dev/null
+++ b/src/app/patient-dashboard/common/otz-snapshot/otz-snapshot.component.ts
@@ -0,0 +1,215 @@
+import { Component, OnInit } from '@angular/core';
+import { Router, ActivatedRoute } from '@angular/router';
+import { Patient } from 'src/app/models/patient.model';
+import { PatientService } from '../../services/patient.service';
+import { HivSummaryResourceService } from 'src/app/etl-api/hiv-summary-resource.service';
+import { EncounterResourceService } from 'src/app/openmrs-api/encounter-resource.service';
+import { LabsResourceService } from 'src/app/etl-api/labs-resource.service';
+import { take } from 'rxjs/operators';
+import * as moment from 'moment';
+import * as _ from 'lodash';
+
+@Component({
+ selector: 'app-otz-snapshot',
+ templateUrl: './otz-snapshot.component.html',
+ styleUrls: ['./otz-snapshot.component.css']
+})
+export class OtzSnapshotComponent implements OnInit {
+ selectedItem = 'summary';
+ subscription: any;
+ patient: Patient;
+ otzEnrollment = false;
+ programManagerUrl: any;
+ groupManagerUrl: any;
+ otzProgramExit: any;
+ dateEnrolled: any;
+ dateCompleted: any;
+ loadingData: boolean;
+ hasLoadedData: boolean;
+ patientCareStatus: any;
+ clinicalEncounters: any;
+ patientData: any;
+ hasData: boolean;
+ isHEIActive: boolean;
+ viralLoadCategory: string;
+ isOtzDiscontinued = false;
+ reasonForDiscontinuation: string;
+ otzDiscontinuationDate: any;
+ viralLoadHistory: any[];
+ isPatientEligibleForOtz = false;
+
+ constructor(
+ private patientService: PatientService,
+ private hivSummaryResourceService: HivSummaryResourceService,
+ private labsResourceService: LabsResourceService,
+ private encounterResource: EncounterResourceService,
+ private router: Router,
+ private route: ActivatedRoute
+ ) {}
+
+ ngOnInit() {
+ this.subscription = this.patientService.currentlyLoadedPatient.subscribe(
+ (patient) => {
+ this.patient = new Patient({});
+ if (patient) {
+ this.isHEIActive = patient.enrolledPrograms.some((program) => {
+ return (
+ program.programUuid === 'a8e7c30d-6d2f-401c-bb52-d4433689a36b' &&
+ program.isEnrolled === true
+ );
+ });
+ this.programManagerUrl =
+ '/patient-dashboard/patient/' +
+ patient.uuid +
+ '/general/general/program-manager/new-program';
+ this.otzProgramExit =
+ '/patient-dashboard/patient/' +
+ patient.uuid +
+ '/general/general/formentry/ab16711d-890d-4128-95ce-0e955babd711';
+ this.groupManagerUrl =
+ '/patient-dashboard/patient/' +
+ patient.uuid +
+ '/general/general/group-enrollment';
+ this.getOtzEnrollments(patient.person.age, patient.enrolledPrograms);
+ this.getHivSummary(patient);
+ this.getHistoricalPatientLabResults(patient);
+ this.getOtzDiscontinuation(patient);
+ }
+ }
+ );
+ }
+
+ selectItem(item: string) {
+ this.selectedItem = item;
+ }
+
+ private getOtzEnrollments(age, enrolledPrograms) {
+ const otz = enrolledPrograms.filter(
+ (program) =>
+ program.concept.uuid === 'fd90d6b2-7302-4a9c-ad1b-1f93eff77afb'
+ );
+ if (otz.length > 0 && otz[0].isEnrolled) {
+ this.dateEnrolled = otz[0].dateEnrolled;
+ this.otzEnrollment = true;
+ } else {
+ this.dateCompleted = otz[0].dateCompleted;
+ }
+ if (age > 9 && age <= 24) {
+ this.isPatientEligibleForOtz = true;
+ }
+ }
+
+ private getOtzDiscontinuation(patient) {
+ patient.encounters.filter((encounter) => {
+ console.log(encounter);
+ const reasonForDiscontinuation = encounter.obs.filter((obs) => {
+ return obs.concept.uuid === 'a89e3f94-1350-11df-a1f1-0026b9348838';
+ });
+ console.log(reasonForDiscontinuation);
+ if (reasonForDiscontinuation.length > 0) {
+ this.isOtzDiscontinued = true;
+ this.reasonForDiscontinuation =
+ reasonForDiscontinuation[0].value.display;
+ this.otzDiscontinuationDate = encounter.encounterDatetime;
+ }
+ });
+ }
+
+ public getHivSummary(patient) {
+ this.loadingData = true;
+ this.hivSummaryResourceService
+ .getHivSummary(patient.uuid, 0, 10, false, this.isHEIActive)
+ .pipe(take(1))
+ .subscribe((results) => {
+ let latestVlResult: any;
+ let latestVlDate = '';
+ let latestVl = null;
+ this.loadingData = false;
+ this.hasLoadedData = true;
+ if (results[0]) {
+ latestVlResult = this.getlatestVlResult(results);
+ latestVlDate = latestVlResult.vl_1_date;
+ latestVl = latestVlResult.vl_1;
+ this.patientCareStatus = results[0].patient_care_status;
+ }
+ this.clinicalEncounters = this.getClinicalEncounters(results);
+ this.patientData = _.first(this.clinicalEncounters);
+ const patientDataCopy = this.patientData;
+
+ if (!_.isNil(this.patientData)) {
+ // assign latest vl and vl_1_date
+ this.patientData = Object.assign(patientDataCopy, {
+ vl_1_date: latestVlDate,
+ vl_1: latestVl
+ });
+ this.hasData = true;
+ }
+ if (latestVl) {
+ this.viralLoadCategory = this.getCategory(latestVl);
+ }
+ });
+ }
+
+ private getCategory(value: number): string {
+ if (value <= 50) {
+ return 'LDL';
+ } else if (value <= 200) {
+ return 'Low Risk Low Level Viremia';
+ } else if (value <= 500) {
+ return 'High Risk Low Level Viremia';
+ } else {
+ return 'Suspected Treatment Failure';
+ }
+ }
+
+ public getHistoricalPatientLabResults(patient) {
+ this.labsResourceService
+ .getHistoricalPatientLabResults(patient.uuid, {
+ startIndex: '0',
+ limit: '20'
+ })
+ .pipe(take(1))
+ .subscribe((results) => {
+ this.getViralLoadHistory(results);
+ });
+ }
+
+ private getViralLoadHistory(labResults: any[]): any {
+ const filteredArray = labResults.filter((item) => {
+ return item.hiv_viral_load !== null && item.test_datetime !== null;
+ });
+
+ filteredArray.sort((a, b) => {
+ const dateA = new Date(a.test_datetime).getTime();
+ const dateB = new Date(b.test_datetime).getTime();
+ return dateB - dateA;
+ });
+
+ const result = filteredArray.map((item) => {
+ return {
+ hiv_viral_load: item.hiv_viral_load,
+ test_datetime: item.test_datetime
+ };
+ });
+ this.viralLoadHistory = result;
+ }
+
+ private getClinicalEncounters(summaries: any[]): any[] {
+ if (summaries) {
+ return _.filter(summaries, (summary: any) => {
+ return summary.is_clinical_encounter === 1;
+ });
+ }
+ }
+
+ private getlatestVlResult(hivSummaryData) {
+ const orderByVlDate = _.orderBy(
+ hivSummaryData,
+ (hivSummary) => {
+ return moment(hivSummary.vl_1_date);
+ },
+ ['desc']
+ );
+ return orderByVlDate[0];
+ }
+}
diff --git a/src/app/patient-dashboard/common/patient-banner/patient-banner.component.html b/src/app/patient-dashboard/common/patient-banner/patient-banner.component.html
index eb55436c8..249cabc65 100644
--- a/src/app/patient-dashboard/common/patient-banner/patient-banner.component.html
+++ b/src/app/patient-dashboard/common/patient-banner/patient-banner.component.html
@@ -403,6 +403,23 @@
OVC ID: Not assigned
+
+
+ Enroll client to OTZ
+
+
Family History
diff --git a/src/app/patient-dashboard/common/patient-banner/patient-banner.component.ts b/src/app/patient-dashboard/common/patient-banner/patient-banner.component.ts
index 7fe36d0a1..6b90d1e65 100644
--- a/src/app/patient-dashboard/common/patient-banner/patient-banner.component.ts
+++ b/src/app/patient-dashboard/common/patient-banner/patient-banner.component.ts
@@ -48,6 +48,8 @@ export class PatientBannerComponent implements OnInit, OnDestroy, OnChanges {
public relationship: Relationship;
public isStaging = true;
public ovcEnrollment = false;
+ public otzEnrollmentBtn = false;
+ public isPatientEligibleForOtz = false;
public isPatientVerified = false;
public verificationStatus = false;
modalRef: BsModalRef;
@@ -90,11 +92,11 @@ export class PatientBannerComponent implements OnInit, OnDestroy, OnChanges {
this.patient = patient;
this.searchIdentifiers = patient.searchIdentifiers;
this.getVerificationStatus();
+ this.getOtzEnrollments(patient.person.age, patient.enrolledPrograms);
this.getOvcEnrollments(
patient.enrolledPrograms,
patient.person.birthdate
);
-
const attributes = patient.person.attributes;
_.each(attributes, (attribute) => {
// get the test patient attribute
@@ -305,6 +307,29 @@ export class PatientBannerComponent implements OnInit, OnDestroy, OnChanges {
}
}
+ private getOtzEnrollments(age, enrolledPrograms) {
+ if (age > 9 && age <= 24) {
+ this.isPatientEligibleForOtz = true;
+ }
+ const otz = enrolledPrograms.filter(
+ (program) =>
+ program.concept.uuid === 'fd90d6b2-7302-4a9c-ad1b-1f93eff77afb'
+ );
+ if (otz.length > 0 && otz[0].isEnrolled) {
+ this.otzEnrollmentBtn = true;
+ }
+ }
+
+ public enrollToOtz() {
+ const otzEnrollmentFormUuid = 'ca5ccb72-5623-4b94-97a3-6b5dac5f8560';
+ this.router.navigate([
+ '/patient-dashboard/patient/' +
+ this.patient.uuid +
+ '/general/general/formentry/' +
+ otzEnrollmentFormUuid
+ ]);
+ }
+
/* Family History */
public navigateToFamilyHistory() {
if (this.familyTestingEncounterUuid == null) {
diff --git a/src/app/patient-dashboard/common/patient-dashboard.common.module.ts b/src/app/patient-dashboard/common/patient-dashboard.common.module.ts
index 4c8ee52de..cda1544f9 100644
--- a/src/app/patient-dashboard/common/patient-dashboard.common.module.ts
+++ b/src/app/patient-dashboard/common/patient-dashboard.common.module.ts
@@ -135,6 +135,7 @@ import { AddPatientEducationComponent } from './patient-info/education/add-patie
import { EditPatientEducationComponent } from './patient-info/education/edit-patient-education.component';
import { OvcSnapshotComponent } from './ovc-snapshot/ovc-snapshot.component';
import { UserDefaultPropertiesService } from 'src/app/user-default-properties/user-default-properties.service';
+import { OtzSnapshotComponent } from './otz-snapshot/otz-snapshot.component';
@NgModule({
imports: [
@@ -291,7 +292,8 @@ import { UserDefaultPropertiesService } from 'src/app/user-default-properties/us
PatientEducationComponent,
AddPatientEducationComponent,
EditPatientEducationComponent,
- OvcSnapshotComponent
+ OvcSnapshotComponent,
+ OtzSnapshotComponent
],
providers: [
{
diff --git a/src/app/patient-dashboard/common/visit/visit-starter/visit-starter.component.html b/src/app/patient-dashboard/common/visit/visit-starter/visit-starter.component.html
index 3cf806eab..c815fec69 100644
--- a/src/app/patient-dashboard/common/visit/visit-starter/visit-starter.component.html
+++ b/src/app/patient-dashboard/common/visit/visit-starter/visit-starter.component.html
@@ -54,7 +54,8 @@
-
+
COVID-19 Assessment Status :
- {{ covid19VaccinationSummary?.vaccination_status }} Appointment No-show Risk :
+ {{ (prediction.predicted_prob_disengage * 100).toFixed(2) }}%({{
+ prediction.predicted_risk
+ }})
200 && this.patient.person.age <= 19"
style="display: inline-block"
>
- COVID-19 Screening Outcome :
- {{
- covid19VaccinationSummary?.covid_screening_outcome_this_visit
- }}
-
-
-
-
- Appointment No-show Risk :
- {{ (prediction.predicted_prob_disengage * 100).toFixed(2) }}%({{
- prediction.predicted_risk
- }})
+ Jua Mtoto Wako
diff --git a/src/app/patient-dashboard/patient-dashboard.routes.ts b/src/app/patient-dashboard/patient-dashboard.routes.ts
index fddbe47ca..0e0adb047 100644
--- a/src/app/patient-dashboard/patient-dashboard.routes.ts
+++ b/src/app/patient-dashboard/patient-dashboard.routes.ts
@@ -29,6 +29,7 @@ import { EditProgramComponent } from '../program-manager/edit-program/edit-progr
import { GroupEnrollmentSummaryComponent } from './group-enrollment/group-enrollment-summary.component';
import { OncologySummaryComponent } from './oncology/oncology-summary/oncology-summary.component';
import { OvcSnapshotComponent } from './common/ovc-snapshot/ovc-snapshot.component';
+import { OtzSnapshotComponent } from './common/otz-snapshot/otz-snapshot.component';
export const routes = [
{
@@ -191,6 +192,10 @@ export const routes = [
{
path: ':programClass/:program/patient-ovc-enrollment',
component: OvcSnapshotComponent
+ },
+ {
+ path: ':programClass/:program/patient-otz-enrollment',
+ component: OtzSnapshotComponent
}
]
}
diff --git a/src/app/program-manager/new-program/new-program.component.html b/src/app/program-manager/new-program/new-program.component.html
index 662645a82..cdb826963 100644
--- a/src/app/program-manager/new-program/new-program.component.html
+++ b/src/app/program-manager/new-program/new-program.component.html
@@ -118,7 +118,7 @@
Select Program
-
+
diff --git a/src/app/program-manager/new-program/new-program.component.ts b/src/app/program-manager/new-program/new-program.component.ts
index f81c0344b..4c2488936 100644
--- a/src/app/program-manager/new-program/new-program.component.ts
+++ b/src/app/program-manager/new-program/new-program.component.ts
@@ -53,6 +53,7 @@ export class NewProgramComponent
public enrollPatientToGroup = false;
public modalRef: BsModalRef;
public autoEnrolFromGroup = false;
+ showOtzEnrollmentForm = false;
constructor(
public patientService: PatientService,
@@ -136,14 +137,30 @@ export class NewProgramComponent
this.selectedProgram = _.find(this.availablePrograms, (_program: any) => {
return _program.programUuid === this.program;
});
- this.programVisitConfig = this.allPatientProgramVisitConfigs[this.program];
- this.addToStepInfo({
- selectedProgram: this.selectedProgram,
- programVisitConfig: this.programVisitConfig
- });
- this.checkForRequiredQuestions();
- this.checkIfEnrollmentIsAllowed();
- this.goToDetails();
+ if (
+ this.selectedProgram.concept.uuid ===
+ 'fd90d6b2-7302-4a9c-ad1b-1f93eff77afb'
+ ) {
+ const otzEnrollmentFormUuid = 'ca5ccb72-5623-4b94-97a3-6b5dac5f8560';
+ this.showOtzEnrollmentForm = true;
+ this.router.navigate([
+ '/patient-dashboard/patient/' +
+ this.patient.uuid +
+ '/general/general/formentry/' +
+ otzEnrollmentFormUuid
+ ]);
+ } else {
+ this.programVisitConfig = this.allPatientProgramVisitConfigs[
+ this.program
+ ];
+ this.addToStepInfo({
+ selectedProgram: this.selectedProgram,
+ programVisitConfig: this.programVisitConfig
+ });
+ this.checkForRequiredQuestions();
+ this.checkIfEnrollmentIsAllowed();
+ this.goToDetails();
+ }
}
public goToProgram() {
diff --git a/src/app/program-visit-encounter-search/program-visits-config.json b/src/app/program-visit-encounter-search/program-visits-config.json
index 049b072d7..eec37f58b 100644
--- a/src/app/program-visit-encounter-search/program-visits-config.json
+++ b/src/app/program-visit-encounter-search/program-visits-config.json
@@ -324,6 +324,15 @@
],
"visitTypes": []
},
+ "203571d6-a4f2-4953-9e8b-e1105e2340f5": {
+ "name": "OTZ PROGRAM",
+ "dataDependencies": [
+ "patient",
+ "enrollment",
+ "hivLastTenClinicalEncounters"
+ ],
+ "visitTypes": []
+ },
"781d8a88-1359-11df-a1f1-0026b9348838": {
"name": "BSG PROGRAM",
"dataDependencies": [
diff --git a/src/app/shared/dynamic-route/schema/patient.dashboard.conf.json b/src/app/shared/dynamic-route/schema/patient.dashboard.conf.json
index eccbf775c..149bf0bc3 100644
--- a/src/app/shared/dynamic-route/schema/patient.dashboard.conf.json
+++ b/src/app/shared/dynamic-route/schema/patient.dashboard.conf.json
@@ -65,6 +65,11 @@
"url": "patient-ovc-enrollment",
"label": "OVC",
"icon": "fa fa-child"
+ },
+ {
+ "url": "patient-otz-enrollment",
+ "label": "OTZ",
+ "icon": "fa fa-child"
}
]
},
@@ -358,6 +363,36 @@
}
]
},
+ {
+ "programName": "OTZ",
+ "programUuid": "203571d6-a4f2-4953-9e8b-e1105e2340f5",
+ "baseRoute": "203571d6-a4f2-4953-9e8b-e1105e2340f5",
+ "alias": "hiv",
+ "published": true,
+ "requiresPatientEnrollment": true,
+ "routes": [
+ {
+ "url": "visit",
+ "label": "Visit",
+ "icon": "icon-i-outpatient"
+ },
+ {
+ "url": "patient-encounters",
+ "label": "Encounters",
+ "icon": "icon-i-immunizations"
+ },
+ {
+ "url": "patient-vitals",
+ "label": "Vitals",
+ "icon": "fa fa-heartbeat"
+ },
+ {
+ "url": "lab-data-summary",
+ "label": "Lab Data Summary",
+ "icon": "icon-i-laboratory"
+ }
+ ]
+ },
{
"programName": "BSG",
"programUuid": "781d8a88-1359-11df-a1f1-0026b9348838",