Skip to content

Commit

Permalink
#1185 | WIP: allOverdueVisitsIn based on location filters
Browse files Browse the repository at this point in the history
  • Loading branch information
himeshr committed Nov 22, 2023
1 parent f8a95c5 commit eb49d93
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ import {
Settings,
SubjectType,
CustomFilter,
ReportCard
ReportCard,
Program,
ProgramEnrolment,
ProgramEncounter
} from "openchs-models";
import TestConceptFactory from "../test/model/TestConceptFactory";
import TestAddressLevelFactory from "../test/model/TestAddressLevelFactory";
Expand All @@ -43,6 +46,7 @@ import TestApprovalStatusFactory from "../test/model/approval/TestApprovalStatus
import TestEncounterFactory from "../test/model/txn/TestEncounterFactory";
import TestEncounterTypeFactory from "../test/model/TestEncounterTypeFactory";
import moment from "moment";
import TestProgramFactory from '../test/model/TestProgramFactory';

function getCount(test, card, reportFilters) {
return test.reportCardService.getReportCardCount(card, reportFilters).primaryValue
Expand All @@ -59,6 +63,8 @@ class ReportCardServiceIntegrationTest extends BaseIntegrationTest {
db.create(Settings, TestSettingsFactory.createWithDefaults({}));

this.subjectType = db.create(SubjectType, TestSubjectTypeFactory.createWithDefaults({type: SubjectType.types.Person, name: 'Beneficiary'}));
const program = db.create(Program, TestProgramFactory.create({name: 'Mother'}));
const programEncounterType = db.create(EncounterType, TestEncounterTypeFactory.create({name: "Delivery"}));
const encounterType = db.create(EncounterType, TestEncounterTypeFactory.create({name: "Bar"}));
const form = db.create(Form, TestFormFactory.createWithDefaults({formType: Form.formTypes.IndividualProfile}));
const formElementGroup = db.create(FormElementGroup, TestFormElementGroupFactory.create({form: form}));
Expand All @@ -78,6 +84,10 @@ class ReportCardServiceIntegrationTest extends BaseIntegrationTest {
const encounterId1 = General.randomUUID();
const encounterId2 = General.randomUUID();

//TODO add programEnrolment and programEncounters
// const programEncounterId1 = General.randomUUID();
// const programEncounterId2 = General.randomUUID();

const subjectEAS = db.create(EntityApprovalStatus, TestEntityApprovalStatusFactory.create({
entityType: EntityApprovalStatus.entityType.Subject,
entityUUID: subjectId,
Expand Down
108 changes: 63 additions & 45 deletions packages/openchs-android/src/service/IndividualService.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,20 +183,20 @@ class IndividualService extends BaseService {
let programEncounters = [];
if (queryProgramEncounter) {
programEncounters = this.db.objects(ProgramEncounter.schema.name)
.filtered('earliestVisitDateTime <= $0 ' +
'AND maxVisitDateTime >= $1 ' +
'AND encounterDateTime = null ' +
'AND cancelDateTime = null ' +
'AND programEnrolment.programExitDateTime = null ' +
'AND programEnrolment.voided = false ' +
'AND programEnrolment.individual.voided = false ' +
'AND voided = false ',
dateMidnight,
dateMorning);
if (!_.isEmpty(programEncounterCriteria))
.filtered('earliestVisitDateTime <= $0 ' +
'AND maxVisitDateTime >= $1 ' +
'AND encounterDateTime = null ' +
'AND cancelDateTime = null ' +
'AND programEnrolment.programExitDateTime = null ' +
'AND programEnrolment.voided = false ' +
'AND programEnrolment.individual.voided = false ' +
'AND voided = false ',
dateMidnight,
dateMorning);
if (!_.isEmpty(programEncounterCriteria)) {
programEncounters = programEncounters.filtered(`${programEncounterCriteria}`);
if (!_.isNil(addressFilter))
programEncounters = RealmQueryService.filterBasedOnAddress(ProgramEncounter.schema.name, programEncounters, addressFilter);
}
programEncounters = RealmQueryService.filterBasedOnAddress(ProgramEncounter.schema.name, programEncounters, addressFilter);

programEncounters = programEncounters.map((enc) => {
const individual = enc.programEnrolment.individual;
Expand Down Expand Up @@ -232,10 +232,10 @@ class IndividualService extends BaseService {
'AND voided = false ',
dateMidnight,
dateMorning);
if (!_.isEmpty(encounterCriteria))
if (!_.isEmpty(encounterCriteria)) {
encounters = encounters.filtered(`${encounterCriteria}`);
if (!_.isNil(addressFilter))
encounters = RealmQueryService.filterBasedOnAddress(Encounter.schema.name, encounters, addressFilter);
}
encounters = RealmQueryService.filterBasedOnAddress(Encounter.schema.name, encounters, addressFilter);

encounters = encounters.map((enc) => {
const individual = enc.individual;
Expand Down Expand Up @@ -294,17 +294,26 @@ class IndividualService extends BaseService {
const performProgramVisitCriteria = `privilege.name = '${Privilege.privilegeName.performVisit}' AND privilege.entityType = '${Privilege.privilegeEntityType.encounter}'`;
const allowedProgramEncounterTypeUuidsForPerformVisit = privilegeService.allowedEntityTypeUUIDListForCriteria(performProgramVisitCriteria, 'programEncounterTypeUuid');
const dateMorning = moment(date).startOf('day').toDate();
const programEncounters = queryProgramEncounter ? this.db.objects(ProgramEncounter.schema.name)
.filtered('maxVisitDateTime < $0 ' +
const addressFilter = DashboardReportFilter.getAddressFilter(reportFilters);

let programEncounters = [];
if (queryProgramEncounter) {
programEncounters = this.db.objects(ProgramEncounter.schema.name)
.filtered('maxVisitDateTime < $0 ' +
'AND cancelDateTime = null ' +
'AND encounterDateTime = null ' +
'AND programEnrolment.programExitDateTime = null ' +
'AND programEnrolment.voided = false ' +
'AND programEnrolment.individual.voided = false ' +
'AND voided = false ',
dateMorning)
.filtered((_.isEmpty(programEncounterCriteria) ? 'uuid != null' : `${programEncounterCriteria}`))
.map((enc) => {
dateMorning);

if (!_.isEmpty(programEncounterCriteria)) {
programEncounters = programEncounters.filtered(`${programEncounterCriteria}`);
}
programEncounters = RealmQueryService.filterBasedOnAddress(ProgramEncounter.schema.name, programEncounters, addressFilter);

programEncounters = programEncounters.map((enc) => {
const individual = enc.programEnrolment.individual;
const visitName = enc.name || enc.encounterType.operationalEncounterTypeName;
const programName = enc.programEnrolment.program.operationalProgramName || enc.programEnrolment.program.name;
Expand All @@ -323,36 +332,45 @@ class IndividualService extends BaseService {
allow: !privilegeService.hasEverSyncedGroupPrivileges() || privilegeService.hasAllPrivileges() || _.includes(allowedProgramEncounterTypeUuidsForPerformVisit, enc.encounterType.uuid)
}
};
}) : [];
});
}

const allowedGeneralEncounterTypeUuidsForPerformVisit = privilegeService.allowedEntityTypeUUIDListForCriteria(performProgramVisitCriteria, 'encounterTypeUuid');
const encounters = queryGeneralEncounter ? this.db.objects(Encounter.schema.name)
.filtered('maxVisitDateTime < $0 ' +
let encounters = [];
if(queryGeneralEncounter) {
encounters = this.db.objects(Encounter.schema.name)
.filtered('maxVisitDateTime < $0 ' +
'AND cancelDateTime = null ' +
'AND encounterDateTime = null ' +
'AND individual.voided = false ' +
'AND voided = false ',
dateMorning)
.filtered((_.isEmpty(encounterCriteria) ? 'uuid != null' : `${encounterCriteria}`))
.map((enc) => {
const individual = enc.individual;
const visitName = enc.name || enc.encounterType.operationalEncounterTypeName;
const maxVisitDateTime = enc.maxVisitDateTime;
return {
individual,
visitInfo: {
uuid: individual.uuid,
visitName: [{
visit: [visitName, General.formatDate(maxVisitDateTime)],
encounter: enc,
color: '#d0011b',
}],
groupingBy: General.formatDate(maxVisitDateTime),
sortingBy: maxVisitDateTime,
allow: !privilegeService.hasEverSyncedGroupPrivileges() || privilegeService.hasAllPrivileges() || _.includes(allowedGeneralEncounterTypeUuidsForPerformVisit, enc.encounterType.uuid)
}
};
}) : [];
dateMorning);

if(!_.isEmpty(encounterCriteria)) {
encounters = encounters.filtered(`${encounterCriteria}`);
}
encounters = RealmQueryService.filterBasedOnAddress(Encounter.schema.name, encounters, addressFilter);

encounters = encounters.map((enc) => {
const individual = enc.individual;
const visitName = enc.name || enc.encounterType.operationalEncounterTypeName;
const maxVisitDateTime = enc.maxVisitDateTime;
return {
individual,
visitInfo: {
uuid: individual.uuid,
visitName: [{
visit: [visitName, General.formatDate(maxVisitDateTime)],
encounter: enc,
color: '#d0011b',
}],
groupingBy: General.formatDate(maxVisitDateTime),
sortingBy: maxVisitDateTime,
allow: !privilegeService.hasEverSyncedGroupPrivileges() || privilegeService.hasAllPrivileges() || _.includes(allowedGeneralEncounterTypeUuidsForPerformVisit, enc.encounterType.uuid)
}
};
})
};
const allEncounters = [...
[...programEncounters, ...encounters]
.reduce(this._uniqIndividualWithVisitName, new Map())
Expand Down
25 changes: 25 additions & 0 deletions packages/openchs-android/test/model/TestProgramFactory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {Program} from "openchs-models";
import General from "../../src/utility/General";

class TestProgramFactory {
static create({
uuid = General.randomUUID(),
name,
colour = '#012345',
allowMultipleEnrolments = false,
manualEligibilityCheckRequired = false
}) {
const program = new Program();
program.uuid = uuid;
program.name = name;
program.displayName = name;
program.programSubjectLabel = name;
program.operationalProgramName = name;
program.colour = colour;
program.allowMultipleEnrolments = allowMultipleEnrolments;
program.manualEligibilityCheckRequired = manualEligibilityCheckRequired;
return program;
}
}

export default TestProgramFactory;
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import General from "../../src/utility/General";
import {ProgramEncounter} from 'openchs-models';

class TestProgramEncounterFactory {
static create({
uuid = General.randomUUID(),
name,
encounterType,
programEnrolment,
encounterDateTime,
earliestVisitDateTime,
maxVisitDateTime,
subject: subject,
observations = [],
approvalStatuses = []
}) {
const programEncounter = new ProgramEncounter();
programEncounter.uuid = uuid;
programEncounter.name = name;
programEncounter.displayName = name;
programEncounter.encounterType = encounterType;
programEncounter.programEnrolment = programEnrolment;
programEncounter.encounterDateTime = encounterDateTime;
programEncounter.individual = subject;
programEncounter.observations = observations;
programEncounter.approvalStatuses = approvalStatuses;
programEncounter.earliestVisitDateTime = earliestVisitDateTime;
programEncounter.maxVisitDateTime = maxVisitDateTime;
programEncounter.setLatestEntityApprovalStatus(programEncounter.latestEntityApprovalStatus);
return programEncounter;
}
}

export default TestProgramEncounterFactory;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import General from "../../src/utility/General";
import {ProgramEnrolment} from 'openchs-models';

class TestProgramEnrolmentFactory {
static create({
uuid = General.randomUUID(),
name,
program,
subject,
enrolmentDateTime,
encounters = [],
checklists = [],
observations = [],
approvalStatuses = [],
latestEntityApprovalStatus
}) {
const programEnrolment = new ProgramEnrolment();
programEnrolment.uuid = uuid;
programEnrolment.name = name;
programEnrolment.program = program;
programEnrolment.individual = subject;
programEnrolment.displayName = name;
programEnrolment.operationalProgramName = name;
programEnrolment.encounters = encounters;
programEnrolment.checklists = checklists;
programEnrolment.observations = observations;
programEnrolment.enrolmentDateTime = enrolmentDateTime;
programEnrolment.approvalStatuses = approvalStatuses;
programEnrolment.setLatestEntityApprovalStatus(programEnrolment.latestEntityApprovalStatus);

return programEnrolment;
}
}

export default TestProgramEnrolmentFactory;

0 comments on commit eb49d93

Please sign in to comment.