Task are going to cancelled state with appliesIf true

Hi there, I need some help to interpret task state in this case.
A patient_assessment triggers a task with 8 events, the task has as action form the moderate_malnutrition_followup form.
here I have got from the couchdb postgresql table the related task (with the patient) and I have joined them with the moderate_malnutrition_followup date_records to correspondant task doc
The first thing that currently I do not understand is that in the code we have:

  priority: function (contact) {
    const followUps = contact.reports.filter(contactReport =>
      contactReport.form === actionForm &&
      getField(contactReport, 'inputs.source_id') === this.patientAssessment._id
    const followUpNumber=indexOfEvent(this.definition.events, this.event);
    return {level: 'medium', label: `Suivi ${followUpNumber} - ${followUps.length}/${this.definition.events.length}`};

as you see here in the priority label column followUps.length is giving 4,but we have 5 reports of type moderate_malnutrition_followup associated with our contact
if followup is an array of lenght 4 this means that this.patientAssessment is not null nor undefined and we have in the code that

appliesIf: function (contact) {
    const eligibleReports = contact.reports
      .filter(report => report.form === Forms.PATIENT_ASSESSMENT_UNDER_5)
      .filter(report => getField(report, `treat_${treatment}`) === 'true')
      .filter(report => ageInDays(getDynamicReportedDate(report)) < 86);

    this.patientAssessment = getMostRecentReport(eligibleReports, Forms.PATIENT_ASSESSMENT_UNDER_5);
    return !!this.patientAssessment;

so appliesIf is returning true
Any ideas about how contact.reports is missing the 5th malnutrition_moderate_followup record ?
here the patient in question https://muso-mali.app.medicmobile.org/#/contacts/79a3360b-0bf8-4dac-9610-741cb6bb14fb

Hi @bamatic

Checking your spreadsheet, it looks like all of your tasks were completed in November or December 2022 - I’m looking at the state_2_at column. The last one being December 1st.

Looking at your contact, your fifth followup report, this one: https://muso-mali.app.medicmobile.org/#/reports/5b3ba638-f1a5-4100-b404-e7e951ce24fd, has a timestamp of December 15th. So it did not exist at the time that these tasks were completed.

Please correct me if I’m missing something.

Oh, I’ve just noticed you were referring to the tasks that were cancelled.

1 Like

Hi @diana,
if appliesIf return true, and resolvedIf function execution crash for any reasons (maybe getting a property of undefined or whatever) what would happen ? task will go to cancelled status ? this makes sense for me but do not know if this is the real behavior, if yes, this could be found in logs ?
If yes, we could report several cases of task going to cancelled with dates and maybe someone could look up in logs for us.

Hi @bamatic

resolvedIf function execution crash for any reasons

Checking locally, if the resolvedIf function throws an error, the client will see “Error loading tasks”, and the tasks did not change their state.

1 Like

Hi @bamatic

Is it possible that the main assessment report was purged from the user’s device, and this is why the tasks got cancelled?

I’m looking at the purge config, and it seems patient_assessment forms are purged after 30 days?

1 Like

yes i’m pretty sure that this is the reason, we will review purging to avoid treat_MAM assessments to be purged after 30 days and let them go to 90 days

but in cancelled tasks this.patientAssessment is defined and giving the correct value of patientAssessment._id in priorityLabel so now I’m not sure of this, if we have priorityLabel with undefined somewhere yes, but this is not the case, what do you think ?

I have a theory that I’ll confirm tomorrow.
The theory is that purging won’t trigger task recalculation. Tasks are documents that exist on the device and on the server, any changes made to them are through a mechanism that runs on the client device, where their corresponding contact (in this case the patient) is marked as dirty.
Tasks are also recalculated automatically every 7 days.

My theory is that purging doesn’t mark corresponding contacts as dirty, so their corresponding tasks remain stale, until they get automatically recalculated, or, in this case, get recalculated because of user action.
I’ll check this theory and report back.

1 Like

thanks a lot @diana for this answer,
I undestand that it’s when the user submits the action form that the tasks are recalculated so if the patient assessment is not found in the device, because it is purged, the appliesIf method returns false and the task go to the cancelled state

The lenght of array equals to 4 in the priority method is because this has been calculated in a erlier time, in a time when the patient assessment was not yet purged.

Can I understand that if purge mark contact (our patient in this case) as dirty the tasks would not be recalculated so purging won’t affect the task state ?

Hi @bamatic

Can I understand that if purge mark contact (our patient in this case) as dirty the tasks would not be recalculated so purging won’t affect the task state ?

Quite the opposite, the tasks would get recalculated immediately after purging, and will not require a different user action (like submitting that report) to recalculate. In this particular case, the tasks would get cancelled immediately after purging.

1 Like

I’ve created an issue to have purging running on the client to also trigger task recalculation: Update client-side purging to trigger task recalculation · Issue #8037 · medic/cht-core · GitHub

1 Like

So if we want to have our tasks not cancelled after each recalculation we need to avoid purging reports that are used for tasks, or once the report get purged automarically tasks will be recalculated and cancelled.

Correct. Only purge reports once that are no longer required by workflows.

Hi again @diana,
I know I’m asking a lot but if you have a time to look at this spreadsheet and help me to interprete this data I would realy appreciate
prenatal_followup tasks are triggered by pregnancy_family_planning forms

appliesIf: function (contact) {
      const eligibleReports = contact.reports
        .filter(r => r.form === Forms.PREGNANCY_FAMILY_PLANNING)
        .filter(r => !!toDate(getField(r, 'lmp_date')));

      // We use the most recent form for the schedule to handle multiple pregnancies, since
      // the duration of a pregnancy and frequency between is very non-deterministic
      this.pregnancyForm = getMostRecentReport(eligibleReports, Forms.PREGNANCY_FAMILY_PLANNING);
      return !!this.pregnancyForm;

emission ids are calculated with id:lmp+${days}`` where days is taken from elements of this array [14, 28, 42, 56, 70, 84, 98, 112, 126, 140, 154, 168, 182, 196, 203, 210, 217, 224, 231, 238, 245, 252, 259, 266, 273, 280, 287]
I’m ingesting tasks from couchdb/_changes feed, I have three docs with the same emission._id , for the followup of the 259th day, two of them have the same authoredOn value and is consistent with the stateHistory, from Daft to ready and with the app, logged on with the user today 22, the task is in Ready state

But the first row in cancelled state, it has another authoredOn: 1652091404617, and that is consistant with the fact that the only report of type pregnancy_family_planning that i’ve found has _id: "517495f3-48a9-43bc-b74b-3c0a8569dbee" and reported_date: 1652091393019 but the stateHistory is not clear for me ,


the history begins with a draft state and after but in a erlier date is cancelled

And I’m not able to undestand from where this authoredOn: 1647363219262 comes for this cancelled row and also for the others two rows in the spreadsheet.

in addition to this when we add 259 days (22377600000 miliseconds) to the cancelled date 1652091404617 authoredon we have 1674469005000 that is Monday, January 23, 2023 10:16:45 AM consistent with the dueDate 2023-12-23

Hi @bamatic

Task states are calculated on the device, based on device date and time.
The most obvious explanation for this is that the datetime on the device changed, OR someone logged in with the same account from a device with a different datetime.

Can you check the same user and see if you have repeated inconsistencies?