Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [DHIS2-9661][DHIS2-14830] first stage registration #3267

Merged
merged 58 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
91e3f3d
feat: [DHIS2-9661] first stage registration
jasminenguyennn Mar 23, 2023
c64f9dd
fix: [DHIS2-9661] fix flow
jasminenguyennn Mar 23, 2023
5af0f1f
fix: fix cypress
jasminenguyennn Mar 23, 2023
1bcd8b0
Merge branch 'master' into DHIS2-9661-2
jasminenguyennn Mar 27, 2023
becc455
Merge branch 'master' into DHIS2-9661-2
jasminenguyennn Mar 30, 2023
38548e5
Merge branch 'master' into DHIS2-9661-2
jasminenguyennn Mar 31, 2023
f86d718
chore: [DHIS2-9661] post merge
jasminenguyennn Mar 31, 2023
55222fc
fix: [DHIS2-9661] post merge
jasminenguyennn Mar 31, 2023
13f4258
Merge branch 'master' into DHIS2-9661-2
jasminenguyennn Apr 17, 2023
ca02b48
Merge branch 'master' into DHIS2-9661
simonadomnisoru May 25, 2023
089ccec
test: fix the cypress tests
simonadomnisoru May 25, 2023
910c101
fix: get data form IndexDB & first stage with acccess & custom sectio…
simonadomnisoru May 30, 2023
c45d188
fix: getStageWithOpenAfterEnrollment and auto generated events
simonadomnisoru Jun 1, 2023
4430b26
Merge branch 'master' into DHIS2-9661
simonadomnisoru Jun 1, 2023
a6866cf
fix: add attributeCategoryOptions to registration event
simonadomnisoru Jun 1, 2023
861096e
fix: cypress tests
simonadomnisoru Jun 2, 2023
f963fcf
test: add cypress test
simonadomnisoru Jun 2, 2023
05e9896
fix: cypress tests
simonadomnisoru Jun 2, 2023
0c27191
fix: cypress tests
simonadomnisoru Jun 2, 2023
fc2932f
fix: cypress tests
simonadomnisoru Jun 2, 2023
7648b36
fix: cypress tests
simonadomnisoru Jun 2, 2023
545a96c
fix: cypress tests
simonadomnisoru Jun 2, 2023
036119b
fix: add getValidatorContainers to stageOccurredAt field
simonadomnisoru Jun 21, 2023
573436c
Merge branch 'master' into DHIS2-9661
simonadomnisoru Jun 21, 2023
109d585
chore: remove useBuildFirstStageRegistration from useRegistrationForm…
simonadomnisoru Jul 5, 2023
0ace194
chore: move the files from DataEntryDhis2Helpers
simonadomnisoru Jul 5, 2023
9117f67
feat: merge the metadata and use only one DataEntry; improve the onRe…
simonadomnisoru Jul 13, 2023
cd4627b
fix: logic related to first stage on registration page, auto-generate…
simonadomnisoru Jul 18, 2023
e117f84
Merge branch 'master' into DHIS2-9661
simonadomnisoru Jul 18, 2023
ab112c0
fix: cypress tests
simonadomnisoru Jul 18, 2023
050bdc4
fix: cypress tests
simonadomnisoru Jul 18, 2023
1025771
Merge branch 'master' into DHIS2-9661
simonadomnisoru Jul 24, 2023
c0ea42b
chore: simplify dataentry import
simonadomnisoru Jul 24, 2023
2f1615d
refactor: BEFORE_METADATA_BASED_SECTION placement and beforeSectionId…
simonadomnisoru Jul 25, 2023
79c771c
Merge branch 'master' into DHIS2-9661
simonadomnisoru Jul 25, 2023
30ac52a
feat: DHIS2-14830 update program rules execution
simonadomnisoru Jul 31, 2023
711e798
chore: clean code
simonadomnisoru Jul 31, 2023
8fa917b
Merge branch 'master' into DHIS2-9661
simonadomnisoru Jul 31, 2023
b4d8bf2
chore: rely on the order of the events inside the report
simonadomnisoru Aug 1, 2023
ef3d045
Merge branch 'master' into DHIS2-9661
simonadomnisoru Aug 9, 2023
3997f7d
chore: fix typo
simonadomnisoru Aug 9, 2023
72f14d6
chore: rename callback
simonadomnisoru Aug 29, 2023
395e985
fix: convertAndGroupBySection
simonadomnisoru Aug 31, 2023
d264856
fix: splitCurrentClientMainData for enrollemnt and first stage event
simonadomnisoru Aug 31, 2023
eede39a
fix: cypress tests
simonadomnisoru Sep 1, 2023
231569f
Merge branch 'master' into DHIS2-9661
simonadomnisoru Sep 1, 2023
24775e5
fix: flow
simonadomnisoru Sep 1, 2023
fd41e3f
fix: simplify shouldShowAOC logic in getAOCSettingsFn
simonadomnisoru Sep 6, 2023
16961bb
feat: open the enrollmentEventEdit page in edit mode by using initMod…
simonadomnisoru Sep 6, 2023
c61a05b
chore: improve currentEventMainData ids for rules
simonadomnisoru Sep 6, 2023
19611c2
fix: linter
simonadomnisoru Sep 6, 2023
3f00569
chore: improve first stage section names
simonadomnisoru Sep 12, 2023
e1d7578
Merge branch 'master' into DHIS2-9661
simonadomnisoru Sep 12, 2023
6e6a463
chore: increase the cacheVersion
simonadomnisoru Sep 28, 2023
3c7fe40
Merge branch 'master' into DHIS2-9661
simonadomnisoru Sep 28, 2023
ce887fd
fix: custom form not being rendered
simonadomnisoru Sep 29, 2023
81216d7
chore: cypress
simonadomnisoru Oct 2, 2023
1a01f65
Merge branch 'master' into DHIS2-9661
simonadomnisoru Oct 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ And('you create a new tei in Child programme from Ngelehun CHC', () => {
.eq(1)
.type('McQuack')
.blur();
cy.get('[data-test="capture-ui-input"]')
.eq(7)
.type('2023-09-01')
.blur();

clickSave();
});
Expand Down
5 changes: 5 additions & 0 deletions cypress/integration/NewPage.feature
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ Feature: User creates a new entries from the registration page
Scenario: New person in Tracker Program > Submitting the form shows a list with duplicates
Given you are in Child programme registration page
When you fill the Child programme registration form with a first name with value that has duplicates
And you fill in the birth report date
And you click the save person submit button
And you see the possible duplicates modal
When you click the next page button
Expand Down Expand Up @@ -199,3 +200,7 @@ Feature: User creates a new entries from the registration page
Given you are in Child programme reenrollment page
Then you see the form prefield with existing TEI attributes values
And the scope selector has the TEI context

Scenario: First stage appears on registration page
Given you are in Child programme registration page
Then the first stage appears on registration page
16 changes: 16 additions & 0 deletions cypress/integration/NewPage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,13 @@ And('you fill the Child programme registration form with a first name with value
.blur();
});

And('you fill in the birth report date', () => {
cy.get('[data-test="capture-ui-input"]')
.eq(7)
.type('2023-01-01')
.blur();
});

And('you are in the WNCH PNC program registration page', () => {
cy.visit('/#/new?programId=uy2gU8kT1jF&orgUnitId=DiszpKrYNg8');
});
Expand Down Expand Up @@ -565,3 +572,12 @@ Then('you see the enrollment event New page', () => {
cy.url().should('include', '/#/enrollmentEventNew?');
cy.url().should('include', 'stageId=hYyB7FUS5eR');
});


Then('the first stage appears on registration page', () => {
cy.get('[data-test="registration-page-content"]').within(() => {
cy.contains('Data Entry (Birth)').should('exist');
cy.contains('Report date').should('exist');
cy.contains('Apgar Score').should('exist');
});
});
6 changes: 6 additions & 0 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,12 @@ msgstr "Some operations are still runnning. Please wait.."
msgid "Operations running"
msgstr "Operations running"

msgid "Data Entry ({{ stageName }})"
msgstr "Data Entry ({{ stageName }})"

msgid "Data Entry ({{ stageName }} - {{ sectionName }})"
msgstr "Data Entry ({{ stageName }} - {{ sectionName }})"

msgid "Sort"
msgstr "Sort"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type Props = {
formBuilderId: string,
formId: string,
onFieldsValidated: ?(any, formBuilderId: string) => void,
onGetCustomSectionName: ?(name?: string) => string,
};

class D2SectionPlain extends React.PureComponent<Props> {
Expand All @@ -49,6 +50,14 @@ class D2SectionPlain extends React.PureComponent<Props> {
renderSectionHeader() {
const title = this.props.sectionMetaData.name;

if (this.props.onGetCustomSectionName) {
return (
<SectionHeaderSimple
title={this.props.onGetCustomSectionName(title)}
/>
);
}

if (!title) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import i18n from '@dhis2/d2-i18n';
import moment from 'moment';
import { type OrgUnit } from '@dhis2/rules-engine-javascript';
import {
DataEntry,
placements,
withDataEntryField,
withDataEntryFieldIfApplicable,
Expand Down Expand Up @@ -33,7 +32,8 @@ import {
getIncidentDateValidatorContainer,
} from './fieldValidators';
import { sectionKeysForEnrollmentDataEntry } from './constants/sectionKeys.const';
import { type Enrollment, getProgramThrowIfNotFound } from '../../../metaData';
import { type Enrollment, ProgramStage, getProgramThrowIfNotFound } from '../../../metaData';
import { FirstStageRegistrationContainer } from '../../DataEntryDhis2Helpers/FirstStageRegistration/FirstStageRegistration.container';
import {
getCategoryOptionsValidatorContainers,
attributeOptionsKey,
Expand Down Expand Up @@ -333,7 +333,10 @@ type FinalTeiDataEntryProps = {
orgUnitId: string,
onUpdateDataEntryField: Function,
onUpdateFormFieldAsync: Function,
onUpdateFormField: Function
onUpdateFormField: Function,
firstStageMetaData?: {
stage: ProgramStage,
},
};
// final step before the generic dataEntry is inserted
class FinalEnrollmentDataEntry extends React.Component<FinalTeiDataEntryProps> {
Expand All @@ -353,9 +356,10 @@ class FinalEnrollmentDataEntry extends React.Component<FinalTeiDataEntryProps> {

render() {
const { enrollmentMetadata, ...passOnProps } = this.props;

return (
// $FlowFixMe[cannot-spread-inexact] automated comment
<DataEntry
<FirstStageRegistrationContainer
{...passOnProps}
dataEntrySections={FinalEnrollmentDataEntry.dataEntrySectionDefinitions}
formFoundation={enrollmentMetadata.enrollmentForm}
Expand All @@ -382,6 +386,9 @@ type PreEnrollmentDataEntryProps = {
onStartAsyncUpdateField: Function,
onGetUnsavedAttributeValues?: ?Function,
teiId?: ?string,
firstStageMetaData?: {
stage: ProgramStage,
}
};

class PreEnrollmentDataEntryPure extends React.PureComponent<Object> {
Expand All @@ -406,18 +413,18 @@ export class EnrollmentDataEntryComponent extends React.Component<PreEnrollmentD
}

handleUpdateField = (...args: Array<any>) => {
const { programId, orgUnit } = this.props;
this.props.onUpdateField(...args, programId, orgUnit);
const { programId, orgUnit, firstStageMetaData } = this.props;
this.props.onUpdateField(...args, programId, orgUnit, firstStageMetaData?.stage);
}

handleUpdateDataEntryField = (...args: Array<any>) => {
const { programId, orgUnit } = this.props;
this.props.onUpdateDataEntryField(...args, programId, orgUnit);
const { programId, orgUnit, firstStageMetaData } = this.props;
this.props.onUpdateDataEntryField(...args, programId, orgUnit, firstStageMetaData?.stage);
}

handleStartAsyncUpdateField = (...args: Array<any>) => {
const { programId, orgUnit } = this.props;
this.props.onStartAsyncUpdateField(...args, programId, orgUnit);
const { programId, orgUnit, firstStageMetaData } = this.props;
this.props.onStartAsyncUpdateField(...args, programId, orgUnit, firstStageMetaData?.stage);
}

render() {
Expand All @@ -429,6 +436,7 @@ export class EnrollmentDataEntryComponent extends React.Component<PreEnrollmentD
onGetUnsavedAttributeValues,
...passOnProps
} = this.props;

return (
// $FlowFixMe[cannot-spread-inexact] automated comment
<PreEnrollmentDataEntryPure
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @flow
import type { OrgUnit } from '@dhis2/rules-engine-javascript';
import { connect } from 'react-redux';
import { ProgramStage } from '../../../metaData';
import { updateFieldBatch, asyncUpdateSuccessBatch, updateDataEntryFieldBatch } from './actions/enrollment.actionBatchs';
import { startAsyncUpdateFieldForNewEnrollment } from './actions/enrollment.actions';
import { EnrollmentDataEntryComponent } from './EnrollmentDataEntry.component';
Expand All @@ -15,25 +16,28 @@ const mapDispatchToProps = (dispatch: ReduxDispatch) => ({
data: any,
programId: string,
orgUnit: OrgUnit,
stage?: ProgramStage,
) => {
dispatch(updateDataEntryFieldBatch(innerAction, programId, orgUnit));
dispatch(updateDataEntryFieldBatch(innerAction, programId, orgUnit, stage));
},
onUpdateField: (
innerAction: ReduxAction<any, any>,
programId: string,
orgUnit: OrgUnit,
stage?: ProgramStage,
) => {
dispatch(updateFieldBatch(innerAction, programId, orgUnit));
dispatch(updateFieldBatch(innerAction, programId, orgUnit, stage));
},
onStartAsyncUpdateField: (
innerAction: ReduxAction<any, any>,
dataEntryId: string,
itemId: string,
programId: string,
orgUnit: OrgUnit,
stage?: ProgramStage,
) => {
const onAsyncUpdateSuccess = (successInnerAction: ReduxAction<any, any>) =>
asyncUpdateSuccessBatch(successInnerAction, dataEntryId, itemId, programId, orgUnit);
asyncUpdateSuccessBatch(successInnerAction, dataEntryId, itemId, programId, orgUnit, stage);
const onAsyncUpdateError = (errorInnerAction: ReduxAction<any, any>) => errorInnerAction;

dispatch(startAsyncUpdateFieldForNewEnrollment(innerAction, onAsyncUpdateSuccess, onAsyncUpdateError));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,38 @@ import type {
} from '@dhis2/rules-engine-javascript';
import { getApplicableRuleEffectsForTrackerProgram, updateRulesEffects } from '../../../../rules';
import { rulesExecutedPostUpdateField } from '../../../DataEntry/actions/dataEntry.actions';
import type { TrackerProgram, RenderFoundation } from '../../../../metaData';
import { TrackerProgram, RenderFoundation, ProgramStage } from '../../../../metaData';
import { startRunRulesPostUpdateField } from '../../../DataEntry';
import { startRunRulesOnUpdateForNewEnrollment } from './enrollment.actions';
import { convertValue } from '../../../../converters/formToClient';

export const batchActionTypes = {
RULES_EXECUTED_POST_UPDATE_FIELD_FOR_ENROLLMENT: 'RulesExecutedPostUpdateFieldForEnrollment',
UPDATE_FIELD_NEW_ENROLLMENT_ACTION_BATCH: 'UpdateFieldNewEnrollmentActionBatch',
UPDATE_DATA_ENTRY_FIELD_NEW_ENROLLMENT_ACTION_BATCH: 'UpdateDataEntryFieldNewEnrollmentActionBatch',
};

export const getCurrentEventValuesFromStage = (attributeValues?: TEIValues, stage?: ProgramStage) => {
const currentEventValues = {};
if (!stage) {
return { currentEventValues, attributeValues };
}

const dataElements = [...stage.stageForm.getElements().values()].map(({ id, type }) => ({ id, type }));

if (attributeValues) {
Object.keys(attributeValues).forEach((attributeId) => {
const found = dataElements.find(element => element.id === attributeId);
if (found) {
currentEventValues[attributeId] = convertValue(attributeValues[attributeId], found.type);
delete attributeValues[attributeId];
}
});
}

return { currentEventValues, attributeValues };
};

export const runRulesOnUpdateFieldBatch = (
program: TrackerProgram,
foundation: RenderFoundation,
Expand All @@ -26,17 +48,33 @@ export const runRulesOnUpdateFieldBatch = (
itemId: string,
orgUnit: OrgUnit,
enrollmentData?: Enrollment,
attributeValues?: TEIValues,
teiAttributeValues?: TEIValues,
extraActions: Array<ReduxAction<any, any>> = [],
uid: string,
stage?: ProgramStage,
) => {
const effects = getApplicableRuleEffectsForTrackerProgram({
program,
orgUnit,
enrollmentData,
attributeValues,
});
let effects;

if (stage) {
const { attributeValues, currentEventValues } = getCurrentEventValuesFromStage(teiAttributeValues, stage);
const currentEvent = { ...currentEventValues, programStageId: stage.id };
effects = getApplicableRuleEffectsForTrackerProgram({
program,
stage,
orgUnit,
currentEvent,
enrollmentData,
attributeValues,
});
} else {
effects = getApplicableRuleEffectsForTrackerProgram({
program,
stage,
orgUnit,
enrollmentData,
attributeValues: teiAttributeValues,
});
}
return batchActions([
updateRulesEffects(effects, formId),
rulesExecutedPostUpdateField(dataEntryId, itemId, uid),
Expand All @@ -48,29 +86,31 @@ export const updateDataEntryFieldBatch = (
innerAction: ReduxAction<any, any>,
programId: string,
orgUnit: OrgUnit,
stage?: ProgramStage,
) => {
const { dataEntryId, itemId } = innerAction.payload;
const uid = uuid();

return batchActions([
innerAction,
startRunRulesPostUpdateField(dataEntryId, itemId, uid),
startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit),
startRunRulesPostUpdateField(dataEntryId, itemId, uid, stage),
startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit, stage),
], batchActionTypes.UPDATE_DATA_ENTRY_FIELD_NEW_ENROLLMENT_ACTION_BATCH);
};

export const updateFieldBatch = (
innerAction: ReduxAction<any, any>,
programId: string,
orgUnit: OrgUnit,
stage?: ProgramStage,
) => {
const { dataEntryId, itemId } = innerAction.payload;
const uid = uuid();

return batchActions([
innerAction,
startRunRulesPostUpdateField(dataEntryId, itemId, uid),
startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit),
startRunRulesPostUpdateField(dataEntryId, itemId, uid, stage),
startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit, stage),
], batchActionTypes.UPDATE_FIELD_NEW_ENROLLMENT_ACTION_BATCH);
};

Expand All @@ -80,12 +120,13 @@ export const asyncUpdateSuccessBatch = (
itemId: string,
programId: string,
orgUnit: OrgUnit,
stage?: ProgramStage,
) => {
const uid = uuid();

return batchActions([
innerAction,
startRunRulesPostUpdateField(dataEntryId, itemId, uid),
startRunRulesOnUpdateForNewEnrollment({ ...innerAction.payload, dataEntryId, itemId }, uid, programId, orgUnit),
startRunRulesPostUpdateField(dataEntryId, itemId, uid, stage),
startRunRulesOnUpdateForNewEnrollment({ ...innerAction.payload, dataEntryId, itemId }, uid, programId, orgUnit, stage),
], batchActionTypes.UPDATE_FIELD_NEW_ENROLLMENT_ACTION_BATCH);
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @flow
import type { OrgUnit } from '@dhis2/rules-engine-javascript';
import { actionCreator, actionPayloadAppender } from '../../../../actions/actions.utils';
import { ProgramStage } from '../../../../metaData';

export const actionTypes = {
START_RUN_RULES_ON_UPDATE: 'StartRunRulesOnUpdateForNewEnrollment',
Expand All @@ -11,9 +12,10 @@ export const startRunRulesOnUpdateForNewEnrollment = (
uid: string,
programId: string,
orgUnit: OrgUnit,
stage?: ProgramStage,
) =>
actionCreator(actionTypes.START_RUN_RULES_ON_UPDATE)(
{ innerPayload: payload, uid, programId, orgUnit });
{ innerPayload: payload, uid, programId, orgUnit, stage });

export const startAsyncUpdateFieldForNewEnrollment = (
innerAction: ReduxAction<any, any>,
Expand Down
Loading