diff --git a/src/app/clinic-schedule-lib/daily-schedule/daily-schedule-appointments.component.ts b/src/app/clinic-schedule-lib/daily-schedule/daily-schedule-appointments.component.ts index fd30a3aee..dd1aad580 100644 --- a/src/app/clinic-schedule-lib/daily-schedule/daily-schedule-appointments.component.ts +++ b/src/app/clinic-schedule-lib/daily-schedule/daily-schedule-appointments.component.ts @@ -36,6 +36,21 @@ export class DailyScheduleAppointmentsComponent implements OnInit, OnDestroy { width: 120, field: 'arv_first_regimen_start_date' }, + { + headerName: 'Weight', + width: 200, + field: 'weight' + }, + { + headerName: 'Height', + width: 200, + field: 'height' + }, + { + headerName: 'WHO Stage', + width: 200, + field: 'stage' + }, { headerName: 'Covid-19 Assessment Status', width: 250, diff --git a/src/app/clinic-schedule-lib/daily-schedule/daily-schedule-not-returned.component.ts b/src/app/clinic-schedule-lib/daily-schedule/daily-schedule-not-returned.component.ts index 10a69bf8a..395f31ce7 100644 --- a/src/app/clinic-schedule-lib/daily-schedule/daily-schedule-not-returned.component.ts +++ b/src/app/clinic-schedule-lib/daily-schedule/daily-schedule-not-returned.component.ts @@ -40,6 +40,21 @@ export class DailyScheduleNotReturnedComponent implements OnInit, OnDestroy { width: 120, field: 'arv_first_regimen_start_date' }, + { + headerName: 'Weight', + width: 200, + field: 'weight' + }, + { + headerName: 'Height', + width: 200, + field: 'height' + }, + { + headerName: 'WHO Stage', + width: 200, + field: 'stage' + }, { headerName: 'Covid-19 Assessment Status', width: 250, diff --git a/src/app/etl-api/family-testing-resource.service.ts b/src/app/etl-api/family-testing-resource.service.ts index 923e0b159..dbc9b6eb6 100644 --- a/src/app/etl-api/family-testing-resource.service.ts +++ b/src/app/etl-api/family-testing-resource.service.ts @@ -130,9 +130,13 @@ export class FamilyTestingService { ); } - public getPatientEncounters(patientUuid: string) { - const familyTestingEncounterTypeUuid = - '975ae894-7660-4224-b777-468c2e710a2a'; + public getPatientEncounters( + patientUuid: string, + isFamilyTestingEncounter: boolean + ) { + const familyTestingEncounterTypeUuid = isFamilyTestingEncounter + ? '975ae894-7660-4224-b777-468c2e710a2a' + : '5a58f6f5-f5a6-47eb-a644-626abd83f83b'; return this.http.get( `${this.amrsUrl()}encounter?patient=${patientUuid}&encounterType=${familyTestingEncounterTypeUuid}` ); diff --git a/src/app/group-manager/group-detail/group-detail-summary.component.html b/src/app/group-manager/group-detail/group-detail-summary.component.html index f7a444eb1..fc629b506 100644 --- a/src/app/group-manager/group-detail/group-detail-summary.component.html +++ b/src/app/group-manager/group-detail/group-detail-summary.component.html @@ -108,10 +108,10 @@

Group Summary

- + Group Activity: - {{ groupActivity?.value }} + {{ groupActivity?.value }} diff --git a/src/app/group-manager/group-detail/group-detail-summary.component.ts b/src/app/group-manager/group-detail/group-detail-summary.component.ts index b2b2783cb..509119428 100644 --- a/src/app/group-manager/group-detail/group-detail-summary.component.ts +++ b/src/app/group-manager/group-detail/group-detail-summary.component.ts @@ -550,6 +550,7 @@ export class GroupDetailSummaryComponent implements OnInit, OnDestroy { public showUpdateGroupModal(modal) { let program = null; let provider = null; + const context = this.validOTZProgram; this.program ? (program = this.program) : (program = { name: null, value: null }); @@ -571,7 +572,7 @@ export class GroupDetailSummaryComponent implements OnInit, OnDestroy { groupProgram: { label: program['name'], value: program['uuid'] }, provider: { label: provider.person.display, value: provider.person.uuid }, address: this.landmark.value, - groupActivity: this.groupActivity.value, + groupActivity: context ? this.groupActivity.value : null, groupUuid: this.group.uuid, actionButtonText: 'Save Changes' }; diff --git a/src/app/group-manager/group-detail/group-detail.component.html b/src/app/group-manager/group-detail/group-detail.component.html index 133b77188..0d3ae5fa5 100644 --- a/src/app/group-manager/group-detail/group-detail.component.html +++ b/src/app/group-manager/group-detail/group-detail.component.html @@ -240,10 +240,7 @@
{{ enrollmentErrorMessage }}
-
+
The patient is not enrolled in this program.
-
- Patient is not eligible for OTZ enrollment -
!group.voided ); } + const targetProgramUuid = '203571d6-a4f2-4953-9e8b-e1105e2340f5'; + const checkOTZProgram = programsEnrolled.some( + (program) => program.programUuid === targetProgramUuid + ); const validation = this.communityGroupMemberService.validateMemberEnrollment( programsEnrolled, currentGroupsEnrolled, @@ -778,9 +782,17 @@ export class GroupDetailComponent implements OnInit, OnDestroy, AfterViewInit { this.validatingEnrollment = false; this.showEnrollmentAlert('Patient already enrolled in this group!'); break; - case !validation.notEnrolledInGroupProgram.found: + case !validation.notEnrolledInGroupProgram.found && + checkOTZProgram && + this.isOtzProgram: this.validatingEnrollment = false; this.validateAge(patient); + if (this.showOTZEnrollmentMsg) { + this.showEnrollButton(patient); + } + break; + case !validation.notEnrolledInGroupProgram.found: + this.validatingEnrollment = false; this.showEnrollButton(patient); break; case validation.enrolledInAnotherGroupInSameProgram.found: @@ -839,12 +851,16 @@ export class GroupDetailComponent implements OnInit, OnDestroy, AfterViewInit { } private validateAge(patient) { - if (patient._person.age > 9 && patient._person.age <= 24) { + const age = patient._person.age; + + if (age > 9 && age <= 24) { this.showOTZEnrollmentMsg = true; - } else { - this.showOTZEnrollmentMsg = false; + return; } + + this.showEnrollmentAlert('Patient is not eligible for OTZ enrollment!'); } + private enrollPatientToGroup(group: Group, patient: Patient) { this.communityGroupMemberService .createMember(group.uuid, patient.uuid) @@ -859,6 +875,9 @@ export class GroupDetailComponent implements OnInit, OnDestroy, AfterViewInit { private showEnrollmentAlert(msg: string) { this.enrollmentErrorMessage = msg; + setTimeout(() => { + this.enrollmentErrorMessage = ''; + }, 5000); } private transferPatientFromGroup(groupToEnroll, groupToUnenroll, patient) { diff --git a/src/app/hiv-care-lib/ipt-report/ipt-report-patient-list.component.ts b/src/app/hiv-care-lib/ipt-report/ipt-report-patient-list.component.ts index 17f8d855b..3b94196be 100644 --- a/src/app/hiv-care-lib/ipt-report/ipt-report-patient-list.component.ts +++ b/src/app/hiv-care-lib/ipt-report/ipt-report-patient-list.component.ts @@ -38,6 +38,9 @@ export class IptReportPatientListComponent implements OnInit { public addExtraColumns() { const extraColumns = { + weight: 'Weight', + height: 'Height', + stage: 'WHO Stage', phone_number: 'Phone Number', enrollment_date: 'Date Enrolled', last_appointment: 'Latest Appointment', diff --git a/src/app/hiv-care-lib/moh-731-report/moh-731-patientlist.component.ts b/src/app/hiv-care-lib/moh-731-report/moh-731-patientlist.component.ts index 68f88ce7c..6d0eca38c 100644 --- a/src/app/hiv-care-lib/moh-731-report/moh-731-patientlist.component.ts +++ b/src/app/hiv-care-lib/moh-731-report/moh-731-patientlist.component.ts @@ -240,6 +240,9 @@ export class Moh731PatientListComponent implements OnInit, OnChanges { public addExtraColumns(indicators: Array) { const extraColumns = { + weight: 'Weight', + height: 'Height', + stage: 'WHO Stage', location: 'Location', enrollment_date: 'Enrollment Date', arv_first_regimen_start_date: 'ARVs Initial Start Date', diff --git a/src/app/lab-order-search/lab-order-search-helper.service.ts b/src/app/lab-order-search/lab-order-search-helper.service.ts index 3f91b81ea..3300610a3 100644 --- a/src/app/lab-order-search/lab-order-search-helper.service.ts +++ b/src/app/lab-order-search/lab-order-search-helper.service.ts @@ -14,6 +14,7 @@ export class LabOrdersSearchHelperService { conceptUuid: 'a898fe80-1350-11df-a1f1-0026b9348838', display: 'DNA PCR' }, + { type: 'VL', conceptUuid: 'a8982474-1350-11df-a1f1-0026b9348838', @@ -24,6 +25,11 @@ export class LabOrdersSearchHelperService { conceptUuid: 'a896cce6-1350-11df-a1f1-0026b9348838', display: 'CD4 Panel' }, + { + type: 'HPV', + conceptUuid: 'a8a46fd6-1350-11df-a1f1-0026b9348838', + display: 'HPV' + }, { type: 'Other', conceptUuid: '', @@ -31,6 +37,14 @@ export class LabOrdersSearchHelperService { } ]; } + public get hpvTestSampleTypes() { + return [ + { + id: 1, + display: 'Cervical Swab' + } + ]; + } public get sampleTypes() { return [ @@ -181,6 +195,41 @@ export class LabOrdersSearchHelperService { }; } + public createHpvPayload( + order: any, + encounterObs: any, + encounterLocationUuid: any, + patientIdentifier: any, + patientName: any, + sex: any, + birthDate: any, + dateRecieved: any, + sampleType: any, + isPregnant = 0, + breastfeeding = 0 + ) { + const vlJustificationUuid: any = this.findObsValueByConceptUuid( + encounterObs, + '0a98f01f-57f1-44b7-aacf-e1121650a967' + ); + + return { + type: 'HPV', + locationUuid: encounterLocationUuid, + orderNumber: order.orderNumber, + providerIdentifier: order.orderer.identifier, + patientName: patientName, + patientIdentifier: patientIdentifier, + sex: sex, + birthDate: this.formatDate(birthDate), + sampleType: sampleType, + vlJustificationUuid: vlJustificationUuid, + isPregnant: isPregnant, + breastfeeding: breastfeeding, + dateDrawn: this.formatDate(order.dateActivated), + dateReceived: this.formatDate(dateRecieved) + }; + } public createViralLoadPayload( order, encounterObs, diff --git a/src/app/lab-order-search/lab-order-search-post.component.html b/src/app/lab-order-search/lab-order-search-post.component.html index 50aee64a0..3a718fd01 100644 --- a/src/app/lab-order-search/lab-order-search-post.component.html +++ b/src/app/lab-order-search/lab-order-search-post.component.html @@ -160,6 +160,34 @@
+ +
+
+ HPV Summary Info +
+ + + + + + + + + + + + + + + + + + + +
Entry Point:{{ HPVData.entryPoint }}
HIV Status:{{ HPVData.hivStatus }}
Type Of Screening:{{ HPVData.typeOfScreening }}
Sample Collection Method:{{ HPVData.sampleCollectionMethod }}
+
+
+
@@ -214,6 +242,26 @@
+
+
+
+ + +
+
+
diff --git a/src/app/lab-order-search/lab-order-search-post.component.ts b/src/app/lab-order-search/lab-order-search-post.component.ts index 3a7c7366b..c7e3ef7d2 100644 --- a/src/app/lab-order-search/lab-order-search-post.component.ts +++ b/src/app/lab-order-search/lab-order-search-post.component.ts @@ -72,11 +72,19 @@ export class LabOrderSearchPostComponent implements OnInit, OnChanges { public hivSummary: any; public error: any; public hasDnaPcr = false; + public isHPVtest = false; public dnaPcrData: any = { hivStatusOfMother: '', infantProphylaxis: '', infantFeeding: '' }; + public HPVData: any = { + entryPoint: '', + hivStatus: '', + typeOfScreening: '', + sampleCollectionMethod: '', + dateOfSampleCollection: '' + }; public isPregnant = false; public isBreastfeeding = false; @@ -84,6 +92,7 @@ export class LabOrderSearchPostComponent implements OnInit, OnChanges { public labLocations: any; public patientIdentifers = []; public sampleTypes: any; + public hpvTestSampleTypes: any; public orderTypes: any; public isBusy = true; @@ -104,6 +113,7 @@ export class LabOrderSearchPostComponent implements OnInit, OnChanges { this.labLocations = this.labOrdersSearchHelperService.labLocations; this.sampleTypes = this.labOrdersSearchHelperService.sampleTypes; this.orderTypes = this.labOrdersSearchHelperService.orderTypes; + this.hpvTestSampleTypes = this.labOrdersSearchHelperService.hpvTestSampleTypes; } public ngOnInit() { @@ -152,6 +162,7 @@ export class LabOrderSearchPostComponent implements OnInit, OnChanges { this.displayPregnancy(); this.loadHivSummary(this.person.uuid); this.displayDnaPcrInputs(); + this.displayHPVInputs(); this.setDefaultLocation(); } @@ -224,7 +235,64 @@ export class LabOrderSearchPostComponent implements OnInit, OnChanges { } ); } + public displayHPVInputs() { + const ot = this.orderType.type; + if (ot !== 'HPV') { + return; + } else { + this.isHPVtest = true; + this.HPVData.entryPoint = this.hpvValue( + this.findObs( + this.order.encounter.obs, + 'a8a17e48-1350-11df-a1f1-0026b9348838' + ).display + ); + this.HPVData.hivStatus = this.hpvValue( + this.findObs( + this.order.encounter.obs, + '9e4d6436-4040-46a3-a0ae-6dbc0acfe593' + ).display + ); + this.HPVData.typeOfScreening = this.hpvValue( + this.findObs( + this.order.encounter.obs, + '6048b6bd-c698-48c9-8d20-424ab0b3d628' + ).display + ); + this.HPVData.sampleCollectionMethod = this.hpvValue( + this.findObs( + this.order.encounter.obs, + 'aa14f397-5d82-4cd3-8dc8-bb381a935717' + ).display + ); + this.HPVData.dateOfSampleCollection = this.hpvValue( + this.findObs( + this.order.encounter.obs, + 'e07623c2-38af-4caa-8d8d-d01791441c59' + ).display + ); + } + } + public hpvValue(displayString: any) { + const parts = displayString.split(':'); + return parts.length > 1 ? parts[1].trim() : displayString; + } + public getHpvConceptValues(uuid: string, property: string) { + this.conceptResourceService + .getConceptByUuid(uuid) + .pipe(take(1)) + .subscribe( + (data) => { + if (data) { + this.dnaPcrData[property] += `${data.name.display} ,`; + } + }, + (error) => { + console.error('Failed to load concepts ', error); + } + ); + } public displayDnaPcrInputs() { const ot = this.orderType.type; if (ot !== 'DNAPCR') { @@ -298,8 +366,10 @@ export class LabOrderSearchPostComponent implements OnInit, OnChanges { if (!this.hasLoadingTimeRequiredInputs()) { return; } + const payload = this.getPayload(); const location = this.selectedLabLocation; + console.log('uchunguzi ', payload); this.isBusy = true; this.labOrderPostService .postOrderToEid(location, payload) @@ -387,6 +457,21 @@ export class LabOrderSearchPostComponent implements OnInit, OnChanges { this.isBreastfeeding ? 1 : 0 ); } + if (this.orderType.type === 'HPV') { + payload = this.labOrdersSearchHelperService.createHpvPayload( + order, + obs, + locationUuid, + patientIdentifier, + patientName, + gender, + birthdate, + this.dateReceived, + this.selectedSampleType, + this.isPregnant ? 1 : 0, + this.isBreastfeeding ? 1 : 0 + ); + } if (this.orderType.type === 'CD4') { payload = this.labOrdersSearchHelperService.createCD4Payload( diff --git a/src/app/models/group.model.ts b/src/app/models/group.model.ts index eaecc745a..c4e729881 100644 --- a/src/app/models/group.model.ts +++ b/src/app/models/group.model.ts @@ -39,17 +39,27 @@ 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 + let lastMeetingDate: any; + + if (this._openmrsModel.cohortVisits.length > 0) { + lastMeetingDate = this.getLatestMeetingDate( + this._openmrsModel.cohortVisits + ); + } else { + lastMeetingDate = new Date(this._openmrsModel.startDate); + } + + // if last meeting date is more than 6 months ago, group is inactive if (lastMeetingDate) { const today = new Date(); - const threeMonthsAgo = new Date(today.setMonth(today.getMonth() - 3)); - if (lastMeetingDate < threeMonthsAgo) { + const sixMonthsAgo = new Date(); + sixMonthsAgo.setMonth(today.getMonth() - 6); + + if (lastMeetingDate <= sixMonthsAgo) { return 'Inactive'; } } + return this._openmrsModel.endDate ? 'Disbanded' : 'Active'; } 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 6b90d1e65..81349130a 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 @@ -52,6 +52,7 @@ export class PatientBannerComponent implements OnInit, OnDestroy, OnChanges { public isPatientEligibleForOtz = false; public isPatientVerified = false; public verificationStatus = false; + private isFamilyTestingEncounter = false; modalRef: BsModalRef; modalConfig = { backdrop: true, @@ -121,11 +122,32 @@ export class PatientBannerComponent implements OnInit, OnDestroy, OnChanges { ); this.getHIVPatient(_.filter(patient.enrolledPrograms, 'isEnrolled')); this.familyTestingService - .getPatientEncounters(this.patient.uuid) + .getPatientEncounters(this.patient.uuid, true) .subscribe((response: any) => { - this.familyTestingEncounterUuid = _.first(response.results); + if (response.results && response.results.length > 0) { + this.isFamilyTestingEncounter = true; + this.familyTestingEncounterUuid = _.first( + response.results + ); + } else { + this.isFamilyTestingEncounter = false; + } }); - this.getPatientEncounters(); + + setTimeout(async () => { + if (!this.isFamilyTestingEncounter) { + this.familyTestingService + .getPatientEncounters(this.patient.uuid, false) + .subscribe((response: any) => { + if (response.results && response.results.length > 0) { + this.familyTestingEncounterUuid = _.first( + response.results + ); + } + }); + } + this.getPatientEncounters(this.isFamilyTestingEncounter); + }, 4000); } else { this.searchIdentifiers = undefined; this.birthdate = undefined; @@ -347,7 +369,6 @@ export class PatientBannerComponent implements OnInit, OnDestroy, OnChanges { this.displayContacts = false; } public updateContacts() { - console.log('this.patient.uuid ', this.patient.uuid); const encounterUuid = _.first(this.patientEncounters).uuid; const familyPartnerHistoryForm = `3fbc8512-b37b-4bc2-a0f4-8d0ac7955127`; const url = `/patient-dashboard/patient/${this.patient.uuid}/general/general/formentry/${familyPartnerHistoryForm}`; @@ -361,9 +382,10 @@ export class PatientBannerComponent implements OnInit, OnDestroy, OnChanges { this.displayContacts = false; } - public getPatientEncounters() { - const familyAndPartnerTestingFormUuid = - '3fbc8512-b37b-4bc2-a0f4-8d0ac7955127'; + public getPatientEncounters(isFamilyTestingEncounter: boolean) { + const familyAndPartnerTestingFormUuid = isFamilyTestingEncounter + ? '3fbc8512-b37b-4bc2-a0f4-8d0ac7955127' + : '8b196bad-6ee5-4290-b1be-101539e04290'; this.encounterResourceService .getEncountersByPatientUuid(this.patient.uuid, false, null) .pipe(take(1))