Skip to content

Commit

Permalink
fix: [DHIS2-11804] add missing dependencies to rules engine execution
Browse files Browse the repository at this point in the history
  • Loading branch information
JoakimSM authored Jan 28, 2022
1 parent bab1add commit a83c7cd
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 51 deletions.
2 changes: 1 addition & 1 deletion notes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#FLOW-TYPED
to install libdefs:
flow-typed install --libdefDir fromReactScripts
move folders to flow-typed directory
move folders to flow-typed directory
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ export const getStructureEvents = (compareDates: CompareDates) => {
return (currentEvent: EventData = {}, otherEvents: EventsData = []) => {
const otherEventsFiltered = otherEvents
.filter(event => event.eventDate &&
[eventStatuses.COMPLETED, eventStatuses.ACTIVE, eventStatuses.VISITED].includes(event.status));
[eventStatuses.COMPLETED, eventStatuses.ACTIVE, eventStatuses.VISITED].includes(event.status) &&
event.eventId !== currentEvent.eventId,
);

const events = [...otherEventsFiltered, currentEvent]
.sort(compareEvents);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export const actionTypes = {
EVENT_FROM_URL_COULD_NOT_BE_RETRIEVED: 'EventFromUrlCouldNotBeRetrievedForEditEvent',
ORG_UNIT_RETRIEVED_ON_URL_UPDATE: 'OrgUnitRetrievedForEditEventOnUrlUpdate',
ORG_UNIT_RETRIEVAL_FAILED_ON_URL_UPDATE: 'OrgUnitRetrievalFailedForEditEventOnUrlUpdate',
START_OPEN_EVENT_FOR_EDIT: 'StartOpenEventForEditInDataEntry',
ADD_EVENT_NOTE: 'AddEventNote',
REMOVE_EVENT_NOTE: 'RemoveEventNote',
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import { loadEditDataEntry } from '../../DataEntry/actions/dataEntry.actions';
import { addFormData } from '../../D2Form/actions/form.actions';
import { EventProgram, TrackerProgram } from '../../../metaData/Program';
import { getStageFromEvent } from '../../../metaData/helpers/getStageFromEvent';
import type { Event } from '../../Pages/common/EnrollmentOverviewDomain/useCommonEnrollmentDomainData'; // TODO: This module/widget should not have a dependency to this
import { getEnrollmentForRulesEngine, getAttributeValuesForRulesEngine } from '../helpers';
import type { EnrollmentData, AttributeValue } from '../../Pages/common/EnrollmentOverviewDomain/useCommonEnrollmentDomainData';
import { prepareEnrollmentEventsForRulesEngine } from '../../../events/getEnrollmentEvents';

export const batchActionTypes = {
Expand Down Expand Up @@ -79,7 +80,18 @@ function getLoadActions(
];
}

export const openEventForEditInDataEntry = (
export const openEventForEditInDataEntry = ({
loadedValues: {
eventContainer,
dataEntryValues,
formValues,
},
orgUnit,
foundation,
program,
enrollment,
attributeValues,
}: {
loadedValues: {
eventContainer: Object,
dataEntryValues: Object,
Expand All @@ -88,8 +100,9 @@ export const openEventForEditInDataEntry = (
orgUnit: Object,
foundation: RenderFoundation,
program: Program | EventProgram | TrackerProgram,
allEvents?: ?Array<Event>,
) => {
enrollment?: EnrollmentData,
attributeValues?: Array<AttributeValue>,
}) => {
const dataEntryId = editEventIds.dataEntryId;
const itemId = editEventIds.itemId;
const dataEntryPropsToInclude = [
Expand All @@ -112,7 +125,6 @@ export const openEventForEditInDataEntry = (
},
];
const formId = getDataEntryKey(dataEntryId, itemId);
const { eventContainer, dataEntryValues, formValues } = loadedValues;
const dataEntryActions =
getLoadActions(
dataEntryId,
Expand All @@ -139,7 +151,11 @@ export const openEventForEditInDataEntry = (
stage,
orgUnit,
currentEvent,
otherEvents: allEvents ? prepareEnrollmentEventsForRulesEngine(allEvents) : undefined,
otherEvents: prepareEnrollmentEventsForRulesEngine(
enrollment?.events.filter(event => event.event !== currentEvent.eventId),
),
enrollmentData: getEnrollmentForRulesEngine(enrollment),
attributeValues: getAttributeValuesForRulesEngine(attributeValues, program.attributes),
});
} else if (program instanceof EventProgram) {
effects = getApplicableRuleEffectsForEventProgram({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,10 @@ import { map } from 'rxjs/operators';
import { batchActions } from 'redux-batched-actions';
import { rulesExecutedPostUpdateField } from '../../../DataEntry/actions/dataEntry.actions';
import {
actionTypes as editEventActionTypes,
} from '../../../Pages/ViewEvent/ViewEventComponent/editEvent.actions';
import {
openEventForEditInDataEntry,
prerequisitesErrorOpeningEventForEditInDataEntry,
batchActionTypes as editEventDataEntryBatchActionTypes,
actionTypes as editEventDataEntryActionTypes,
} from '../editEventDataEntry.actions';
import { getProgramAndStageFromEvent, getProgramThrowIfNotFound } from '../../../../metaData';
import { getProgramThrowIfNotFound } from '../../../../metaData';
import {
getCurrentClientValues,
getCurrentClientMainData,
Expand All @@ -26,29 +21,7 @@ import { getStageFromEvent } from '../../../../metaData/helpers/getStageFromEven
import { EventProgram, TrackerProgram } from '../../../../metaData/Program';
import { getDataEntryKey } from '../../../DataEntry/common/getDataEntryKey';
import { prepareEnrollmentEventsForRulesEngine } from '../../../../events/getEnrollmentEvents';

export const openEditEventInDataEntryEpic = (action$: InputObservable, store: ReduxStore) =>
action$.pipe(
ofType(
editEventActionTypes.ORG_UNIT_RETRIEVED_ON_URL_UPDATE,
editEventActionTypes.ORG_UNIT_RETRIEVAL_FAILED_ON_URL_UPDATE,
editEventActionTypes.START_OPEN_EVENT_FOR_EDIT,
),
map((action) => {
const state = store.value;
const eventContainer = action.payload.eventContainer;
const orgUnit = action.payload.orgUnit;

const metadataContainer = getProgramAndStageFromEvent(eventContainer.event);
if (metadataContainer.error) {
return prerequisitesErrorOpeningEventForEditInDataEntry(metadataContainer.error);
}
const foundation = metadataContainer.stage.stageForm;
const program = metadataContainer.program;


return batchActions(openEventForEditInDataEntry(eventContainer, orgUnit, foundation, program, state.enrollmentDomain.enrollment?.events));
}));
import { getEnrollmentForRulesEngine, getAttributeValuesForRulesEngine } from '../../helpers';

const runRulesForEditSingleEvent = (store: ReduxStore, dataEntryId: string, itemId: string, uid: string, fieldData?: ?FieldData) => {
const state = store.value;
Expand All @@ -72,18 +45,22 @@ const runRulesForEditSingleEvent = (store: ReduxStore, dataEntryId: string, item
const currentEventValues = foundation ? getCurrentClientValues(state, foundation, formId, fieldData) : {};
const currentEventMainData = foundation ? getCurrentClientMainData(state, itemId, dataEntryId, foundation) : {};
// $FlowFixMe
const currentEvent = { ...currentEventValues, ...currentEventMainData };
const currentEvent = { ...currentEventValues, ...currentEventMainData, eventId };

let effects;
if (program instanceof TrackerProgram) {
const otherEvents = state.enrollmentDomain.enrollments?.events;
// TODO: Add attributeValues & enrollmentData
const { enrollment, attributeValues } = state.enrollmentDomain;

effects = getApplicableRuleEffectsForTrackerProgram({
program,
stage,
orgUnit,
currentEvent,
otherEvents: otherEvents ? prepareEnrollmentEventsForRulesEngine(otherEvents) : undefined,
otherEvents: prepareEnrollmentEventsForRulesEngine(
enrollment?.events.filter(enrollmentEvent => enrollmentEvent.event !== currentEvent.eventId),
),
enrollmentData: getEnrollmentForRulesEngine(enrollment),
attributeValues: getAttributeValuesForRulesEngine(attributeValues, program.attributes),
});
} else {
effects = getApplicableRuleEffectsForEventProgram({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,18 @@ export const loadEditEventDataEntryEpic = (action$: InputObservable, store: Redu

const program = metadataContainer.program;
const foundation = metadataContainer.stage.stageForm;
const { enrollment, attributeValues } = state.enrollmentDomain;

return batchActions([
showEditEventDataEntry(),
...openEventForEditInDataEntry(loadedValues, orgUnit, foundation, program, state.enrollmentDomain.enrollment?.events),
...openEventForEditInDataEntry({
loadedValues,
orgUnit,
foundation,
program,
enrollment,
attributeValues,
}),
]);
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ import type { ClientEventContainer } from '../../../events/eventRequests';
import { TrackerProgram, EventProgram } from '../../../metaData/Program';
import { getStageFromEvent } from '../../../metaData/helpers/getStageFromEvent';
import { prepareEnrollmentEventsForRulesEngine } from '../../../events/getEnrollmentEvents';
import type { Event } from '../../Pages/common/EnrollmentOverviewDomain/useCommonEnrollmentDomainData'; // TODO: This module/widget should not have a dependency to this
import { getEnrollmentForRulesEngine, getAttributeValuesForRulesEngine } from '../helpers';
import type {
EnrollmentData,
AttributeValue,
} from '../../Pages/common/EnrollmentOverviewDomain/useCommonEnrollmentDomainData';


export const actionTypes = {
VIEW_EVENT_DATA_ENTRY_LOADED: 'ViewEventDataEntryLoadedForViewSingleEvent',
Expand All @@ -29,7 +34,21 @@ function getAssignee(clientAssignee: ?Object) {
}

export const loadViewEventDataEntry =
async (eventContainer: ClientEventContainer, orgUnit: Object, foundation: RenderFoundation, program: Program, allEvents?: ?Array<Event>) => {
async ({
eventContainer,
orgUnit,
foundation,
program,
enrollment,
attributeValues,
}: {
eventContainer: ClientEventContainer,
orgUnit: Object,
foundation: RenderFoundation,
program: Program,
enrollment?: EnrollmentData,
attributeValues?: Array<AttributeValue>,
}) => {
const dataEntryId = viewEventIds.dataEntryId;
const itemId = viewEventIds.itemId;
const dataEntryPropsToInclude = [
Expand Down Expand Up @@ -74,13 +93,17 @@ export const loadViewEventDataEntry =
if (!stage) {
throw Error(i18n.t('stage not found in rules execution'));
}
// TODO: Add attributeValues & enrollmentData

effects = getApplicableRuleEffectsForTrackerProgram({
program,
stage,
orgUnit,
currentEvent,
otherEvents: allEvents ? prepareEnrollmentEventsForRulesEngine(allEvents) : undefined,
otherEvents: prepareEnrollmentEventsForRulesEngine(
enrollment?.events.filter(event => event.event !== currentEvent.eventId),
),
enrollmentData: getEnrollmentForRulesEngine(enrollment),
attributeValues: getAttributeValuesForRulesEngine(attributeValues, program.attributes),
});
} else if (program instanceof EventProgram) {
effects = getApplicableRuleEffectsForEventProgram({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,16 @@ export const loadViewEventDataEntryEpic: Epic = (action$, store) =>
}
const foundation = metadataContainer.stage.stageForm;
const program = metadataContainer.program;
return from(loadViewEventDataEntry(eventContainer, orgUnit, foundation, program, state.enrollmentDomain.enrollment?.events))
const { enrollment, attributeValues } = state.enrollmentDomain;

return from(loadViewEventDataEntry({
eventContainer,
orgUnit,
foundation,
program,
enrollment,
attributeValues,
}))
.pipe(
map(item => batchActions(item)),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// @flow
import { convertServerToClient } from '../../../converters';
import { type DataElement } from '../../../metaData';
import type {
AttributeValue,
} from '../../Pages/common/EnrollmentOverviewDomain/useCommonEnrollmentDomainData';

export const getAttributeValuesForRulesEngine = (attributeValues: Array<AttributeValue> = [], attributes: Array<DataElement>) =>
attributeValues.reduce((acc, { id, value }) => {
const dataElement = attributes.find(({ id: attributeId }) => id === attributeId);
if (dataElement) {
acc[id] = convertServerToClient(value, dataElement.type);
}
return acc;
}, {});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// @flow
import { convertServerToClient } from '../../../converters';
import { dataElementTypes } from '../../../metaData';
import type {
EnrollmentData,
} from '../../Pages/common/EnrollmentOverviewDomain/useCommonEnrollmentDomainData';

export const getEnrollmentForRulesEngine = ({ enrollmentDate, incidentDate, enrollment }: EnrollmentData = {}): { enrollmentId: string, enrollmentDate: string, incidentDate?: string } => ({
enrollmentId: enrollment,
// $FlowFixMe
enrollmentDate: convertServerToClient(enrollmentDate, dataElementTypes.DATE),
// $FlowFixMe
incidentDate: convertServerToClient(incidentDate, dataElementTypes.DATE),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @flow
export { getAttributeValuesForRulesEngine } from './getAttributeValuesForRulesEngine';
export { getEnrollmentForRulesEngine } from './getEnrollmentForRulesEngine';
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export async function getEnrollmentEvents() {
}

export const prepareEnrollmentEventsForRulesEngine =
(apiEvents: Array<ApiEnrollmentEvent>, currentEvent?: EventData): EventsData =>
(apiEvents?: Array<ApiEnrollmentEvent> = [], currentEvent?: EventData): EventsData =>
apiEvents
.map(apiEvent => (currentEvent && currentEvent.eventId === apiEvent.event
? currentEvent
Expand Down
2 changes: 0 additions & 2 deletions src/epics/trackerCapture.epics.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import {
getOrgUnitOnUrlUpdateEpic,
} from 'capture-core/components/Pages/ViewEvent/epics/editEvent.epics';
import {
openEditEventInDataEntryEpic,
runRulesOnUpdateDataEntryFieldForEditSingleEventEpic,
runRulesOnUpdateFieldForEditSingleEventEpic,
} from 'capture-core/components/WidgetEventEdit/DataEntry/epics/editEventDataEntry.epics';
Expand Down Expand Up @@ -255,7 +254,6 @@ export const epics = combineEpics(
cancelNewEventEpic,
getEventFromUrlEpic,
getOrgUnitOnUrlUpdateEpic,
openEditEventInDataEntryEpic,
runRulesOnUpdateDataEntryFieldForEditSingleEventEpic,
runRulesOnUpdateFieldForEditSingleEventEpic,
saveEditEventLocationChangeEpic,
Expand Down

0 comments on commit a83c7cd

Please sign in to comment.