execute method

Future<TrackerRuleResult> execute({
  1. required TrackedEntityInstance trackedEntityInstance,
  2. required String program,
  3. TrackedEntityAttributeValue? changedAttributeValue,
})

Implementation

Future<TrackerRuleResult> execute(
    {required TrackedEntityInstance trackedEntityInstance,
    required String program,
    TrackedEntityAttributeValue? changedAttributeValue}) async {
  try {
    List<ProgramRule> programRules =
        await ProgramRuleQuery(database: database)
            .withActions()
            .where(attribute: 'program', value: program)
            .get();

    List<ProgramRuleVariable> programRuleVariables =
        await ProgramRuleVariableQuery(database: database)
            .where(attribute: 'program', value: program)
            .get();

    List<TrackedEntityAttributeValue> attributes =
        await TrackedEntityAttributeValueQuery(database: database)
            .where(
                attribute: 'trackedEntityInstance',
                value: trackedEntityInstance.trackedEntityInstance)
            .get();

    trackedEntityInstance =
        await TrackedEntityInstanceQuery(database: database)
                .withEnrollments()
                .byId(trackedEntityInstance.trackedEntityInstance ?? '')
                .getOne() ??
            trackedEntityInstance;

    final dataValueEntities =
        DataValueEntities.fromAttributeValues(attributes);

    List<Enrollment> enrollments = (trackedEntityInstance.enrollments ?? []);

    List<ProgramRuleAction> programRuleActions = ProgramRuleEngine.execute(
        dataValueEntities: dataValueEntities,
        programRules: programRules,
        additionalValues: {
          'incident_date':
              enrollments.isNotEmpty ? enrollments[0].incidentDate : null,
          'enrollment_date':
              enrollments.isNotEmpty ? enrollments[0].enrollmentDate : null,
          'enrollment_id':
              enrollments.isNotEmpty ? enrollments[0].enrollment : null,
          'current_date': DateTime.now().toIso8601String(),
          'event_date': enrollments.isNotEmpty
              ? (enrollments[0].events ?? []).isNotEmpty
                  ? enrollments[0].events![0].eventDate
                  : DateTime.now().toIso8601String()
              : DateTime.now().toIso8601String(),
        },
        programRuleVariables: programRuleVariables);

    final queue = Queue(parallel: 50);
    num availableItemCount = 0;

    programRuleActions.forEach((programRuleAction) {
      if (programRuleAction.programRuleActionType == 'ASSIGN' &&
          programRuleAction.trackedEntityAttribute != null &&
          programRuleAction.data != null) {
        availableItemCount++;
        queue.add(() => TrackedEntityAttributeValueQuery(database: database)
            .setData(TrackedEntityAttributeValue(
                synced: false,
                lastUpdated: DateTime.now().toIso8601String(),
                id:
                    "${trackedEntityInstance.trackedEntityInstance}_${programRuleAction.trackedEntityAttribute}",
                dirty: true,
                attribute: programRuleAction.trackedEntityAttribute as String,
                trackedEntityInstance:
                    trackedEntityInstance.trackedEntityInstance,
                value: programRuleAction.data as String))
            .save());
      }
    });

    if (availableItemCount == 0) {
      queue.cancel();
    } else {
      await queue.onComplete;
    }

    TrackedEntityInstance? updatedTrackedEntityInstance =
        await TrackedEntityInstanceQuery(database: database)
            .withAttributes()
            .withEnrollments()
            .byId(trackedEntityInstance.id as String)
            .getOne();

    return TrackerRuleResult(
        programRuleActions: programRuleActions,
        trackedEntityInstance:
            updatedTrackedEntityInstance ?? trackedEntityInstance);
  } catch (e) {
    return TrackerRuleResult(
        programRuleActions: [], trackedEntityInstance: trackedEntityInstance);
  }
}