Skip to content

Commit

Permalink
#1382 - programmatically update AddressLevelState for selected addres…
Browse files Browse the repository at this point in the history
…es. Intialise filters with nullobjects when there is no previous value for them.
  • Loading branch information
petmongrels committed Jun 19, 2024
1 parent 724b750 commit 0f5c9ac
Show file tree
Hide file tree
Showing 18 changed files with 146 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class PersonRegisterActionsIntegrationTest extends BaseIntegrationTest {
super.setup();
this.executeInWrite((db) => {
this.concept = db.create(Concept, TestConceptFactory.createWithDefaults({dataType: Concept.dataType.Text}));
this.addressLevel = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1}));
this.addressLevel = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1, type: "1"}));
this.gender = db.create(Gender, TestGenderFactory.createWithDefaults({name: "Male"}));
db.create(Settings, TestSettingsFactory.createWithDefaults({}));
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class RealmDBOperationsCascadeTest extends BaseIntegrationTest {
name: 'concept-1',
dataType: Concept.dataType.Text
}), updateMode);
this.savedAddressLevel = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1}));
this.savedAddressLevel = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1, type: "1"}));

//Create Individual
this.individual = db.create(Individual, TestSubjectFactory.createWithDefaults({
Expand Down Expand Up @@ -101,4 +101,4 @@ class RealmDBOperationsCascadeTest extends BaseIntegrationTest {
}
}

export default RealmDBOperationsCascadeTest;
export default RealmDBOperationsCascadeTest;
4 changes: 2 additions & 2 deletions packages/openchs-android/integrationTest/RealmProxyTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function shouldFail(baseIntegrationTest, obs, updateMode) {
function shouldFailSubjectCreationWithoutSubjectType(baseIntegrationTest, sub, updateMode) {
baseIntegrationTest.executeInWrite((db) => {
try {
let savedAddressLevel = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1}));
let savedAddressLevel = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1, type: "1"}));
sub.lowestAddressLevel = savedAddressLevel;
db.create(Individual, sub, updateMode);
assert.fail("Subject without subjectType should have failed to save.");
Expand Down Expand Up @@ -55,7 +55,7 @@ function conceptNameShouldRemainSameOnEntityObservationSave(baseIntegrationTest,
dataType: Concept.dataType.Text, keyValues: [{key: "subjectTypeUUID", value: "c47088d6-ac67-4e4d-b5af-158468a83202"}]
}), updateMode);
assert.isNotNull(originalConcept);
const savedAddressLevel = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1}));
const savedAddressLevel = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1, type: "1"}));

assert.equal(originalConcept.keyValues.length, 1);
assert.equal(originalConcept.keyValues[0].key, "subjectTypeUUID");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import TestOrganisationConfigFactory from "../../test/model/TestOrganisationConf
class TestOrganisationService {
static setupOrganisation(db) {
const returnData = {};
returnData.addressLevel = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1}));
returnData.addressLevel2 = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1}));
returnData.addressLevel = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1, type: "1"}));
returnData.addressLevel2 = db.create(AddressLevel, TestAddressLevelFactory.createWithDefaults({level: 1, type: "1"}));
returnData.gender = db.create(Gender, TestGenderFactory.createWithDefaults({name: "Male"}));
db.create(Settings, TestSettingsFactory.createWithDefaults({}));
db.create(OrganisationConfig, TestOrganisationConfigFactory.createWithDefaults({}));
Expand Down
35 changes: 25 additions & 10 deletions packages/openchs-android/src/action/common/AddressLevelsState.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import _ from 'lodash';

function adjustForDisplayedLevels(allCurrentLevels, selectedLevel, newLevels) {
const toRemove = allCurrentLevels.filter(l => !_.isEmpty(l.locationMappings) && l.level < selectedLevel.level && l.parentUuid !== selectedLevel.parentUuid);
return new AddressLevelsState(allCurrentLevels).addLevels(newLevels)
.removeLevels(toRemove)
.removeUnwantedLevels();
}

class AddressLevelsState {
constructor(levels = []) {
const unsortedLevels = Object.entries(_.uniqBy(levels, l => l.uuid)
Expand All @@ -20,15 +27,14 @@ class AddressLevelsState {
this.levels = levelTypeOrderedUnsortedLevels.map(([levelNum, levels]) => {
const levelType = levels[0].type;
const other = _.find(levels, (level) => _.startsWith(level.name, "Other"));
if(!_.isNil(other)) {
if (!_.isNil(other)) {
const levelsExcludingOther = _.filter(levels, (level) => level.name !== other.name);
const sortedLevels = _.sortBy(levelsExcludingOther, "name");
const levelsEndingWithOther = _.concat(sortedLevels, other);
return [levelType, levelsEndingWithOther];
} else {
return [levelType, _.sortBy(levels, "name")];
}

});
}

Expand Down Expand Up @@ -62,27 +68,24 @@ class AddressLevelsState {
addLevel(type, selectedLevel, newLevels = []) {
let levelMap = new Map(this.levels);
const levels = levelMap.get(type);
levelMap.set(type, levels.map(l => _.assignIn({},l,{
levelMap.set(type, levels.map(l => _.assignIn({}, l, {
isSelected: l.uuid === selectedLevel.uuid ? !l.isSelected : l.isSelected
})));
return new AddressLevelsState(this._asList(levelMap)).addOrRemoveLevels(selectedLevel.uuid, newLevels).removeUnwantedLevels();
}

selectLevel(type, selectedLevel, newLevels = []) {
selectLevel(selectedLevel, newLevels = []) {
const allCurrentLevels = this._asList();
if (_.isEmpty(selectedLevel.locationMappings)) {
allCurrentLevels.forEach(l => {
l.isSelected = l.uuid === selectedLevel.uuid ? !l.isSelected : false;
})
});
} else {
allCurrentLevels.filter(it => it.level === selectedLevel.level).forEach(l => {
l.isSelected = l.uuid === selectedLevel.uuid ? !l.isSelected : false
});
}
const toRemove = allCurrentLevels.filter(l => !_.isEmpty(l.locationMappings) && l.level < selectedLevel.level && l.parentUuid !== selectedLevel.parentUuid);
return new AddressLevelsState(allCurrentLevels).addLevels(newLevels)
.removeLevels(toRemove)
.removeUnwantedLevels();
return adjustForDisplayedLevels(allCurrentLevels, selectedLevel, newLevels);
}

addLevels(levels) {
Expand Down Expand Up @@ -122,13 +125,25 @@ class AddressLevelsState {
}

findAllChildrenFromCurrentLevels(levels = []) {
if(_.isEmpty(levels)) {
if (_.isEmpty(levels)) {
return levels;
}
const parentUUIDs = _.defaultTo(levels.map(p => p.uuid), []);
const children = this._asList().filter(l => _.includes(parentUUIDs, l.parentUuid));
return _.concat(levels, this.findAllChildrenFromCurrentLevels(children));
}

setSelectedAddresses(addresses) {
let returnAddressLevelState = this;
const orderedAddresses = _.orderBy(addresses, (x) => x.level, "desc");
orderedAddresses.forEach(selectedAddress => {
const matchingAddress = _.find(returnAddressLevelState._asList(), (address) => selectedAddress.uuid === address.uuid);
matchingAddress.isSelected = true;
const allCurrentLevels = returnAddressLevelState._asList();
returnAddressLevelState = adjustForDisplayedLevels(allCurrentLevels, matchingAddress, []);
});
return returnAddressLevelState;
}
}

export default AddressLevelsState;
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ class CustomDashboardActions {
newState.dashboards = dashboards;
newState.activeDashboardUUID = _.get(_.head(dashboards), 'uuid');

// context.get(CustomDashboardCacheService).clearAllCache();

return loadCurrentDashboardInfo(context, newState);
}

Expand All @@ -63,7 +61,7 @@ class CustomDashboardActions {
const itemKey = action.reportCardUUID;
const rcUUID = context.get(ReportCardService).getPlainUUIDFromCompositeReportCardUUID(action.reportCardUUID);
const reportCard = context.get(EntityService).findByUUID(rcUUID, ReportCard.schema.name);
const {selectedFilterValues} = context.get(CustomDashboardCacheService).getDashboardCache(state.activeDashboardUUID);
const {selectedFilterValues} = context.get(CustomDashboardService).getDashboardData(state.activeDashboardUUID);
const ruleInputArray = context.get(DashboardFilterService).toRuleInputObjects(state.activeDashboardUUID, selectedFilterValues);

reportCard.itemKey = itemKey;
Expand Down Expand Up @@ -99,7 +97,7 @@ class CustomDashboardActions {
}

static refreshCount(state, action, context) {
const {dashboardCache, selectedFilterValues} = context.get(CustomDashboardCacheService).getDashboardCache(state.activeDashboardUUID);
const {selectedFilterValues} = context.get(CustomDashboardService).getDashboardData(state.activeDashboardUUID);

const I18n = context.get(MessageService).getI18n();
const reportCardSectionMappings = state.reportCardSectionMappings;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {ArrayUtil, Concept, CustomFilter, ModelGeneral} from 'openchs-models';
import CustomDashboardCacheService from '../../service/CustomDashboardCacheService';

import General from "../../utility/General";
import {JSONStringify} from "../../utility/JsonStringify";
import FormMetaDataSelection from "../../model/FormMetaDataSelection";
import CustomDashboardService from "../../service/customDashboard/CustomDashboardService";

class FiltersActionsV2 {
static getInitialState() {
Expand All @@ -23,7 +23,7 @@ class FiltersActionsV2 {
const dashboardFilterService = context.get(DashboardFilterService);
const filterConfigs = dashboardFilterService.getFilterConfigsForDashboard(action.dashboardUUID);
const filters = dashboardFilterService.getFilters(action.dashboardUUID);
const {selectedFilterValues, dashboardCache} = context.get(CustomDashboardCacheService).getDashboardCache(action.dashboardUUID);
const {selectedFilterValues, dashboardCache} = context.get(CustomDashboardService).getDashboardData(action.dashboardUUID);
Object.keys(filterConfigs).forEach((uuid) => {
if (filterConfigs[uuid].type === CustomFilter.type.SubjectType && _.isNil(selectedFilterValues[uuid])) {
selectedFilterValues[uuid] = FormMetaDataSelection.createNew();
Expand Down Expand Up @@ -94,7 +94,7 @@ class FiltersActionsV2 {
static appliedFilter(state, action, context) {
//Init data
const {filterConfigs, selectedValues} = state;
const {navigateToDashboardView, setFiltersDataOnDashboardView} = action;
const {navigateToDashboardView} = action;
const newState = {...state, filterApplied: true, filterErrors: {}};
const filledFilterValues = {};
Object.keys(selectedValues).forEach((filterUUID) => {
Expand All @@ -113,14 +113,11 @@ class FiltersActionsV2 {
newState.loading = false;
return newState;
}
const customDashboardCacheService = context.get(CustomDashboardCacheService);
customDashboardCacheService.setSelectedFilterValues(newState.dashboardUUID, filledFilterValues, true);
const customDashboardService = context.get(CustomDashboardService);
customDashboardService.setSelectedFilterValues(newState.dashboardUUID, filledFilterValues, true);

//Invoke callbacks. Used only in test.
// setFiltersDataOnDashboardView(serializableFilterData);
const dashboardFilterService = context.get(DashboardFilterService);
const ruleInputArray = dashboardFilterService.toRuleInputObjects(newState.dashboardUUID, filledFilterValues);
General.logDebugTemp("FiltersActionsV2", `ruleInputArray: ${JSONStringify(ruleInputArray)}`);
navigateToDashboardView(ruleInputArray);
return newState;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,17 @@ class MyDashboardActions {
allIndividuals,
dueChecklist
] = state.returnEmpty ? [[], [], [], [], [], [], [], []] : (fetchFromDB ? [
MyDashboardActions.commonIndividuals(individualService.allScheduledVisitsIn(dashboardCacheFilter.filterDate, [], dashboardCacheFilter.encountersFilters, dashboardCacheFilter.generalEncountersFilters, queryProgramEncounter, queryGeneralEncounter), state.individualUUIDs),
MyDashboardActions.commonIndividuals(individualService.allOverdueVisitsIn(dashboardCacheFilter.filterDate, [], dashboardCacheFilter.encountersFilters, dashboardCacheFilter.generalEncountersFilters, queryProgramEncounter, queryGeneralEncounter), state.individualUUIDs),
MyDashboardActions.commonIndividuals(individualService.allScheduledVisitsIn(dashboardCacheFilter.filterDate, [], RealmQueryService.orQuery(dashboardCacheFilter.encountersFilters), RealmQueryService.orQuery(dashboardCacheFilter.generalEncountersFilters), queryProgramEncounter, queryGeneralEncounter), state.individualUUIDs),

MyDashboardActions.commonIndividuals(individualService.allOverdueVisitsIn(dashboardCacheFilter.filterDate, [], RealmQueryService.orQuery(dashboardCacheFilter.encountersFilters), RealmQueryService.orQuery(dashboardCacheFilter.generalEncountersFilters), queryProgramEncounter, queryGeneralEncounter), state.individualUUIDs),

MyDashboardActions.commonIndividuals(individualService.recentlyCompletedVisitsIn(dashboardCacheFilter.filterDate, [], dashboardCacheFilter.encountersFilters, dashboardCacheFilter.generalEncountersFilters, queryProgramEncounter, queryGeneralEncounter), state.individualUUIDs),

MyDashboardActions.commonIndividuals(individualService.recentlyRegistered(dashboardCacheFilter.filterDate, [], dashboardCacheFilter.individualFilters, dashboardCacheFilter.selectedPrograms, getApplicableEncounterTypes(dashboardCacheFilter)), state.individualUUIDs),

MyDashboardActions.commonIndividuals(individualService.recentlyEnrolled(dashboardCacheFilter.filterDate, [], dashboardCacheFilter.enrolmentFilters), state.individualUUIDs),
MyDashboardActions.commonIndividuals(individualService.allInWithFilters(dashboardCacheFilter.filterDate, [], dashboardCacheFilter.individualFilters, dashboardCacheFilter.selectedPrograms, getApplicableEncounterTypes(dashboardCacheFilter)), state.individualUUIDs, true),
MyDashboardActions.commonIndividuals(individualService.allInWithFilters(dashboardCacheFilter.filterDate, [], RealmQueryService.orQuery(dashboardCacheFilter.individualFilters), dashboardCacheFilter.selectedPrograms, getApplicableEncounterTypes(dashboardCacheFilter)), state.individualUUIDs, true),

MyDashboardActions.commonIndividuals(dueChecklistWithChecklistItem.individual, state.individualUUIDs)
]
: [state.scheduled, state.overdue, state.recentlyCompletedVisits, state.recentlyCompletedRegistration, state.recentlyCompletedEnrolment, state.total, state.dueChecklist]);
Expand Down Expand Up @@ -361,13 +366,20 @@ class MyDashboardActions {
].filter(Boolean).join(" AND ");

const transformedSelectedLocations = (action.selectedLocations && !_.isNil(action.selectedLocations)) ? action.selectedLocations.map(({
uuid,
name,
level,
type,
isSelected,
parentUuid
}) => ({uuid, name, level, type, parentUuid, isSelected})) : [];
uuid,
name,
level,
type,
isSelected,
parentUuid
}) => ({
uuid,
name,
level,
type,
parentUuid,
isSelected
})) : [];
const newState = {
...state,
filters: newFilters,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import BaseService from './BaseService.js'
import _ from 'lodash';
import RealmQueryService from "./query/RealmQueryService";

class BaseAddressLevelService extends BaseService {
constructor(db, beanStore) {
Expand Down Expand Up @@ -37,7 +38,12 @@ class BaseAddressLevelService extends BaseService {
}

getAllAtLevel(levelQuery) {
return [...this.findAllByCriteria(`${levelQuery} AND voided = false`, this.getSchema()).sorted('level', true)];
const query = _.isEmpty(levelQuery) ? "" : `${levelQuery} AND`;
return [...this.findAllByCriteria(`${query} voided = false`, this.getSchema()).sorted('level', true)];
}

getAllAtLevels(levels) {
return this.getAllAtLevel(RealmQueryService.orKeyValueQuery("level", levels));
}

highestLevel(minLevelTypeUUIDs) {
Expand Down
Loading

0 comments on commit 0f5c9ac

Please sign in to comment.