Giter Club home page Giter Club logo

avni-models's People

Contributors

1t5j0y avatar arjunk avatar darshanatakpsl avatar dependabot[bot] avatar himeshr avatar himeshr-egov avatar hithacker avatar mahalakshme avatar petmongrels avatar sachsk avatar sidsamanvay avatar swapnil106111 avatar vinayvenu avatar vindeolal avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

avni-models's Issues

getEncounters doesn't sortBy cancelDateTime

Issue:
getEncounters function in Individual.js and ProgramEnrolment.js has facility to consider cancelled encounters as well. But it is not considering cancelDateTime when sorting the encounters. Hence when need to get the latest(including cancelled encounters) another sorting as below need to be done in the report card query:

const encounters = enrolment.getEncounters(false);
      const sortedEncounters = _.sortBy(encounters, (encounter) => {
      return _.isNil(encounter.cancelDateTime)? moment().diff(encounter.encounterDateTime) : 
      moment().diff(encounter.cancelDateTime)}); 
      const latestEncounter = _.head(sortedEncounters);

Significance of fixing this issue:

  • To prevent code duplication of above in the implementations
  • For faster work in implementation team.

Unable to retreive RepeatableQuestionGroup Observation concept value for a ProgramEncounter

In "Lend a hand India" org, for "LAHI Intern" Subject, "Internship LAHI" Program, "LAHI INTERN ATTENDANCE" Program Encounter is to be created.

As part of the ProgramEncounter's Decision rule, we need to fetch "Date of Attendance" concept value from within the "Attendance Day" RepeatableQuestionGroup's groupObservations.

Attempting this results in failure, as following method fails to handle the array nature of "Attendance Day" RepeatableQuestionGroup :

const dateOfAttendance = programEncounter.findObservation("Date of Attendance","Attendance Day");
**ERROR: undefined is not an object (evaluating 't.concept.name')**

In avni-models, AbstractEncounter.js:

  findObservation(conceptNameOrUuid, parentConceptNameOrUuid) {
    const observations = _.isNil(parentConceptNameOrUuid) ? this.observations : this.findGroupedObservation(parentConceptNameOrUuid);
    return _.find(observations, (observation) => {
      return (observation.concept.name === conceptNameOrUuid) || (observation.concept.uuid === conceptNameOrUuid);
    });
  }

ERROR is at "(observation.concept.name === conceptNameOrUuid)".. observation.concept is undefined.

Instead, we should fetch the value from the first entry in RepeatableQuestionGroup as follows:

const groupedObservations = programEncounter.findGroupedObservation("Attendance Day");
  const groupObservations = _.isEmpty(groupedObservations) ? [] : groupedObservations[0].groupObservations;
  const dateOfAttendance =  _.find(groupObservations, (observation) => {
    return (observation.concept.name === "Date of Attendance");
  });

Tech tasks:

  • Handle fetch value of a concept from RepeatableQuestionGroup Observations
    I. for all repetition in RepeatableQuestionGroup
    II. for a single repetition in RepeatableQuestionGroup
    III. for specific repetition in RepeatableQuestionGroup based on some filter criteria

Unable to get affiliatedGroups for Individual

Background info

In Jss Phulwari programs, "Child enrolment" form, ..

  • We determine the Phulwari to be associated based on village name
  • AffiliationGroups are set for the Individual using the GroupAffiliation FormElement
  • in the EnrolmentId FormElement, we have a rule that fetches the affiliatedGroups. It then uses the villageName, PhulwariName(extracted from affiliatedGroups) and GeneratedID (From IdSource) to come up with final Enrolment ID.

Issue

During EnrolmentId FormElement rule execution, we fail to fetch affiliatedGroups, resulting in "Enrolment ID" not being set.

Rule snippet

const phulwariName = _.get(_.find(programEnrolment.individual.affiliatedGroups, ({voided}) => !voided), ['groupSubject', 'firstName'], '');

Root Cause

After ReactNative upgrade, we are not able to access temp property affiliatedGroups in Individual from enrolment during ProgramEnrolment Create / edit. This is due to the fact that, individual returned for enrolment.individual is the realmDb object, which is fetched fresh from db.

Therefore the rule fails to fetch affiliatedGroups on individual of an enrolment, and therefore "Enrolment ID" generation fails.

Possible fix

We cannot convert temp property affiliatedGroups to persistent value of individual, as the individual does not get saved duing enrolment form filling. Therefore the only solution is to switch to using Enrolment to store the temp property affiliatedGroups and modify the Rules suitably. This has already been tested to work in dev environment.

Final solution after pairing with Vinay

  • We do not like the approach of using temporary variables for storing the affiliatedGroups information. All such details should be passed to the ruleEvaluationService as part of the entityContext object.

  • Also, in the Subject/ Person summary view, pass the required affiliatedGroups separately from state during invocation and dont expect it to be a temp variable in Individual.

Code changes impact following scenarios, which should be verified during testing:

  • Subject registration summary has GroupAffiliation msg (Phulwari org, Individual subject registration)
  • Enrolment to program has Enrolment ID auto generated based on GroupAffiliation (JSS SIngrauli org, Child enrolment)

Post release steps

After the release, Support team would need to modify all rules that refer to "individual.affiliatedGroups" to instead use "params.entityContext.affiliatedGroups".

Old Rule snippet

const phulwariName = _.get(_.find(programEnrolment.individual.affiliatedGroups, ({voided}) => !voided), ['groupSubject', 'firstName'], '');

New Rule snippet

const phulwariName = _.get(_.find(params.entityContext.affiliatedGroups, ({voided}) => !voided), ['groupSubject', 'firstName'], '');

##Support ticket
https://avni.freshdesk.com/a/tickets/2925

Refactor model to cater to richer display of non-primitive data types

With the introduction of subject and location concept data types, there is need to update the model to allow for richer display of these data types on the clients.

Tech tasks:

  • Model: Introduce a Displayable type which includes both the text to be displayed as well as a backing entity object that can be accessed by the respective clients to generate the richer display.
  • Model: Add plumbing in order to fetch the backing entity objects as required based on the data type.
  • Server: Update Server to return the required entity objects against observations.
  • DEA: Update Data Entry App to use the new displayable class
  • Android Client: Update Android client to use the new displayable type.

Acceptance criteria:
All observations in Registration, Enrolment, Encounter, Program encounter should continue to be shown as before. Observations with concepts data type Subject will be linked to the particular subject.

Add support in rules-server to handle question group concepts - both repeatable and non-repeatable

Issue: For question group concepts, model functions doesn't execute as expected in message rule

Ticket: https://avni.freshdesk.com/a/tickets/2518 - workaround for this issue was done by using the model function in decision rule here

Steps to reproduce:

  • Go to Lend A Hand India in prod
  • go to LAHI INTERN ATTENDANCE encounter type
  • In message rule, programEncounter.findGroupedObservation("Attendance Day") and programEncounter.getObservationValue("Date of Attendance", "Attendance Day") returns [] and undefined respectively even when these values are defined. (Attendance Day is question group concept and Date of Attendance is a concept within that question group).
  • programEncounter.findGroupedObservation works as expected in encounter decision rule.

Expectation:
let dateTime = programEncounter.getObservationValue("Date of Attendance", "Attendance Day"); and

const groupedObservations = programEncounter.findGroupedObservation("Attendance Day");
const groupObservations = _.isEmpty(groupedObservations) ? [] : groupedObservations[0].groupObservations;
  const dateOfAttendance =  _.find(groupObservations, (observation) => {
  return (observation.concept.name === "Date of Attendance");
  });

in message rule should return date as expected.

Analysis:
Printing the observations in decision rule vs in message rule:

decision_rule.png

message_rule.png

looks like observations when sent from server to rule-server to execute message rule is not handled for group observations but in client since the data is accessible it works in decision rule.

Add method in models to check for active program enrolment

Usecase:
Currently when I want to check when an individual is actively enrolled in a program(say Child program) in say, in report card query, I need to do the below:
enrolment.program.name === 'Child' && _.isNil(enrolment.programExitDateTime) && !enrolment.voided

Instead I would like to have a method, in models like below:

const isActive = (programName) => {
return this.program.name === programName && _.isNil(this.programExitDateTime) && !this.voided
}

Need:

  • This is to prevent missing out checking voided or if the program is exited in rules/report card queries
  • To keep the code in rules and report card queries more concise.
  • Currently the method isActive available doesn't do all the checks.

Encounter sync is extremely slow

See attached sync log from the server. While other entity syncs take very little time, save of encounters progressively degrades pretty fast.

App version: 3.38.5

Analysis notes and solution

This is caused by higher number of encounters per subject. In this case, when number of encounters per subject goes to the 100s, save takes a lot of time.

Root cause is the slow implementation of BaseEntity.mergeOn() method. This method takes m parents, looks at all their children and returns one parent with unique values of all their children in it. For m subjects with n encounters each, the merge has a loop that iterates m * n * n times. m is usually around 1-10 and n can go from 1 to 1000.

The purpose of the merge is to identify unique values in a list of m * n items. If we use hashmaps instead of doing a triple loop, this operation can be done with a complexity of O(m*n).

https://app.zenhub.com/files/64590403/5bb599a4-6a6c-4a55-80fc-257b65a9e7d3/download

Testing notes

  • Sync of
    • Individuals
    • Encounters
    • Program Encounters
    • Checklists
    • Group Subjects
    • Individual Relationships
    • Approvals
    • Tasks
    • Forms (forms, form element groups, form elements, concepts, concept answers)
  • Verify that sync brings in data correctly. Push testing is not relevant
  • Test for higher number of items to be synced and different organisations
  • Fast sync, upload etc testing not relevant

Issue with scheduledEncountersOfType

The following snippet ideally should give some value only if there is a visit scheduled of the specified type which is not completed and cancelled. (and not consider the visit user is completing) But at any moment it gives 'hello>>>>', [ { that: {} } ] irrespective if there is already a visit scheduled or a scheduled visit is being completed of that type.

As an implementor we do not have any way to identify if the visit is already scheduled or not!

const hello = programEncounter.programEnrolment.scheduledEncountersOfType('Child followup');
console.log('hello>>>>', hello);

Duplication of code across webapp and rules-server

Case:

  • Both rules-server and webapp use response/request from avni-server. In both cases, to be able to use model functions, we are doing mapping of observations of Subject/Encounter/Enrolment, etc., using mapObservations functions in both code bases. This I think has lead to duplication of code for mapping the observations.

Need:

  • To avoid repeating the fixes in both codebases. I think fix for this made in rules-server might to be repeated in webapp, to get the repeatable question group work in data entry app
  • To have the code in one place

What can be done:

  • Mapping of observations code can be moved to models. Already it is done partially in avni-models using fromObs methods in concept classes.
  • More analysis need to be done to understand why it was not done before

Create one method to get observation from last filled encounter from individual

Context :

So In lahi we have requirement for dashboard Interested but not applied to get latest general encounter Program Eligibility and check Status is "Interested but not applied" or not. For that we are currently using individual.findLatestObservationFromEncounters() to get that but when there are two general encounter it is giving proper data.

Requirement :

For general encounter create one method to get observation from last completed encounter.

Acceptance Criteria :

method should give observation form the last completed encounter.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.