From 0223035b202ccc6f1dee38fa9a3824b06ffac510 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 14 Aug 2024 19:22:15 +0300 Subject: [PATCH 001/185] Drush scrip WIP [ci skip] --- .../custom/hedley_ncda/hedley_ncda.module | 2 +- .../scripts/generate-data-for-all.php | 2 +- .../hedley_reports/hedley_reports.module | 14 +++ .../scripts/generate-completion-data.php | 88 +++++++++++++++++++ .../scripts/generate-data-for-all.php | 4 +- 5 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php diff --git a/server/hedley/modules/custom/hedley_ncda/hedley_ncda.module b/server/hedley/modules/custom/hedley_ncda/hedley_ncda.module index b2f615dcc9..c242c3f178 100644 --- a/server/hedley/modules/custom/hedley_ncda/hedley_ncda.module +++ b/server/hedley/modules/custom/hedley_ncda/hedley_ncda.module @@ -1162,7 +1162,7 @@ function hedley_ncda_resolve_immunization_bundles() { * * Adds a condition to select entities that don't have field_ncda_data set. */ -function hedley_ncda_query_exclude_set_alter(QueryAlterableInterface $query) { +function hedley_ncda_query_exclude_set_ncda_data_alter(QueryAlterableInterface $query) { $query->leftJoin('field_data_field_ncda_data', 'fnd', 'node.nid = fnd.entity_id'); $query->isNull('fnd.field_ncda_data_value'); } diff --git a/server/hedley/modules/custom/hedley_ncda/scripts/generate-data-for-all.php b/server/hedley/modules/custom/hedley_ncda/scripts/generate-data-for-all.php index c5640a6455..3f55c1aa05 100644 --- a/server/hedley/modules/custom/hedley_ncda/scripts/generate-data-for-all.php +++ b/server/hedley/modules/custom/hedley_ncda/scripts/generate-data-for-all.php @@ -37,7 +37,7 @@ ->addTag('exclude_deleted'); if ($exclude_set) { - $base_query->addTag('exclude_set'); + $base_query->addTag('exclude_set_ncda_data'); } $count_query = clone $base_query; diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 770995621e..9ebed4726d 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -1853,3 +1853,17 @@ function hedley_reports_filter_impacted_ids(array $ids, array $impacted) { return in_array($id, $impacted); }); } + +/** + * Implements hook_query_TAG_alter(). + * + * Adds a condition to select entities that don't have field_reports_data set. + */ +function hedley_ncda_query_exclude_set_reports_data_alter(QueryAlterableInterface $query) { + $query->leftJoin('field_data_field_reports_data', 'fnd', 'node.nid = fnd.entity_id'); + $query->isNull('fnd.field_reports_data_value'); +} + +function hedley_reports_generate_completion_data_for_nutrition_encounter($encounter) { + +} diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php new file mode 100644 index 0000000000..614d6c294a --- /dev/null +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php @@ -0,0 +1,88 @@ +entityCondition('entity_type', 'node') + ->entityCondition('bundle', $type) + ->propertyCondition('status', NODE_PUBLISHED); + +if ($exclude_set) { + $base_query->addTag('exclude_set_reports_data'); +} + +$count_query = clone $base_query; +$count_query->propertyCondition('nid', $nid, '>'); +$count = $count_query->count()->execute(); + +if ($count == 0) { + drush_print("There are no nodes of type $type in DB."); + exit; +} + +$total = 0; +drush_print("$count nodes of type $type located."); + +while (TRUE) { + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + hedley_reports_generate_completion_data_for_nutrition_encounter($node); + $total++; + + $memory = round(memory_get_usage() / 1048576); + if ($memory >= $memory_limit) { + drush_print(dt('Stopped before out of memory. Start process from the node ID @nid', ['@nid' => $nid])); + return; + } + } + + $memory = round(memory_get_usage() / 1048576); + drush_print("Calculated so far: $total, Memory: $memory"); + + // Free up memory. + drupal_static_reset(); + + $nid = end($ids); +} + +drush_print("Done! Completion data calculated for $total encounters."); diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-data-for-all.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-data-for-all.php index edce8d56f4..4f6868090f 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-data-for-all.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-data-for-all.php @@ -19,7 +19,7 @@ // Get the number of nodes to be processed. $batch = drush_get_option('batch', 50); -// Flag to generate NCDA data only if it was not generated already. +// Flag to generate data only if it was not generated already. $exclude_set = drush_get_option('exclude_set', FALSE); // Get allowed memory limit. @@ -34,7 +34,7 @@ ->addTag('exclude_deleted'); if ($exclude_set) { - $base_query->addTag('exclude_set'); + $base_query->addTag('exclude_set_reports_data'); } $count_query = clone $base_query; From 65dd74e2deddcc64d49e504a5f7687c09ea1a8c6 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 14 Aug 2024 19:24:05 +0300 Subject: [PATCH 002/185] Add 'reports_data' field to Nutrition encounter CT [ci skip] --- ...hedley_reports.features.field_instance.inc | 41 +++++++++++++++++++ .../custom/hedley_reports/hedley_reports.info | 1 + .../hedley_reports.strongarm.inc | 4 +- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.features.field_instance.inc b/server/hedley/modules/custom/hedley_reports/hedley_reports.features.field_instance.inc index 98b4260d16..517f97eb4b 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.features.field_instance.inc +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.features.field_instance.inc @@ -11,6 +11,45 @@ function hedley_reports_field_default_field_instances() { $field_instances = array(); + // Exported field_instance: 'node-nutrition_encounter-field_reports_data'. + $field_instances['node-nutrition_encounter-field_reports_data'] = array( + 'bundle' => 'nutrition_encounter', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 5, + ), + 'teaser' => array( + 'label' => 'above', + 'settings' => array(), + 'type' => 'hidden', + 'weight' => 0, + ), + ), + 'entity_type' => 'node', + 'field_name' => 'field_reports_data', + 'label' => 'Completion Data', + 'required' => FALSE, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'module' => 'text', + 'settings' => array( + 'rows' => 5, + ), + 'type' => 'text_textarea', + 'weight' => 7, + ), + ); + // Exported field_instance: 'node-report_data-field_cell'. $field_instances['node-report_data-field_cell'] = array( 'bundle' => 'report_data', @@ -205,6 +244,7 @@ function hedley_reports_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -415,6 +455,7 @@ function hedley_reports_field_default_field_instances() { // Included for use with string extractors like potx. t('Additional Data'); t('Cell'); + t('Completion Data'); t('Data File'); t('Data Scope'); t('District'); diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.info b/server/hedley/modules/custom/hedley_reports/hedley_reports.info index 1a3940c575..0946b1ee78 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.info +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.info @@ -18,6 +18,7 @@ features[features_api][] = api:2 features[field_base][] = field_data_file features[field_base][] = field_data_scope features[field_base][] = field_report_variant +features[field_instance][] = node-nutrition_encounter-field_reports_data features[field_instance][] = node-report_data-field_cell features[field_instance][] = node-report_data-field_data_file features[field_instance][] = node-report_data-field_data_scope diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.strongarm.inc b/server/hedley/modules/custom/hedley_reports/hedley_reports.strongarm.inc index 1412fde749..2863492290 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.strongarm.inc +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.strongarm.inc @@ -16,15 +16,15 @@ function hedley_reports_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__report_data'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__report_data'] = $strongarm; From 76108971877255f370ec20950b306a5dc98c37b9 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 14 Aug 2024 22:40:50 +0300 Subject: [PATCH 003/185] Initial working script [ci skip] --- .../hedley_admin/scripts/muac-report.php | 7 +- .../hedley_reports/hedley_reports.module | 99 ++++++++++++++++++- .../scripts/generate-completion-data.php | 6 +- 3 files changed, 104 insertions(+), 8 deletions(-) diff --git a/server/hedley/modules/custom/hedley_admin/scripts/muac-report.php b/server/hedley/modules/custom/hedley_admin/scripts/muac-report.php index 56687ea32e..33d88e87ab 100644 --- a/server/hedley/modules/custom/hedley_admin/scripts/muac-report.php +++ b/server/hedley/modules/custom/hedley_admin/scripts/muac-report.php @@ -29,12 +29,7 @@ $health_centers[$row->nid] = $row->title; } -// Resolve all Nurses. We need to determine if measurement was taken -// by nurse or CHW. -$query = db_select('field_data_field_role', 'fr') - ->fields('fr', ['entity_id']); -$query->condition('fr.field_role_value', 'nurse'); -$nurses = $query->execute()->fetchCol(); +$nurses = hedley_ncda_resolve_nurses_ids(); $encounter_types = [ 'acute_illness_muac' => 'Acute Illness', diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 9ebed4726d..bba6a2b4ba 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -1864,6 +1864,103 @@ function hedley_ncda_query_exclude_set_reports_data_alter(QueryAlterableInterfac $query->isNull('fnd.field_reports_data_value'); } -function hedley_reports_generate_completion_data_for_nutrition_encounter($encounter) { +function hedley_ncda_resolve_nurses_ids() { + // Resolve all Nurses. We need to determine if measurement was taken by nurse or CHW. + $query = db_select('field_data_field_role', 'fr'); + $query->addField('fr', 'entity_id'); + $query->condition('fr.field_role_value', 'nurse'); + return $query->execute()->fetchCol(); +} + +function hedley_reports_generate_completion_data_for_nutrition_encounter($encounter, $nurses) { + // Activities that are always taken during encounter. + $expected = [ + 'nutrition_height', + 'nutrition_nutrition', + 'nutrition_photo', + 'nutrition_weight', + ]; + $completed = []; + + $participant_id = $encounter->field_individual_participant[LANGUAGE_NONE][0]['target_id']; + $participant = node_load($participant_id); + $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + $person = node_load($person_id); + $birth_date = explode(' ', $person->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; + $date_measured = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $birth_date_obj = new DateTime($birth_date); + $date_measured_obj = new DateTime($date_measured); + $interval = $date_measured_obj->diff($birth_date_obj); + $age_in_months = ($interval->y * 12) + $interval->m; + // MUAC is taken starting age of 6 months. + if ($age_in_months >= 6) { + $expected[] = 'nutrition_muac'; + } + + // Loading all measurements that belong to encounter. + $query = db_select('field_data_field_nutrition_encounter', 'ne'); + $query->addField('ne', 'entity_id'); + $query->condition('ne.field_nutrition_encounter_target_id', $encounter->nid); + $ids = $query->execute()->fetchCol(); + + if (empty($ids)) { + return [ + 'expected' => implode(', ', $expected), + 'completed' => '', + ]; + } + + // Ordering measurements by type. + $measurements_by_type = []; + $measurements = node_load_multiple($ids); + foreach ($measurements as $measurement) { + $measurements_by_type[$measurement->type] = $measurement; + } + + $assessment = ''; + if (!empty($measurements_by_type['nutrition_nutrition'])) { + $assessment = $measurements_by_type['nutrition_nutrition']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; + } + else if (!empty($measurements_by_type['nutrition_follow_up'])) { + $assessment = $measurements_by_type['nutrition_follow_up']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; + } + + // If assessment was made, we expect all next steps activities. + if (!empty($assessment) && $assessment !== 'none') { + $expected = array_merge( + $expected, + [ + 'nutrition_contributing_factors', + 'nutrition_follow_up', + 'nutrition_health_education', + 'nutrition_send_to_hc' + ] + ); + } + + // NCDA activity is expected if: + // 1. NCDA feature is enabled. + // 2. Encounter was performed after NCDA launch date. + // 3. Encounter was recorded by nurse (and not by CHW). + // 4. Child was under age of 24 months. + $ncda_enabled = variable_get('hedley_admin_feature_ncda_enabled', FALSE); + $ncda_launch_date = '2023-11-20'; + $ncda_launch_date_obj = new DateTime($ncda_launch_date); + $nurse_id = reset($measurements_by_type)->field_nurse[LANGUAGE_NONE][0]['target_id']; + $is_nurse = in_array($nurse_id, $nurses); + + if ($ncda_enabled && $date_measured >= $ncda_launch_date_obj && $is_nurse && $age_in_months < 24) { + $expected[] = 'nutrition_ncda'; + } + foreach ($expected as $measurement_type) { + if (!empty($measurements_by_type[$measurement_type])) { + $completed[] = $measurement_type; + } + } + + return [ + 'expected' => implode(',', $expected), + 'completed' => implode(',', $completed), + ]; } diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php index 614d6c294a..a8fed831d7 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php @@ -45,6 +45,8 @@ exit; } +$nurses = hedley_ncda_resolve_nurses_ids(); + $total = 0; drush_print("$count nodes of type $type located."); @@ -66,7 +68,9 @@ $ids = array_keys($result['node']); $nodes = node_load_multiple($ids); foreach ($nodes as $node) { - hedley_reports_generate_completion_data_for_nutrition_encounter($node); + $completion_data = hedley_reports_generate_completion_data_for_nutrition_encounter($node, $nurses); + $node->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); + node_save($node); $total++; $memory = round(memory_get_usage() / 1048576); From 11a35af6140bd2eb91351bf96908e5071335aca1 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 15 Aug 2024 10:53:29 +0300 Subject: [PATCH 004/185] Improve code [ci skip] --- .../hedley_reports/hedley_reports.module | 100 +++++++++++++----- 1 file changed, 74 insertions(+), 26 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index bba6a2b4ba..b50127fe15 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -1872,7 +1872,31 @@ function hedley_ncda_resolve_nurses_ids() { return $query->execute()->fetchCol(); } +/** + * Callback for Elm application of Completion report menu. + * + * @return string + * The HTML markup for the Elm application. + */ +function hedley_reports_completion_report_callback_menu() { + return hedley_reports_callback_menu_by_page('completion-menu'); +} + function hedley_reports_generate_completion_data_for_nutrition_encounter($encounter, $nurses) { + // To reduce memory usage, mapping measurement types as single characters. + $mapping = [ + 'nutrition_height' => 'a', + 'nutrition_nutrition' => 'b', + 'nutrition_photo' => 'c', + 'nutrition_weight' => 'd', + 'nutrition_muac' => 'e', + 'nutrition_contributing_factors' => 'f', + 'nutrition_follow_up' => 'g', + 'nutrition_health_education' => 'h', + 'nutrition_send_to_hc' => 'i', + 'nutrition_ncda' => 'j', + ]; + // Activities that are always taken during encounter. $expected = [ 'nutrition_height', @@ -1882,37 +1906,50 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun ]; $completed = []; - $participant_id = $encounter->field_individual_participant[LANGUAGE_NONE][0]['target_id']; - $participant = node_load($participant_id); - $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; - $person = node_load($person_id); - $birth_date = explode(' ', $person->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; - $date_measured = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; - $birth_date_obj = new DateTime($birth_date); - $date_measured_obj = new DateTime($date_measured); - $interval = $date_measured_obj->diff($birth_date_obj); - $age_in_months = ($interval->y * 12) + $interval->m; - // MUAC is taken starting age of 6 months. - if ($age_in_months >= 6) { - $expected[] = 'nutrition_muac'; - } + // Was encounter recorded by nurse or CHW? + $taken_by = $encounter->field_nutrition_encounter_type[LANGUAGE_NONE][0]['value']; // Loading all measurements that belong to encounter. $query = db_select('field_data_field_nutrition_encounter', 'ne'); $query->addField('ne', 'entity_id'); $query->condition('ne.field_nutrition_encounter_target_id', $encounter->nid); - $ids = $query->execute()->fetchCol(); + $measurements_ids = $query->execute()->fetchCol(); - if (empty($ids)) { - return [ - 'expected' => implode(', ', $expected), - 'completed' => '', - ]; + if (empty($measurements_ids)) { + return hedley_reports_generate_completion_result($expected, $completed, $taken_by, $mapping); + } + + // Try to resolve age in months at a time encounter was performed. + try { + // Get participant ID and node. + $participant_id = $encounter->field_individual_participant[LANGUAGE_NONE][0]['target_id']; + $participant = node_load($participant_id); + + // Get person ID and node + $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + $person = node_load($person_id); + + // Get birthdate and date measured. + $birth_date = explode(' ', $person->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; + $date_measured = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + + // Calculate age in months. + $birth_date_obj = new DateTime($birth_date); + $date_measured_obj = new DateTime($date_measured); + $interval = $date_measured_obj->diff($birth_date_obj); + $age_in_months = ($interval->y * 12) + $interval->m; + } catch (Exception $e) { + $age_in_months = NULL; + } + + // MUAC is taken starting age of 6 months. + if (isset($age_in_months) && $age_in_months >= 6) { + $expected[] = 'nutrition_muac'; } // Ordering measurements by type. $measurements_by_type = []; - $measurements = node_load_multiple($ids); + $measurements = node_load_multiple($measurements_ids); foreach ($measurements as $measurement) { $measurements_by_type[$measurement->type] = $measurement; } @@ -1933,7 +1970,7 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun 'nutrition_contributing_factors', 'nutrition_follow_up', 'nutrition_health_education', - 'nutrition_send_to_hc' + 'nutrition_send_to_hc', ] ); } @@ -1946,10 +1983,8 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun $ncda_enabled = variable_get('hedley_admin_feature_ncda_enabled', FALSE); $ncda_launch_date = '2023-11-20'; $ncda_launch_date_obj = new DateTime($ncda_launch_date); - $nurse_id = reset($measurements_by_type)->field_nurse[LANGUAGE_NONE][0]['target_id']; - $is_nurse = in_array($nurse_id, $nurses); - if ($ncda_enabled && $date_measured >= $ncda_launch_date_obj && $is_nurse && $age_in_months < 24) { + if ($ncda_enabled && $date_measured >= $ncda_launch_date_obj && ($taken_by == 'nurse') && isset($age_in_months) && $age_in_months < 24) { $expected[] = 'nutrition_ncda'; } @@ -1959,8 +1994,21 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun } } + return hedley_reports_generate_completion_result($expected, $completed, $taken_by, $mapping); +} + +function hedley_reports_generate_completion_result($expected, $completed, $taken_by, $mapping) { + foreach ($expected as $index => $measurement_type) { + $expected[$index] = $mapping[$measurement_type]; + } + + foreach ($completed as $index => $measurement_type) { + $completed[$index] = $mapping[$measurement_type]; + } + return [ 'expected' => implode(',', $expected), 'completed' => implode(',', $completed), + 'taken_by' => $taken_by, ]; -} +} \ No newline at end of file From 12f2cbf6f2fc20e871037ed178c6923aecc4db76 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 15 Aug 2024 10:54:10 +0300 Subject: [PATCH 005/185] Completion menu infra on back-end [ci skip] --- .../hedley_reports/hedley_reports.module | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index b50127fe15..61d02835c2 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -21,21 +21,21 @@ function hedley_reports_menu() { $items['admin/reports/statistical-queries'] = array( 'title' => 'Statistical Queries', 'description' => 'View Statistical Queries', - 'page callback' => 'hedley_reports_aggregated_callback_menu', + 'page callback' => 'hedley_reports_statistical_queries_report_callback_menu', 'access callback' => 'hedley_reports_statistical_queries_report_access', ); $items['admin/reports/statistical-queries/all'] = array( 'title' => 'Entire Population', 'description' => 'View report for Entire Population', - 'page callback' => 'hedley_reports_aggregated_callback_global', + 'page callback' => 'hedley_reports_statistical_queries_report_callback_global', 'access callback' => 'hedley_reports_statistical_queries_report_access', ); $items['admin/reports/statistical-queries/demographics/%'] = array( 'title' => 'Province', 'description' => 'View report for province', - 'page callback' => 'hedley_reports_aggregated_callback_province', + 'page callback' => 'hedley_reports_statistical_queries_report_callback_province', 'page arguments' => [4], 'access callback' => 'hedley_reports_statistical_queries_report_access', ); @@ -43,7 +43,7 @@ function hedley_reports_menu() { $items['admin/reports/statistical-queries/demographics/%/%'] = array( 'title' => 'District', 'description' => 'View report for district', - 'page callback' => 'hedley_reports_aggregated_callback_district', + 'page callback' => 'hedley_reports_statistical_queries_report_callback_district', 'page arguments' => [4, 5], 'access callback' => 'hedley_reports_statistical_queries_report_access', ); @@ -51,7 +51,7 @@ function hedley_reports_menu() { $items['admin/reports/statistical-queries/demographics/%/%/%'] = array( 'title' => 'Sector', 'description' => 'View report for sector', - 'page callback' => 'hedley_reports_aggregated_callback_sector', + 'page callback' => 'hedley_reports_statistical_queries_report_callback_sector', 'page arguments' => [4, 5, 6], 'access callback' => 'hedley_reports_statistical_queries_report_access', ); @@ -59,7 +59,7 @@ function hedley_reports_menu() { $items['admin/reports/statistical-queries/demographics/%/%/%/%'] = array( 'title' => 'Cell', 'description' => 'View report for cell', - 'page callback' => 'hedley_reports_aggregated_callback_cell', + 'page callback' => 'hedley_reports_statistical_queries_report_callback_cell', 'page arguments' => [4, 5, 6, 7], 'access callback' => 'hedley_reports_statistical_queries_report_access', ); @@ -67,7 +67,7 @@ function hedley_reports_menu() { $items['admin/reports/statistical-queries/demographics/%/%/%/%/%'] = array( 'title' => 'Village', 'description' => 'View report for village', - 'page callback' => 'hedley_reports_aggregated_callback_village', + 'page callback' => 'hedley_reports_statistical_queries_report_callback_village', 'page arguments' => [4, 5, 6, 7, 8], 'access callback' => 'hedley_reports_statistical_queries_report_access', ); @@ -75,7 +75,7 @@ function hedley_reports_menu() { $items['admin/reports/statistical-queries/health-center/%'] = array( 'title' => 'Health center', 'description' => 'View report for health center', - 'page callback' => 'hedley_reports_aggregated_callback_health_center', + 'page callback' => 'hedley_reports_statistical_queries_report_callback_health_center', 'page arguments' => [4], 'access callback' => 'hedley_reports_statistical_queries_report_access', ); @@ -175,12 +175,16 @@ function hedley_reports_calculate_aggregated_data_worker($queue_item) { } /** - * Callback for Elm application of administrative division selection. + * Callback for Elm application of Statistical Queries menu. * * @return string * The HTML markup for the Elm application. */ -function hedley_reports_aggregated_callback_menu() { +function hedley_reports_statistical_queries_report_callback_menu() { + return hedley_reports_callback_menu_by_page('reports-menu'); +} + +function hedley_reports_callback_menu_by_page($page) { $site = variable_get('hedley_general_site_name', ''); $health_centers_data = []; @@ -193,7 +197,7 @@ function hedley_reports_aggregated_callback_menu() { ]; } - return hedley_general_build_elm_app('reports-menu', [ + return hedley_general_build_elm_app($page, [ 'site' => $site, 'health_centers' => $health_centers_data, ]); @@ -584,7 +588,7 @@ function hedley_reports_nutrition_metrics_to_string($values) { * @return string * The HTML markup for the Elm application. */ -function hedley_reports_aggregated_callback_global() { +function hedley_reports_statistical_queries_report_callback_global() { return hedley_reports_build_results_app(); } @@ -597,7 +601,7 @@ function hedley_reports_aggregated_callback_global() { * @return string * The HTML markup for the Elm application. */ -function hedley_reports_aggregated_callback_province($province) { +function hedley_reports_statistical_queries_report_callback_province($province) { return hedley_reports_build_results_app($province); } @@ -612,7 +616,7 @@ function hedley_reports_aggregated_callback_province($province) { * @return string * The HTML markup for the Elm application. */ -function hedley_reports_aggregated_callback_district($province, $district) { +function hedley_reports_statistical_queries_report_callback_district($province, $district) { return hedley_reports_build_results_app($province, $district); } @@ -629,7 +633,7 @@ function hedley_reports_aggregated_callback_district($province, $district) { * @return string * The HTML markup for the Elm application. */ -function hedley_reports_aggregated_callback_sector($province, $district, $sector) { +function hedley_reports_statistical_queries_report_callback_sector($province, $district, $sector) { return hedley_reports_build_results_app($province, $district, $sector); } @@ -648,7 +652,7 @@ function hedley_reports_aggregated_callback_sector($province, $district, $sector * @return string * The HTML markup for the Elm application. */ -function hedley_reports_aggregated_callback_cell($province, $district, $sector, $cell) { +function hedley_reports_statistical_queries_report_callback_cell($province, $district, $sector, $cell) { return hedley_reports_build_results_app($province, $district, $sector, $cell); } @@ -669,7 +673,7 @@ function hedley_reports_aggregated_callback_cell($province, $district, $sector, * @return string * The HTML markup for the Elm application. */ -function hedley_reports_aggregated_callback_village($province, $district, $sector, $cell, $village) { +function hedley_reports_statistical_queries_report_callback_village($province, $district, $sector, $cell, $village) { return hedley_reports_build_results_app($province, $district, $sector, $cell, $village); } @@ -682,7 +686,7 @@ function hedley_reports_aggregated_callback_village($province, $district, $secto * @return string * The HTML markup for the Elm application. */ -function hedley_reports_aggregated_callback_health_center($health_center) { +function hedley_reports_statistical_queries_report_callback_health_center($health_center) { return hedley_reports_build_results_app(NULL, NULL, NULL, NULL, NULL, $health_center); } @@ -2011,4 +2015,4 @@ function hedley_reports_generate_completion_result($expected, $completed, $taken 'completed' => implode(',', $completed), 'taken_by' => $taken_by, ]; -} \ No newline at end of file +} From 348b2a5c9726f8ad23d6560040cef118fa5cc45b Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 15 Aug 2024 12:07:26 +0300 Subject: [PATCH 006/185] Initial Elm APP [ci skip] --- server/elm/src/App/Fetch.elm | 8 + server/elm/src/App/Model.elm | 8 + server/elm/src/App/Types.elm | 6 +- server/elm/src/App/Update.elm | 52 + server/elm/src/App/View.elm | 25 + server/elm/src/Backend/Completion/Decoder.elm | 37 + server/elm/src/Backend/Completion/Model.elm | 23 + server/elm/src/Backend/Completion/Update.elm | 24 + .../src/Backend/CompletionMenu/Decoder.elm | 15 + .../elm/src/Backend/CompletionMenu/Model.elm | 15 + .../elm/src/Backend/CompletionMenu/Update.elm | 24 + server/elm/src/Backend/Components/Decoder.elm | 13 + server/elm/src/Backend/Components/Model.elm | 16 + server/elm/src/Backend/Model.elm | 8 + .../elm/src/Backend/ReportsMenu/Decoder.elm | 8 +- server/elm/src/Backend/ReportsMenu/Model.elm | 11 +- server/elm/src/Backend/Update.elm | 16 + server/elm/src/Pages/Completion/Fetch.elm | 9 + server/elm/src/Pages/Completion/Model.elm | 14 + server/elm/src/Pages/Completion/Update.elm | 24 + server/elm/src/Pages/Completion/View.elm | 39 + server/elm/src/Pages/CompletionMenu/Model.elm | 25 + .../elm/src/Pages/CompletionMenu/Update.elm | 31 + server/elm/src/Pages/CompletionMenu/View.elm | 110 ++ .../{ReportsMenu => Components}/Types.elm | 2 +- .../{ReportsMenu => Components}/Utils.elm | 4 +- server/elm/src/Pages/Components/View.elm | 4 +- server/elm/src/Pages/ReportsMenu/Model.elm | 4 +- server/elm/src/Pages/ReportsMenu/Update.elm | 2 +- server/elm/src/Pages/ReportsMenu/View.elm | 4 +- server/elm/src/Translate.elm | 2 +- .../custom/hedley_general/js/elm-main.js | 1068 ++++++++++++----- .../hedley_reports/hedley_reports.module | 8 + 33 files changed, 1297 insertions(+), 362 deletions(-) create mode 100644 server/elm/src/Backend/Completion/Decoder.elm create mode 100644 server/elm/src/Backend/Completion/Model.elm create mode 100644 server/elm/src/Backend/Completion/Update.elm create mode 100644 server/elm/src/Backend/CompletionMenu/Decoder.elm create mode 100644 server/elm/src/Backend/CompletionMenu/Model.elm create mode 100644 server/elm/src/Backend/CompletionMenu/Update.elm create mode 100644 server/elm/src/Backend/Components/Decoder.elm create mode 100644 server/elm/src/Backend/Components/Model.elm create mode 100644 server/elm/src/Pages/Completion/Fetch.elm create mode 100644 server/elm/src/Pages/Completion/Model.elm create mode 100644 server/elm/src/Pages/Completion/Update.elm create mode 100644 server/elm/src/Pages/Completion/View.elm create mode 100644 server/elm/src/Pages/CompletionMenu/Model.elm create mode 100644 server/elm/src/Pages/CompletionMenu/Update.elm create mode 100644 server/elm/src/Pages/CompletionMenu/View.elm rename server/elm/src/Pages/{ReportsMenu => Components}/Types.elm (74%) rename server/elm/src/Pages/{ReportsMenu => Components}/Utils.elm (86%) diff --git a/server/elm/src/App/Fetch.elm b/server/elm/src/App/Fetch.elm index dcdc306dba..1554dd66fe 100644 --- a/server/elm/src/App/Fetch.elm +++ b/server/elm/src/App/Fetch.elm @@ -2,6 +2,7 @@ module App.Fetch exposing (fetch) import App.Model exposing (..) import App.Types exposing (Page(..)) +import Pages.Completion.Fetch import Pages.Reports.Fetch import Pages.Scoreboard.Fetch @@ -39,5 +40,12 @@ fetch model = Pages.Reports.Fetch.fetch model.backend model.reportsPage |> List.map (\subMsg -> MsgBackend subMsg) + CompletionMenu -> + [] + + Completion -> + Pages.Completion.Fetch.fetch model.backend model.completionPage + |> List.map (\subMsg -> MsgBackend subMsg) + NotFound -> [] diff --git a/server/elm/src/App/Model.elm b/server/elm/src/App/Model.elm index 722601b640..7cc011753e 100644 --- a/server/elm/src/App/Model.elm +++ b/server/elm/src/App/Model.elm @@ -10,6 +10,8 @@ import App.Types exposing (Language(..), Page(..)) import Backend.Model import Error.Model exposing (Error) import Json.Decode exposing (Value) +import Pages.Completion.Model +import Pages.CompletionMenu.Model import Pages.Reports.Model import Pages.ReportsMenu.Model import Pages.Scoreboard.Model @@ -31,6 +33,8 @@ type Msg | MsgScoreboardPage Pages.Scoreboard.Model.Msg | MsgReportsMenuPage Pages.ReportsMenu.Model.Msg | MsgReportsPage Pages.Reports.Model.Msg + | MsgCompletionMenuPage Pages.CompletionMenu.Model.Msg + | MsgCompletionPage Pages.Completion.Model.Msg | SetCurrentTime Time.Posix @@ -53,6 +57,8 @@ type alias Model = , scoreboardPage : Pages.Scoreboard.Model.Model , reportsMenuPage : Pages.ReportsMenu.Model.Model , reportsPage : Pages.Reports.Model.Model + , completionMenuPage : Pages.CompletionMenu.Model.Model + , completionPage : Pages.Completion.Model.Model } @@ -68,4 +74,6 @@ emptyModel = , scoreboardPage = Pages.Scoreboard.Model.emptyModel , reportsMenuPage = Pages.ReportsMenu.Model.emptyModel , reportsPage = Pages.Reports.Model.emptyModel + , completionMenuPage = Pages.CompletionMenu.Model.emptyModel + , completionPage = Pages.Completion.Model.emptyModel } diff --git a/server/elm/src/App/Types.elm b/server/elm/src/App/Types.elm index 16706313dc..be33195c81 100644 --- a/server/elm/src/App/Types.elm +++ b/server/elm/src/App/Types.elm @@ -6,10 +6,12 @@ module App.Types exposing type Page - = ScoreboardMenu - | Scoreboard + = CompletionMenu + | Completion | ReportsMenu | Reports + | ScoreboardMenu + | Scoreboard | NotFound diff --git a/server/elm/src/App/Update.elm b/server/elm/src/App/Update.elm index 9d38496dc4..efed99f38b 100644 --- a/server/elm/src/App/Update.elm +++ b/server/elm/src/App/Update.elm @@ -8,6 +8,8 @@ import App.Fetch exposing (fetch) import App.Model exposing (..) import App.Types exposing (Page(..)) import App.Utils exposing (updateSubModel) +import Backend.Completion.Model +import Backend.CompletionMenu.Model import Backend.Model import Backend.Reports.Model import Backend.ReportsMenu.Model @@ -15,6 +17,8 @@ import Backend.Scoreboard.Model import Backend.ScoreboardMenu.Model import Backend.Update import Gizra.NominalDate exposing (fromLocalDateTime) +import Pages.Completion.Update +import Pages.CompletionMenu.Update import Pages.Reports.Update import Pages.ReportsMenu.Update import Pages.Scoreboard.Update @@ -70,6 +74,24 @@ init flags = model |> Tuple.first + CompletionMenu -> + update + (Backend.CompletionMenu.Model.SetData flags.appData + |> Backend.Model.MsgCompletionMenu + |> MsgBackend + ) + model + |> Tuple.first + + Completion -> + update + (Backend.Completion.Model.SetData flags.appData + |> Backend.Model.MsgCompletion + |> MsgBackend + ) + model + |> Tuple.first + NotFound -> model @@ -100,6 +122,12 @@ resolveActivePage page = "reports-results" -> Reports + "completion-menu" -> + CompletionMenu + + "completion-results" -> + Completion + _ -> NotFound @@ -162,6 +190,30 @@ update msg model = (\subCmds -> MsgReportsPage subCmds) model + MsgCompletionMenuPage subMsg -> + updateSubModel + subMsg + model.completionMenuPage + (\subMsg_ subModel -> Pages.CompletionMenu.Update.update subMsg_ subModel) + (\subModel model_ -> { model_ | completionMenuPage = subModel }) + (\subCmds -> MsgCompletionMenuPage subCmds) + model + + MsgCompletionPage subMsg -> + updateSubModel + subMsg + model.completionPage + (\subMsg_ subModel -> + Pages.Completion.Update.update + (fromLocalDateTime model.currentTime) + model.backend + subMsg_ + subModel + ) + (\subModel model_ -> { model_ | completionPage = subModel }) + (\subCmds -> MsgCompletionPage subCmds) + model + SetCurrentTime date -> ( { model | currentTime = date } , Cmd.none diff --git a/server/elm/src/App/View.elm b/server/elm/src/App/View.elm index b39d45f5f6..531d94bc69 100644 --- a/server/elm/src/App/View.elm +++ b/server/elm/src/App/View.elm @@ -5,6 +5,8 @@ import App.Types exposing (Page(..)) import Error.View import Gizra.NominalDate exposing (fromLocalDateTime) import Html exposing (..) +import Pages.Completion.View +import Pages.CompletionMenu.View import Pages.Reports.View import Pages.ReportsMenu.View import Pages.Scoreboard.View @@ -58,6 +60,29 @@ view model = model.reportsPage ] + CompletionMenu -> + div [] + [ Error.View.view model.language model.errors + , Html.map MsgCompletionMenuPage <| + Pages.CompletionMenu.View.view + model.language + model.themePath + model.backend + model.completionMenuPage + ] + + Completion -> + div [] + [ Error.View.view model.language model.errors + , Html.map MsgCompletionPage <| + Pages.Completion.View.view + model.language + (fromLocalDateTime model.currentTime) + model.themePath + model.backend + model.completionPage + ] + NotFound -> div [] [ text "Wrong page?" ] diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm new file mode 100644 index 0000000000..e55f6c4038 --- /dev/null +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -0,0 +1,37 @@ +module Backend.Completion.Decoder exposing (decodeCompletionData) + +import AssocList as Dict +import Backend.Completion.Model exposing (..) +import Backend.Decoder exposing (decodeSite) +import Date +import EverySet exposing (EverySet) +import Gizra.Json exposing (decodeFloat, decodeInt) +import Gizra.NominalDate exposing (NominalDate, decodeYYYYMMDD, diffMonths) +import Json.Decode exposing (Decoder, andThen, bool, fail, list, map, maybe, nullable, oneOf, string, succeed) +import Json.Decode.Pipeline exposing (optional, optionalAt, required) +import Maybe.Extra exposing (isNothing) + + +decodeCompletionData : Decoder CompletionData +decodeCompletionData = + succeed CompletionData + |> required "site" decodeSite + |> required "entity_name" string + |> required "entity_type" decodeSelectedEntity + + +decodeSelectedEntity : Decoder SelectedEntity +decodeSelectedEntity = + string + |> andThen + (\entityType -> + case entityType of + "global" -> + succeed EntityGlobal + + "health-center" -> + succeed EntityHealthCenter + + _ -> + fail <| entityType ++ " is unknown SelectedEntity type" + ) diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm new file mode 100644 index 0000000000..d589e58b3d --- /dev/null +++ b/server/elm/src/Backend/Completion/Model.elm @@ -0,0 +1,23 @@ +module Backend.Completion.Model exposing (..) + +import App.Types exposing (Site) +import AssocList as Dict exposing (Dict) +import EverySet exposing (EverySet) +import Gizra.NominalDate exposing (NominalDate) +import Json.Encode exposing (Value) + + +type alias CompletionData = + { site : Site + , entityName : String + , entityType : SelectedEntity + } + + +type SelectedEntity + = EntityGlobal + | EntityHealthCenter + + +type Msg + = SetData Value diff --git a/server/elm/src/Backend/Completion/Update.elm b/server/elm/src/Backend/Completion/Update.elm new file mode 100644 index 0000000000..a322bfce6d --- /dev/null +++ b/server/elm/src/Backend/Completion/Update.elm @@ -0,0 +1,24 @@ +module Backend.Completion.Update exposing (update) + +import Backend.Completion.Decoder exposing (decodeCompletionData) +import Backend.Completion.Model exposing (Msg(..)) +import Backend.Model exposing (ModelBackend) +import Backend.Types exposing (BackendReturn) +import Error.Utils exposing (noError) +import Gizra.NominalDate exposing (NominalDate) +import Json.Decode exposing (decodeValue) + + +update : NominalDate -> Msg -> ModelBackend -> BackendReturn Msg +update currentDate msg model = + case msg of + SetData value -> + let + modelUpdated = + { model | completionData = Just <| decodeValue decodeCompletionData value } + in + BackendReturn + modelUpdated + Cmd.none + noError + [] diff --git a/server/elm/src/Backend/CompletionMenu/Decoder.elm b/server/elm/src/Backend/CompletionMenu/Decoder.elm new file mode 100644 index 0000000000..8561b3e4c8 --- /dev/null +++ b/server/elm/src/Backend/CompletionMenu/Decoder.elm @@ -0,0 +1,15 @@ +module Backend.CompletionMenu.Decoder exposing (decodeMenuData) + +import Backend.CompletionMenu.Model exposing (..) +import Backend.Components.Decoder exposing (decodeHealthCenterData) +import Backend.Decoder exposing (decodeSite) +import Gizra.Json exposing (decodeInt) +import Json.Decode exposing (Decoder, andThen, list, string, succeed) +import Json.Decode.Pipeline exposing (required) + + +decodeMenuData : Decoder MenuData +decodeMenuData = + succeed MenuData + |> required "site" decodeSite + |> required "health_centers" (list decodeHealthCenterData) diff --git a/server/elm/src/Backend/CompletionMenu/Model.elm b/server/elm/src/Backend/CompletionMenu/Model.elm new file mode 100644 index 0000000000..b64af0e11e --- /dev/null +++ b/server/elm/src/Backend/CompletionMenu/Model.elm @@ -0,0 +1,15 @@ +module Backend.CompletionMenu.Model exposing (..) + +import App.Types exposing (Site) +import Backend.Components.Model exposing (HealthCenterData) +import Json.Encode exposing (Value) + + +type alias MenuData = + { site : Site + , healthCenters : List HealthCenterData + } + + +type Msg + = SetData Value diff --git a/server/elm/src/Backend/CompletionMenu/Update.elm b/server/elm/src/Backend/CompletionMenu/Update.elm new file mode 100644 index 0000000000..4901d76212 --- /dev/null +++ b/server/elm/src/Backend/CompletionMenu/Update.elm @@ -0,0 +1,24 @@ +module Backend.CompletionMenu.Update exposing (update) + +import Backend.CompletionMenu.Decoder exposing (decodeMenuData) +import Backend.CompletionMenu.Model exposing (Msg(..)) +import Backend.Model exposing (ModelBackend) +import Backend.Types exposing (BackendReturn) +import Error.Utils exposing (noError) +import Gizra.NominalDate exposing (NominalDate) +import Json.Decode exposing (decodeValue) + + +update : NominalDate -> Msg -> ModelBackend -> BackendReturn Msg +update currentDate msg model = + case msg of + SetData value -> + let + modelUpdated = + { model | completionMenuData = Just <| decodeValue decodeMenuData value } + in + BackendReturn + modelUpdated + Cmd.none + noError + [] diff --git a/server/elm/src/Backend/Components/Decoder.elm b/server/elm/src/Backend/Components/Decoder.elm new file mode 100644 index 0000000000..728826f5ea --- /dev/null +++ b/server/elm/src/Backend/Components/Decoder.elm @@ -0,0 +1,13 @@ +module Backend.Components.Decoder exposing (decodeHealthCenterData) + +import Backend.Components.Model exposing (HealthCenterData) +import Gizra.Json exposing (decodeInt) +import Json.Decode exposing (Decoder, string, succeed) +import Json.Decode.Pipeline exposing (required) + + +decodeHealthCenterData : Decoder HealthCenterData +decodeHealthCenterData = + succeed HealthCenterData + |> required "id" decodeInt + |> required "name" string diff --git a/server/elm/src/Backend/Components/Model.elm b/server/elm/src/Backend/Components/Model.elm new file mode 100644 index 0000000000..efa27588a5 --- /dev/null +++ b/server/elm/src/Backend/Components/Model.elm @@ -0,0 +1,16 @@ +module Backend.Components.Model exposing (..) + +{-| The return value of Backend update functions +-} + +import Error.Model exposing (Error) + + +type alias HealthCenterData = + { id : HealthCenterId + , name : String + } + + +type alias HealthCenterId = + Int diff --git a/server/elm/src/Backend/Model.elm b/server/elm/src/Backend/Model.elm index 299edb4663..841e14d56e 100644 --- a/server/elm/src/Backend/Model.elm +++ b/server/elm/src/Backend/Model.elm @@ -5,6 +5,8 @@ on the backend. So, conceptually it is a kind of a local cache of some of the things on the backend. -} +import Backend.Completion.Model exposing (CompletionData) +import Backend.CompletionMenu.Model import Backend.Reports.Model exposing (ReportsData) import Backend.ReportsMenu.Model import Backend.Scoreboard.Model exposing (ScoreboardData) @@ -17,6 +19,8 @@ type alias ModelBackend = , scoreboardData : Maybe (Result Json.Decode.Error ScoreboardData) , reportsMenuData : Maybe (Result Json.Decode.Error Backend.ReportsMenu.Model.MenuData) , reportsData : Maybe (Result Json.Decode.Error ReportsData) + , completionMenuData : Maybe (Result Json.Decode.Error Backend.CompletionMenu.Model.MenuData) + , completionData : Maybe (Result Json.Decode.Error CompletionData) } @@ -26,6 +30,8 @@ emptyModelBackend = , scoreboardData = Nothing , reportsMenuData = Nothing , reportsData = Nothing + , completionMenuData = Nothing + , completionData = Nothing } @@ -37,3 +43,5 @@ type Msg | MsgScoreboard Backend.Scoreboard.Model.Msg | MsgReports Backend.Reports.Model.Msg | MsgReportsMenu Backend.ReportsMenu.Model.Msg + | MsgCompletion Backend.Completion.Model.Msg + | MsgCompletionMenu Backend.CompletionMenu.Model.Msg diff --git a/server/elm/src/Backend/ReportsMenu/Decoder.elm b/server/elm/src/Backend/ReportsMenu/Decoder.elm index 62af38fc7a..714e570b53 100644 --- a/server/elm/src/Backend/ReportsMenu/Decoder.elm +++ b/server/elm/src/Backend/ReportsMenu/Decoder.elm @@ -1,5 +1,6 @@ module Backend.ReportsMenu.Decoder exposing (decodeMenuData) +import Backend.Components.Decoder exposing (decodeHealthCenterData) import Backend.Decoder exposing (decodeSite) import Backend.ReportsMenu.Model exposing (..) import Gizra.Json exposing (decodeInt) @@ -12,10 +13,3 @@ decodeMenuData = succeed MenuData |> required "site" decodeSite |> required "health_centers" (list decodeHealthCenterData) - - -decodeHealthCenterData : Decoder HealthCenterData -decodeHealthCenterData = - succeed HealthCenterData - |> required "id" decodeInt - |> required "name" string diff --git a/server/elm/src/Backend/ReportsMenu/Model.elm b/server/elm/src/Backend/ReportsMenu/Model.elm index 93886e2152..ea8045117f 100644 --- a/server/elm/src/Backend/ReportsMenu/Model.elm +++ b/server/elm/src/Backend/ReportsMenu/Model.elm @@ -1,6 +1,7 @@ module Backend.ReportsMenu.Model exposing (..) import App.Types exposing (Site) +import Backend.Components.Model exposing (HealthCenterData) import Json.Encode exposing (Value) @@ -12,13 +13,3 @@ type alias MenuData = type Msg = SetData Value - - -type alias HealthCenterData = - { id : HealthCenterId - , name : String - } - - -type alias HealthCenterId = - Int diff --git a/server/elm/src/Backend/Update.elm b/server/elm/src/Backend/Update.elm index 06910b8332..f03b3a6acc 100644 --- a/server/elm/src/Backend/Update.elm +++ b/server/elm/src/Backend/Update.elm @@ -1,5 +1,7 @@ module Backend.Update exposing (updateBackend) +import Backend.Completion.Update +import Backend.CompletionMenu.Update import Backend.Model exposing (..) import Backend.Reports.Update import Backend.ReportsMenu.Update @@ -40,3 +42,17 @@ updateBackend currentDate msg model = (\subMsg_ model_ -> Backend.Reports.Update.update currentDate subMsg_ model_) (\subCmds -> MsgReports subCmds) model + + MsgCompletionMenu subMsg -> + updateSubModel + subMsg + (\subMsg_ model_ -> Backend.CompletionMenu.Update.update currentDate subMsg_ model_) + (\subCmds -> MsgCompletionMenu subCmds) + model + + MsgCompletion subMsg -> + updateSubModel + subMsg + (\subMsg_ model_ -> Backend.Completion.Update.update currentDate subMsg_ model_) + (\subCmds -> MsgCompletion subCmds) + model diff --git a/server/elm/src/Pages/Completion/Fetch.elm b/server/elm/src/Pages/Completion/Fetch.elm new file mode 100644 index 0000000000..3b2a07fbd0 --- /dev/null +++ b/server/elm/src/Pages/Completion/Fetch.elm @@ -0,0 +1,9 @@ +module Pages.Completion.Fetch exposing (fetch) + +import Backend.Model +import Pages.Completion.Model exposing (Model) + + +fetch : Backend.Model.ModelBackend -> Model -> List Backend.Model.Msg +fetch modelBackend model = + [] diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm new file mode 100644 index 0000000000..254477f456 --- /dev/null +++ b/server/elm/src/Pages/Completion/Model.elm @@ -0,0 +1,14 @@ +module Pages.Completion.Model exposing (..) + + +type alias Model = + {} + + +emptyModel : Model +emptyModel = + {} + + +type Msg + = NoOp diff --git a/server/elm/src/Pages/Completion/Update.elm b/server/elm/src/Pages/Completion/Update.elm new file mode 100644 index 0000000000..4f3b05fb71 --- /dev/null +++ b/server/elm/src/Pages/Completion/Update.elm @@ -0,0 +1,24 @@ +module Pages.Completion.Update exposing (update) + +import App.Model exposing (PagesReturn) +import App.Ports +import AssocList as Dict exposing (Dict) +import Backend.Model exposing (ModelBackend) +import Date exposing (Interval(..), Unit(..)) +import Error.Utils exposing (noError) +import Gizra.NominalDate exposing (NominalDate) +import Maybe.Extra +import Pages.Completion.Model exposing (..) +import RemoteData exposing (RemoteData(..)) +import Task exposing (Task) + + +update : NominalDate -> ModelBackend -> Msg -> Model -> PagesReturn Model Msg +update currentDate modelBackend msg model = + case msg of + NoOp -> + PagesReturn + model + Cmd.none + noError + [] diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm new file mode 100644 index 0000000000..fb5b387966 --- /dev/null +++ b/server/elm/src/Pages/Completion/View.elm @@ -0,0 +1,39 @@ +module Pages.Completion.View exposing (view) + +import App.Types exposing (Language, Site) +import AssocList as Dict exposing (Dict) +import Backend.Completion.Model exposing (CompletionData) +import Backend.Model exposing (ModelBackend) +import Date exposing (Interval(..), Unit(..)) +import DateSelector.SelectorPopup exposing (viewCalendarPopup) +import Gizra.Html exposing (emptyNode) +import Gizra.NominalDate exposing (NominalDate, customFormatDDMMYYYY, formatDDMMYYYY, sortByDateDesc) +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (onClick) +import List.Extra +import Maybe.Extra exposing (isJust, isNothing) +import Pages.Completion.Model exposing (..) +import RemoteData exposing (RemoteData(..)) +import Round +import Time exposing (Month(..)) +import Translate exposing (TranslationId, translate) +import Utils.Html exposing (viewModal) + + +view : Language -> NominalDate -> String -> ModelBackend -> Model -> Html Msg +view language currentDate themePath modelBackend model = + case modelBackend.completionData of + Just (Ok data) -> + viewCompletionData language currentDate themePath data model + + Just (Err err) -> + text <| Debug.toString err + + Nothing -> + emptyNode + + +viewCompletionData : Language -> NominalDate -> String -> CompletionData -> Model -> Html Msg +viewCompletionData language currentDate themePath data model = + text "viewCompletionData" diff --git a/server/elm/src/Pages/CompletionMenu/Model.elm b/server/elm/src/Pages/CompletionMenu/Model.elm new file mode 100644 index 0000000000..63c8a76c54 --- /dev/null +++ b/server/elm/src/Pages/CompletionMenu/Model.elm @@ -0,0 +1,25 @@ +module Pages.CompletionMenu.Model exposing (..) + +import Backend.Components.Model exposing (HealthCenterId) +import Pages.Components.Types exposing (PopulationSelectionOption) + + +type alias Model = + { populationSelection : Maybe PopulationSelectionOption + , selectedHealthCenter : Maybe HealthCenterId + , selected : Bool + } + + +emptyModel : Model +emptyModel = + { populationSelection = Nothing + , selectedHealthCenter = Nothing + , selected = False + } + + +type Msg + = SetPopulationSelection String + | SetHealthCenter String + | SelectionMade diff --git a/server/elm/src/Pages/CompletionMenu/Update.elm b/server/elm/src/Pages/CompletionMenu/Update.elm new file mode 100644 index 0000000000..cc3d6f12ee --- /dev/null +++ b/server/elm/src/Pages/CompletionMenu/Update.elm @@ -0,0 +1,31 @@ +module Pages.CompletionMenu.Update exposing (update) + +import App.Model exposing (PagesReturn) +import Error.Utils exposing (noError) +import Pages.CompletionMenu.Model exposing (..) +import Pages.Components.Utils exposing (populationSelectionOptionFromString) + + +update : Msg -> Model -> PagesReturn Model Msg +update msg model = + case msg of + SetPopulationSelection value -> + PagesReturn + { model | populationSelection = populationSelectionOptionFromString value } + Cmd.none + noError + [] + + SetHealthCenter value -> + PagesReturn + { model | selectedHealthCenter = String.toInt value } + Cmd.none + noError + [] + + SelectionMade -> + PagesReturn + { model | selected = True } + Cmd.none + noError + [] diff --git a/server/elm/src/Pages/CompletionMenu/View.elm b/server/elm/src/Pages/CompletionMenu/View.elm new file mode 100644 index 0000000000..9e6312905a --- /dev/null +++ b/server/elm/src/Pages/CompletionMenu/View.elm @@ -0,0 +1,110 @@ +module Pages.CompletionMenu.View exposing (view) + +import App.Types exposing (Language) +import AssocList as Dict +import Backend.CompletionMenu.Model exposing (MenuData) +import Backend.Entities exposing (fromEntityId, toEntityId) +import Backend.Model exposing (ModelBackend) +import Gizra.Html exposing (emptyNode) +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (onClick, onInput) +import List.Extra +import Maybe.Extra exposing (isJust) +import Pages.CompletionMenu.Model exposing (..) +import Pages.Components.Model exposing (DemographicsSelection) +import Pages.Components.Types exposing (PopulationSelectionOption(..)) +import Pages.Components.Utils exposing (populationSelectionOptionFromString, populationSelectionOptionToString) +import Pages.Components.View exposing (viewDemographicsSelection, viewDemographicsSelectionActionButton) +import Pages.Utils + exposing + ( viewCustomLabel + , viewCustomSelectListInput + , viewGeoLocationSelectListInput + , viewLoadDataButton + , viewSelectListInput + , wrapSelectListInput + ) +import Translate exposing (TranslationId, translate) +import Utils.GeoLocation exposing (..) + + +view : Language -> String -> ModelBackend -> Model -> Html Msg +view language themePath modelBackend model = + case modelBackend.completionMenuData of + Just (Ok data) -> + viewMenu language themePath data model + + Just (Err err) -> + text <| Debug.toString err + + Nothing -> + emptyNode + + +viewMenu : Language -> String -> MenuData -> Model -> Html Msg +viewMenu language themePath data model = + let + populationSelectionInput = + viewSelectListInput language + model.populationSelection + [ SelectionOptionGlobal, SelectionOptionHealthCenter ] + populationSelectionOptionToString + SetPopulationSelection + Translate.PopulationSelectionOption + "select-input" + |> wrapSelectListInput language Translate.Scope False + + ( derivedInputs, actionButton_ ) = + Maybe.map + (\populationSelection -> + case populationSelection of + SelectionOptionGlobal -> + ( [], viewLoadDataButton language "/admin/completion/completion/all" SelectionMade ) + + SelectionOptionHealthCenter -> + let + options = + List.sortBy .name data.healthCenters + |> List.map (\healthCenter -> ( healthCenter.name, healthCenter.id )) + in + ( [ viewCustomSelectListInput + model.selectedHealthCenter + options + String.fromInt + SetHealthCenter + "select-input" + True + |> wrapSelectListInput language Translate.HealthCenter False + ] + , Maybe.map + (\selectedHealthCenter -> + viewLoadDataButton language + ("/admin/completion/completion/health-center/" ++ String.fromInt selectedHealthCenter) + SelectionMade + ) + model.selectedHealthCenter + |> Maybe.withDefault emptyNode + ) + + -- This option is not in use. + SelectionOptionDemographics -> + ( [], emptyNode ) + ) + model.populationSelection + |> Maybe.withDefault ( [], emptyNode ) + + actionButton = + if model.selected then + text <| translate language Translate.PleaseWaitMessage + + else + actionButton_ + in + div [ class "page-content completion-menu" ] + [ viewCustomLabel language Translate.SelectScope ":" "header" + , div [ class "inputs" ] <| + populationSelectionInput + :: derivedInputs + , div [ class "actions" ] [ actionButton ] + ] diff --git a/server/elm/src/Pages/ReportsMenu/Types.elm b/server/elm/src/Pages/Components/Types.elm similarity index 74% rename from server/elm/src/Pages/ReportsMenu/Types.elm rename to server/elm/src/Pages/Components/Types.elm index 667b7ef811..e431af03b2 100644 --- a/server/elm/src/Pages/ReportsMenu/Types.elm +++ b/server/elm/src/Pages/Components/Types.elm @@ -1,4 +1,4 @@ -module Pages.ReportsMenu.Types exposing (..) +module Pages.Components.Types exposing (..) type PopulationSelectionOption diff --git a/server/elm/src/Pages/ReportsMenu/Utils.elm b/server/elm/src/Pages/Components/Utils.elm similarity index 86% rename from server/elm/src/Pages/ReportsMenu/Utils.elm rename to server/elm/src/Pages/Components/Utils.elm index ac9ff64305..8c16402a11 100644 --- a/server/elm/src/Pages/ReportsMenu/Utils.elm +++ b/server/elm/src/Pages/Components/Utils.elm @@ -1,6 +1,6 @@ -module Pages.ReportsMenu.Utils exposing (..) +module Pages.Components.Utils exposing (..) -import Pages.ReportsMenu.Types exposing (..) +import Pages.Components.Types exposing (PopulationSelectionOption(..)) populationSelectionOptionToString : PopulationSelectionOption -> String diff --git a/server/elm/src/Pages/Components/View.elm b/server/elm/src/Pages/Components/View.elm index 3555851331..e7c38be989 100644 --- a/server/elm/src/Pages/Components/View.elm +++ b/server/elm/src/Pages/Components/View.elm @@ -10,9 +10,7 @@ import Html.Attributes exposing (..) import Html.Events exposing (onClick, onInput) import Maybe.Extra exposing (isJust) import Pages.Components.Model exposing (DemographicsSelection) -import Pages.ReportsMenu.Model exposing (..) -import Pages.ReportsMenu.Types exposing (..) -import Pages.ReportsMenu.Utils exposing (populationSelectionOptionToString) +import Pages.Components.Utils exposing (populationSelectionOptionToString) import Pages.Utils exposing ( viewCustomLabel diff --git a/server/elm/src/Pages/ReportsMenu/Model.elm b/server/elm/src/Pages/ReportsMenu/Model.elm index 6267f5eecc..b3dd2bc758 100644 --- a/server/elm/src/Pages/ReportsMenu/Model.elm +++ b/server/elm/src/Pages/ReportsMenu/Model.elm @@ -1,8 +1,8 @@ module Pages.ReportsMenu.Model exposing (..) -import Backend.ReportsMenu.Model exposing (HealthCenterId) +import Backend.Components.Model exposing (HealthCenterId) import Pages.Components.Model exposing (DemographicsSelection, emptyDemographicsSelection) -import Pages.ReportsMenu.Types exposing (..) +import Pages.Components.Types exposing (PopulationSelectionOption) type alias Model = diff --git a/server/elm/src/Pages/ReportsMenu/Update.elm b/server/elm/src/Pages/ReportsMenu/Update.elm index 07ba9048e9..710b880eea 100644 --- a/server/elm/src/Pages/ReportsMenu/Update.elm +++ b/server/elm/src/Pages/ReportsMenu/Update.elm @@ -2,8 +2,8 @@ module Pages.ReportsMenu.Update exposing (update) import App.Model exposing (PagesReturn) import Error.Utils exposing (noError) +import Pages.Components.Utils exposing (populationSelectionOptionFromString) import Pages.ReportsMenu.Model exposing (..) -import Pages.ReportsMenu.Utils exposing (populationSelectionOptionFromString) update : Msg -> Model -> PagesReturn Model Msg diff --git a/server/elm/src/Pages/ReportsMenu/View.elm b/server/elm/src/Pages/ReportsMenu/View.elm index 07fed6c9d0..6fec8032ae 100644 --- a/server/elm/src/Pages/ReportsMenu/View.elm +++ b/server/elm/src/Pages/ReportsMenu/View.elm @@ -12,10 +12,10 @@ import Html.Events exposing (onClick, onInput) import List.Extra import Maybe.Extra exposing (isJust) import Pages.Components.Model exposing (DemographicsSelection) +import Pages.Components.Types exposing (PopulationSelectionOption(..)) +import Pages.Components.Utils exposing (populationSelectionOptionToString) import Pages.Components.View exposing (viewDemographicsSelection, viewDemographicsSelectionActionButton) import Pages.ReportsMenu.Model exposing (..) -import Pages.ReportsMenu.Types exposing (..) -import Pages.ReportsMenu.Utils exposing (populationSelectionOptionToString) import Pages.Utils exposing ( generateReportsHeaderImage diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 3e5d0c4071..bde40cbed1 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -8,8 +8,8 @@ import App.Types exposing (Language(..)) import Backend.Reports.Model exposing (AcuteIllnessDiagnosis(..), NutritionReportTableType(..)) import Backend.Scoreboard.Model import Date +import Pages.Components.Types exposing (PopulationSelectionOption(..)) import Pages.Reports.Model exposing (ReportType(..)) -import Pages.ReportsMenu.Types exposing (PopulationSelectionOption(..)) import Pages.Scoreboard.Model exposing (..) import Time exposing (Month(..)) diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index acae4d5c1f..fd1aa2b326 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5404,6 +5404,10 @@ var $elm$browser$Browser$element = _Browser_element; var $author$project$App$Model$MsgBackend = function (a) { return {$: 'MsgBackend', a: a}; }; +var $author$project$Pages$Completion$Fetch$fetch = F2( + function (modelBackend, model) { + return _List_Nil; + }); var $author$project$Pages$Reports$Fetch$fetch = F2( function (modelBackend, model) { return _List_Nil; @@ -5433,11 +5437,26 @@ var $author$project$App$Fetch$fetch = function (model) { return $author$project$App$Model$MsgBackend(subMsg); }, A2($author$project$Pages$Reports$Fetch$fetch, model.backend, model.reportsPage)); + case 'CompletionMenu': + return _List_Nil; + case 'Completion': + return A2( + $elm$core$List$map, + function (subMsg) { + return $author$project$App$Model$MsgBackend(subMsg); + }, + A2($author$project$Pages$Completion$Fetch$fetch, model.backend, model.completionPage)); default: return _List_Nil; } }; var $elm$json$Json$Decode$field = _Json_decodeField; +var $author$project$Backend$Model$MsgCompletion = function (a) { + return {$: 'MsgCompletion', a: a}; +}; +var $author$project$Backend$Model$MsgCompletionMenu = function (a) { + return {$: 'MsgCompletionMenu', a: a}; +}; var $author$project$Backend$Model$MsgReports = function (a) { return {$: 'MsgReports', a: a}; }; @@ -5453,6 +5472,12 @@ var $author$project$Backend$Model$MsgScoreboardMenu = function (a) { var $author$project$App$Model$SetCurrentTime = function (a) { return {$: 'SetCurrentTime', a: a}; }; +var $author$project$Backend$Completion$Model$SetData = function (a) { + return {$: 'SetData', a: a}; +}; +var $author$project$Backend$CompletionMenu$Model$SetData = function (a) { + return {$: 'SetData', a: a}; +}; var $author$project$Backend$Reports$Model$SetData = function (a) { return {$: 'SetData', a: a}; }; @@ -5480,6 +5505,8 @@ var $elm$core$Basics$composeR = F3( }); var $author$project$App$Types$English = {$: 'English'}; var $author$project$App$Types$NotFound = {$: 'NotFound'}; +var $author$project$Pages$Completion$Model$emptyModel = {}; +var $author$project$Pages$CompletionMenu$Model$emptyModel = {populationSelection: $elm$core$Maybe$Nothing, selected: false, selectedHealthCenter: $elm$core$Maybe$Nothing}; var $krisajenkins$remotedata$RemoteData$NotAsked = {$: 'NotAsked'}; var $author$project$Pages$Reports$Model$emptyModel = {limitDate: $elm$core$Maybe$Nothing, limitDateSelectorPopupState: $elm$core$Maybe$Nothing, nutritionReportData: $krisajenkins$remotedata$RemoteData$NotAsked, reportType: $elm$core$Maybe$Nothing, startDate: $elm$core$Maybe$Nothing, startDateSelectorPopupState: $elm$core$Maybe$Nothing}; var $author$project$Pages$Components$Model$emptyDemographicsSelection = {cell: $elm$core$Maybe$Nothing, district: $elm$core$Maybe$Nothing, province: $elm$core$Maybe$Nothing, sector: $elm$core$Maybe$Nothing, village: $elm$core$Maybe$Nothing}; @@ -5487,7 +5514,7 @@ var $author$project$Pages$ReportsMenu$Model$emptyModel = {populationSelection: $ var $author$project$Pages$Scoreboard$Model$ModeValues = {$: 'ModeValues'}; var $author$project$Pages$Scoreboard$Model$emptyModel = {viewMode: $author$project$Pages$Scoreboard$Model$ModeValues, yearSelectorGap: 0}; var $author$project$Pages$ScoreboardMenu$Model$emptyModel = {selected: false, selectedDemographics: $author$project$Pages$Components$Model$emptyDemographicsSelection}; -var $author$project$Backend$Model$emptyModelBackend = {reportsData: $elm$core$Maybe$Nothing, reportsMenuData: $elm$core$Maybe$Nothing, scoreboardData: $elm$core$Maybe$Nothing, scoreboardMenuData: $elm$core$Maybe$Nothing}; +var $author$project$Backend$Model$emptyModelBackend = {completionData: $elm$core$Maybe$Nothing, completionMenuData: $elm$core$Maybe$Nothing, reportsData: $elm$core$Maybe$Nothing, reportsMenuData: $elm$core$Maybe$Nothing, scoreboardData: $elm$core$Maybe$Nothing, scoreboardMenuData: $elm$core$Maybe$Nothing}; var $elm$time$Time$Posix = function (a) { return {$: 'Posix', a: a}; }; @@ -5495,6 +5522,8 @@ var $elm$time$Time$millisToPosix = $elm$time$Time$Posix; var $author$project$App$Model$emptyModel = { activePage: $author$project$App$Types$NotFound, backend: $author$project$Backend$Model$emptyModelBackend, + completionMenuPage: $author$project$Pages$CompletionMenu$Model$emptyModel, + completionPage: $author$project$Pages$Completion$Model$emptyModel, currentTime: $elm$time$Time$millisToPosix(0), errors: _List_Nil, language: $author$project$App$Types$English, @@ -5516,6 +5545,8 @@ var $elm$time$Time$Zone = F2( }); var $elm$time$Time$customZone = $elm$time$Time$Zone; var $elm$time$Time$now = _Time_now($elm$time$Time$millisToPosix); +var $author$project$App$Types$Completion = {$: 'Completion'}; +var $author$project$App$Types$CompletionMenu = {$: 'CompletionMenu'}; var $author$project$App$Types$Reports = {$: 'Reports'}; var $author$project$App$Types$ReportsMenu = {$: 'ReportsMenu'}; var $author$project$App$Types$Scoreboard = {$: 'Scoreboard'}; @@ -5530,10 +5561,20 @@ var $author$project$App$Update$resolveActivePage = function (page) { return $author$project$App$Types$ReportsMenu; case 'reports-results': return $author$project$App$Types$Reports; + case 'completion-menu': + return $author$project$App$Types$CompletionMenu; + case 'completion-results': + return $author$project$App$Types$Completion; default: return $author$project$App$Types$NotFound; } }; +var $author$project$App$Model$MsgCompletionMenuPage = function (a) { + return {$: 'MsgCompletionMenuPage', a: a}; +}; +var $author$project$App$Model$MsgCompletionPage = function (a) { + return {$: 'MsgCompletionPage', a: a}; +}; var $author$project$App$Model$MsgReportsMenuPage = function (a) { return {$: 'MsgReportsMenuPage', a: a}; }; @@ -5762,11 +5803,69 @@ var $justinmimbs$date$Date$fromPosix = F2( var $elm$time$Time$utc = A2($elm$time$Time$Zone, 0, _List_Nil); var $author$project$Gizra$NominalDate$fromLocalDateTime = $justinmimbs$date$Date$fromPosix($elm$time$Time$utc); var $elm$core$Platform$Cmd$none = $elm$core$Platform$Cmd$batch(_List_Nil); -var $krisajenkins$remotedata$RemoteData$Loading = {$: 'Loading'}; var $author$project$App$Model$PagesReturn = F4( function (model, cmd, error, appMsgs) { return {appMsgs: appMsgs, cmd: cmd, error: error, model: model}; }); +var $author$project$Error$Utils$noError = $elm$core$Maybe$Nothing; +var $author$project$Pages$Completion$Update$update = F4( + function (currentDate, modelBackend, msg, model) { + return A4($author$project$App$Model$PagesReturn, model, $elm$core$Platform$Cmd$none, $author$project$Error$Utils$noError, _List_Nil); + }); +var $author$project$Pages$Components$Types$SelectionOptionDemographics = {$: 'SelectionOptionDemographics'}; +var $author$project$Pages$Components$Types$SelectionOptionGlobal = {$: 'SelectionOptionGlobal'}; +var $author$project$Pages$Components$Types$SelectionOptionHealthCenter = {$: 'SelectionOptionHealthCenter'}; +var $author$project$Pages$Components$Utils$populationSelectionOptionFromString = function (selectionOption) { + switch (selectionOption) { + case 'all': + return $elm$core$Maybe$Just($author$project$Pages$Components$Types$SelectionOptionGlobal); + case 'demographics': + return $elm$core$Maybe$Just($author$project$Pages$Components$Types$SelectionOptionDemographics); + case 'hc': + return $elm$core$Maybe$Just($author$project$Pages$Components$Types$SelectionOptionHealthCenter); + default: + return $elm$core$Maybe$Nothing; + } +}; +var $author$project$Pages$CompletionMenu$Update$update = F2( + function (msg, model) { + switch (msg.$) { + case 'SetPopulationSelection': + var value = msg.a; + return A4( + $author$project$App$Model$PagesReturn, + _Utils_update( + model, + { + populationSelection: $author$project$Pages$Components$Utils$populationSelectionOptionFromString(value) + }), + $elm$core$Platform$Cmd$none, + $author$project$Error$Utils$noError, + _List_Nil); + case 'SetHealthCenter': + var value = msg.a; + return A4( + $author$project$App$Model$PagesReturn, + _Utils_update( + model, + { + selectedHealthCenter: $elm$core$String$toInt(value) + }), + $elm$core$Platform$Cmd$none, + $author$project$Error$Utils$noError, + _List_Nil); + default: + return A4( + $author$project$App$Model$PagesReturn, + _Utils_update( + model, + {selected: true}), + $elm$core$Platform$Cmd$none, + $author$project$Error$Utils$noError, + _List_Nil); + } + }); +var $krisajenkins$remotedata$RemoteData$Loading = {$: 'Loading'}; var $elm$core$Maybe$andThen = F2( function (callback, maybeValue) { if (maybeValue.$ === 'Just') { @@ -5864,7 +5963,6 @@ var $author$project$Pages$Reports$Utils$isWideScope = function (selectedEntity) _List_fromArray( [$author$project$Backend$Reports$Model$EntityGlobal, $author$project$Backend$Reports$Model$EntityProvince, $author$project$Backend$Reports$Model$EntityDistrict, $author$project$Backend$Reports$Model$EntityHealthCenter])); }; -var $author$project$Error$Utils$noError = $elm$core$Maybe$Nothing; var $elm_community$maybe_extra$Maybe$Extra$or = F2( function (ma, mb) { if (ma.$ === 'Nothing') { @@ -6517,21 +6615,6 @@ var $author$project$Pages$Reports$Update$update = F4( _List_Nil); } }); -var $author$project$Pages$ReportsMenu$Types$SelectionOptionDemographics = {$: 'SelectionOptionDemographics'}; -var $author$project$Pages$ReportsMenu$Types$SelectionOptionGlobal = {$: 'SelectionOptionGlobal'}; -var $author$project$Pages$ReportsMenu$Types$SelectionOptionHealthCenter = {$: 'SelectionOptionHealthCenter'}; -var $author$project$Pages$ReportsMenu$Utils$populationSelectionOptionFromString = function (selectionOption) { - switch (selectionOption) { - case 'all': - return $elm$core$Maybe$Just($author$project$Pages$ReportsMenu$Types$SelectionOptionGlobal); - case 'demographics': - return $elm$core$Maybe$Just($author$project$Pages$ReportsMenu$Types$SelectionOptionDemographics); - case 'hc': - return $elm$core$Maybe$Just($author$project$Pages$ReportsMenu$Types$SelectionOptionHealthCenter); - default: - return $elm$core$Maybe$Nothing; - } -}; var $author$project$Pages$ReportsMenu$Update$update = F2( function (msg, model) { switch (msg.$) { @@ -6542,7 +6625,7 @@ var $author$project$Pages$ReportsMenu$Update$update = F2( _Utils_update( model, { - populationSelection: $author$project$Pages$ReportsMenu$Utils$populationSelectionOptionFromString(value) + populationSelection: $author$project$Pages$Components$Utils$populationSelectionOptionFromString(value) }), $elm$core$Platform$Cmd$none, $author$project$Error$Utils$noError, @@ -6637,6 +6720,136 @@ var $author$project$Backend$Types$BackendReturn = F4( function (model, cmd, error, appMsgs) { return {appMsgs: appMsgs, cmd: cmd, error: error, model: model}; }); +var $author$project$Backend$Completion$Model$CompletionData = F3( + function (site, entityName, entityType) { + return {entityName: entityName, entityType: entityType, site: site}; + }); +var $author$project$Backend$Completion$Model$EntityGlobal = {$: 'EntityGlobal'}; +var $author$project$Backend$Completion$Model$EntityHealthCenter = {$: 'EntityHealthCenter'}; +var $elm$json$Json$Decode$fail = _Json_fail; +var $elm$json$Json$Decode$string = _Json_decodeString; +var $author$project$Backend$Completion$Decoder$decodeSelectedEntity = A2( + $elm$json$Json$Decode$andThen, + function (entityType) { + switch (entityType) { + case 'global': + return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EntityGlobal); + case 'health-center': + return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EntityHealthCenter); + default: + return $elm$json$Json$Decode$fail(entityType + ' is unknown SelectedEntity type'); + } + }, + $elm$json$Json$Decode$string); +var $author$project$App$Types$SiteBurundi = {$: 'SiteBurundi'}; +var $author$project$App$Types$SiteRwanda = {$: 'SiteRwanda'}; +var $author$project$App$Types$SiteUnknown = {$: 'SiteUnknown'}; +var $elm$core$String$toLower = _String_toLower; +var $author$project$Backend$Decoder$siteFromString = function (str) { + var _v0 = $elm$core$String$toLower(str); + switch (_v0) { + case 'rwanda': + return $author$project$App$Types$SiteRwanda; + case 'burundi': + return $author$project$App$Types$SiteBurundi; + default: + return $author$project$App$Types$SiteUnknown; + } +}; +var $author$project$Backend$Decoder$decodeSite = A2( + $elm$json$Json$Decode$andThen, + A2($elm$core$Basics$composeR, $author$project$Backend$Decoder$siteFromString, $elm$json$Json$Decode$succeed), + $elm$json$Json$Decode$string); +var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom = $elm$json$Json$Decode$map2($elm$core$Basics$apR); +var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required = F3( + function (key, valDecoder, decoder) { + return A2( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom, + A2($elm$json$Json$Decode$field, key, valDecoder), + decoder); + }); +var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'entity_type', + $author$project$Backend$Completion$Decoder$decodeSelectedEntity, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'entity_name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData)))); +var $elm$json$Json$Decode$decodeValue = _Json_run; +var $author$project$Backend$Completion$Update$update = F3( + function (currentDate, msg, model) { + var value = msg.a; + var modelUpdated = _Utils_update( + model, + { + completionData: $elm$core$Maybe$Just( + A2($elm$json$Json$Decode$decodeValue, $author$project$Backend$Completion$Decoder$decodeCompletionData, value)) + }); + return A4($author$project$Backend$Types$BackendReturn, modelUpdated, $elm$core$Platform$Cmd$none, $author$project$Error$Utils$noError, _List_Nil); + }); +var $author$project$Backend$CompletionMenu$Model$MenuData = F2( + function (site, healthCenters) { + return {healthCenters: healthCenters, site: site}; + }); +var $author$project$Backend$Components$Model$HealthCenterData = F2( + function (id, name) { + return {id: id, name: name}; + }); +var $elm$json$Json$Decode$int = _Json_decodeInt; +var $elm$json$Json$Decode$oneOf = _Json_oneOf; +var $author$project$Gizra$Json$decodeInt = $elm$json$Json$Decode$oneOf( + _List_fromArray( + [ + $elm$json$Json$Decode$int, + A2( + $elm$json$Json$Decode$andThen, + function (s) { + var _v0 = $elm$core$String$toInt(s); + if (_v0.$ === 'Just') { + var value = _v0.a; + return $elm$json$Json$Decode$succeed(value); + } else { + return $elm$json$Json$Decode$fail('Not an integer'); + } + }, + $elm$json$Json$Decode$string) + ])); +var $author$project$Backend$Components$Decoder$decodeHealthCenterData = A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'id', + $author$project$Gizra$Json$decodeInt, + $elm$json$Json$Decode$succeed($author$project$Backend$Components$Model$HealthCenterData))); +var $elm$json$Json$Decode$list = _Json_decodeList; +var $author$project$Backend$CompletionMenu$Decoder$decodeMenuData = A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'health_centers', + $elm$json$Json$Decode$list($author$project$Backend$Components$Decoder$decodeHealthCenterData), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$CompletionMenu$Model$MenuData))); +var $author$project$Backend$CompletionMenu$Update$update = F3( + function (currentDate, msg, model) { + var value = msg.a; + var modelUpdated = _Utils_update( + model, + { + completionMenuData: $elm$core$Maybe$Just( + A2($elm$json$Json$Decode$decodeValue, $author$project$Backend$CompletionMenu$Decoder$decodeMenuData, value)) + }); + return A4($author$project$Backend$Types$BackendReturn, modelUpdated, $elm$core$Platform$Cmd$none, $author$project$Error$Utils$noError, _List_Nil); + }); var $author$project$Backend$Reports$Model$ReportsData = F5( function (site, entityName, entityType, records, nutritionReportData) { return {entityName: entityName, entityType: entityType, nutritionReportData: nutritionReportData, records: records, site: site}; @@ -6653,8 +6866,6 @@ var $author$project$Backend$Reports$Model$NutritionTableIncidenceYearOneOrMore = var $author$project$Backend$Reports$Model$NutritionTableIncidenceYearTwoOrMore = {$: 'NutritionTableIncidenceYearTwoOrMore'}; var $author$project$Backend$Reports$Model$NutritionTablePrevalanceOneOrMore = {$: 'NutritionTablePrevalanceOneOrMore'}; var $author$project$Backend$Reports$Model$NutritionTablePrevalanceTwoOrMore = {$: 'NutritionTablePrevalanceTwoOrMore'}; -var $elm$json$Json$Decode$fail = _Json_fail; -var $elm$json$Json$Decode$string = _Json_decodeString; var $author$project$Backend$Reports$Decoder$decodeNutritionReportTableType = A2( $elm$json$Json$Decode$andThen, function (tableType) { @@ -6680,15 +6891,6 @@ var $author$project$Backend$Reports$Decoder$decodeNutritionReportTableType = A2( } }, $elm$json$Json$Decode$string); -var $elm$json$Json$Decode$list = _Json_decodeList; -var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom = $elm$json$Json$Decode$map2($elm$core$Basics$apR); -var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required = F3( - function (key, valDecoder, decoder) { - return A2( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom, - A2($elm$json$Json$Decode$field, key, valDecoder), - decoder); - }); var $author$project$Backend$Reports$Decoder$decodeBackendGeneratedNutritionReportTableDate = A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, 'underweight_severe', @@ -7637,25 +7839,6 @@ var $author$project$Backend$Reports$Decoder$decodeGender = A2( $author$project$Backend$Reports$Utils$genderFromString(gender))); }, $elm$json$Json$Decode$string); -var $elm$json$Json$Decode$int = _Json_decodeInt; -var $elm$json$Json$Decode$oneOf = _Json_oneOf; -var $author$project$Gizra$Json$decodeInt = $elm$json$Json$Decode$oneOf( - _List_fromArray( - [ - $elm$json$Json$Decode$int, - A2( - $elm$json$Json$Decode$andThen, - function (s) { - var _v0 = $elm$core$String$toInt(s); - if (_v0.$ === 'Just') { - var value = _v0.a; - return $elm$json$Json$Decode$succeed(value); - } else { - return $elm$json$Json$Decode$fail('Not an integer'); - } - }, - $elm$json$Json$Decode$string) - ])); var $author$project$Backend$Reports$Model$NutritionEncounterData = F2( function (startDate, nutritionData) { return {nutritionData: nutritionData, startDate: startDate}; @@ -7862,7 +8045,6 @@ var $elm$json$Json$Decode$nullable = function (decoder) { A2($elm$json$Json$Decode$map, $elm$core$Maybe$Just, decoder) ])); }; -var $elm$json$Json$Decode$decodeValue = _Json_run; var $elm$json$Json$Decode$value = _Json_decodeValue; var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalDecoder = F3( function (pathDecoder, valDecoder, fallback) { @@ -8099,25 +8281,6 @@ var $author$project$Backend$Reports$Decoder$decodeSelectedEntity = A2( } }, $elm$json$Json$Decode$string); -var $author$project$App$Types$SiteBurundi = {$: 'SiteBurundi'}; -var $author$project$App$Types$SiteRwanda = {$: 'SiteRwanda'}; -var $author$project$App$Types$SiteUnknown = {$: 'SiteUnknown'}; -var $elm$core$String$toLower = _String_toLower; -var $author$project$Backend$Decoder$siteFromString = function (str) { - var _v0 = $elm$core$String$toLower(str); - switch (_v0) { - case 'rwanda': - return $author$project$App$Types$SiteRwanda; - case 'burundi': - return $author$project$App$Types$SiteBurundi; - default: - return $author$project$App$Types$SiteUnknown; - } -}; -var $author$project$Backend$Decoder$decodeSite = A2( - $elm$json$Json$Decode$andThen, - A2($elm$core$Basics$composeR, $author$project$Backend$Decoder$siteFromString, $elm$json$Json$Decode$succeed), - $elm$json$Json$Decode$string); var $author$project$Backend$Reports$Decoder$decodeReportsData = A4( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalAt, _List_fromArray( @@ -8157,23 +8320,10 @@ var $author$project$Backend$ReportsMenu$Model$MenuData = F2( function (site, healthCenters) { return {healthCenters: healthCenters, site: site}; }); -var $author$project$Backend$ReportsMenu$Model$HealthCenterData = F2( - function (id, name) { - return {id: id, name: name}; - }); -var $author$project$Backend$ReportsMenu$Decoder$decodeHealthCenterData = A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'name', - $elm$json$Json$Decode$string, - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'id', - $author$project$Gizra$Json$decodeInt, - $elm$json$Json$Decode$succeed($author$project$Backend$ReportsMenu$Model$HealthCenterData))); var $author$project$Backend$ReportsMenu$Decoder$decodeMenuData = A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, 'health_centers', - $elm$json$Json$Decode$list($author$project$Backend$ReportsMenu$Decoder$decodeHealthCenterData), + $elm$json$Json$Decode$list($author$project$Backend$Components$Decoder$decodeHealthCenterData), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, 'site', @@ -8859,7 +9009,7 @@ var $author$project$Backend$Update$updateBackend = F3( return $author$project$Backend$Model$MsgReportsMenu(subCmds); }, model); - default: + case 'MsgReports': var subMsg = msg.a; return A4( $author$project$Backend$Utils$updateSubModel, @@ -8872,25 +9022,51 @@ var $author$project$Backend$Update$updateBackend = F3( return $author$project$Backend$Model$MsgReports(subCmds); }, model); - } - }); -var $elm_community$maybe_extra$Maybe$Extra$unwrap = F3( - function (d, f, m) { - if (m.$ === 'Nothing') { - return d; - } else { - var a = m.a; - return f(a); - } - }); -var $author$project$App$Utils$handleErrors = F2( - function (maybeError, model) { - var errors = A3( - $elm_community$maybe_extra$Maybe$Extra$unwrap, - model.errors, - function (error) { - return A2($elm$core$List$cons, error, model.errors); - }, + case 'MsgCompletionMenu': + var subMsg = msg.a; + return A4( + $author$project$Backend$Utils$updateSubModel, + subMsg, + F2( + function (subMsg_, model_) { + return A3($author$project$Backend$CompletionMenu$Update$update, currentDate, subMsg_, model_); + }), + function (subCmds) { + return $author$project$Backend$Model$MsgCompletionMenu(subCmds); + }, + model); + default: + var subMsg = msg.a; + return A4( + $author$project$Backend$Utils$updateSubModel, + subMsg, + F2( + function (subMsg_, model_) { + return A3($author$project$Backend$Completion$Update$update, currentDate, subMsg_, model_); + }), + function (subCmds) { + return $author$project$Backend$Model$MsgCompletion(subCmds); + }, + model); + } + }); +var $elm_community$maybe_extra$Maybe$Extra$unwrap = F3( + function (d, f, m) { + if (m.$ === 'Nothing') { + return d; + } else { + var a = m.a; + return f(a); + } + }); +var $author$project$App$Utils$handleErrors = F2( + function (maybeError, model) { + var errors = A3( + $elm_community$maybe_extra$Maybe$Extra$unwrap, + model.errors, + function (error) { + return A2($elm$core$List$cons, error, model.errors); + }, maybeError); return _Utils_update( model, @@ -9031,6 +9207,51 @@ var $author$project$App$Update$update = F2( return $author$project$App$Model$MsgReportsPage(subCmds); }, model); + case 'MsgCompletionMenuPage': + var subMsg = msg.a; + return A6( + $author$project$App$Utils$updateSubModel, + subMsg, + model.completionMenuPage, + F2( + function (subMsg_, subModel) { + return A2($author$project$Pages$CompletionMenu$Update$update, subMsg_, subModel); + }), + F2( + function (subModel, model_) { + return _Utils_update( + model_, + {completionMenuPage: subModel}); + }), + function (subCmds) { + return $author$project$App$Model$MsgCompletionMenuPage(subCmds); + }, + model); + case 'MsgCompletionPage': + var subMsg = msg.a; + return A6( + $author$project$App$Utils$updateSubModel, + subMsg, + model.completionPage, + F2( + function (subMsg_, subModel) { + return A4( + $author$project$Pages$Completion$Update$update, + $author$project$Gizra$NominalDate$fromLocalDateTime(model.currentTime), + model.backend, + subMsg_, + subModel); + }), + F2( + function (subModel, model_) { + return _Utils_update( + model_, + {completionPage: subModel}); + }), + function (subCmds) { + return $author$project$App$Model$MsgCompletionPage(subCmds); + }, + model); default: var date = msg.a; return _Utils_Tuple2( @@ -9076,6 +9297,20 @@ var $author$project$App$Update$init = function (flags) { $author$project$Backend$Model$MsgReports( $author$project$Backend$Reports$Model$SetData(flags.appData))), model).a; + case 'CompletionMenu': + return A2( + $author$project$App$Update$update, + $author$project$App$Model$MsgBackend( + $author$project$Backend$Model$MsgCompletionMenu( + $author$project$Backend$CompletionMenu$Model$SetData(flags.appData))), + model).a; + case 'Completion': + return A2( + $author$project$App$Update$update, + $author$project$App$Model$MsgBackend( + $author$project$Backend$Model$MsgCompletion( + $author$project$Backend$Completion$Model$SetData(flags.appData))), + model).a; default: return model; } @@ -10055,14 +10290,378 @@ var $author$project$Error$View$view = F2( errors)) ])); }); -var $author$project$Gizra$Html$emptyNode = $elm$html$Html$text(''); -var $elm$core$Debug$toString = _Debug_toString; +var $author$project$Gizra$Html$emptyNode = $elm$html$Html$text(''); +var $elm$core$Debug$toString = _Debug_toString; +var $author$project$Pages$Completion$View$viewCompletionData = F5( + function (language, currentDate, themePath, data, model) { + return $elm$html$Html$text('viewCompletionData'); + }); +var $author$project$Pages$Completion$View$view = F5( + function (language, currentDate, themePath, modelBackend, model) { + var _v0 = modelBackend.completionData; + if (_v0.$ === 'Just') { + if (_v0.a.$ === 'Ok') { + var data = _v0.a.a; + return A5($author$project$Pages$Completion$View$viewCompletionData, language, currentDate, themePath, data, model); + } else { + var err = _v0.a.a; + return $elm$html$Html$text( + $elm$core$Debug$toString(err)); + } + } else { + return $author$project$Gizra$Html$emptyNode; + } + }); +var $author$project$Translate$PleaseWaitMessage = {$: 'PleaseWaitMessage'}; +var $author$project$Translate$PopulationSelectionOption = function (a) { + return {$: 'PopulationSelectionOption', a: a}; +}; +var $author$project$Translate$Scope = {$: 'Scope'}; +var $author$project$Translate$SelectScope = {$: 'SelectScope'}; +var $author$project$Pages$CompletionMenu$Model$SelectionMade = {$: 'SelectionMade'}; +var $author$project$Pages$CompletionMenu$Model$SetHealthCenter = function (a) { + return {$: 'SetHealthCenter', a: a}; +}; +var $author$project$Pages$CompletionMenu$Model$SetPopulationSelection = function (a) { + return {$: 'SetPopulationSelection', a: a}; +}; +var $author$project$Pages$Components$Utils$populationSelectionOptionToString = function (selectionOption) { + switch (selectionOption.$) { + case 'SelectionOptionGlobal': + return 'all'; + case 'SelectionOptionDemographics': + return 'demographics'; + default: + return 'hc'; + } +}; +var $elm$core$List$sortBy = _List_sortBy; +var $author$project$Pages$Utils$viewCustomLabel = F4( + function (language, translationId, suffix, class_) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class(class_) + ]), + _List_fromArray( + [ + $elm$html$Html$text( + _Utils_ap( + A2($author$project$Translate$translate, language, translationId), + suffix)) + ])); + }); +var $elm$html$Html$option = _VirtualDom_node('option'); +var $elm$json$Json$Encode$bool = _Json_wrap; +var $elm$html$Html$Attributes$boolProperty = F2( + function (key, bool) { + return A2( + _VirtualDom_property, + key, + $elm$json$Json$Encode$bool(bool)); + }); +var $elm$html$Html$Attributes$selected = $elm$html$Html$Attributes$boolProperty('selected'); +var $elm$html$Html$Attributes$value = $elm$html$Html$Attributes$stringProperty('value'); +var $author$project$Pages$Utils$emptySelectOption = function (isSelected) { + return A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value(''), + $elm$html$Html$Attributes$selected(isSelected) + ]), + _List_fromArray( + [ + $elm$html$Html$text('') + ])); +}; +var $elm$html$Html$Events$alwaysStop = function (x) { + return _Utils_Tuple2(x, true); +}; +var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { + return {$: 'MayStopPropagation', a: a}; +}; +var $elm$virtual_dom$VirtualDom$on = _VirtualDom_on; +var $elm$html$Html$Events$stopPropagationOn = F2( + function (event, decoder) { + return A2( + $elm$virtual_dom$VirtualDom$on, + event, + $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); + }); +var $elm$html$Html$Events$targetValue = A2( + $elm$json$Json$Decode$at, + _List_fromArray( + ['target', 'value']), + $elm$json$Json$Decode$string); +var $elm$html$Html$Events$onInput = function (tagger) { + return A2( + $elm$html$Html$Events$stopPropagationOn, + 'input', + A2( + $elm$json$Json$Decode$map, + $elm$html$Html$Events$alwaysStop, + A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); +}; +var $elm$html$Html$select = _VirtualDom_node('select'); +var $author$project$Pages$Utils$viewCustomSelectListInput = F6( + function (currentValue, options, toStringFunc, setMsg, inputClass, withEmptyOption) { + var emptyOption = withEmptyOption ? $author$project$Pages$Utils$emptySelectOption( + _Utils_eq(currentValue, $elm$core$Maybe$Nothing)) : $author$project$Gizra$Html$emptyNode; + return A2( + $elm$html$Html$select, + _List_fromArray( + [ + $elm$html$Html$Events$onInput(setMsg), + $elm$html$Html$Attributes$class(inputClass) + ]), + A2( + $elm$core$List$cons, + emptyOption, + A2( + $elm$core$List$map, + function (_v0) { + var label = _v0.a; + var value_ = _v0.b; + return A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value( + toStringFunc(value_)), + $elm$html$Html$Attributes$selected( + _Utils_eq( + currentValue, + $elm$core$Maybe$Just(value_))) + ]), + _List_fromArray( + [ + $elm$html$Html$text(label) + ])); + }, + options))); + }); +var $author$project$Translate$LoadData = {$: 'LoadData'}; +var $elm$html$Html$a = _VirtualDom_node('a'); +var $elm$html$Html$button = _VirtualDom_node('button'); +var $elm$html$Html$Attributes$href = function (url) { + return A2( + $elm$html$Html$Attributes$stringProperty, + 'href', + _VirtualDom_noJavaScriptUri(url)); +}; +var $elm$virtual_dom$VirtualDom$Normal = function (a) { + return {$: 'Normal', a: a}; +}; +var $elm$html$Html$Events$on = F2( + function (event, decoder) { + return A2( + $elm$virtual_dom$VirtualDom$on, + event, + $elm$virtual_dom$VirtualDom$Normal(decoder)); + }); +var $elm$html$Html$Events$onClick = function (msg) { + return A2( + $elm$html$Html$Events$on, + 'click', + $elm$json$Json$Decode$succeed(msg)); +}; +var $author$project$Pages$Utils$viewMenuActionButton = F4( + function (language, path, label, selectionMadeMsg) { + return A2( + $elm$html$Html$a, + _List_fromArray( + [ + $elm$html$Html$Attributes$href(path) + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick(selectionMadeMsg) + ]), + _List_fromArray( + [ + $elm$html$Html$text( + A2($author$project$Translate$translate, language, label)) + ])) + ])); + }); +var $author$project$Pages$Utils$viewLoadDataButton = F3( + function (language, path, selectionMadeMsg) { + return A4($author$project$Pages$Utils$viewMenuActionButton, language, path, $author$project$Translate$LoadData, selectionMadeMsg); + }); +var $author$project$Pages$Utils$viewSelectListInput = F7( + function (language, currentValue, options, toStringFunc, setMsg, transId, inputClass) { + var transFunc = A2( + $elm$core$Basics$composeR, + transId, + $author$project$Translate$translate(language)); + var optionsPairs = A2( + $elm$core$List$map, + function (option) { + return _Utils_Tuple2( + transFunc(option), + option); + }, + options); + return A6($author$project$Pages$Utils$viewCustomSelectListInput, currentValue, optionsPairs, toStringFunc, setMsg, inputClass, true); + }); +var $elm$html$Html$Attributes$classList = function (classes) { + return $elm$html$Html$Attributes$class( + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $elm$core$Tuple$first, + A2($elm$core$List$filter, $elm$core$Tuple$second, classes)))); +}; +var $author$project$Pages$Utils$viewLabel = F2( + function (language, translationId) { + return A4($author$project$Pages$Utils$viewCustomLabel, language, translationId, ':', 'label'); + }); +var $author$project$Pages$Utils$wrapSelectListInput = F4( + function (language, labelTransId, disabled, selectList) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$classList( + _List_fromArray( + [ + _Utils_Tuple2('select-input-wrapper', true), + _Utils_Tuple2('disabled', disabled) + ])) + ]), + _List_fromArray( + [ + A2($author$project$Pages$Utils$viewLabel, language, labelTransId), + selectList + ])); + }); +var $author$project$Pages$CompletionMenu$View$viewMenu = F4( + function (language, themePath, data, model) { + var populationSelectionInput = A4( + $author$project$Pages$Utils$wrapSelectListInput, + language, + $author$project$Translate$Scope, + false, + A7( + $author$project$Pages$Utils$viewSelectListInput, + language, + model.populationSelection, + _List_fromArray( + [$author$project$Pages$Components$Types$SelectionOptionGlobal, $author$project$Pages$Components$Types$SelectionOptionHealthCenter]), + $author$project$Pages$Components$Utils$populationSelectionOptionToString, + $author$project$Pages$CompletionMenu$Model$SetPopulationSelection, + $author$project$Translate$PopulationSelectionOption, + 'select-input')); + var _v0 = A2( + $elm$core$Maybe$withDefault, + _Utils_Tuple2(_List_Nil, $author$project$Gizra$Html$emptyNode), + A2( + $elm$core$Maybe$map, + function (populationSelection) { + switch (populationSelection.$) { + case 'SelectionOptionGlobal': + return _Utils_Tuple2( + _List_Nil, + A3($author$project$Pages$Utils$viewLoadDataButton, language, '/admin/completion/completion/all', $author$project$Pages$CompletionMenu$Model$SelectionMade)); + case 'SelectionOptionHealthCenter': + var options = A2( + $elm$core$List$map, + function (healthCenter) { + return _Utils_Tuple2(healthCenter.name, healthCenter.id); + }, + A2( + $elm$core$List$sortBy, + function ($) { + return $.name; + }, + data.healthCenters)); + return _Utils_Tuple2( + _List_fromArray( + [ + A4( + $author$project$Pages$Utils$wrapSelectListInput, + language, + $author$project$Translate$HealthCenter, + false, + A6($author$project$Pages$Utils$viewCustomSelectListInput, model.selectedHealthCenter, options, $elm$core$String$fromInt, $author$project$Pages$CompletionMenu$Model$SetHealthCenter, 'select-input', true)) + ]), + A2( + $elm$core$Maybe$withDefault, + $author$project$Gizra$Html$emptyNode, + A2( + $elm$core$Maybe$map, + function (selectedHealthCenter) { + return A3( + $author$project$Pages$Utils$viewLoadDataButton, + language, + '/admin/completion/completion/health-center/' + $elm$core$String$fromInt(selectedHealthCenter), + $author$project$Pages$CompletionMenu$Model$SelectionMade); + }, + model.selectedHealthCenter))); + default: + return _Utils_Tuple2(_List_Nil, $author$project$Gizra$Html$emptyNode); + } + }, + model.populationSelection)); + var derivedInputs = _v0.a; + var actionButton_ = _v0.b; + var actionButton = model.selected ? $elm$html$Html$text( + A2($author$project$Translate$translate, language, $author$project$Translate$PleaseWaitMessage)) : actionButton_; + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('page-content completion-menu') + ]), + _List_fromArray( + [ + A4($author$project$Pages$Utils$viewCustomLabel, language, $author$project$Translate$SelectScope, ':', 'header'), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('inputs') + ]), + A2($elm$core$List$cons, populationSelectionInput, derivedInputs)), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('actions') + ]), + _List_fromArray( + [actionButton])) + ])); + }); +var $author$project$Pages$CompletionMenu$View$view = F4( + function (language, themePath, modelBackend, model) { + var _v0 = modelBackend.completionMenuData; + if (_v0.$ === 'Just') { + if (_v0.a.$ === 'Ok') { + var data = _v0.a.a; + return A4($author$project$Pages$CompletionMenu$View$viewMenu, language, themePath, data, model); + } else { + var err = _v0.a.a; + return $elm$html$Html$text( + $elm$core$Debug$toString(err)); + } + } else { + return $author$project$Gizra$Html$emptyNode; + } + }); var $author$project$Translate$NewScope = {$: 'NewScope'}; var $author$project$Translate$ReportType = function (a) { return {$: 'ReportType', a: a}; }; var $author$project$Translate$ReportTypeLabel = {$: 'ReportTypeLabel'}; -var $author$project$Translate$Scope = {$: 'Scope'}; var $author$project$Translate$SelectLimitDate = {$: 'SelectLimitDate'}; var $author$project$Translate$SelectStartDate = {$: 'SelectStartDate'}; var $author$project$Translate$SelectedScope = function (a) { @@ -10084,7 +10683,6 @@ var $author$project$Pages$Reports$Model$SetStartDateSelectorState = function (a) return {$: 'SetStartDateSelectorState', a: a}; }; var $author$project$Translate$WideScopeNote = {$: 'WideScopeNote'}; -var $elm$html$Html$a = _VirtualDom_node('a'); var $elm$core$Basics$min = F2( function (x, y) { return (_Utils_cmp(x, y) < 0) ? x : y; @@ -10117,7 +10715,6 @@ var $justinmimbs$date$Date$add = F3( return $justinmimbs$date$Date$RD(rd + n); } }); -var $elm$html$Html$button = _VirtualDom_node('button'); var $justinmimbs$date$Date$day = A2( $elm$core$Basics$composeR, $justinmimbs$date$Date$toCalendarDate, @@ -10761,12 +11358,6 @@ var $author$project$Pages$Utils$generateReportsHeaderImage = function (themePath ]), _List_Nil); }; -var $elm$html$Html$Attributes$href = function (url) { - return A2( - $elm$html$Html$Attributes$stringProperty, - 'href', - _VirtualDom_noJavaScriptUri(url)); -}; var $elm_community$maybe_extra$Maybe$Extra$isJust = function (m) { if (m.$ === 'Nothing') { return false; @@ -10794,23 +11385,6 @@ var $elm$core$Maybe$map3 = F4( } } }); -var $elm$virtual_dom$VirtualDom$Normal = function (a) { - return {$: 'Normal', a: a}; -}; -var $elm$virtual_dom$VirtualDom$on = _VirtualDom_on; -var $elm$html$Html$Events$on = F2( - function (event, decoder) { - return A2( - $elm$virtual_dom$VirtualDom$on, - event, - $elm$virtual_dom$VirtualDom$Normal(decoder)); - }); -var $elm$html$Html$Events$onClick = function (msg) { - return A2( - $elm$html$Html$Events$on, - 'click', - $elm$json$Json$Decode$succeed(msg)); -}; var $author$project$Pages$Reports$Utils$reportTypeToString = function (reportType) { switch (reportType.$) { case 'ReportAcuteIllness': @@ -10990,16 +11564,6 @@ var $author$project$Pages$Reports$View$viewDownloadCSVButton = F3( ])) ])); }); -var $elm$html$Html$Attributes$classList = function (classes) { - return $elm$html$Html$Attributes$class( - A2( - $elm$core$String$join, - ' ', - A2( - $elm$core$List$map, - $elm$core$Tuple$first, - A2($elm$core$List$filter, $elm$core$Tuple$second, classes)))); -}; var $author$project$Pages$Reports$View$viewCustomCells = F2( function (labelClass, valueClass) { return $elm$core$List$indexedMap( @@ -11666,18 +12230,6 @@ var $author$project$DateSelector$Selector$dateWithMonth = F2( d, A2($author$project$DateSelector$Selector$daysInMonth, y, m))); }); -var $elm$html$Html$option = _VirtualDom_node('option'); -var $elm$html$Html$select = _VirtualDom_node('select'); -var $elm$json$Json$Encode$bool = _Json_wrap; -var $elm$html$Html$Attributes$boolProperty = F2( - function (key, bool) { - return A2( - _VirtualDom_property, - key, - $elm$json$Json$Encode$bool(bool)); - }); -var $elm$html$Html$Attributes$selected = $elm$html$Html$Attributes$boolProperty('selected'); -var $elm$html$Html$Attributes$value = $elm$html$Html$Attributes$stringProperty('value'); var $author$project$DateSelector$Selector$viewMonthSelectList = F4( function (language, minimum, maximum, selectedDate) { var isInvertedMinMax = _Utils_eq( @@ -11983,22 +12535,6 @@ var $author$project$DateSelector$SelectorPopup$viewCalendarPopup = F3( }, popupState); }); -var $author$project$Pages$Utils$viewCustomLabel = F4( - function (language, translationId, suffix, class_) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class(class_) - ]), - _List_fromArray( - [ - $elm$html$Html$text( - _Utils_ap( - A2($author$project$Translate$translate, language, translationId), - suffix)) - ])); - }); var $author$project$Pages$Reports$View$demographicsReportEncountersDataToCSV = function (data) { return A2( $elm$core$String$join, @@ -12906,7 +13442,6 @@ var $author$project$Pages$Reports$View$backendGeneratedNutritionReportTableDateT ]) }; }); -var $elm$core$List$sortBy = _List_sortBy; var $author$project$Pages$Reports$View$generareNutritionReportDataFromBackendGeneratedData = F3( function (language, currentDate, data) { var nutritionTableTypeToNumber = function (tableType) { @@ -14681,122 +15216,6 @@ var $author$project$Pages$Reports$View$viewPrenatalReport = F4( A3($author$project$Pages$Reports$View$viewDownloadCSVButton, language, csvFileName, csvContent) ]))); }); -var $author$project$Pages$Utils$emptySelectOption = function (isSelected) { - return A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value(''), - $elm$html$Html$Attributes$selected(isSelected) - ]), - _List_fromArray( - [ - $elm$html$Html$text('') - ])); -}; -var $elm$html$Html$Events$alwaysStop = function (x) { - return _Utils_Tuple2(x, true); -}; -var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { - return {$: 'MayStopPropagation', a: a}; -}; -var $elm$html$Html$Events$stopPropagationOn = F2( - function (event, decoder) { - return A2( - $elm$virtual_dom$VirtualDom$on, - event, - $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); - }); -var $elm$html$Html$Events$targetValue = A2( - $elm$json$Json$Decode$at, - _List_fromArray( - ['target', 'value']), - $elm$json$Json$Decode$string); -var $elm$html$Html$Events$onInput = function (tagger) { - return A2( - $elm$html$Html$Events$stopPropagationOn, - 'input', - A2( - $elm$json$Json$Decode$map, - $elm$html$Html$Events$alwaysStop, - A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); -}; -var $author$project$Pages$Utils$viewCustomSelectListInput = F6( - function (currentValue, options, toStringFunc, setMsg, inputClass, withEmptyOption) { - var emptyOption = withEmptyOption ? $author$project$Pages$Utils$emptySelectOption( - _Utils_eq(currentValue, $elm$core$Maybe$Nothing)) : $author$project$Gizra$Html$emptyNode; - return A2( - $elm$html$Html$select, - _List_fromArray( - [ - $elm$html$Html$Events$onInput(setMsg), - $elm$html$Html$Attributes$class(inputClass) - ]), - A2( - $elm$core$List$cons, - emptyOption, - A2( - $elm$core$List$map, - function (_v0) { - var label = _v0.a; - var value_ = _v0.b; - return A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value( - toStringFunc(value_)), - $elm$html$Html$Attributes$selected( - _Utils_eq( - currentValue, - $elm$core$Maybe$Just(value_))) - ]), - _List_fromArray( - [ - $elm$html$Html$text(label) - ])); - }, - options))); - }); -var $author$project$Pages$Utils$viewSelectListInput = F7( - function (language, currentValue, options, toStringFunc, setMsg, transId, inputClass) { - var transFunc = A2( - $elm$core$Basics$composeR, - transId, - $author$project$Translate$translate(language)); - var optionsPairs = A2( - $elm$core$List$map, - function (option) { - return _Utils_Tuple2( - transFunc(option), - option); - }, - options); - return A6($author$project$Pages$Utils$viewCustomSelectListInput, currentValue, optionsPairs, toStringFunc, setMsg, inputClass, true); - }); -var $author$project$Pages$Utils$viewLabel = F2( - function (language, translationId) { - return A4($author$project$Pages$Utils$viewCustomLabel, language, translationId, ':', 'label'); - }); -var $author$project$Pages$Utils$wrapSelectListInput = F4( - function (language, labelTransId, disabled, selectList) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$classList( - _List_fromArray( - [ - _Utils_Tuple2('select-input-wrapper', true), - _Utils_Tuple2('disabled', disabled) - ])) - ]), - _List_fromArray( - [ - A2($author$project$Pages$Utils$viewLabel, language, labelTransId), - selectList - ])); - }); var $author$project$Pages$Reports$View$viewReportsData = F5( function (language, currentDate, themePath, data, model) { var scopeLabel = function () { @@ -15167,12 +15586,6 @@ var $author$project$Pages$Reports$View$view = F5( return $author$project$Gizra$Html$emptyNode; } }); -var $author$project$Translate$LoadData = {$: 'LoadData'}; -var $author$project$Translate$PleaseWaitMessage = {$: 'PleaseWaitMessage'}; -var $author$project$Translate$PopulationSelectionOption = function (a) { - return {$: 'PopulationSelectionOption', a: a}; -}; -var $author$project$Translate$SelectScope = {$: 'SelectScope'}; var $author$project$Pages$ReportsMenu$Model$SelectionMade = {$: 'SelectionMade'}; var $author$project$Pages$ReportsMenu$Model$SetGeoLocation = F2( function (a, b) { @@ -15184,16 +15597,6 @@ var $author$project$Pages$ReportsMenu$Model$SetHealthCenter = function (a) { var $author$project$Pages$ReportsMenu$Model$SetPopulationSelection = function (a) { return {$: 'SetPopulationSelection', a: a}; }; -var $author$project$Pages$ReportsMenu$Utils$populationSelectionOptionToString = function (selectionOption) { - switch (selectionOption.$) { - case 'SelectionOptionGlobal': - return 'all'; - case 'SelectionOptionDemographics': - return 'demographics'; - default: - return 'hc'; - } -}; var $author$project$Backend$Entities$EntityId = function (a) { return {$: 'EntityId', a: a}; }; @@ -34677,29 +35080,6 @@ var $author$project$Pages$Components$View$viewDemographicsSelection = F4( return _List_fromArray( [provinceInput, districtInput, sectorInput, cellInput, villageInput]); }); -var $author$project$Pages$Utils$viewMenuActionButton = F4( - function (language, path, label, selectionMadeMsg) { - return A2( - $elm$html$Html$a, - _List_fromArray( - [ - $elm$html$Html$Attributes$href(path) - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$button, - _List_fromArray( - [ - $elm$html$Html$Events$onClick(selectionMadeMsg) - ]), - _List_fromArray( - [ - $elm$html$Html$text( - A2($author$project$Translate$translate, language, label)) - ])) - ])); - }); var $author$project$Pages$Components$View$viewDemographicsSelectionActionButton = F6( function (language, site, pathPrefix, label, selectionMadeMsg, selection) { var geoInfo = $author$project$Utils$GeoLocation$getGeoInfo(site); @@ -34776,10 +35156,6 @@ var $author$project$Pages$Components$View$viewDemographicsSelectionActionButton var path = pathPrefix + ('/' + (provincePart + (districtPart + (sectorPart + (cellPart + villagePart))))); return A4($author$project$Pages$Utils$viewMenuActionButton, language, path, label, selectionMadeMsg); }); -var $author$project$Pages$Utils$viewLoadDataButton = F3( - function (language, path, selectionMadeMsg) { - return A4($author$project$Pages$Utils$viewMenuActionButton, language, path, $author$project$Translate$LoadData, selectionMadeMsg); - }); var $author$project$Pages$ReportsMenu$View$viewMenu = F4( function (language, themePath, data, model) { var populationSelectionInput = A4( @@ -34792,8 +35168,8 @@ var $author$project$Pages$ReportsMenu$View$viewMenu = F4( language, model.populationSelection, _List_fromArray( - [$author$project$Pages$ReportsMenu$Types$SelectionOptionGlobal, $author$project$Pages$ReportsMenu$Types$SelectionOptionDemographics, $author$project$Pages$ReportsMenu$Types$SelectionOptionHealthCenter]), - $author$project$Pages$ReportsMenu$Utils$populationSelectionOptionToString, + [$author$project$Pages$Components$Types$SelectionOptionGlobal, $author$project$Pages$Components$Types$SelectionOptionDemographics, $author$project$Pages$Components$Types$SelectionOptionHealthCenter]), + $author$project$Pages$Components$Utils$populationSelectionOptionToString, $author$project$Pages$ReportsMenu$Model$SetPopulationSelection, $author$project$Translate$PopulationSelectionOption, 'select-input')); @@ -36853,6 +37229,36 @@ var $author$project$App$View$view = function (model) { model.backend, model.reportsPage)) ])); + case 'CompletionMenu': + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + A2($author$project$Error$View$view, model.language, model.errors), + A2( + $elm$html$Html$map, + $author$project$App$Model$MsgCompletionMenuPage, + A4($author$project$Pages$CompletionMenu$View$view, model.language, model.themePath, model.backend, model.completionMenuPage)) + ])); + case 'Completion': + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + A2($author$project$Error$View$view, model.language, model.errors), + A2( + $elm$html$Html$map, + $author$project$App$Model$MsgCompletionPage, + A5( + $author$project$Pages$Completion$View$view, + model.language, + $author$project$Gizra$NominalDate$fromLocalDateTime(model.currentTime), + model.themePath, + model.backend, + model.completionPage)) + ])); default: return A2( $elm$html$Html$div, diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 61d02835c2..30c59ae94f 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -80,6 +80,14 @@ function hedley_reports_menu() { 'access callback' => 'hedley_reports_statistical_queries_report_access', ); + $items['admin/reports/completion'] = array( + 'title' => 'Completion report', + 'description' => 'View Completion report', + 'page callback' => 'hedley_reports_completion_report_callback_menu', + // @todo : what access do we need here? + 'access callback' => 'hedley_reports_statistical_queries_report_access', + ); + return $items; } From 9ef86346985ec75683770ab1551dc63a868fb441 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 15 Aug 2024 14:49:15 +0300 Subject: [PATCH 007/185] Results page WIP [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 80 +- server/elm/src/Backend/Completion/Model.elm | 28 + server/elm/src/Backend/Decoder.elm | 9 +- server/elm/src/Backend/Reports/Decoder.elm | 9 +- server/elm/src/Pages/Completion/View.elm | 4 + server/elm/src/Pages/CompletionMenu/View.elm | 4 +- .../custom/hedley_general/js/elm-main.js | 1189 +++++++++-------- .../hedley_reports/hedley_reports.module | 172 ++- .../scripts/generate-completion-data.php | 3 +- 9 files changed, 921 insertions(+), 577 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index e55f6c4038..e5c27bdc32 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -2,7 +2,7 @@ module Backend.Completion.Decoder exposing (decodeCompletionData) import AssocList as Dict import Backend.Completion.Model exposing (..) -import Backend.Decoder exposing (decodeSite) +import Backend.Decoder exposing (decodeSite, decodeWithFallback) import Date import EverySet exposing (EverySet) import Gizra.Json exposing (decodeFloat, decodeInt) @@ -18,6 +18,7 @@ decodeCompletionData = |> required "site" decodeSite |> required "entity_name" string |> required "entity_type" decodeSelectedEntity + |> required "results" (list (decodeEncounterData decodeNutritionActivities)) decodeSelectedEntity : Decoder SelectedEntity @@ -35,3 +36,80 @@ decodeSelectedEntity = _ -> fail <| entityType ++ " is unknown SelectedEntity type" ) + + +decodeEncounterData : Decoder (List activity) -> Decoder (EncounterData activity) +decodeEncounterData activitiesDecoder = + succeed EncounterData + |> required "start_date" decodeYYYYMMDD + |> required "expected" activitiesDecoder + |> required "completed" activitiesDecoder + |> required "taken_by" (nullable (decodeWithFallback TakenByUnknown decodeTakenBy)) + + +decodeNutritionActivities : Decoder (List NutritionActivity) +decodeNutritionActivities = + string + |> andThen + (String.split "," + >> List.map nutritionActivityFromMapping + >> Maybe.Extra.values + >> succeed + ) + + +nutritionActivityFromMapping : String -> Maybe NutritionActivity +nutritionActivityFromMapping mapped = + case mapped of + "a" -> + Just NutritionHeight + + "b" -> + Just NutritionNutrition + + "c" -> + Just NutritionPhoto + + "d" -> + Just NutritionWeight + + "e" -> + Just NutritionMUAC + + "f" -> + Just NutritionContributingFactors + + "g" -> + Just NutritionFollowUp + + "h" -> + Just NutritionHealthEducation + + "i" -> + Just NutritionSendToHC + + "j" -> + Just NutritionNCDA + + _ -> + Nothing + + +decodeTakenBy : Decoder TakenBy +decodeTakenBy = + string + |> andThen + (\takenBy -> + case takenBy of + "nurse" -> + succeed TakenByNurse + + "chw" -> + succeed TakenByCHW + + "unknown" -> + succeed TakenByUnknown + + _ -> + fail <| takenBy ++ " is unknown TakenBy type" + ) diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index d589e58b3d..571d37e166 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -11,6 +11,7 @@ type alias CompletionData = { site : Site , entityName : String , entityType : SelectedEntity + , nutritionIndividualData : List (EncounterData NutritionActivity) } @@ -19,5 +20,32 @@ type SelectedEntity | EntityHealthCenter +type alias EncounterData activity = + { startDate : NominalDate + , expectedActivities : List activity + , completedActivities : List activity + , takenBy : Maybe TakenBy + } + + +type NutritionActivity + = NutritionHeight + | NutritionNutrition + | NutritionPhoto + | NutritionWeight + | NutritionMUAC + | NutritionContributingFactors + | NutritionFollowUp + | NutritionHealthEducation + | NutritionSendToHC + | NutritionNCDA + + +type TakenBy + = TakenByNurse + | TakenByCHW + | TakenByUnknown + + type Msg = SetData Value diff --git a/server/elm/src/Backend/Decoder.elm b/server/elm/src/Backend/Decoder.elm index fdaa385fa7..cf6b4ff1e0 100644 --- a/server/elm/src/Backend/Decoder.elm +++ b/server/elm/src/Backend/Decoder.elm @@ -1,8 +1,8 @@ -module Backend.Decoder exposing (decodeSite) +module Backend.Decoder exposing (decodeSite, decodeWithFallback) import App.Types exposing (Site(..)) import Backend.ScoreboardMenu.Model exposing (..) -import Json.Decode exposing (Decoder, andThen, string, succeed) +import Json.Decode exposing (Decoder, andThen, oneOf, string, succeed) import Json.Decode.Pipeline exposing (required) @@ -23,3 +23,8 @@ siteFromString str = _ -> SiteUnknown + + +decodeWithFallback : a -> Decoder a -> Decoder a +decodeWithFallback fallback decoder = + oneOf [ decoder, succeed fallback ] diff --git a/server/elm/src/Backend/Reports/Decoder.elm b/server/elm/src/Backend/Reports/Decoder.elm index 720f2cdb9c..0447087fea 100644 --- a/server/elm/src/Backend/Reports/Decoder.elm +++ b/server/elm/src/Backend/Reports/Decoder.elm @@ -1,14 +1,14 @@ module Backend.Reports.Decoder exposing (decodeReportsData) import AssocList as Dict -import Backend.Decoder exposing (decodeSite) +import Backend.Decoder exposing (decodeSite, decodeWithFallback) import Backend.Reports.Model exposing (..) import Backend.Reports.Utils exposing (..) import Date import EverySet exposing (EverySet) import Gizra.Json exposing (decodeFloat, decodeInt) import Gizra.NominalDate exposing (NominalDate, decodeYYYYMMDD, diffMonths) -import Json.Decode exposing (Decoder, andThen, bool, fail, list, map, maybe, nullable, oneOf, string, succeed) +import Json.Decode exposing (Decoder, andThen, bool, fail, list, map, nullable, oneOf, string, succeed) import Json.Decode.Pipeline exposing (optional, optionalAt, required) import Maybe.Extra exposing (isNothing) @@ -332,8 +332,3 @@ decodeNutritionReportTableType = _ -> fail <| tableType ++ " is unknown NutritionReportTableType type" ) - - -decodeWithFallback : a -> Decoder a -> Decoder a -decodeWithFallback fallback decoder = - oneOf [ decoder, succeed fallback ] diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index fb5b387966..098957e119 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -36,4 +36,8 @@ view language currentDate themePath modelBackend model = viewCompletionData : Language -> NominalDate -> String -> CompletionData -> Model -> Html Msg viewCompletionData language currentDate themePath data model = + let + _ = + Debug.log "" data + in text "viewCompletionData" diff --git a/server/elm/src/Pages/CompletionMenu/View.elm b/server/elm/src/Pages/CompletionMenu/View.elm index 9e6312905a..22abc5c66c 100644 --- a/server/elm/src/Pages/CompletionMenu/View.elm +++ b/server/elm/src/Pages/CompletionMenu/View.elm @@ -60,7 +60,7 @@ viewMenu language themePath data model = (\populationSelection -> case populationSelection of SelectionOptionGlobal -> - ( [], viewLoadDataButton language "/admin/completion/completion/all" SelectionMade ) + ( [], viewLoadDataButton language "/admin/reports/completion/all" SelectionMade ) SelectionOptionHealthCenter -> let @@ -80,7 +80,7 @@ viewMenu language themePath data model = , Maybe.map (\selectedHealthCenter -> viewLoadDataButton language - ("/admin/completion/completion/health-center/" ++ String.fromInt selectedHealthCenter) + ("/admin/reports/completion/health-center/" ++ String.fromInt selectedHealthCenter) SelectionMade ) model.selectedHealthCenter diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index fd1aa2b326..4908219993 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -6720,368 +6720,99 @@ var $author$project$Backend$Types$BackendReturn = F4( function (model, cmd, error, appMsgs) { return {appMsgs: appMsgs, cmd: cmd, error: error, model: model}; }); -var $author$project$Backend$Completion$Model$CompletionData = F3( - function (site, entityName, entityType) { - return {entityName: entityName, entityType: entityType, site: site}; +var $author$project$Backend$Completion$Model$CompletionData = F4( + function (site, entityName, entityType, nutritionIndividualData) { + return {entityName: entityName, entityType: entityType, nutritionIndividualData: nutritionIndividualData, site: site}; }); -var $author$project$Backend$Completion$Model$EntityGlobal = {$: 'EntityGlobal'}; -var $author$project$Backend$Completion$Model$EntityHealthCenter = {$: 'EntityHealthCenter'}; +var $author$project$Backend$Completion$Model$EncounterData = F4( + function (startDate, expectedActivities, completedActivities, takenBy) { + return {completedActivities: completedActivities, expectedActivities: expectedActivities, startDate: startDate, takenBy: takenBy}; + }); +var $author$project$Backend$Completion$Model$TakenByUnknown = {$: 'TakenByUnknown'}; +var $author$project$Backend$Completion$Model$TakenByCHW = {$: 'TakenByCHW'}; +var $author$project$Backend$Completion$Model$TakenByNurse = {$: 'TakenByNurse'}; var $elm$json$Json$Decode$fail = _Json_fail; var $elm$json$Json$Decode$string = _Json_decodeString; -var $author$project$Backend$Completion$Decoder$decodeSelectedEntity = A2( +var $author$project$Backend$Completion$Decoder$decodeTakenBy = A2( $elm$json$Json$Decode$andThen, - function (entityType) { - switch (entityType) { - case 'global': - return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EntityGlobal); - case 'health-center': - return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EntityHealthCenter); + function (takenBy) { + switch (takenBy) { + case 'nurse': + return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$TakenByNurse); + case 'chw': + return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$TakenByCHW); + case 'unknown': + return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$TakenByUnknown); default: - return $elm$json$Json$Decode$fail(entityType + ' is unknown SelectedEntity type'); + return $elm$json$Json$Decode$fail(takenBy + ' is unknown TakenBy type'); } }, $elm$json$Json$Decode$string); -var $author$project$App$Types$SiteBurundi = {$: 'SiteBurundi'}; -var $author$project$App$Types$SiteRwanda = {$: 'SiteRwanda'}; -var $author$project$App$Types$SiteUnknown = {$: 'SiteUnknown'}; -var $elm$core$String$toLower = _String_toLower; -var $author$project$Backend$Decoder$siteFromString = function (str) { - var _v0 = $elm$core$String$toLower(str); - switch (_v0) { - case 'rwanda': - return $author$project$App$Types$SiteRwanda; - case 'burundi': - return $author$project$App$Types$SiteBurundi; - default: - return $author$project$App$Types$SiteUnknown; - } -}; -var $author$project$Backend$Decoder$decodeSite = A2( - $elm$json$Json$Decode$andThen, - A2($elm$core$Basics$composeR, $author$project$Backend$Decoder$siteFromString, $elm$json$Json$Decode$succeed), - $elm$json$Json$Decode$string); -var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom = $elm$json$Json$Decode$map2($elm$core$Basics$apR); -var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required = F3( - function (key, valDecoder, decoder) { - return A2( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom, - A2($elm$json$Json$Decode$field, key, valDecoder), - decoder); +var $elm$json$Json$Decode$oneOf = _Json_oneOf; +var $author$project$Backend$Decoder$decodeWithFallback = F2( + function (fallback, decoder) { + return $elm$json$Json$Decode$oneOf( + _List_fromArray( + [ + decoder, + $elm$json$Json$Decode$succeed(fallback) + ])); }); -var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_type', - $author$project$Backend$Completion$Decoder$decodeSelectedEntity, - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_name', - $elm$json$Json$Decode$string, - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'site', - $author$project$Backend$Decoder$decodeSite, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData)))); -var $elm$json$Json$Decode$decodeValue = _Json_run; -var $author$project$Backend$Completion$Update$update = F3( - function (currentDate, msg, model) { - var value = msg.a; - var modelUpdated = _Utils_update( - model, - { - completionData: $elm$core$Maybe$Just( - A2($elm$json$Json$Decode$decodeValue, $author$project$Backend$Completion$Decoder$decodeCompletionData, value)) - }); - return A4($author$project$Backend$Types$BackendReturn, modelUpdated, $elm$core$Platform$Cmd$none, $author$project$Error$Utils$noError, _List_Nil); +var $elm$core$Basics$composeL = F3( + function (g, f, x) { + return g( + f(x)); }); -var $author$project$Backend$CompletionMenu$Model$MenuData = F2( - function (site, healthCenters) { - return {healthCenters: healthCenters, site: site}; +var $elm$parser$Parser$Advanced$Bad = F2( + function (a, b) { + return {$: 'Bad', a: a, b: b}; }); -var $author$project$Backend$Components$Model$HealthCenterData = F2( - function (id, name) { - return {id: id, name: name}; +var $elm$parser$Parser$Advanced$Good = F3( + function (a, b, c) { + return {$: 'Good', a: a, b: b, c: c}; }); -var $elm$json$Json$Decode$int = _Json_decodeInt; -var $elm$json$Json$Decode$oneOf = _Json_oneOf; -var $author$project$Gizra$Json$decodeInt = $elm$json$Json$Decode$oneOf( - _List_fromArray( - [ - $elm$json$Json$Decode$int, - A2( - $elm$json$Json$Decode$andThen, - function (s) { - var _v0 = $elm$core$String$toInt(s); - if (_v0.$ === 'Just') { - var value = _v0.a; - return $elm$json$Json$Decode$succeed(value); +var $elm$parser$Parser$Advanced$Parser = function (a) { + return {$: 'Parser', a: a}; +}; +var $elm$parser$Parser$Advanced$andThen = F2( + function (callback, _v0) { + var parseA = _v0.a; + return $elm$parser$Parser$Advanced$Parser( + function (s0) { + var _v1 = parseA(s0); + if (_v1.$ === 'Bad') { + var p = _v1.a; + var x = _v1.b; + return A2($elm$parser$Parser$Advanced$Bad, p, x); } else { - return $elm$json$Json$Decode$fail('Not an integer'); + var p1 = _v1.a; + var a = _v1.b; + var s1 = _v1.c; + var _v2 = callback(a); + var parseB = _v2.a; + var _v3 = parseB(s1); + if (_v3.$ === 'Bad') { + var p2 = _v3.a; + var x = _v3.b; + return A2($elm$parser$Parser$Advanced$Bad, p1 || p2, x); + } else { + var p2 = _v3.a; + var b = _v3.b; + var s2 = _v3.c; + return A3($elm$parser$Parser$Advanced$Good, p1 || p2, b, s2); + } } - }, - $elm$json$Json$Decode$string) - ])); -var $author$project$Backend$Components$Decoder$decodeHealthCenterData = A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'name', - $elm$json$Json$Decode$string, - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'id', - $author$project$Gizra$Json$decodeInt, - $elm$json$Json$Decode$succeed($author$project$Backend$Components$Model$HealthCenterData))); -var $elm$json$Json$Decode$list = _Json_decodeList; -var $author$project$Backend$CompletionMenu$Decoder$decodeMenuData = A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'health_centers', - $elm$json$Json$Decode$list($author$project$Backend$Components$Decoder$decodeHealthCenterData), - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'site', - $author$project$Backend$Decoder$decodeSite, - $elm$json$Json$Decode$succeed($author$project$Backend$CompletionMenu$Model$MenuData))); -var $author$project$Backend$CompletionMenu$Update$update = F3( - function (currentDate, msg, model) { - var value = msg.a; - var modelUpdated = _Utils_update( - model, - { - completionMenuData: $elm$core$Maybe$Just( - A2($elm$json$Json$Decode$decodeValue, $author$project$Backend$CompletionMenu$Decoder$decodeMenuData, value)) }); - return A4($author$project$Backend$Types$BackendReturn, modelUpdated, $elm$core$Platform$Cmd$none, $author$project$Error$Utils$noError, _List_Nil); }); -var $author$project$Backend$Reports$Model$ReportsData = F5( - function (site, entityName, entityType, records, nutritionReportData) { - return {entityName: entityName, entityType: entityType, nutritionReportData: nutritionReportData, records: records, site: site}; +var $elm$parser$Parser$andThen = $elm$parser$Parser$Advanced$andThen; +var $elm$parser$Parser$UnexpectedChar = {$: 'UnexpectedChar'}; +var $elm$parser$Parser$Advanced$AddRight = F2( + function (a, b) { + return {$: 'AddRight', a: a, b: b}; }); -var $author$project$Backend$Reports$Model$BackendGeneratedNutritionReportTableDate = F8( - function (tableType, captions, stuntingModerate, stuntingSevere, wastingModerate, wastingSevere, underweightModerate, underweightSevere) { - return {captions: captions, stuntingModerate: stuntingModerate, stuntingSevere: stuntingSevere, tableType: tableType, underweightModerate: underweightModerate, underweightSevere: underweightSevere, wastingModerate: wastingModerate, wastingSevere: wastingSevere}; - }); -var $author$project$Backend$Reports$Model$NutritionTableIncidenceMonthOneOrMore = {$: 'NutritionTableIncidenceMonthOneOrMore'}; -var $author$project$Backend$Reports$Model$NutritionTableIncidenceMonthTwoOrMore = {$: 'NutritionTableIncidenceMonthTwoOrMore'}; -var $author$project$Backend$Reports$Model$NutritionTableIncidenceQuarterOneOrMore = {$: 'NutritionTableIncidenceQuarterOneOrMore'}; -var $author$project$Backend$Reports$Model$NutritionTableIncidenceQuarterTwoOrMore = {$: 'NutritionTableIncidenceQuarterTwoOrMore'}; -var $author$project$Backend$Reports$Model$NutritionTableIncidenceYearOneOrMore = {$: 'NutritionTableIncidenceYearOneOrMore'}; -var $author$project$Backend$Reports$Model$NutritionTableIncidenceYearTwoOrMore = {$: 'NutritionTableIncidenceYearTwoOrMore'}; -var $author$project$Backend$Reports$Model$NutritionTablePrevalanceOneOrMore = {$: 'NutritionTablePrevalanceOneOrMore'}; -var $author$project$Backend$Reports$Model$NutritionTablePrevalanceTwoOrMore = {$: 'NutritionTablePrevalanceTwoOrMore'}; -var $author$project$Backend$Reports$Decoder$decodeNutritionReportTableType = A2( - $elm$json$Json$Decode$andThen, - function (tableType) { - switch (tableType) { - case 'prevalence-1': - return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTablePrevalanceOneOrMore); - case 'prevalence-2': - return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTablePrevalanceTwoOrMore); - case 'incidence-month-1': - return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceMonthOneOrMore); - case 'incidence-month-2': - return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceMonthTwoOrMore); - case 'incidence-quarter-1': - return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceQuarterOneOrMore); - case 'incidence-quarter-2': - return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceQuarterTwoOrMore); - case 'incidence-year-1': - return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceYearOneOrMore); - case 'incidence-year-2': - return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceYearTwoOrMore); - default: - return $elm$json$Json$Decode$fail(tableType + ' is unknown NutritionReportTableType type'); - } - }, - $elm$json$Json$Decode$string); -var $author$project$Backend$Reports$Decoder$decodeBackendGeneratedNutritionReportTableDate = A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'underweight_severe', - $elm$json$Json$Decode$list($elm$json$Json$Decode$string), - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'underweight_moderate', - $elm$json$Json$Decode$list($elm$json$Json$Decode$string), - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'wasting_severe', - $elm$json$Json$Decode$list($elm$json$Json$Decode$string), - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'wasting_moderate', - $elm$json$Json$Decode$list($elm$json$Json$Decode$string), - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'stunting_severe', - $elm$json$Json$Decode$list($elm$json$Json$Decode$string), - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'stunting_moderate', - $elm$json$Json$Decode$list($elm$json$Json$Decode$string), - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'period', - $elm$json$Json$Decode$list($elm$json$Json$Decode$string), - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'type', - $author$project$Backend$Reports$Decoder$decodeNutritionReportTableType, - $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$BackendGeneratedNutritionReportTableDate))))))))); -var $author$project$Backend$Reports$Model$Female = {$: 'Female'}; -var $author$project$Backend$Reports$Model$PatientData = function (id) { - return function (created) { - return function (birthDate) { - return function (gender) { - return function (acuteIllnessData) { - return function (prenatalData) { - return function (homeVisitData) { - return function (wellChildData) { - return function (childScorecardData) { - return function (ncdData) { - return function (hivData) { - return function (tuberculosisData) { - return function (individualNutritionData) { - return function (groupNutritionPmtctData) { - return function (groupNutritionFbfData) { - return function (groupNutritionSorwatheData) { - return function (groupNutritionChwData) { - return function (groupNutritionAchiData) { - return {acuteIllnessData: acuteIllnessData, birthDate: birthDate, childScorecardData: childScorecardData, created: created, gender: gender, groupNutritionAchiData: groupNutritionAchiData, groupNutritionChwData: groupNutritionChwData, groupNutritionFbfData: groupNutritionFbfData, groupNutritionPmtctData: groupNutritionPmtctData, groupNutritionSorwatheData: groupNutritionSorwatheData, hivData: hivData, homeVisitData: homeVisitData, id: id, individualNutritionData: individualNutritionData, ncdData: ncdData, prenatalData: prenatalData, tuberculosisData: tuberculosisData, wellChildData: wellChildData}; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; -}; -var $author$project$Backend$Reports$Model$AcuteIllnessEncounterCHW = {$: 'AcuteIllnessEncounterCHW'}; -var $author$project$Backend$Reports$Model$AcuteIllnessEncounterData = F3( - function (startDate, encounterType, diagnosis) { - return {diagnosis: diagnosis, encounterType: encounterType, startDate: startDate}; - }); -var $author$project$Backend$Reports$Model$DiagnosisCovid19Suspect = {$: 'DiagnosisCovid19Suspect'}; -var $author$project$Backend$Reports$Model$DiagnosisFeverOfUnknownOrigin = {$: 'DiagnosisFeverOfUnknownOrigin'}; -var $author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionComplicated = {$: 'DiagnosisGastrointestinalInfectionComplicated'}; -var $author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionUncomplicated = {$: 'DiagnosisGastrointestinalInfectionUncomplicated'}; -var $author$project$Backend$Reports$Model$DiagnosisLowRiskCovid19 = {$: 'DiagnosisLowRiskCovid19'}; -var $author$project$Backend$Reports$Model$DiagnosisMalariaComplicated = {$: 'DiagnosisMalariaComplicated'}; -var $author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicated = {$: 'DiagnosisMalariaUncomplicated'}; -var $author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicatedAndPregnant = {$: 'DiagnosisMalariaUncomplicatedAndPregnant'}; -var $author$project$Backend$Reports$Model$DiagnosisPneuminialCovid19 = {$: 'DiagnosisPneuminialCovid19'}; -var $author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionComplicated = {$: 'DiagnosisRespiratoryInfectionComplicated'}; -var $author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionUncomplicated = {$: 'DiagnosisRespiratoryInfectionUncomplicated'}; -var $author$project$Backend$Reports$Model$DiagnosisSevereCovid19 = {$: 'DiagnosisSevereCovid19'}; -var $author$project$Backend$Reports$Model$DiagnosisSimpleColdAndCough = {$: 'DiagnosisSimpleColdAndCough'}; -var $author$project$Backend$Reports$Model$DiagnosisTuberculosisSuspect = {$: 'DiagnosisTuberculosisSuspect'}; -var $author$project$Backend$Reports$Model$DiagnosisUndeterminedMoreEvaluationNeeded = {$: 'DiagnosisUndeterminedMoreEvaluationNeeded'}; -var $author$project$Backend$Reports$Decoder$acuteIllnessDiagnosisFromMapping = function (mapping) { - switch (mapping) { - case 'a': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisCovid19Suspect); - case 'b': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisSevereCovid19); - case 'c': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisPneuminialCovid19); - case 'd': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisLowRiskCovid19); - case 'e': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisMalariaComplicated); - case 'f': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicated); - case 'g': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicatedAndPregnant); - case 'h': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionComplicated); - case 'i': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionUncomplicated); - case 'j': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisSimpleColdAndCough); - case 'k': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionComplicated); - case 'l': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionUncomplicated); - case 'm': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisFeverOfUnknownOrigin); - case 'n': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisUndeterminedMoreEvaluationNeeded); - case 'o': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisTuberculosisSuspect); - default: - return $elm$core$Maybe$Nothing; - } -}; -var $author$project$Backend$Reports$Model$AcuteIllnessEncounterNurse = {$: 'AcuteIllnessEncounterNurse'}; -var $author$project$Backend$Reports$Model$AcuteIllnessEncounterNurseSubsequent = {$: 'AcuteIllnessEncounterNurseSubsequent'}; -var $author$project$Backend$Reports$Decoder$acuteIllnessEncounterTypeFromString = function (encounterType) { - switch (encounterType) { - case 'nurse-encounter': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$AcuteIllnessEncounterNurse); - case 'nurse-encounter-subsequent': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$AcuteIllnessEncounterNurseSubsequent); - case 'chw-encounter': - return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$AcuteIllnessEncounterCHW); - default: - return $elm$core$Maybe$Nothing; - } -}; -var $elm$parser$Parser$Advanced$Bad = F2( - function (a, b) { - return {$: 'Bad', a: a, b: b}; - }); -var $elm$parser$Parser$Advanced$Good = F3( - function (a, b, c) { - return {$: 'Good', a: a, b: b, c: c}; - }); -var $elm$parser$Parser$Advanced$Parser = function (a) { - return {$: 'Parser', a: a}; -}; -var $elm$parser$Parser$Advanced$andThen = F2( - function (callback, _v0) { - var parseA = _v0.a; - return $elm$parser$Parser$Advanced$Parser( - function (s0) { - var _v1 = parseA(s0); - if (_v1.$ === 'Bad') { - var p = _v1.a; - var x = _v1.b; - return A2($elm$parser$Parser$Advanced$Bad, p, x); - } else { - var p1 = _v1.a; - var a = _v1.b; - var s1 = _v1.c; - var _v2 = callback(a); - var parseB = _v2.a; - var _v3 = parseB(s1); - if (_v3.$ === 'Bad') { - var p2 = _v3.a; - var x = _v3.b; - return A2($elm$parser$Parser$Advanced$Bad, p1 || p2, x); - } else { - var p2 = _v3.a; - var b = _v3.b; - var s2 = _v3.c; - return A3($elm$parser$Parser$Advanced$Good, p1 || p2, b, s2); - } - } - }); - }); -var $elm$parser$Parser$andThen = $elm$parser$Parser$Advanced$andThen; -var $elm$parser$Parser$UnexpectedChar = {$: 'UnexpectedChar'}; -var $elm$parser$Parser$Advanced$AddRight = F2( - function (a, b) { - return {$: 'AddRight', a: a, b: b}; - }); -var $elm$parser$Parser$Advanced$DeadEnd = F4( - function (row, col, problem, contextStack) { - return {col: col, contextStack: contextStack, problem: problem, row: row}; +var $elm$parser$Parser$Advanced$DeadEnd = F4( + function (row, col, problem, contextStack) { + return {col: col, contextStack: contextStack, problem: problem, row: row}; }); var $elm$parser$Parser$Advanced$Empty = {$: 'Empty'}; var $elm$parser$Parser$Advanced$fromState = F2( @@ -7606,173 +7337,571 @@ var $justinmimbs$date$Date$fromYearAndDayOfYear = function (_v0) { var wdn = doy.b; return A3($justinmimbs$date$Date$fromWeekParts, y, wn, wdn); default: - var od = doy.a; - return A2($justinmimbs$date$Date$fromOrdinalParts, y, od); + var od = doy.a; + return A2($justinmimbs$date$Date$fromOrdinalParts, y, od); + } +}; +var $justinmimbs$date$Date$int4 = A2( + $elm$parser$Parser$mapChompedString, + F2( + function (str, _v0) { + return A2( + $elm$core$Maybe$withDefault, + 0, + $elm$core$String$toInt(str)); + }), + A2( + $elm$parser$Parser$ignorer, + A2( + $elm$parser$Parser$ignorer, + A2( + $elm$parser$Parser$ignorer, + A2( + $elm$parser$Parser$ignorer, + A2( + $elm$parser$Parser$ignorer, + $elm$parser$Parser$succeed(_Utils_Tuple0), + $elm$parser$Parser$oneOf( + _List_fromArray( + [ + $elm$parser$Parser$chompIf( + function (c) { + return _Utils_eq( + c, + _Utils_chr('-')); + }), + $elm$parser$Parser$succeed(_Utils_Tuple0) + ]))), + $elm$parser$Parser$chompIf($elm$core$Char$isDigit)), + $elm$parser$Parser$chompIf($elm$core$Char$isDigit)), + $elm$parser$Parser$chompIf($elm$core$Char$isDigit)), + $elm$parser$Parser$chompIf($elm$core$Char$isDigit))); +var $elm$parser$Parser$Problem = function (a) { + return {$: 'Problem', a: a}; +}; +var $elm$parser$Parser$Advanced$problem = function (x) { + return $elm$parser$Parser$Advanced$Parser( + function (s) { + return A2( + $elm$parser$Parser$Advanced$Bad, + false, + A2($elm$parser$Parser$Advanced$fromState, s, x)); + }); +}; +var $elm$parser$Parser$problem = function (msg) { + return $elm$parser$Parser$Advanced$problem( + $elm$parser$Parser$Problem(msg)); +}; +var $justinmimbs$date$Date$resultToParser = function (result) { + if (result.$ === 'Ok') { + var x = result.a; + return $elm$parser$Parser$succeed(x); + } else { + var message = result.a; + return $elm$parser$Parser$problem(message); + } +}; +var $justinmimbs$date$Date$parser = A2( + $elm$parser$Parser$andThen, + A2($elm$core$Basics$composeR, $justinmimbs$date$Date$fromYearAndDayOfYear, $justinmimbs$date$Date$resultToParser), + A2( + $elm$parser$Parser$keeper, + A2( + $elm$parser$Parser$keeper, + $elm$parser$Parser$succeed($elm$core$Tuple$pair), + $justinmimbs$date$Date$int4), + $justinmimbs$date$Date$dayOfYear)); +var $elm$parser$Parser$DeadEnd = F3( + function (row, col, problem) { + return {col: col, problem: problem, row: row}; + }); +var $elm$parser$Parser$problemToDeadEnd = function (p) { + return A3($elm$parser$Parser$DeadEnd, p.row, p.col, p.problem); +}; +var $elm$parser$Parser$Advanced$bagToList = F2( + function (bag, list) { + bagToList: + while (true) { + switch (bag.$) { + case 'Empty': + return list; + case 'AddRight': + var bag1 = bag.a; + var x = bag.b; + var $temp$bag = bag1, + $temp$list = A2($elm$core$List$cons, x, list); + bag = $temp$bag; + list = $temp$list; + continue bagToList; + default: + var bag1 = bag.a; + var bag2 = bag.b; + var $temp$bag = bag1, + $temp$list = A2($elm$parser$Parser$Advanced$bagToList, bag2, list); + bag = $temp$bag; + list = $temp$list; + continue bagToList; + } + } + }); +var $elm$parser$Parser$Advanced$run = F2( + function (_v0, src) { + var parse = _v0.a; + var _v1 = parse( + {col: 1, context: _List_Nil, indent: 1, offset: 0, row: 1, src: src}); + if (_v1.$ === 'Good') { + var value = _v1.b; + return $elm$core$Result$Ok(value); + } else { + var bag = _v1.b; + return $elm$core$Result$Err( + A2($elm$parser$Parser$Advanced$bagToList, bag, _List_Nil)); + } + }); +var $elm$parser$Parser$run = F2( + function (parser, source) { + var _v0 = A2($elm$parser$Parser$Advanced$run, parser, source); + if (_v0.$ === 'Ok') { + var a = _v0.a; + return $elm$core$Result$Ok(a); + } else { + var problems = _v0.a; + return $elm$core$Result$Err( + A2($elm$core$List$map, $elm$parser$Parser$problemToDeadEnd, problems)); + } + }); +var $justinmimbs$date$Date$fromIsoString = A2( + $elm$core$Basics$composeR, + $elm$parser$Parser$run( + A2( + $elm$parser$Parser$keeper, + $elm$parser$Parser$succeed($elm$core$Basics$identity), + A2( + $elm$parser$Parser$ignorer, + $justinmimbs$date$Date$parser, + A2( + $elm$parser$Parser$andThen, + $justinmimbs$date$Date$resultToParser, + $elm$parser$Parser$oneOf( + _List_fromArray( + [ + A2($elm$parser$Parser$map, $elm$core$Result$Ok, $elm$parser$Parser$end), + A2( + $elm$parser$Parser$map, + $elm$core$Basics$always( + $elm$core$Result$Err('Expected a date only, not a date and time')), + $elm$parser$Parser$chompIf( + $elm$core$Basics$eq( + _Utils_chr('T')))), + $elm$parser$Parser$succeed( + $elm$core$Result$Err('Expected a date only')) + ])))))), + $elm$core$Result$mapError( + A2( + $elm$core$Basics$composeR, + $elm$core$List$head, + A2( + $elm$core$Basics$composeR, + $elm$core$Maybe$map($justinmimbs$date$Date$deadEndToString), + $elm$core$Maybe$withDefault(''))))); +var $elm_community$json_extra$Json$Decode$Extra$fromResult = function (result) { + if (result.$ === 'Ok') { + var successValue = result.a; + return $elm$json$Json$Decode$succeed(successValue); + } else { + var errorMessage = result.a; + return $elm$json$Json$Decode$fail(errorMessage); + } +}; +var $author$project$Gizra$NominalDate$decodeYYYYMMDD = A2( + $elm$json$Json$Decode$andThen, + A2($elm$core$Basics$composeL, $elm_community$json_extra$Json$Decode$Extra$fromResult, $justinmimbs$date$Date$fromIsoString), + $elm$json$Json$Decode$string); +var $elm$json$Json$Decode$null = _Json_decodeNull; +var $elm$json$Json$Decode$nullable = function (decoder) { + return $elm$json$Json$Decode$oneOf( + _List_fromArray( + [ + $elm$json$Json$Decode$null($elm$core$Maybe$Nothing), + A2($elm$json$Json$Decode$map, $elm$core$Maybe$Just, decoder) + ])); +}; +var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom = $elm$json$Json$Decode$map2($elm$core$Basics$apR); +var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required = F3( + function (key, valDecoder, decoder) { + return A2( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom, + A2($elm$json$Json$Decode$field, key, valDecoder), + decoder); + }); +var $author$project$Backend$Completion$Decoder$decodeEncounterData = function (activitiesDecoder) { + return A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'taken_by', + $elm$json$Json$Decode$nullable( + A2($author$project$Backend$Decoder$decodeWithFallback, $author$project$Backend$Completion$Model$TakenByUnknown, $author$project$Backend$Completion$Decoder$decodeTakenBy)), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'completed', + activitiesDecoder, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'expected', + activitiesDecoder, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'start_date', + $author$project$Gizra$NominalDate$decodeYYYYMMDD, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EncounterData))))); +}; +var $author$project$Backend$Completion$Model$NutritionContributingFactors = {$: 'NutritionContributingFactors'}; +var $author$project$Backend$Completion$Model$NutritionFollowUp = {$: 'NutritionFollowUp'}; +var $author$project$Backend$Completion$Model$NutritionHealthEducation = {$: 'NutritionHealthEducation'}; +var $author$project$Backend$Completion$Model$NutritionHeight = {$: 'NutritionHeight'}; +var $author$project$Backend$Completion$Model$NutritionMUAC = {$: 'NutritionMUAC'}; +var $author$project$Backend$Completion$Model$NutritionNCDA = {$: 'NutritionNCDA'}; +var $author$project$Backend$Completion$Model$NutritionNutrition = {$: 'NutritionNutrition'}; +var $author$project$Backend$Completion$Model$NutritionPhoto = {$: 'NutritionPhoto'}; +var $author$project$Backend$Completion$Model$NutritionSendToHC = {$: 'NutritionSendToHC'}; +var $author$project$Backend$Completion$Model$NutritionWeight = {$: 'NutritionWeight'}; +var $author$project$Backend$Completion$Decoder$nutritionActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHeight); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionNutrition); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionPhoto); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionWeight); + case 'e': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionMUAC); + case 'f': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionContributingFactors); + case 'g': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionFollowUp); + case 'h': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHealthEducation); + case 'i': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionSendToHC); + case 'j': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionNCDA); + default: + return $elm$core$Maybe$Nothing; + } +}; +var $author$project$Backend$Completion$Decoder$decodeNutritionActivities = A2( + $elm$json$Json$Decode$andThen, + A2( + $elm$core$Basics$composeR, + $elm$core$String$split(','), + A2( + $elm$core$Basics$composeR, + $elm$core$List$map($author$project$Backend$Completion$Decoder$nutritionActivityFromMapping), + A2($elm$core$Basics$composeR, $elm_community$maybe_extra$Maybe$Extra$values, $elm$json$Json$Decode$succeed))), + $elm$json$Json$Decode$string); +var $author$project$Backend$Completion$Model$EntityGlobal = {$: 'EntityGlobal'}; +var $author$project$Backend$Completion$Model$EntityHealthCenter = {$: 'EntityHealthCenter'}; +var $author$project$Backend$Completion$Decoder$decodeSelectedEntity = A2( + $elm$json$Json$Decode$andThen, + function (entityType) { + switch (entityType) { + case 'global': + return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EntityGlobal); + case 'health-center': + return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EntityHealthCenter); + default: + return $elm$json$Json$Decode$fail(entityType + ' is unknown SelectedEntity type'); + } + }, + $elm$json$Json$Decode$string); +var $author$project$App$Types$SiteBurundi = {$: 'SiteBurundi'}; +var $author$project$App$Types$SiteRwanda = {$: 'SiteRwanda'}; +var $author$project$App$Types$SiteUnknown = {$: 'SiteUnknown'}; +var $elm$core$String$toLower = _String_toLower; +var $author$project$Backend$Decoder$siteFromString = function (str) { + var _v0 = $elm$core$String$toLower(str); + switch (_v0) { + case 'rwanda': + return $author$project$App$Types$SiteRwanda; + case 'burundi': + return $author$project$App$Types$SiteBurundi; + default: + return $author$project$App$Types$SiteUnknown; + } +}; +var $author$project$Backend$Decoder$decodeSite = A2( + $elm$json$Json$Decode$andThen, + A2($elm$core$Basics$composeR, $author$project$Backend$Decoder$siteFromString, $elm$json$Json$Decode$succeed), + $elm$json$Json$Decode$string); +var $elm$json$Json$Decode$list = _Json_decodeList; +var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'results', + $elm$json$Json$Decode$list( + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Decoder$decodeNutritionActivities)), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'entity_type', + $author$project$Backend$Completion$Decoder$decodeSelectedEntity, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'entity_name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData))))); +var $elm$json$Json$Decode$decodeValue = _Json_run; +var $author$project$Backend$Completion$Update$update = F3( + function (currentDate, msg, model) { + var value = msg.a; + var modelUpdated = _Utils_update( + model, + { + completionData: $elm$core$Maybe$Just( + A2($elm$json$Json$Decode$decodeValue, $author$project$Backend$Completion$Decoder$decodeCompletionData, value)) + }); + return A4($author$project$Backend$Types$BackendReturn, modelUpdated, $elm$core$Platform$Cmd$none, $author$project$Error$Utils$noError, _List_Nil); + }); +var $author$project$Backend$CompletionMenu$Model$MenuData = F2( + function (site, healthCenters) { + return {healthCenters: healthCenters, site: site}; + }); +var $author$project$Backend$Components$Model$HealthCenterData = F2( + function (id, name) { + return {id: id, name: name}; + }); +var $elm$json$Json$Decode$int = _Json_decodeInt; +var $author$project$Gizra$Json$decodeInt = $elm$json$Json$Decode$oneOf( + _List_fromArray( + [ + $elm$json$Json$Decode$int, + A2( + $elm$json$Json$Decode$andThen, + function (s) { + var _v0 = $elm$core$String$toInt(s); + if (_v0.$ === 'Just') { + var value = _v0.a; + return $elm$json$Json$Decode$succeed(value); + } else { + return $elm$json$Json$Decode$fail('Not an integer'); + } + }, + $elm$json$Json$Decode$string) + ])); +var $author$project$Backend$Components$Decoder$decodeHealthCenterData = A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'id', + $author$project$Gizra$Json$decodeInt, + $elm$json$Json$Decode$succeed($author$project$Backend$Components$Model$HealthCenterData))); +var $author$project$Backend$CompletionMenu$Decoder$decodeMenuData = A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'health_centers', + $elm$json$Json$Decode$list($author$project$Backend$Components$Decoder$decodeHealthCenterData), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$CompletionMenu$Model$MenuData))); +var $author$project$Backend$CompletionMenu$Update$update = F3( + function (currentDate, msg, model) { + var value = msg.a; + var modelUpdated = _Utils_update( + model, + { + completionMenuData: $elm$core$Maybe$Just( + A2($elm$json$Json$Decode$decodeValue, $author$project$Backend$CompletionMenu$Decoder$decodeMenuData, value)) + }); + return A4($author$project$Backend$Types$BackendReturn, modelUpdated, $elm$core$Platform$Cmd$none, $author$project$Error$Utils$noError, _List_Nil); + }); +var $author$project$Backend$Reports$Model$ReportsData = F5( + function (site, entityName, entityType, records, nutritionReportData) { + return {entityName: entityName, entityType: entityType, nutritionReportData: nutritionReportData, records: records, site: site}; + }); +var $author$project$Backend$Reports$Model$BackendGeneratedNutritionReportTableDate = F8( + function (tableType, captions, stuntingModerate, stuntingSevere, wastingModerate, wastingSevere, underweightModerate, underweightSevere) { + return {captions: captions, stuntingModerate: stuntingModerate, stuntingSevere: stuntingSevere, tableType: tableType, underweightModerate: underweightModerate, underweightSevere: underweightSevere, wastingModerate: wastingModerate, wastingSevere: wastingSevere}; + }); +var $author$project$Backend$Reports$Model$NutritionTableIncidenceMonthOneOrMore = {$: 'NutritionTableIncidenceMonthOneOrMore'}; +var $author$project$Backend$Reports$Model$NutritionTableIncidenceMonthTwoOrMore = {$: 'NutritionTableIncidenceMonthTwoOrMore'}; +var $author$project$Backend$Reports$Model$NutritionTableIncidenceQuarterOneOrMore = {$: 'NutritionTableIncidenceQuarterOneOrMore'}; +var $author$project$Backend$Reports$Model$NutritionTableIncidenceQuarterTwoOrMore = {$: 'NutritionTableIncidenceQuarterTwoOrMore'}; +var $author$project$Backend$Reports$Model$NutritionTableIncidenceYearOneOrMore = {$: 'NutritionTableIncidenceYearOneOrMore'}; +var $author$project$Backend$Reports$Model$NutritionTableIncidenceYearTwoOrMore = {$: 'NutritionTableIncidenceYearTwoOrMore'}; +var $author$project$Backend$Reports$Model$NutritionTablePrevalanceOneOrMore = {$: 'NutritionTablePrevalanceOneOrMore'}; +var $author$project$Backend$Reports$Model$NutritionTablePrevalanceTwoOrMore = {$: 'NutritionTablePrevalanceTwoOrMore'}; +var $author$project$Backend$Reports$Decoder$decodeNutritionReportTableType = A2( + $elm$json$Json$Decode$andThen, + function (tableType) { + switch (tableType) { + case 'prevalence-1': + return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTablePrevalanceOneOrMore); + case 'prevalence-2': + return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTablePrevalanceTwoOrMore); + case 'incidence-month-1': + return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceMonthOneOrMore); + case 'incidence-month-2': + return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceMonthTwoOrMore); + case 'incidence-quarter-1': + return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceQuarterOneOrMore); + case 'incidence-quarter-2': + return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceQuarterTwoOrMore); + case 'incidence-year-1': + return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceYearOneOrMore); + case 'incidence-year-2': + return $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$NutritionTableIncidenceYearTwoOrMore); + default: + return $elm$json$Json$Decode$fail(tableType + ' is unknown NutritionReportTableType type'); + } + }, + $elm$json$Json$Decode$string); +var $author$project$Backend$Reports$Decoder$decodeBackendGeneratedNutritionReportTableDate = A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'underweight_severe', + $elm$json$Json$Decode$list($elm$json$Json$Decode$string), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'underweight_moderate', + $elm$json$Json$Decode$list($elm$json$Json$Decode$string), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'wasting_severe', + $elm$json$Json$Decode$list($elm$json$Json$Decode$string), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'wasting_moderate', + $elm$json$Json$Decode$list($elm$json$Json$Decode$string), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'stunting_severe', + $elm$json$Json$Decode$list($elm$json$Json$Decode$string), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'stunting_moderate', + $elm$json$Json$Decode$list($elm$json$Json$Decode$string), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'period', + $elm$json$Json$Decode$list($elm$json$Json$Decode$string), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'type', + $author$project$Backend$Reports$Decoder$decodeNutritionReportTableType, + $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$BackendGeneratedNutritionReportTableDate))))))))); +var $author$project$Backend$Reports$Model$Female = {$: 'Female'}; +var $author$project$Backend$Reports$Model$PatientData = function (id) { + return function (created) { + return function (birthDate) { + return function (gender) { + return function (acuteIllnessData) { + return function (prenatalData) { + return function (homeVisitData) { + return function (wellChildData) { + return function (childScorecardData) { + return function (ncdData) { + return function (hivData) { + return function (tuberculosisData) { + return function (individualNutritionData) { + return function (groupNutritionPmtctData) { + return function (groupNutritionFbfData) { + return function (groupNutritionSorwatheData) { + return function (groupNutritionChwData) { + return function (groupNutritionAchiData) { + return {acuteIllnessData: acuteIllnessData, birthDate: birthDate, childScorecardData: childScorecardData, created: created, gender: gender, groupNutritionAchiData: groupNutritionAchiData, groupNutritionChwData: groupNutritionChwData, groupNutritionFbfData: groupNutritionFbfData, groupNutritionPmtctData: groupNutritionPmtctData, groupNutritionSorwatheData: groupNutritionSorwatheData, hivData: hivData, homeVisitData: homeVisitData, id: id, individualNutritionData: individualNutritionData, ncdData: ncdData, prenatalData: prenatalData, tuberculosisData: tuberculosisData, wellChildData: wellChildData}; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +}; +var $author$project$Backend$Reports$Model$AcuteIllnessEncounterCHW = {$: 'AcuteIllnessEncounterCHW'}; +var $author$project$Backend$Reports$Model$AcuteIllnessEncounterData = F3( + function (startDate, encounterType, diagnosis) { + return {diagnosis: diagnosis, encounterType: encounterType, startDate: startDate}; + }); +var $author$project$Backend$Reports$Model$DiagnosisCovid19Suspect = {$: 'DiagnosisCovid19Suspect'}; +var $author$project$Backend$Reports$Model$DiagnosisFeverOfUnknownOrigin = {$: 'DiagnosisFeverOfUnknownOrigin'}; +var $author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionComplicated = {$: 'DiagnosisGastrointestinalInfectionComplicated'}; +var $author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionUncomplicated = {$: 'DiagnosisGastrointestinalInfectionUncomplicated'}; +var $author$project$Backend$Reports$Model$DiagnosisLowRiskCovid19 = {$: 'DiagnosisLowRiskCovid19'}; +var $author$project$Backend$Reports$Model$DiagnosisMalariaComplicated = {$: 'DiagnosisMalariaComplicated'}; +var $author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicated = {$: 'DiagnosisMalariaUncomplicated'}; +var $author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicatedAndPregnant = {$: 'DiagnosisMalariaUncomplicatedAndPregnant'}; +var $author$project$Backend$Reports$Model$DiagnosisPneuminialCovid19 = {$: 'DiagnosisPneuminialCovid19'}; +var $author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionComplicated = {$: 'DiagnosisRespiratoryInfectionComplicated'}; +var $author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionUncomplicated = {$: 'DiagnosisRespiratoryInfectionUncomplicated'}; +var $author$project$Backend$Reports$Model$DiagnosisSevereCovid19 = {$: 'DiagnosisSevereCovid19'}; +var $author$project$Backend$Reports$Model$DiagnosisSimpleColdAndCough = {$: 'DiagnosisSimpleColdAndCough'}; +var $author$project$Backend$Reports$Model$DiagnosisTuberculosisSuspect = {$: 'DiagnosisTuberculosisSuspect'}; +var $author$project$Backend$Reports$Model$DiagnosisUndeterminedMoreEvaluationNeeded = {$: 'DiagnosisUndeterminedMoreEvaluationNeeded'}; +var $author$project$Backend$Reports$Decoder$acuteIllnessDiagnosisFromMapping = function (mapping) { + switch (mapping) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisCovid19Suspect); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisSevereCovid19); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisPneuminialCovid19); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisLowRiskCovid19); + case 'e': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisMalariaComplicated); + case 'f': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicated); + case 'g': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicatedAndPregnant); + case 'h': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionComplicated); + case 'i': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionUncomplicated); + case 'j': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisSimpleColdAndCough); + case 'k': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionComplicated); + case 'l': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionUncomplicated); + case 'm': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisFeverOfUnknownOrigin); + case 'n': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisUndeterminedMoreEvaluationNeeded); + case 'o': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$DiagnosisTuberculosisSuspect); + default: + return $elm$core$Maybe$Nothing; } }; -var $justinmimbs$date$Date$int4 = A2( - $elm$parser$Parser$mapChompedString, - F2( - function (str, _v0) { - return A2( - $elm$core$Maybe$withDefault, - 0, - $elm$core$String$toInt(str)); - }), - A2( - $elm$parser$Parser$ignorer, - A2( - $elm$parser$Parser$ignorer, - A2( - $elm$parser$Parser$ignorer, - A2( - $elm$parser$Parser$ignorer, - A2( - $elm$parser$Parser$ignorer, - $elm$parser$Parser$succeed(_Utils_Tuple0), - $elm$parser$Parser$oneOf( - _List_fromArray( - [ - $elm$parser$Parser$chompIf( - function (c) { - return _Utils_eq( - c, - _Utils_chr('-')); - }), - $elm$parser$Parser$succeed(_Utils_Tuple0) - ]))), - $elm$parser$Parser$chompIf($elm$core$Char$isDigit)), - $elm$parser$Parser$chompIf($elm$core$Char$isDigit)), - $elm$parser$Parser$chompIf($elm$core$Char$isDigit)), - $elm$parser$Parser$chompIf($elm$core$Char$isDigit))); -var $elm$parser$Parser$Problem = function (a) { - return {$: 'Problem', a: a}; -}; -var $elm$parser$Parser$Advanced$problem = function (x) { - return $elm$parser$Parser$Advanced$Parser( - function (s) { - return A2( - $elm$parser$Parser$Advanced$Bad, - false, - A2($elm$parser$Parser$Advanced$fromState, s, x)); - }); -}; -var $elm$parser$Parser$problem = function (msg) { - return $elm$parser$Parser$Advanced$problem( - $elm$parser$Parser$Problem(msg)); -}; -var $justinmimbs$date$Date$resultToParser = function (result) { - if (result.$ === 'Ok') { - var x = result.a; - return $elm$parser$Parser$succeed(x); - } else { - var message = result.a; - return $elm$parser$Parser$problem(message); +var $author$project$Backend$Reports$Model$AcuteIllnessEncounterNurse = {$: 'AcuteIllnessEncounterNurse'}; +var $author$project$Backend$Reports$Model$AcuteIllnessEncounterNurseSubsequent = {$: 'AcuteIllnessEncounterNurseSubsequent'}; +var $author$project$Backend$Reports$Decoder$acuteIllnessEncounterTypeFromString = function (encounterType) { + switch (encounterType) { + case 'nurse-encounter': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$AcuteIllnessEncounterNurse); + case 'nurse-encounter-subsequent': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$AcuteIllnessEncounterNurseSubsequent); + case 'chw-encounter': + return $elm$core$Maybe$Just($author$project$Backend$Reports$Model$AcuteIllnessEncounterCHW); + default: + return $elm$core$Maybe$Nothing; } }; -var $justinmimbs$date$Date$parser = A2( - $elm$parser$Parser$andThen, - A2($elm$core$Basics$composeR, $justinmimbs$date$Date$fromYearAndDayOfYear, $justinmimbs$date$Date$resultToParser), - A2( - $elm$parser$Parser$keeper, - A2( - $elm$parser$Parser$keeper, - $elm$parser$Parser$succeed($elm$core$Tuple$pair), - $justinmimbs$date$Date$int4), - $justinmimbs$date$Date$dayOfYear)); -var $elm$parser$Parser$DeadEnd = F3( - function (row, col, problem) { - return {col: col, problem: problem, row: row}; - }); -var $elm$parser$Parser$problemToDeadEnd = function (p) { - return A3($elm$parser$Parser$DeadEnd, p.row, p.col, p.problem); -}; -var $elm$parser$Parser$Advanced$bagToList = F2( - function (bag, list) { - bagToList: - while (true) { - switch (bag.$) { - case 'Empty': - return list; - case 'AddRight': - var bag1 = bag.a; - var x = bag.b; - var $temp$bag = bag1, - $temp$list = A2($elm$core$List$cons, x, list); - bag = $temp$bag; - list = $temp$list; - continue bagToList; - default: - var bag1 = bag.a; - var bag2 = bag.b; - var $temp$bag = bag1, - $temp$list = A2($elm$parser$Parser$Advanced$bagToList, bag2, list); - bag = $temp$bag; - list = $temp$list; - continue bagToList; - } - } - }); -var $elm$parser$Parser$Advanced$run = F2( - function (_v0, src) { - var parse = _v0.a; - var _v1 = parse( - {col: 1, context: _List_Nil, indent: 1, offset: 0, row: 1, src: src}); - if (_v1.$ === 'Good') { - var value = _v1.b; - return $elm$core$Result$Ok(value); - } else { - var bag = _v1.b; - return $elm$core$Result$Err( - A2($elm$parser$Parser$Advanced$bagToList, bag, _List_Nil)); - } - }); -var $elm$parser$Parser$run = F2( - function (parser, source) { - var _v0 = A2($elm$parser$Parser$Advanced$run, parser, source); - if (_v0.$ === 'Ok') { - var a = _v0.a; - return $elm$core$Result$Ok(a); - } else { - var problems = _v0.a; - return $elm$core$Result$Err( - A2($elm$core$List$map, $elm$parser$Parser$problemToDeadEnd, problems)); - } - }); -var $justinmimbs$date$Date$fromIsoString = A2( - $elm$core$Basics$composeR, - $elm$parser$Parser$run( - A2( - $elm$parser$Parser$keeper, - $elm$parser$Parser$succeed($elm$core$Basics$identity), - A2( - $elm$parser$Parser$ignorer, - $justinmimbs$date$Date$parser, - A2( - $elm$parser$Parser$andThen, - $justinmimbs$date$Date$resultToParser, - $elm$parser$Parser$oneOf( - _List_fromArray( - [ - A2($elm$parser$Parser$map, $elm$core$Result$Ok, $elm$parser$Parser$end), - A2( - $elm$parser$Parser$map, - $elm$core$Basics$always( - $elm$core$Result$Err('Expected a date only, not a date and time')), - $elm$parser$Parser$chompIf( - $elm$core$Basics$eq( - _Utils_chr('T')))), - $elm$parser$Parser$succeed( - $elm$core$Result$Err('Expected a date only')) - ])))))), - $elm$core$Result$mapError( - A2( - $elm$core$Basics$composeR, - $elm$core$List$head, - A2( - $elm$core$Basics$composeR, - $elm$core$Maybe$map($justinmimbs$date$Date$deadEndToString), - $elm$core$Maybe$withDefault(''))))); var $elm$core$Result$toMaybe = function (result) { if (result.$ === 'Ok') { var v = result.a; @@ -8018,33 +8147,6 @@ var $author$project$Backend$Reports$Decoder$decodePrenatalEncounterData = A2( return $elm$json$Json$Decode$fail('Failed to decode PrenatalEncounterData'); }, $elm$json$Json$Decode$string); -var $elm$core$Basics$composeL = F3( - function (g, f, x) { - return g( - f(x)); - }); -var $elm_community$json_extra$Json$Decode$Extra$fromResult = function (result) { - if (result.$ === 'Ok') { - var successValue = result.a; - return $elm$json$Json$Decode$succeed(successValue); - } else { - var errorMessage = result.a; - return $elm$json$Json$Decode$fail(errorMessage); - } -}; -var $author$project$Gizra$NominalDate$decodeYYYYMMDD = A2( - $elm$json$Json$Decode$andThen, - A2($elm$core$Basics$composeL, $elm_community$json_extra$Json$Decode$Extra$fromResult, $justinmimbs$date$Date$fromIsoString), - $elm$json$Json$Decode$string); -var $elm$json$Json$Decode$null = _Json_decodeNull; -var $elm$json$Json$Decode$nullable = function (decoder) { - return $elm$json$Json$Decode$oneOf( - _List_fromArray( - [ - $elm$json$Json$Decode$null($elm$core$Maybe$Nothing), - A2($elm$json$Json$Decode$map, $elm$core$Maybe$Just, decoder) - ])); -}; var $elm$json$Json$Decode$value = _Json_decodeValue; var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalDecoder = F3( function (pathDecoder, valDecoder, fallback) { @@ -8108,15 +8210,6 @@ var $author$project$Backend$Reports$Decoder$decodePrenatalParticipantData = A3( 'created', $author$project$Gizra$NominalDate$decodeYYYYMMDD, $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$PrenatalParticipantData))))); -var $author$project$Backend$Reports$Decoder$decodeWithFallback = F2( - function (fallback, decoder) { - return $elm$json$Json$Decode$oneOf( - _List_fromArray( - [ - decoder, - $elm$json$Json$Decode$succeed(fallback) - ])); - }); var $elm$json$Json$Decode$at = F2( function (fields, decoder) { return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields); @@ -8241,7 +8334,7 @@ var $author$project$Backend$Reports$Decoder$decodePatientData = A4( A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, 'gender', - A2($author$project$Backend$Reports$Decoder$decodeWithFallback, $author$project$Backend$Reports$Model$Female, $author$project$Backend$Reports$Decoder$decodeGender), + A2($author$project$Backend$Decoder$decodeWithFallback, $author$project$Backend$Reports$Model$Female, $author$project$Backend$Reports$Decoder$decodeGender), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, 'birth_date', @@ -10292,8 +10385,10 @@ var $author$project$Error$View$view = F2( }); var $author$project$Gizra$Html$emptyNode = $elm$html$Html$text(''); var $elm$core$Debug$toString = _Debug_toString; +var $elm$core$Debug$log = _Debug_log; var $author$project$Pages$Completion$View$viewCompletionData = F5( function (language, currentDate, themePath, data, model) { + var _v0 = A2($elm$core$Debug$log, '', data); return $elm$html$Html$text('viewCompletionData'); }); var $author$project$Pages$Completion$View$view = F5( @@ -10570,7 +10665,7 @@ var $author$project$Pages$CompletionMenu$View$viewMenu = F4( case 'SelectionOptionGlobal': return _Utils_Tuple2( _List_Nil, - A3($author$project$Pages$Utils$viewLoadDataButton, language, '/admin/completion/completion/all', $author$project$Pages$CompletionMenu$Model$SelectionMade)); + A3($author$project$Pages$Utils$viewLoadDataButton, language, '/admin/reports/completion/all', $author$project$Pages$CompletionMenu$Model$SelectionMade)); case 'SelectionOptionHealthCenter': var options = A2( $elm$core$List$map, @@ -10602,7 +10697,7 @@ var $author$project$Pages$CompletionMenu$View$viewMenu = F4( return A3( $author$project$Pages$Utils$viewLoadDataButton, language, - '/admin/completion/completion/health-center/' + $elm$core$String$fromInt(selectedHealthCenter), + '/admin/reports/completion/health-center/' + $elm$core$String$fromInt(selectedHealthCenter), $author$project$Pages$CompletionMenu$Model$SelectionMade); }, model.selectedHealthCenter))); diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 30c59ae94f..1b2e7b9d36 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -88,6 +88,23 @@ function hedley_reports_menu() { 'access callback' => 'hedley_reports_statistical_queries_report_access', ); + $items['admin/reports/completion/all'] = array( + 'title' => 'Entire Population', + 'description' => 'View Completion report for Entire Population', + 'page callback' => 'hedley_reports_completion_report_callback_global', + // @todo : what access do we need here? + 'access callback' => 'hedley_reports_statistical_queries_report_access', + ); + + $items['admin/reports/completion/health-center/%'] = array( + 'title' => 'Health center', + 'description' => 'View Completion report for health center', + 'page callback' => 'hedley_reports_completion_report_callback_health_center', + 'page arguments' => [4], + // @todo : what access do we need here? + 'access callback' => 'hedley_reports_statistical_queries_report_access', + ); + return $items; } @@ -597,7 +614,7 @@ function hedley_reports_nutrition_metrics_to_string($values) { * The HTML markup for the Elm application. */ function hedley_reports_statistical_queries_report_callback_global() { - return hedley_reports_build_results_app(); + return hedley_reports_build_statistical_queries_results_app(); } /** @@ -610,7 +627,7 @@ function hedley_reports_statistical_queries_report_callback_global() { * The HTML markup for the Elm application. */ function hedley_reports_statistical_queries_report_callback_province($province) { - return hedley_reports_build_results_app($province); + return hedley_reports_build_statistical_queries_results_app($province); } /** @@ -625,7 +642,7 @@ function hedley_reports_statistical_queries_report_callback_province($province) * The HTML markup for the Elm application. */ function hedley_reports_statistical_queries_report_callback_district($province, $district) { - return hedley_reports_build_results_app($province, $district); + return hedley_reports_build_statistical_queries_results_app($province, $district); } /** @@ -642,7 +659,7 @@ function hedley_reports_statistical_queries_report_callback_district($province, * The HTML markup for the Elm application. */ function hedley_reports_statistical_queries_report_callback_sector($province, $district, $sector) { - return hedley_reports_build_results_app($province, $district, $sector); + return hedley_reports_build_statistical_queries_results_app($province, $district, $sector); } /** @@ -661,7 +678,7 @@ function hedley_reports_statistical_queries_report_callback_sector($province, $d * The HTML markup for the Elm application. */ function hedley_reports_statistical_queries_report_callback_cell($province, $district, $sector, $cell) { - return hedley_reports_build_results_app($province, $district, $sector, $cell); + return hedley_reports_build_statistical_queries_results_app($province, $district, $sector, $cell); } /** @@ -682,7 +699,7 @@ function hedley_reports_statistical_queries_report_callback_cell($province, $dis * The HTML markup for the Elm application. */ function hedley_reports_statistical_queries_report_callback_village($province, $district, $sector, $cell, $village) { - return hedley_reports_build_results_app($province, $district, $sector, $cell, $village); + return hedley_reports_build_statistical_queries_results_app($province, $district, $sector, $cell, $village); } /** @@ -695,7 +712,7 @@ function hedley_reports_statistical_queries_report_callback_village($province, $ * The HTML markup for the Elm application. */ function hedley_reports_statistical_queries_report_callback_health_center($health_center) { - return hedley_reports_build_results_app(NULL, NULL, NULL, NULL, NULL, $health_center); + return hedley_reports_build_statistical_queries_results_app(NULL, NULL, NULL, NULL, NULL, $health_center); } /** @@ -720,7 +737,7 @@ function hedley_reports_statistical_queries_report_callback_health_center($healt * @return string * The HTML markup for the Elm application. */ -function hedley_reports_build_results_app($province = NULL, $district = NULL, $sector = NULL, $cell = NULL, $village = NULL, $health_center = NULL) { +function hedley_reports_build_statistical_queries_results_app($province = NULL, $district = NULL, $sector = NULL, $cell = NULL, $village = NULL, $health_center = NULL) { $data = []; if (empty($province)) { @@ -1894,7 +1911,126 @@ function hedley_reports_completion_report_callback_menu() { return hedley_reports_callback_menu_by_page('completion-menu'); } -function hedley_reports_generate_completion_data_for_nutrition_encounter($encounter, $nurses) { +/** + * Callback for Completion report of all patients. + * + * @return string + * The HTML markup for the Elm application. + */ +function hedley_reports_completion_report_callback_global() { + return hedley_reports_build_completion_results_app(); +} + +/** + * Callback for Completion report of health center. + * + * @param int $health_center + * Health center ID. + * + * @return string + * The HTML markup for the Elm application. + */ +function hedley_reports_completion_report_callback_health_center($health_center) { + return hedley_reports_build_completion_results_app($health_center); +} + +/** + * Build results app for Completion Report. + * + * Based on input fields, determines administrative divisions for which + * data is provided. + * + * @param int|null $health_center + * Health center ID (optional). + * + * @return string + * The HTML markup for the Elm application. + */ +function hedley_reports_build_completion_results_app($health_center = NULL) { + $data = []; + + if (empty($health_center)) { + $data['entity_name'] = 'Global'; + $data['entity_type'] = 'global'; + } + else { + $wrapper = entity_metadata_wrapper('node', $health_center); + $data['entity_name'] = $wrapper->label(); + $data['entity_type'] = 'health-center'; + } + + $data['site'] = variable_get('hedley_general_site_name', ''); + + $data['results'] = hedley_reports_generate_completion_results_data($health_center); + + return hedley_general_build_elm_app('completion-results', $data); +} + +/** + * Generate Completion report data which is stored on person nodes. + * + * @param int|null $health_center + * Health center ID. + * + * @return array + * An array of generated data. + */ +function hedley_reports_generate_completion_results_data($health_center) { + $base_query = new EntityFieldQuery(); + $base_query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'nutrition_encounter') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_reports_data', 'value', NULL, 'IS NOT NULL') + ->propertyOrderBy('nid'); + + if (!empty($health_center)) { + $base_query->fieldCondition('field_shards', 'target_id', $health_center); + } + + $data = []; + $nid = 0; + $batch = 400; + while (TRUE) { + // Free up memory. + drupal_static_reset(); + + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + $json_data = $node->field_reports_data[LANGUAGE_NONE][0]['value']; + if (empty($json_data)) { + continue; + } + + $data[] = json_decode($json_data); + // Explicitly unset large variables after use for memory optimization. + unset($json_data); + } + + $nid = end($ids); + // Explicitly unset large variables after use for memory optimization. + unset($nodes); + } + + return $data; +} + +function hedley_reports_generate_completion_data_for_nutrition_encounter($encounter) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ 'nutrition_height' => 'a', @@ -1919,7 +2055,9 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun $completed = []; // Was encounter recorded by nurse or CHW? - $taken_by = $encounter->field_nutrition_encounter_type[LANGUAGE_NONE][0]['value']; + $taken_by = $encounter->field_nutrition_encounter_type[LANGUAGE_NONE][0]['value']; + // Resolve encounter start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; // Loading all measurements that belong to encounter. $query = db_select('field_data_field_nutrition_encounter', 'ne'); @@ -1928,7 +2066,7 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun $measurements_ids = $query->execute()->fetchCol(); if (empty($measurements_ids)) { - return hedley_reports_generate_completion_result($expected, $completed, $taken_by, $mapping); + return hedley_reports_generate_completion_result($expected, $completed, $start_date, $taken_by, $mapping); } // Try to resolve age in months at a time encounter was performed. @@ -1943,12 +2081,11 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun // Get birthdate and date measured. $birth_date = explode(' ', $person->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; - $date_measured = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; // Calculate age in months. $birth_date_obj = new DateTime($birth_date); - $date_measured_obj = new DateTime($date_measured); - $interval = $date_measured_obj->diff($birth_date_obj); + $start_date_obj = new DateTime($start_date); + $interval = $start_date_obj->diff($birth_date_obj); $age_in_months = ($interval->y * 12) + $interval->m; } catch (Exception $e) { $age_in_months = NULL; @@ -1996,7 +2133,7 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun $ncda_launch_date = '2023-11-20'; $ncda_launch_date_obj = new DateTime($ncda_launch_date); - if ($ncda_enabled && $date_measured >= $ncda_launch_date_obj && ($taken_by == 'nurse') && isset($age_in_months) && $age_in_months < 24) { + if ($ncda_enabled && $start_date >= $ncda_launch_date_obj && ($taken_by == 'nurse') && isset($age_in_months) && $age_in_months < 24) { $expected[] = 'nutrition_ncda'; } @@ -2006,10 +2143,10 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun } } - return hedley_reports_generate_completion_result($expected, $completed, $taken_by, $mapping); + return hedley_reports_generate_completion_result($expected, $completed, $start_date, $taken_by, $mapping); } -function hedley_reports_generate_completion_result($expected, $completed, $taken_by, $mapping) { +function hedley_reports_generate_completion_result($expected, $completed, $start_date, $taken_by, $mapping) { foreach ($expected as $index => $measurement_type) { $expected[$index] = $mapping[$measurement_type]; } @@ -2019,6 +2156,7 @@ function hedley_reports_generate_completion_result($expected, $completed, $taken } return [ + 'start_date' => $start_date, 'expected' => implode(',', $expected), 'completed' => implode(',', $completed), 'taken_by' => $taken_by, diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php index a8fed831d7..119aa749a4 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php @@ -45,6 +45,7 @@ exit; } +// @todo: do we need this? $nurses = hedley_ncda_resolve_nurses_ids(); $total = 0; @@ -68,7 +69,7 @@ $ids = array_keys($result['node']); $nodes = node_load_multiple($ids); foreach ($nodes as $node) { - $completion_data = hedley_reports_generate_completion_data_for_nutrition_encounter($node, $nurses); + $completion_data = hedley_reports_generate_completion_data_for_nutrition_encounter($node); $node->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); node_save($node); $total++; From 0642ff275ee82795f682a3b466537a8e65b8f41e Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 15 Aug 2024 16:22:16 +0300 Subject: [PATCH 008/185] Display results [ci skip] --- server/elm/src/Pages/Completion/Model.elm | 17 + server/elm/src/Pages/Completion/View.elm | 88 +- server/elm/src/Pages/Reports/Model.elm | 7 - server/elm/src/Pages/Reports/View.elm | 38 +- server/elm/src/Pages/Utils.elm | 30 + server/elm/src/Translate.elm | 92 ++ .../modules/custom/hedley_general/css/elm.css | 14 +- .../custom/hedley_general/js/elm-main.js | 811 +++++++++++------- 8 files changed, 748 insertions(+), 349 deletions(-) diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index 254477f456..aa9bea9d33 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -1,5 +1,7 @@ module Pages.Completion.Model exposing (..) +import Backend.Completion.Model exposing (NutritionActivity(..)) + type alias Model = {} @@ -12,3 +14,18 @@ emptyModel = type Msg = NoOp + + +allNutritionActivities : List NutritionActivity +allNutritionActivities = + [ NutritionHeight + , NutritionNutrition + , NutritionPhoto + , NutritionWeight + , NutritionMUAC + , NutritionContributingFactors + , NutritionFollowUp + , NutritionHealthEducation + , NutritionSendToHC + , NutritionNCDA + ] diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index 098957e119..efbdde7383 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -2,7 +2,7 @@ module Pages.Completion.View exposing (view) import App.Types exposing (Language, Site) import AssocList as Dict exposing (Dict) -import Backend.Completion.Model exposing (CompletionData) +import Backend.Completion.Model exposing (CompletionData, EncounterData, NutritionActivity(..), SelectedEntity(..)) import Backend.Model exposing (ModelBackend) import Date exposing (Interval(..), Unit(..)) import DateSelector.SelectorPopup exposing (viewCalendarPopup) @@ -14,6 +14,8 @@ import Html.Events exposing (onClick) import List.Extra import Maybe.Extra exposing (isJust, isNothing) import Pages.Completion.Model exposing (..) +import Pages.Model exposing (MetricsResultsTableData) +import Pages.Utils exposing (viewStandardCells, viewStandardRow) import RemoteData exposing (RemoteData(..)) import Round import Time exposing (Month(..)) @@ -37,7 +39,85 @@ view language currentDate themePath modelBackend model = viewCompletionData : Language -> NominalDate -> String -> CompletionData -> Model -> Html Msg viewCompletionData language currentDate themePath data model = let - _ = - Debug.log "" data + topBar = + let + scopeLabel = + case data.entityType of + EntityGlobal -> + translate language Translate.Global + + EntityHealthCenter -> + data.entityName + in + div [ class "top-bar" ] + [ div [ class "new-selection" ] + [ a [ href "/admin/reports/completion" ] + [ button [] + [ text <| translate language Translate.NewScope ] + ] + ] + , div [ class "scope" ] + [ text <| translate language Translate.Scope ++ ": " ++ scopeLabel ] + ] + + reportData = + generateNutritionReportData language data.nutritionIndividualData + + captionsRow = + viewStandardCells reportData.captions + |> div [ class "row captions" ] + in + div [ class "page-content completion" ] + [ topBar + , div [ class "inputs" ] + [ div [ class "report" ] + [ div [ class "table" ] <| + captionsRow + :: List.map viewStandardRow reportData.rows + ] + ] + ] + + +generateNutritionReportData : + Language + -> List (EncounterData NutritionActivity) + -> MetricsResultsTableData +generateNutritionReportData language records = + let + count resolveFunc activity = + List.filter (resolveFunc >> List.member activity) records + |> List.length + + calcualtePercentage nominator total = + if total == 0 then + "0" + + else + Round.round 3 ((toFloat nominator / toFloat total) * 100) ++ "%" in - text "viewCompletionData" + { heading = translate language Translate.NutritionIndividual + , captions = + [ translate language Translate.Activity + , translate language Translate.Expected + , translate language Translate.Completed + , "%" + ] + , rows = + List.map + (\activity -> + let + expected = + count .expectedActivities activity + + completed = + count .completedActivities activity + in + [ translate language <| Translate.NutritionActivity activity + , String.fromInt expected + , String.fromInt completed + , calcualtePercentage completed expected + ] + ) + allNutritionActivities + } diff --git a/server/elm/src/Pages/Reports/Model.elm b/server/elm/src/Pages/Reports/Model.elm index 75dc87faa3..f6cd96d1ce 100644 --- a/server/elm/src/Pages/Reports/Model.elm +++ b/server/elm/src/Pages/Reports/Model.elm @@ -89,13 +89,6 @@ emptyNutritionMetricsResults = } -type alias MetricsResultsTableData = - { heading : String - , captions : List String - , rows : List (List String) - } - - type Msg = SetReportType String | SetStartDate Date diff --git a/server/elm/src/Pages/Reports/View.elm b/server/elm/src/Pages/Reports/View.elm index 752796fc9e..88d1bb2deb 100644 --- a/server/elm/src/Pages/Reports/View.elm +++ b/server/elm/src/Pages/Reports/View.elm @@ -25,9 +25,19 @@ import Html.Attributes exposing (..) import Html.Events exposing (onClick) import List.Extra import Maybe.Extra exposing (isJust, isNothing) +import Pages.Model exposing (MetricsResultsTableData) import Pages.Reports.Model exposing (..) import Pages.Reports.Utils exposing (..) -import Pages.Utils exposing (generateReportsHeaderImage, viewCustomLabel, viewSelectListInput, wrapSelectListInput) +import Pages.Utils + exposing + ( generateReportsHeaderImage + , viewCustomCells + , viewCustomLabel + , viewSelectListInput + , viewStandardCells + , viewStandardRow + , wrapSelectListInput + ) import RemoteData exposing (RemoteData(..)) import Round import Time exposing (Month(..)) @@ -1743,32 +1753,6 @@ generateAcuteIllnessReportData language startDate records = } -viewStandardRow : List String -> Html any -viewStandardRow = - viewStandardCells - >> div [ class "row" ] - - -viewStandardCells : List String -> List (Html any) -viewStandardCells = - viewCustomCells "label" "value" - - -viewCustomCells : String -> String -> List String -> List (Html any) -viewCustomCells labelClass valueClass = - List.indexedMap - (\index cellText -> - div - [ classList - [ ( "item", True ) - , ( labelClass, index == 0 ) - , ( valueClass, index /= 0 ) - ] - ] - [ text cellText ] - ) - - viewDownloadCSVButton : Language -> String -> String -> Html Msg viewDownloadCSVButton language csvFileName csvContent = div [ class "download-csv-wrapper" ] diff --git a/server/elm/src/Pages/Utils.elm b/server/elm/src/Pages/Utils.elm index 214ed5ac6a..c91288bdfa 100644 --- a/server/elm/src/Pages/Utils.elm +++ b/server/elm/src/Pages/Utils.elm @@ -249,3 +249,33 @@ viewMenuActionButton language path label selectionMadeMsg = generateReportsHeaderImage : String -> Html any generateReportsHeaderImage themePath = img [ src <| "/" ++ themePath ++ "/icons/statistical-queries.png" ] [] + + + +-- Table + + +viewStandardRow : List String -> Html any +viewStandardRow = + viewStandardCells + >> div [ class "row" ] + + +viewStandardCells : List String -> List (Html any) +viewStandardCells = + viewCustomCells "label" "value" + + +viewCustomCells : String -> String -> List String -> List (Html any) +viewCustomCells labelClass valueClass = + List.indexedMap + (\index cellText -> + div + [ classList + [ ( "item", True ) + , ( labelClass, index == 0 ) + , ( valueClass, index /= 0 ) + ] + ] + [ text cellText ] + ) diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index bde40cbed1..fcb88fd4c4 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -5,6 +5,7 @@ module Translate exposing ) import App.Types exposing (Language(..)) +import Backend.Completion.Model exposing (NutritionActivity(..)) import Backend.Reports.Model exposing (AcuteIllnessDiagnosis(..), NutritionReportTableType(..)) import Backend.Scoreboard.Model import Date @@ -52,6 +53,7 @@ type StringIdHttpError type TranslationId = ACHI + | Activity | AcuteIllnessDiagnosis AcuteIllnessDiagnosis | AcuteIllnessTotal | AcuteMalnutrition @@ -66,6 +68,7 @@ type TranslationId | Colline | CollineSub | Commune + | Completed | Diagnosis | District | Demographics @@ -73,6 +76,7 @@ type TranslationId | EmptyString | Encounters | EncounterType + | Expected | FBF | Female | GenerateReport @@ -111,7 +115,9 @@ type TranslationId | None | NumberOfVisits Int | NumberOfVisitsLabel + | NutritionActivity NutritionActivity | NutritionBehavior + | NutritionIndividual | NutritionReportTableType NutritionReportTableType | NutritionTotal | PleaseWaitMessage @@ -171,6 +177,12 @@ translationSet transId = , kirundi = Nothing } + Activity -> + { english = "Activity" + , kinyarwanda = Nothing + , kirundi = Nothing + } + AcuteIllnessDiagnosis diagnosis -> case diagnosis of DiagnosisCovid19Suspect -> @@ -323,6 +335,12 @@ translationSet transId = , kirundi = Nothing } + Completed -> + { english = "Completed" + , kinyarwanda = Nothing + , kirundi = Nothing + } + CBNP -> { english = "CBNP" , kinyarwanda = Nothing @@ -383,6 +401,12 @@ translationSet transId = , kirundi = Nothing } + Expected -> + { english = "Expected" + , kinyarwanda = Nothing + , kirundi = Nothing + } + FBF -> { english = "FBF" , kinyarwanda = Nothing @@ -769,12 +793,80 @@ translationSet transId = , kirundi = Nothing } + NutritionActivity activity -> + case activity of + NutritionHeight -> + { english = "Height" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NutritionNutrition -> + { english = "Nutrition" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NutritionPhoto -> + { english = "Photo" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NutritionWeight -> + { english = "Weight" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NutritionMUAC -> + { english = "MUAC" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NutritionContributingFactors -> + { english = "Contributing Factors" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NutritionFollowUp -> + { english = "Follow Up" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NutritionHealthEducation -> + { english = "Health Education" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NutritionSendToHC -> + { english = "Referal" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NutritionNCDA -> + { english = "NutritionNCDA" + , kinyarwanda = Nothing + , kirundi = Nothing + } + NutritionBehavior -> { english = "Nutrition Behavior" , kinyarwanda = Nothing , kirundi = Nothing } + NutritionIndividual -> + { english = "Nutrition Individual" + , kinyarwanda = Nothing + , kirundi = Nothing + } + NutritionReportTableType tableType -> case tableType of NutritionTablePrevalanceOneOrMore -> diff --git a/server/hedley/modules/custom/hedley_general/css/elm.css b/server/hedley/modules/custom/hedley_general/css/elm.css index 541899d77c..c0ad3f781a 100644 --- a/server/hedley/modules/custom/hedley_general/css/elm.css +++ b/server/hedley/modules/custom/hedley_general/css/elm.css @@ -291,19 +291,25 @@ body.admin-menu #page-wrapper #header { } .page-content.reports, -.page-content.reports-menu { +.page-content.reports-menu, +.page-content.completion, +.page-content.completion-menu { background: white; margin-top: 0; padding-top: 0; } .page-content.reports .select-input-wrapper .select-input, -.page-content.reports-menu .select-input-wrapper .select-input { +.page-content.reports-menu .select-input-wrapper .select-input, +.page-content.completion .select-input-wrapper .select-input, +.page-content.completion-menu .select-input-wrapper .select-input { border: 2px solid #3b3b3b; } .page-content.reports .select-input-wrapper .select-input:focus, -.page-content.reports-menu .select-input-wrapper .select-input:focus { +.page-content.reports-menu .select-input-wrapper .select-input:focus, +.page-content.completion .select-input-wrapper .select-input:focus, +.page-content.completion-menu .select-input-wrapper .select-input:focus { outline-color: #3b3b3b; } @@ -399,6 +405,8 @@ body.admin-menu #page-wrapper #header { .page-content.reports-menu .actions a button, .page-content.reports .top-bar .new-selection a button, +.page-content.completion-menu .actions a button, +.page-content.completion .top-bar .new-selection a button, .page-content.reports .inputs .report button.download-csv { background-color: white; border: 2px solid #3b3b3b; diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 4908219993..46421c50e7 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -9644,6 +9644,8 @@ var $author$project$Translate$translationSet = function (transId) { switch (transId.$) { case 'ACHI': return {english: 'ACHI', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Activity': + return {english: 'Activity', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessDiagnosis': var diagnosis = transId.a; switch (diagnosis.$) { @@ -9758,6 +9760,8 @@ var $author$project$Translate$translationSet = function (transId) { }; case 'Commune': return {english: 'Commune', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Completed': + return {english: 'Completed', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'CBNP': return {english: 'CBNP', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Cell': @@ -9778,6 +9782,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Encounters', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'EncounterType': return {english: 'Encounter Type', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Expected': + return {english: 'Expected', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'FBF': return {english: 'FBF', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Female': @@ -10025,8 +10031,34 @@ var $author$project$Translate$translationSet = function (transId) { }); case 'NumberOfVisitsLabel': return {english: '# Visits', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionActivity': + var activity = transId.a; + switch (activity.$) { + case 'NutritionHeight': + return {english: 'Height', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionNutrition': + return {english: 'Nutrition', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionPhoto': + return {english: 'Photo', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionWeight': + return {english: 'Weight', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionMUAC': + return {english: 'MUAC', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionContributingFactors': + return {english: 'Contributing Factors', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionFollowUp': + return {english: 'Follow Up', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionHealthEducation': + return {english: 'Health Education', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionSendToHC': + return {english: 'Referal', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + default: + return {english: 'NutritionNCDA', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + } case 'NutritionBehavior': return {english: 'Nutrition Behavior', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionIndividual': + return {english: 'Nutrition Individual', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NutritionReportTableType': var tableType = transId.a; switch (tableType.$) { @@ -10385,11 +10417,464 @@ var $author$project$Error$View$view = F2( }); var $author$project$Gizra$Html$emptyNode = $elm$html$Html$text(''); var $elm$core$Debug$toString = _Debug_toString; -var $elm$core$Debug$log = _Debug_log; +var $author$project$Translate$NewScope = {$: 'NewScope'}; +var $author$project$Translate$Scope = {$: 'Scope'}; +var $elm$html$Html$a = _VirtualDom_node('a'); +var $elm$html$Html$button = _VirtualDom_node('button'); +var $author$project$Translate$Activity = {$: 'Activity'}; +var $author$project$Translate$Completed = {$: 'Completed'}; +var $author$project$Translate$Expected = {$: 'Expected'}; +var $author$project$Translate$NutritionActivity = function (a) { + return {$: 'NutritionActivity', a: a}; +}; +var $author$project$Translate$NutritionIndividual = {$: 'NutritionIndividual'}; +var $author$project$Pages$Completion$Model$allNutritionActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$NutritionHeight, $author$project$Backend$Completion$Model$NutritionNutrition, $author$project$Backend$Completion$Model$NutritionPhoto, $author$project$Backend$Completion$Model$NutritionWeight, $author$project$Backend$Completion$Model$NutritionMUAC, $author$project$Backend$Completion$Model$NutritionContributingFactors, $author$project$Backend$Completion$Model$NutritionFollowUp, $author$project$Backend$Completion$Model$NutritionHealthEducation, $author$project$Backend$Completion$Model$NutritionSendToHC, $author$project$Backend$Completion$Model$NutritionNCDA]); +var $elm$core$Basics$abs = function (n) { + return (n < 0) ? (-n) : n; +}; +var $elm$core$String$foldr = _String_foldr; +var $elm$core$String$toList = function (string) { + return A3($elm$core$String$foldr, $elm$core$List$cons, _List_Nil, string); +}; +var $myrho$elm_round$Round$addSign = F2( + function (signed, str) { + var isNotZero = A2( + $elm$core$List$any, + function (c) { + return (!_Utils_eq( + c, + _Utils_chr('0'))) && (!_Utils_eq( + c, + _Utils_chr('.'))); + }, + $elm$core$String$toList(str)); + return _Utils_ap( + (signed && isNotZero) ? '-' : '', + str); + }); +var $elm$core$String$fromFloat = _String_fromNumber; +var $elm$core$String$cons = _String_cons; +var $elm$core$Char$fromCode = _Char_fromCode; +var $myrho$elm_round$Round$increaseNum = function (_v0) { + var head = _v0.a; + var tail = _v0.b; + if (_Utils_eq( + head, + _Utils_chr('9'))) { + var _v1 = $elm$core$String$uncons(tail); + if (_v1.$ === 'Nothing') { + return '01'; + } else { + var headtail = _v1.a; + return A2( + $elm$core$String$cons, + _Utils_chr('0'), + $myrho$elm_round$Round$increaseNum(headtail)); + } + } else { + var c = $elm$core$Char$toCode(head); + return ((c >= 48) && (c < 57)) ? A2( + $elm$core$String$cons, + $elm$core$Char$fromCode(c + 1), + tail) : '0'; + } +}; +var $elm$core$Basics$isInfinite = _Basics_isInfinite; +var $elm$core$Basics$isNaN = _Basics_isNaN; +var $elm$core$String$fromChar = function (_char) { + return A2($elm$core$String$cons, _char, ''); +}; +var $elm$core$Bitwise$and = _Bitwise_and; +var $elm$core$Bitwise$shiftRightBy = _Bitwise_shiftRightBy; +var $elm$core$String$repeatHelp = F3( + function (n, chunk, result) { + return (n <= 0) ? result : A3( + $elm$core$String$repeatHelp, + n >> 1, + _Utils_ap(chunk, chunk), + (!(n & 1)) ? result : _Utils_ap(result, chunk)); + }); +var $elm$core$String$repeat = F2( + function (n, chunk) { + return A3($elm$core$String$repeatHelp, n, chunk, ''); + }); +var $elm$core$String$padRight = F3( + function (n, _char, string) { + return _Utils_ap( + string, + A2( + $elm$core$String$repeat, + n - $elm$core$String$length(string), + $elm$core$String$fromChar(_char))); + }); +var $elm$core$String$reverse = _String_reverse; +var $myrho$elm_round$Round$splitComma = function (str) { + var _v0 = A2($elm$core$String$split, '.', str); + if (_v0.b) { + if (_v0.b.b) { + var before = _v0.a; + var _v1 = _v0.b; + var after = _v1.a; + return _Utils_Tuple2(before, after); + } else { + var before = _v0.a; + return _Utils_Tuple2(before, '0'); + } + } else { + return _Utils_Tuple2('0', '0'); + } +}; +var $elm$core$Tuple$mapFirst = F2( + function (func, _v0) { + var x = _v0.a; + var y = _v0.b; + return _Utils_Tuple2( + func(x), + y); + }); +var $myrho$elm_round$Round$toDecimal = function (fl) { + var _v0 = A2( + $elm$core$String$split, + 'e', + $elm$core$String$fromFloat( + $elm$core$Basics$abs(fl))); + if (_v0.b) { + if (_v0.b.b) { + var num = _v0.a; + var _v1 = _v0.b; + var exp = _v1.a; + var e = A2( + $elm$core$Maybe$withDefault, + 0, + $elm$core$String$toInt( + A2($elm$core$String$startsWith, '+', exp) ? A2($elm$core$String$dropLeft, 1, exp) : exp)); + var _v2 = $myrho$elm_round$Round$splitComma(num); + var before = _v2.a; + var after = _v2.b; + var total = _Utils_ap(before, after); + var zeroed = (e < 0) ? A2( + $elm$core$Maybe$withDefault, + '0', + A2( + $elm$core$Maybe$map, + function (_v3) { + var a = _v3.a; + var b = _v3.b; + return a + ('.' + b); + }, + A2( + $elm$core$Maybe$map, + $elm$core$Tuple$mapFirst($elm$core$String$fromChar), + $elm$core$String$uncons( + _Utils_ap( + A2( + $elm$core$String$repeat, + $elm$core$Basics$abs(e), + '0'), + total))))) : A3( + $elm$core$String$padRight, + e + 1, + _Utils_chr('0'), + total); + return _Utils_ap( + (fl < 0) ? '-' : '', + zeroed); + } else { + var num = _v0.a; + return _Utils_ap( + (fl < 0) ? '-' : '', + num); + } + } else { + return ''; + } +}; +var $myrho$elm_round$Round$roundFun = F3( + function (functor, s, fl) { + if ($elm$core$Basics$isInfinite(fl) || $elm$core$Basics$isNaN(fl)) { + return $elm$core$String$fromFloat(fl); + } else { + var signed = fl < 0; + var _v0 = $myrho$elm_round$Round$splitComma( + $myrho$elm_round$Round$toDecimal( + $elm$core$Basics$abs(fl))); + var before = _v0.a; + var after = _v0.b; + var r = $elm$core$String$length(before) + s; + var normalized = _Utils_ap( + A2($elm$core$String$repeat, (-r) + 1, '0'), + A3( + $elm$core$String$padRight, + r, + _Utils_chr('0'), + _Utils_ap(before, after))); + var totalLen = $elm$core$String$length(normalized); + var roundDigitIndex = A2($elm$core$Basics$max, 1, r); + var increase = A2( + functor, + signed, + A3($elm$core$String$slice, roundDigitIndex, totalLen, normalized)); + var remains = A3($elm$core$String$slice, 0, roundDigitIndex, normalized); + var num = increase ? $elm$core$String$reverse( + A2( + $elm$core$Maybe$withDefault, + '1', + A2( + $elm$core$Maybe$map, + $myrho$elm_round$Round$increaseNum, + $elm$core$String$uncons( + $elm$core$String$reverse(remains))))) : remains; + var numLen = $elm$core$String$length(num); + var numZeroed = (num === '0') ? num : ((s <= 0) ? _Utils_ap( + num, + A2( + $elm$core$String$repeat, + $elm$core$Basics$abs(s), + '0')) : ((_Utils_cmp( + s, + $elm$core$String$length(after)) < 0) ? (A3($elm$core$String$slice, 0, numLen - s, num) + ('.' + A3($elm$core$String$slice, numLen - s, numLen, num))) : _Utils_ap( + before + '.', + A3( + $elm$core$String$padRight, + s, + _Utils_chr('0'), + after)))); + return A2($myrho$elm_round$Round$addSign, signed, numZeroed); + } + }); +var $myrho$elm_round$Round$round = $myrho$elm_round$Round$roundFun( + F2( + function (signed, str) { + var _v0 = $elm$core$String$uncons(str); + if (_v0.$ === 'Nothing') { + return false; + } else { + if ('5' === _v0.a.a.valueOf()) { + if (_v0.a.b === '') { + var _v1 = _v0.a; + return !signed; + } else { + var _v2 = _v0.a; + return true; + } + } else { + var _v3 = _v0.a; + var _int = _v3.a; + return function (i) { + return ((i > 53) && signed) || ((i >= 53) && (!signed)); + }( + $elm$core$Char$toCode(_int)); + } + } + })); +var $author$project$Pages$Completion$View$generateNutritionReportData = F2( + function (language, records) { + var count = F2( + function (resolveFunc, activity) { + return $elm$core$List$length( + A2( + $elm$core$List$filter, + A2( + $elm$core$Basics$composeR, + resolveFunc, + $elm$core$List$member(activity)), + records)); + }); + var calcualtePercentage = F2( + function (nominator, total) { + return (!total) ? '0' : (A2($myrho$elm_round$Round$round, 3, (nominator / total) * 100) + '%'); + }); + return { + captions: _List_fromArray( + [ + A2($author$project$Translate$translate, language, $author$project$Translate$Activity), + A2($author$project$Translate$translate, language, $author$project$Translate$Expected), + A2($author$project$Translate$translate, language, $author$project$Translate$Completed), + '%' + ]), + heading: A2($author$project$Translate$translate, language, $author$project$Translate$NutritionIndividual), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A2( + count, + function ($) { + return $.expectedActivities; + }, + activity); + var completed = A2( + count, + function ($) { + return $.completedActivities; + }, + activity); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$NutritionActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2(calcualtePercentage, completed, expected) + ]); + }, + $author$project$Pages$Completion$Model$allNutritionActivities) + }; + }); +var $elm$html$Html$Attributes$href = function (url) { + return A2( + $elm$html$Html$Attributes$stringProperty, + 'href', + _VirtualDom_noJavaScriptUri(url)); +}; +var $elm$html$Html$Attributes$classList = function (classes) { + return $elm$html$Html$Attributes$class( + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $elm$core$Tuple$first, + A2($elm$core$List$filter, $elm$core$Tuple$second, classes)))); +}; +var $author$project$Pages$Utils$viewCustomCells = F2( + function (labelClass, valueClass) { + return $elm$core$List$indexedMap( + F2( + function (index, cellText) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$classList( + _List_fromArray( + [ + _Utils_Tuple2('item', true), + _Utils_Tuple2(labelClass, !index), + _Utils_Tuple2(valueClass, !(!index)) + ])) + ]), + _List_fromArray( + [ + $elm$html$Html$text(cellText) + ])); + })); + }); +var $author$project$Pages$Utils$viewStandardCells = A2($author$project$Pages$Utils$viewCustomCells, 'label', 'value'); +var $author$project$Pages$Utils$viewStandardRow = A2( + $elm$core$Basics$composeR, + $author$project$Pages$Utils$viewStandardCells, + $elm$html$Html$div( + _List_fromArray( + [ + $elm$html$Html$Attributes$class('row') + ]))); var $author$project$Pages$Completion$View$viewCompletionData = F5( function (language, currentDate, themePath, data, model) { - var _v0 = A2($elm$core$Debug$log, '', data); - return $elm$html$Html$text('viewCompletionData'); + var topBar = function () { + var scopeLabel = function () { + var _v0 = data.entityType; + if (_v0.$ === 'EntityGlobal') { + return A2($author$project$Translate$translate, language, $author$project$Translate$Global); + } else { + return data.entityName; + } + }(); + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('top-bar') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('new-selection') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$a, + _List_fromArray( + [ + $elm$html$Html$Attributes$href('/admin/reports/completion') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$button, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text( + A2($author$project$Translate$translate, language, $author$project$Translate$NewScope)) + ])) + ])) + ])), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('scope') + ]), + _List_fromArray( + [ + $elm$html$Html$text( + A2($author$project$Translate$translate, language, $author$project$Translate$Scope) + (': ' + scopeLabel)) + ])) + ])); + }(); + var reportData = A2($author$project$Pages$Completion$View$generateNutritionReportData, language, data.nutritionIndividualData); + var captionsRow = A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('row captions') + ]), + $author$project$Pages$Utils$viewStandardCells(reportData.captions)); + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('page-content completion') + ]), + _List_fromArray( + [ + topBar, + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('inputs') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('table') + ]), + A2( + $elm$core$List$cons, + captionsRow, + A2($elm$core$List$map, $author$project$Pages$Utils$viewStandardRow, reportData.rows))) + ])) + ])) + ])); }); var $author$project$Pages$Completion$View$view = F5( function (language, currentDate, themePath, modelBackend, model) { @@ -10411,7 +10896,6 @@ var $author$project$Translate$PleaseWaitMessage = {$: 'PleaseWaitMessage'}; var $author$project$Translate$PopulationSelectionOption = function (a) { return {$: 'PopulationSelectionOption', a: a}; }; -var $author$project$Translate$Scope = {$: 'Scope'}; var $author$project$Translate$SelectScope = {$: 'SelectScope'}; var $author$project$Pages$CompletionMenu$Model$SelectionMade = {$: 'SelectionMade'}; var $author$project$Pages$CompletionMenu$Model$SetHealthCenter = function (a) { @@ -10538,14 +11022,6 @@ var $author$project$Pages$Utils$viewCustomSelectListInput = F6( options))); }); var $author$project$Translate$LoadData = {$: 'LoadData'}; -var $elm$html$Html$a = _VirtualDom_node('a'); -var $elm$html$Html$button = _VirtualDom_node('button'); -var $elm$html$Html$Attributes$href = function (url) { - return A2( - $elm$html$Html$Attributes$stringProperty, - 'href', - _VirtualDom_noJavaScriptUri(url)); -}; var $elm$virtual_dom$VirtualDom$Normal = function (a) { return {$: 'Normal', a: a}; }; @@ -10605,16 +11081,6 @@ var $author$project$Pages$Utils$viewSelectListInput = F7( options); return A6($author$project$Pages$Utils$viewCustomSelectListInput, currentValue, optionsPairs, toStringFunc, setMsg, inputClass, true); }); -var $elm$html$Html$Attributes$classList = function (classes) { - return $elm$html$Html$Attributes$class( - A2( - $elm$core$String$join, - ' ', - A2( - $elm$core$List$map, - $elm$core$Tuple$first, - A2($elm$core$List$filter, $elm$core$Tuple$second, classes)))); -}; var $author$project$Pages$Utils$viewLabel = F2( function (language, translationId) { return A4($author$project$Pages$Utils$viewCustomLabel, language, translationId, ':', 'label'); @@ -10752,7 +11218,6 @@ var $author$project$Pages$CompletionMenu$View$view = F4( return $author$project$Gizra$Html$emptyNode; } }); -var $author$project$Translate$NewScope = {$: 'NewScope'}; var $author$project$Translate$ReportType = function (a) { return {$: 'ReportType', a: a}; }; @@ -10816,29 +11281,11 @@ var $justinmimbs$date$Date$day = A2( function ($) { return $.day; }); -var $justinmimbs$date$Date$ordinalDay = A2( - $elm$core$Basics$composeR, - $justinmimbs$date$Date$toOrdinalDate, - function ($) { - return $.ordinalDay; - }); -var $elm$core$String$cons = _String_cons; -var $elm$core$String$fromChar = function (_char) { - return A2($elm$core$String$cons, _char, ''); -}; -var $elm$core$Bitwise$and = _Bitwise_and; -var $elm$core$Bitwise$shiftRightBy = _Bitwise_shiftRightBy; -var $elm$core$String$repeatHelp = F3( - function (n, chunk, result) { - return (n <= 0) ? result : A3( - $elm$core$String$repeatHelp, - n >> 1, - _Utils_ap(chunk, chunk), - (!(n & 1)) ? result : _Utils_ap(result, chunk)); - }); -var $elm$core$String$repeat = F2( - function (n, chunk) { - return A3($elm$core$String$repeatHelp, n, chunk, ''); +var $justinmimbs$date$Date$ordinalDay = A2( + $elm$core$Basics$composeR, + $justinmimbs$date$Date$toOrdinalDate, + function ($) { + return $.ordinalDay; }); var $elm$core$String$padLeft = F3( function (n, _char, string) { @@ -10849,9 +11296,6 @@ var $elm$core$String$padLeft = F3( $elm$core$String$fromChar(_char)), string); }); -var $elm$core$Basics$abs = function (n) { - return (n < 0) ? (-n) : n; -}; var $justinmimbs$date$Date$padSignedInt = F2( function (length, _int) { return _Utils_ap( @@ -11221,10 +11665,6 @@ var $elm$parser$Parser$Advanced$getOffset = $elm$parser$Parser$Advanced$Parser( return A3($elm$parser$Parser$Advanced$Good, false, s.offset, s); }); var $elm$parser$Parser$getOffset = $elm$parser$Parser$Advanced$getOffset; -var $elm$core$String$foldr = _String_foldr; -var $elm$core$String$toList = function (string) { - return A3($elm$core$String$foldr, $elm$core$List$cons, _List_Nil, string); -}; var $justinmimbs$date$Pattern$fieldRepeats = function (str) { var _v0 = $elm$core$String$toList(str); if (_v0.b && (!_v0.b.b)) { @@ -11659,38 +12099,6 @@ var $author$project$Pages$Reports$View$viewDownloadCSVButton = F3( ])) ])); }); -var $author$project$Pages$Reports$View$viewCustomCells = F2( - function (labelClass, valueClass) { - return $elm$core$List$indexedMap( - F2( - function (index, cellText) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$classList( - _List_fromArray( - [ - _Utils_Tuple2('item', true), - _Utils_Tuple2(labelClass, !index), - _Utils_Tuple2(valueClass, !(!index)) - ])) - ]), - _List_fromArray( - [ - $elm$html$Html$text(cellText) - ])); - })); - }); -var $author$project$Pages$Reports$View$viewStandardCells = A2($author$project$Pages$Reports$View$viewCustomCells, 'label', 'value'); -var $author$project$Pages$Reports$View$viewStandardRow = A2( - $elm$core$Basics$composeR, - $author$project$Pages$Reports$View$viewStandardCells, - $elm$html$Html$div( - _List_fromArray( - [ - $elm$html$Html$Attributes$class('row') - ]))); var $author$project$Pages$Reports$View$viewAcuteIllnessReport = F5( function (language, limitDate, startDate, scopeLabel, records) { var data = A3($author$project$Pages$Reports$View$generateAcuteIllnessReportData, language, startDate, records); @@ -11703,7 +12111,7 @@ var $author$project$Pages$Reports$View$viewAcuteIllnessReport = F5( [ $elm$html$Html$Attributes$class('row captions') ]), - $author$project$Pages$Reports$View$viewStandardCells(data.captions)); + $author$project$Pages$Utils$viewStandardCells(data.captions)); return A2( $elm$html$Html$div, _List_fromArray( @@ -11722,7 +12130,7 @@ var $author$project$Pages$Reports$View$viewAcuteIllnessReport = F5( A2( $elm$core$List$cons, captionsRow, - A2($elm$core$List$map, $author$project$Pages$Reports$View$viewStandardRow, data.rows))) + A2($elm$core$List$map, $author$project$Pages$Utils$viewStandardRow, data.rows))) ]), _List_fromArray( [ @@ -13309,7 +13717,7 @@ var $author$project$Pages$Reports$View$viewDemographicsReportEncounters = F2( [ $elm$html$Html$Attributes$class('row captions') ]), - $author$project$Pages$Reports$View$viewStandardCells(data.captions)) + $author$project$Pages$Utils$viewStandardCells(data.captions)) ]), _Utils_ap( A2($elm$core$List$map, viewRow, data.rows), @@ -13321,7 +13729,7 @@ var $author$project$Pages$Reports$View$viewDemographicsReportEncounters = F2( [ $elm$html$Html$Attributes$class('row encounters-totals') ]), - $author$project$Pages$Reports$View$viewStandardCells( + $author$project$Pages$Utils$viewStandardCells( _List_fromArray( [data.totals.label, data.totals.total, data.totals.unique]))) ])))) @@ -13345,9 +13753,9 @@ var $author$project$Pages$Reports$View$viewDemographicsReportPatients = F3( [ $elm$html$Html$Attributes$class('row captions') ]), - $author$project$Pages$Reports$View$viewStandardCells(tableData.captions)) + $author$project$Pages$Utils$viewStandardCells(tableData.captions)) ]), - A2($elm$core$List$map, $author$project$Pages$Reports$View$viewStandardRow, tableData.rows))); + A2($elm$core$List$map, $author$project$Pages$Utils$viewStandardRow, tableData.rows))); }; return A2( $elm$core$List$cons, @@ -14357,219 +14765,6 @@ var $author$project$Pages$Reports$Utils$resolvePreviousDataSetForMonth = F3( }, A2($elm$core$List$range, 1, 3))); }); -var $myrho$elm_round$Round$addSign = F2( - function (signed, str) { - var isNotZero = A2( - $elm$core$List$any, - function (c) { - return (!_Utils_eq( - c, - _Utils_chr('0'))) && (!_Utils_eq( - c, - _Utils_chr('.'))); - }, - $elm$core$String$toList(str)); - return _Utils_ap( - (signed && isNotZero) ? '-' : '', - str); - }); -var $elm$core$String$fromFloat = _String_fromNumber; -var $elm$core$Char$fromCode = _Char_fromCode; -var $myrho$elm_round$Round$increaseNum = function (_v0) { - var head = _v0.a; - var tail = _v0.b; - if (_Utils_eq( - head, - _Utils_chr('9'))) { - var _v1 = $elm$core$String$uncons(tail); - if (_v1.$ === 'Nothing') { - return '01'; - } else { - var headtail = _v1.a; - return A2( - $elm$core$String$cons, - _Utils_chr('0'), - $myrho$elm_round$Round$increaseNum(headtail)); - } - } else { - var c = $elm$core$Char$toCode(head); - return ((c >= 48) && (c < 57)) ? A2( - $elm$core$String$cons, - $elm$core$Char$fromCode(c + 1), - tail) : '0'; - } -}; -var $elm$core$Basics$isInfinite = _Basics_isInfinite; -var $elm$core$Basics$isNaN = _Basics_isNaN; -var $elm$core$String$padRight = F3( - function (n, _char, string) { - return _Utils_ap( - string, - A2( - $elm$core$String$repeat, - n - $elm$core$String$length(string), - $elm$core$String$fromChar(_char))); - }); -var $elm$core$String$reverse = _String_reverse; -var $myrho$elm_round$Round$splitComma = function (str) { - var _v0 = A2($elm$core$String$split, '.', str); - if (_v0.b) { - if (_v0.b.b) { - var before = _v0.a; - var _v1 = _v0.b; - var after = _v1.a; - return _Utils_Tuple2(before, after); - } else { - var before = _v0.a; - return _Utils_Tuple2(before, '0'); - } - } else { - return _Utils_Tuple2('0', '0'); - } -}; -var $elm$core$Tuple$mapFirst = F2( - function (func, _v0) { - var x = _v0.a; - var y = _v0.b; - return _Utils_Tuple2( - func(x), - y); - }); -var $myrho$elm_round$Round$toDecimal = function (fl) { - var _v0 = A2( - $elm$core$String$split, - 'e', - $elm$core$String$fromFloat( - $elm$core$Basics$abs(fl))); - if (_v0.b) { - if (_v0.b.b) { - var num = _v0.a; - var _v1 = _v0.b; - var exp = _v1.a; - var e = A2( - $elm$core$Maybe$withDefault, - 0, - $elm$core$String$toInt( - A2($elm$core$String$startsWith, '+', exp) ? A2($elm$core$String$dropLeft, 1, exp) : exp)); - var _v2 = $myrho$elm_round$Round$splitComma(num); - var before = _v2.a; - var after = _v2.b; - var total = _Utils_ap(before, after); - var zeroed = (e < 0) ? A2( - $elm$core$Maybe$withDefault, - '0', - A2( - $elm$core$Maybe$map, - function (_v3) { - var a = _v3.a; - var b = _v3.b; - return a + ('.' + b); - }, - A2( - $elm$core$Maybe$map, - $elm$core$Tuple$mapFirst($elm$core$String$fromChar), - $elm$core$String$uncons( - _Utils_ap( - A2( - $elm$core$String$repeat, - $elm$core$Basics$abs(e), - '0'), - total))))) : A3( - $elm$core$String$padRight, - e + 1, - _Utils_chr('0'), - total); - return _Utils_ap( - (fl < 0) ? '-' : '', - zeroed); - } else { - var num = _v0.a; - return _Utils_ap( - (fl < 0) ? '-' : '', - num); - } - } else { - return ''; - } -}; -var $myrho$elm_round$Round$roundFun = F3( - function (functor, s, fl) { - if ($elm$core$Basics$isInfinite(fl) || $elm$core$Basics$isNaN(fl)) { - return $elm$core$String$fromFloat(fl); - } else { - var signed = fl < 0; - var _v0 = $myrho$elm_round$Round$splitComma( - $myrho$elm_round$Round$toDecimal( - $elm$core$Basics$abs(fl))); - var before = _v0.a; - var after = _v0.b; - var r = $elm$core$String$length(before) + s; - var normalized = _Utils_ap( - A2($elm$core$String$repeat, (-r) + 1, '0'), - A3( - $elm$core$String$padRight, - r, - _Utils_chr('0'), - _Utils_ap(before, after))); - var totalLen = $elm$core$String$length(normalized); - var roundDigitIndex = A2($elm$core$Basics$max, 1, r); - var increase = A2( - functor, - signed, - A3($elm$core$String$slice, roundDigitIndex, totalLen, normalized)); - var remains = A3($elm$core$String$slice, 0, roundDigitIndex, normalized); - var num = increase ? $elm$core$String$reverse( - A2( - $elm$core$Maybe$withDefault, - '1', - A2( - $elm$core$Maybe$map, - $myrho$elm_round$Round$increaseNum, - $elm$core$String$uncons( - $elm$core$String$reverse(remains))))) : remains; - var numLen = $elm$core$String$length(num); - var numZeroed = (num === '0') ? num : ((s <= 0) ? _Utils_ap( - num, - A2( - $elm$core$String$repeat, - $elm$core$Basics$abs(s), - '0')) : ((_Utils_cmp( - s, - $elm$core$String$length(after)) < 0) ? (A3($elm$core$String$slice, 0, numLen - s, num) + ('.' + A3($elm$core$String$slice, numLen - s, numLen, num))) : _Utils_ap( - before + '.', - A3( - $elm$core$String$padRight, - s, - _Utils_chr('0'), - after)))); - return A2($myrho$elm_round$Round$addSign, signed, numZeroed); - } - }); -var $myrho$elm_round$Round$round = $myrho$elm_round$Round$roundFun( - F2( - function (signed, str) { - var _v0 = $elm$core$String$uncons(str); - if (_v0.$ === 'Nothing') { - return false; - } else { - if ('5' === _v0.a.a.valueOf()) { - if (_v0.a.b === '') { - var _v1 = _v0.a; - return !signed; - } else { - var _v2 = _v0.a; - return true; - } - } else { - var _v3 = _v0.a; - var _int = _v3.a; - return function (i) { - return ((i > 53) && signed) || ((i >= 53) && (!signed)); - }( - $elm$core$Char$toCode(_int)); - } - } - })); var $author$project$Pages$Reports$View$toMetricsResultsTableData = F3( function (language, heading, data) { var generateRow = function (label) { @@ -14978,7 +15173,7 @@ var $author$project$Pages$Reports$View$viewNutritionMetricsResultsTable = functi [ $elm$html$Html$Attributes$class('row') ]), - A3($author$project$Pages$Reports$View$viewCustomCells, 'row-label', 'value', cells)); + A3($author$project$Pages$Utils$viewCustomCells, 'row-label', 'value', cells)); }; var captionsRow = A2( $elm$html$Html$div, @@ -14986,7 +15181,7 @@ var $author$project$Pages$Reports$View$viewNutritionMetricsResultsTable = functi [ $elm$html$Html$Attributes$class('row') ]), - A3($author$project$Pages$Reports$View$viewCustomCells, 'row-label', 'heading', data.captions)); + A3($author$project$Pages$Utils$viewCustomCells, 'row-label', 'heading', data.captions)); return _List_fromArray( [ A2( @@ -15289,8 +15484,8 @@ var $author$project$Pages$Reports$View$viewPrenatalReport = F4( [ $elm$html$Html$Attributes$class('row captions') ]), - $author$project$Pages$Reports$View$viewStandardCells(tableData.captions)), - A2($elm$core$List$map, $author$project$Pages$Reports$View$viewStandardRow, tableData.rows))) + $author$project$Pages$Utils$viewStandardCells(tableData.captions)), + A2($elm$core$List$map, $author$project$Pages$Utils$viewStandardRow, tableData.rows))) ]); }; var data = A3($author$project$Pages$Reports$View$generatePrenatalReportData, language, limitDate, records); From 54c24c68a13b5cf085dd5030955b9014dd2775a9 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 15 Aug 2024 19:28:23 +0300 Subject: [PATCH 009/185] A fix [ci skip] --- server/elm/src/Translate.elm | 2 +- server/hedley/modules/custom/hedley_general/js/elm-main.js | 2 +- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index fcb88fd4c4..e7dcf2d623 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -850,7 +850,7 @@ translationSet transId = } NutritionNCDA -> - { english = "NutritionNCDA" + { english = "NCDA" , kinyarwanda = Nothing , kirundi = Nothing } diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 46421c50e7..dc147a1511 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -10053,7 +10053,7 @@ var $author$project$Translate$translationSet = function (transId) { case 'NutritionSendToHC': return {english: 'Referal', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; default: - return {english: 'NutritionNCDA', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'NCDA', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; } case 'NutritionBehavior': return {english: 'Nutrition Behavior', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 1b2e7b9d36..aaa2433ab4 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2133,7 +2133,7 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun $ncda_launch_date = '2023-11-20'; $ncda_launch_date_obj = new DateTime($ncda_launch_date); - if ($ncda_enabled && $start_date >= $ncda_launch_date_obj && ($taken_by == 'nurse') && isset($age_in_months) && $age_in_months < 24) { + if ($ncda_enabled && $start_date_obj >= $ncda_launch_date_obj && ($taken_by == 'nurse') && isset($age_in_months) && $age_in_months < 24) { $expected[] = 'nutrition_ncda'; } From 65554f528e8833a2c81c296576cffdaca7c0c927 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 15 Aug 2024 20:29:00 +0300 Subject: [PATCH 010/185] Another fix [ci skip] --- server/elm/src/Pages/Model.elm | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 server/elm/src/Pages/Model.elm diff --git a/server/elm/src/Pages/Model.elm b/server/elm/src/Pages/Model.elm new file mode 100644 index 0000000000..a672dc9f20 --- /dev/null +++ b/server/elm/src/Pages/Model.elm @@ -0,0 +1,8 @@ +module Pages.Model exposing (..) + + +type alias MetricsResultsTableData = + { heading : String + , captions : List String + , rows : List (List String) + } From 797fbad788303bed190544c2d952d66d2c461d9d Mon Sep 17 00:00:00 2001 From: anvmn Date: Sat, 17 Aug 2024 21:29:34 +0300 Subject: [PATCH 011/185] Data filtering [ci skip] --- server/elm/src/Pages/Completion/Model.elm | 25 +- server/elm/src/Pages/Completion/Update.elm | 48 + server/elm/src/Pages/Completion/View.elm | 125 +- server/elm/src/Pages/Components/View.elm | 49 + server/elm/src/Pages/Reports/View.elm | 29 +- server/elm/src/Pages/Utils.elm | 32 +- server/elm/src/Translate.elm | 10 + .../modules/custom/hedley_general/css/elm.css | 12 +- .../hedley_general/hedley_general.module | 2 +- .../custom/hedley_general/js/elm-main.js | 5235 +++++++++-------- 10 files changed, 2991 insertions(+), 2576 deletions(-) diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index aa9bea9d33..28cba93541 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -1,19 +1,40 @@ module Pages.Completion.Model exposing (..) import Backend.Completion.Model exposing (NutritionActivity(..)) +import Date exposing (Date) +import DateSelector.Model exposing (DateSelectorConfig) type alias Model = - {} + { reportType : Maybe ReportType + , startDate : Maybe Date + , startDateSelectorPopupState : Maybe (DateSelectorConfig Msg) + , limitDate : Maybe Date + , limitDateSelectorPopupState : Maybe (DateSelectorConfig Msg) + } emptyModel : Model emptyModel = - {} + { reportType = Nothing + , startDate = Nothing + , startDateSelectorPopupState = Nothing + , limitDate = Nothing + , limitDateSelectorPopupState = Nothing + } + + +type ReportType + = ReportNutritionIndividual type Msg = NoOp + | SetReportType String + | SetStartDate Date + | SetStartDateSelectorState (Maybe (DateSelectorConfig Msg)) + | SetLimitDate Date + | SetLimitDateSelectorState (Maybe (DateSelectorConfig Msg)) allNutritionActivities : List NutritionActivity diff --git a/server/elm/src/Pages/Completion/Update.elm b/server/elm/src/Pages/Completion/Update.elm index 4f3b05fb71..94c8d1874f 100644 --- a/server/elm/src/Pages/Completion/Update.elm +++ b/server/elm/src/Pages/Completion/Update.elm @@ -9,6 +9,7 @@ import Error.Utils exposing (noError) import Gizra.NominalDate exposing (NominalDate) import Maybe.Extra import Pages.Completion.Model exposing (..) +import Pages.Completion.Utils exposing (..) import RemoteData exposing (RemoteData(..)) import Task exposing (Task) @@ -22,3 +23,50 @@ update currentDate modelBackend msg model = Cmd.none noError [] + + SetReportType value -> + PagesReturn + { model + | reportType = reportTypeFromString value + , startDate = Nothing + , limitDate = Nothing + } + Cmd.none + noError + [] + + SetStartDate value -> + PagesReturn + { model | startDate = Just value } + Cmd.none + noError + [] + + SetStartDateSelectorState state -> + let + defaultSelection = + Maybe.Extra.or model.startDate (Maybe.andThen .dateDefault state) + in + PagesReturn + { model | startDateSelectorPopupState = state, startDate = defaultSelection } + Cmd.none + noError + [] + + SetLimitDate value -> + PagesReturn + { model | limitDate = Just value } + Cmd.none + noError + [] + + SetLimitDateSelectorState state -> + let + defaultSelection = + Maybe.Extra.or model.limitDate (Maybe.andThen .dateDefault state) + in + PagesReturn + { model | limitDateSelectorPopupState = state, limitDate = defaultSelection } + Cmd.none + noError + [] diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index efbdde7383..a56a341433 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -14,8 +14,10 @@ import Html.Events exposing (onClick) import List.Extra import Maybe.Extra exposing (isJust, isNothing) import Pages.Completion.Model exposing (..) +import Pages.Completion.Utils exposing (reportTypeToString) +import Pages.Components.View exposing (viewNutritionMetricsResultsTable) import Pages.Model exposing (MetricsResultsTableData) -import Pages.Utils exposing (viewStandardCells, viewStandardRow) +import Pages.Utils exposing (launchDate, viewSelectListInput, wrapSelectListInput) import RemoteData exposing (RemoteData(..)) import Round import Time exposing (Month(..)) @@ -60,25 +62,124 @@ viewCompletionData language currentDate themePath data model = [ text <| translate language Translate.Scope ++ ": " ++ scopeLabel ] ] - reportData = - generateNutritionReportData language data.nutritionIndividualData + dateInputs = + Maybe.map + (\reportType -> + let + startDateInput = + let + dateSelectorConfig = + { select = SetStartDate + , close = SetStartDateSelectorState Nothing + , dateFrom = launchDate + , dateTo = currentDate + , dateDefault = Just launchDate + } - captionsRow = - viewStandardCells reportData.captions - |> div [ class "row captions" ] + dateForView = + Maybe.map formatDDMMYYYY model.startDate + |> Maybe.withDefault "" + in + div + [ class "form-input date" + , onClick <| SetStartDateSelectorState (Just dateSelectorConfig) + ] + [ text dateForView ] + |> wrapSelectListInput language Translate.SelectStartDate False + + limitDateInput = + if + -- Reports requires setting start date before + -- limit date can be shown. + isNothing model.startDate + then + emptyNode + + else + let + dateFrom = + Maybe.withDefault launchDate model.startDate + + dateSelectorConfig = + { select = SetLimitDate + , close = SetLimitDateSelectorState Nothing + , dateFrom = dateFrom + , dateTo = currentDate + , dateDefault = Just currentDate + } + + limitDateForView = + Maybe.map formatDDMMYYYY model.limitDate + |> Maybe.withDefault "" + in + div + [ class "form-input date" + , onClick <| SetLimitDateSelectorState (Just dateSelectorConfig) + ] + [ text limitDateForView ] + |> wrapSelectListInput language Translate.SelectLimitDate False + in + [ startDateInput, limitDateInput ] + ) + model.reportType + |> Maybe.withDefault [] + + content = + if + isJust model.startDateSelectorPopupState + || isJust model.limitDateSelectorPopupState + then + -- Date selector is open, so no need to calcualte + -- intermediate results. + emptyNode + + else + Maybe.map3 + (\reportType startDate limitDate -> + case reportType of + ReportNutritionIndividual -> + viewNutritionIndividualReport language startDate limitDate data.nutritionIndividualData + ) + model.reportType + model.startDate + model.limitDate + |> Maybe.withDefault emptyNode in div [ class "page-content completion" ] [ topBar - , div [ class "inputs" ] - [ div [ class "report" ] - [ div [ class "table" ] <| - captionsRow - :: List.map viewStandardRow reportData.rows - ] + , div [ class "inputs" ] <| + [ viewSelectListInput language + model.reportType + [ ReportNutritionIndividual ] + reportTypeToString + SetReportType + Translate.CompletionReportType + "select-input" + |> wrapSelectListInput language Translate.ReportTypeLabel False ] + ++ dateInputs + ++ [ content ] + , viewModal <| viewCalendarPopup language model.startDateSelectorPopupState model.startDate + , viewModal <| viewCalendarPopup language model.limitDateSelectorPopupState model.limitDate ] +viewNutritionIndividualReport : Language -> NominalDate -> NominalDate -> List (EncounterData NutritionActivity) -> Html Msg +viewNutritionIndividualReport language startDate limitDate reportData = + let + filteredData = + List.filter + (\encounter -> + (not <| Date.compare encounter.startDate startDate == LT) + && (not <| Date.compare encounter.startDate limitDate == GT) + ) + reportData + |> generateNutritionReportData language + in + div [ class "report nutrition-individual" ] <| + viewNutritionMetricsResultsTable filteredData + + generateNutritionReportData : Language -> List (EncounterData NutritionActivity) diff --git a/server/elm/src/Pages/Components/View.elm b/server/elm/src/Pages/Components/View.elm index e7c38be989..58543f7979 100644 --- a/server/elm/src/Pages/Components/View.elm +++ b/server/elm/src/Pages/Components/View.elm @@ -11,6 +11,7 @@ import Html.Events exposing (onClick, onInput) import Maybe.Extra exposing (isJust) import Pages.Components.Model exposing (DemographicsSelection) import Pages.Components.Utils exposing (populationSelectionOptionToString) +import Pages.Model exposing (MetricsResultsTableData) import Pages.Utils exposing ( viewCustomLabel @@ -218,3 +219,51 @@ viewDemographicsSelectionActionButton language site pathPrefix label selectionMa ++ villagePart in viewMenuActionButton language path label selectionMadeMsg + + + +-- Table + + +viewNutritionMetricsResultsTable : MetricsResultsTableData -> List (Html any) +viewNutritionMetricsResultsTable data = + let + captionsRow = + div [ class "row" ] <| + viewCustomCells "row-label" "heading" data.captions + + viewRow cells = + div [ class "row" ] <| + viewCustomCells "row-label" "value" cells + in + [ div [ class "section heading" ] [ text data.heading ] + , div [ class "table wide" ] <| + captionsRow + :: List.map viewRow data.rows + ] + + +viewStandardRow : List String -> Html any +viewStandardRow = + viewStandardCells + >> div [ class "row" ] + + +viewStandardCells : List String -> List (Html any) +viewStandardCells = + viewCustomCells "label" "value" + + +viewCustomCells : String -> String -> List String -> List (Html any) +viewCustomCells labelClass valueClass = + List.indexedMap + (\index cellText -> + div + [ classList + [ ( "item", True ) + , ( labelClass, index == 0 ) + , ( valueClass, index /= 0 ) + ] + ] + [ text cellText ] + ) diff --git a/server/elm/src/Pages/Reports/View.elm b/server/elm/src/Pages/Reports/View.elm index 88d1bb2deb..d9de0fd009 100644 --- a/server/elm/src/Pages/Reports/View.elm +++ b/server/elm/src/Pages/Reports/View.elm @@ -25,17 +25,16 @@ import Html.Attributes exposing (..) import Html.Events exposing (onClick) import List.Extra import Maybe.Extra exposing (isJust, isNothing) +import Pages.Components.View exposing (viewCustomCells, viewNutritionMetricsResultsTable, viewStandardCells, viewStandardRow) import Pages.Model exposing (MetricsResultsTableData) import Pages.Reports.Model exposing (..) import Pages.Reports.Utils exposing (..) import Pages.Utils exposing ( generateReportsHeaderImage - , viewCustomCells + , launchDate , viewCustomLabel , viewSelectListInput - , viewStandardCells - , viewStandardRow , wrapSelectListInput ) import RemoteData exposing (RemoteData(..)) @@ -84,10 +83,6 @@ viewReportsData language currentDate themePath data model = _ -> data.entityName ++ " " ++ (String.toLower <| translate language (Translate.SelectedScope data.entityType)) - -- The date system became live, and first content was uploaded. - launchDate = - Date.fromCalendarDate 2018 Jan 1 - dateInputs = Maybe.map (\reportType -> @@ -128,7 +123,7 @@ viewReportsData language currentDate themePath data model = else let dateFrom = - Maybe.withDefault (Date.add Years -6 currentDate) model.startDate + Maybe.withDefault launchDate model.startDate dateSelectorConfig = { select = SetLimitDate @@ -1370,24 +1365,6 @@ toMetricsResultsTableData language heading data = } -viewNutritionMetricsResultsTable : MetricsResultsTableData -> List (Html Msg) -viewNutritionMetricsResultsTable data = - let - captionsRow = - div [ class "row" ] <| - viewCustomCells "row-label" "heading" data.captions - - viewRow cells = - div [ class "row" ] <| - viewCustomCells "row-label" "value" cells - in - [ div [ class "section heading" ] [ text data.heading ] - , div [ class "table wide" ] <| - captionsRow - :: List.map viewRow data.rows - ] - - viewPrenatalReport : Language -> NominalDate -> String -> List PatientData -> Html Msg viewPrenatalReport language limitDate scopeLabel records = let diff --git a/server/elm/src/Pages/Utils.elm b/server/elm/src/Pages/Utils.elm index c91288bdfa..d6ac99bff2 100644 --- a/server/elm/src/Pages/Utils.elm +++ b/server/elm/src/Pages/Utils.elm @@ -11,6 +11,7 @@ import Html.Attributes exposing (..) import Html.Events exposing (..) import Icons import Svg.Attributes +import Time exposing (Month(..)) import Translate exposing (TranslationId, translate) import Utils.GeoLocation exposing (..) @@ -252,30 +253,11 @@ generateReportsHeaderImage themePath = --- Table +-- Constants -viewStandardRow : List String -> Html any -viewStandardRow = - viewStandardCells - >> div [ class "row" ] - - -viewStandardCells : List String -> List (Html any) -viewStandardCells = - viewCustomCells "label" "value" - - -viewCustomCells : String -> String -> List String -> List (Html any) -viewCustomCells labelClass valueClass = - List.indexedMap - (\index cellText -> - div - [ classList - [ ( "item", True ) - , ( labelClass, index == 0 ) - , ( valueClass, index /= 0 ) - ] - ] - [ text cellText ] - ) +{-| The date system became live, and first content was uploaded. +-} +launchDate : NominalDate +launchDate = + Date.fromCalendarDate 2018 Jan 1 diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index e7dcf2d623..138d6169b2 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -9,6 +9,7 @@ import Backend.Completion.Model exposing (NutritionActivity(..)) import Backend.Reports.Model exposing (AcuteIllnessDiagnosis(..), NutritionReportTableType(..)) import Backend.Scoreboard.Model import Date +import Pages.Completion.Model import Pages.Components.Types exposing (PopulationSelectionOption(..)) import Pages.Reports.Model exposing (ReportType(..)) import Pages.Scoreboard.Model exposing (..) @@ -69,6 +70,7 @@ type TranslationId | CollineSub | Commune | Completed + | CompletionReportType Pages.Completion.Model.ReportType | Diagnosis | District | Demographics @@ -341,6 +343,14 @@ translationSet transId = , kirundi = Nothing } + CompletionReportType reportType -> + case reportType of + Pages.Completion.Model.ReportNutritionIndividual -> + { english = "Nutrition Individual" + , kinyarwanda = Nothing + , kirundi = Nothing + } + CBNP -> { english = "CBNP" , kinyarwanda = Nothing diff --git a/server/hedley/modules/custom/hedley_general/css/elm.css b/server/hedley/modules/custom/hedley_general/css/elm.css index c0ad3f781a..d0406d88f7 100644 --- a/server/hedley/modules/custom/hedley_general/css/elm.css +++ b/server/hedley/modules/custom/hedley_general/css/elm.css @@ -313,7 +313,8 @@ body.admin-menu #page-wrapper #header { outline-color: #3b3b3b; } -.page-content.reports .inputs .form-input.date { +.page-content.reports .inputs .form-input.date, +.page-content.completion .inputs .form-input.date { border: 2px solid #3b3b3b; } @@ -393,6 +394,15 @@ body.admin-menu #page-wrapper #header { width: 120%; } +.page-content .inputs .report.nutrition-individual .table .row .item.row-label { + width: 30%; +} + +.page-content .inputs .report.nutrition-individual .table .row .item.heading, +.page-content .inputs .report.nutrition-individual .table .row .item.value { + width: 20%; +} + .page-content .inputs .report .download-csv-wrapper { height: 50px; } diff --git a/server/hedley/modules/custom/hedley_general/hedley_general.module b/server/hedley/modules/custom/hedley_general/hedley_general.module index be46743f99..225d1a7635 100644 --- a/server/hedley/modules/custom/hedley_general/hedley_general.module +++ b/server/hedley/modules/custom/hedley_general/hedley_general.module @@ -501,7 +501,7 @@ function hedley_general_build_elm_app($page, array $data) { drupal_add_css($path_hedley_general . '/css/elm.css', 'file'); drupal_add_css($path_hedley_general . '/css/date-selector.css', 'file'); - if (in_array($page, ['ncda-results', 'reports-results'])) { + if (in_array($page, ['ncda-results', 'reports-results', 'completion-results'])) { // Add CSS for results pages. $path_system = drupal_get_path('module', 'system'); drupal_add_css($path_system . '/system.base.css', 'file'); diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index dc147a1511..01082e05e5 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5505,7 +5505,7 @@ var $elm$core$Basics$composeR = F3( }); var $author$project$App$Types$English = {$: 'English'}; var $author$project$App$Types$NotFound = {$: 'NotFound'}; -var $author$project$Pages$Completion$Model$emptyModel = {}; +var $author$project$Pages$Completion$Model$emptyModel = {limitDate: $elm$core$Maybe$Nothing, limitDateSelectorPopupState: $elm$core$Maybe$Nothing, reportType: $elm$core$Maybe$Nothing, startDate: $elm$core$Maybe$Nothing, startDateSelectorPopupState: $elm$core$Maybe$Nothing}; var $author$project$Pages$CompletionMenu$Model$emptyModel = {populationSelection: $elm$core$Maybe$Nothing, selected: false, selectedHealthCenter: $elm$core$Maybe$Nothing}; var $krisajenkins$remotedata$RemoteData$NotAsked = {$: 'NotAsked'}; var $author$project$Pages$Reports$Model$emptyModel = {limitDate: $elm$core$Maybe$Nothing, limitDateSelectorPopupState: $elm$core$Maybe$Nothing, nutritionReportData: $krisajenkins$remotedata$RemoteData$NotAsked, reportType: $elm$core$Maybe$Nothing, startDate: $elm$core$Maybe$Nothing, startDateSelectorPopupState: $elm$core$Maybe$Nothing}; @@ -5807,10 +5807,114 @@ var $author$project$App$Model$PagesReturn = F4( function (model, cmd, error, appMsgs) { return {appMsgs: appMsgs, cmd: cmd, error: error, model: model}; }); +var $elm$core$Maybe$andThen = F2( + function (callback, maybeValue) { + if (maybeValue.$ === 'Just') { + var value = maybeValue.a; + return callback(value); + } else { + return $elm$core$Maybe$Nothing; + } + }); var $author$project$Error$Utils$noError = $elm$core$Maybe$Nothing; +var $elm_community$maybe_extra$Maybe$Extra$or = F2( + function (ma, mb) { + if (ma.$ === 'Nothing') { + return mb; + } else { + return ma; + } + }); +var $author$project$Pages$Completion$Model$ReportNutritionIndividual = {$: 'ReportNutritionIndividual'}; +var $author$project$Pages$Completion$Utils$reportTypeFromString = function (reportType) { + if (reportType === 'nutrition-individual') { + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionIndividual); + } else { + return $elm$core$Maybe$Nothing; + } +}; var $author$project$Pages$Completion$Update$update = F4( function (currentDate, modelBackend, msg, model) { - return A4($author$project$App$Model$PagesReturn, model, $elm$core$Platform$Cmd$none, $author$project$Error$Utils$noError, _List_Nil); + switch (msg.$) { + case 'NoOp': + return A4($author$project$App$Model$PagesReturn, model, $elm$core$Platform$Cmd$none, $author$project$Error$Utils$noError, _List_Nil); + case 'SetReportType': + var value = msg.a; + return A4( + $author$project$App$Model$PagesReturn, + _Utils_update( + model, + { + limitDate: $elm$core$Maybe$Nothing, + reportType: $author$project$Pages$Completion$Utils$reportTypeFromString(value), + startDate: $elm$core$Maybe$Nothing + }), + $elm$core$Platform$Cmd$none, + $author$project$Error$Utils$noError, + _List_Nil); + case 'SetStartDate': + var value = msg.a; + return A4( + $author$project$App$Model$PagesReturn, + _Utils_update( + model, + { + startDate: $elm$core$Maybe$Just(value) + }), + $elm$core$Platform$Cmd$none, + $author$project$Error$Utils$noError, + _List_Nil); + case 'SetStartDateSelectorState': + var state = msg.a; + var defaultSelection = A2( + $elm_community$maybe_extra$Maybe$Extra$or, + model.startDate, + A2( + $elm$core$Maybe$andThen, + function ($) { + return $.dateDefault; + }, + state)); + return A4( + $author$project$App$Model$PagesReturn, + _Utils_update( + model, + {startDate: defaultSelection, startDateSelectorPopupState: state}), + $elm$core$Platform$Cmd$none, + $author$project$Error$Utils$noError, + _List_Nil); + case 'SetLimitDate': + var value = msg.a; + return A4( + $author$project$App$Model$PagesReturn, + _Utils_update( + model, + { + limitDate: $elm$core$Maybe$Just(value) + }), + $elm$core$Platform$Cmd$none, + $author$project$Error$Utils$noError, + _List_Nil); + default: + var state = msg.a; + var defaultSelection = A2( + $elm_community$maybe_extra$Maybe$Extra$or, + model.limitDate, + A2( + $elm$core$Maybe$andThen, + function ($) { + return $.dateDefault; + }, + state)); + return A4( + $author$project$App$Model$PagesReturn, + _Utils_update( + model, + {limitDate: defaultSelection, limitDateSelectorPopupState: state}), + $elm$core$Platform$Cmd$none, + $author$project$Error$Utils$noError, + _List_Nil); + } }); var $author$project$Pages$Components$Types$SelectionOptionDemographics = {$: 'SelectionOptionDemographics'}; var $author$project$Pages$Components$Types$SelectionOptionGlobal = {$: 'SelectionOptionGlobal'}; @@ -5866,15 +5970,6 @@ var $author$project$Pages$CompletionMenu$Update$update = F2( } }); var $krisajenkins$remotedata$RemoteData$Loading = {$: 'Loading'}; -var $elm$core$Maybe$andThen = F2( - function (callback, maybeValue) { - if (maybeValue.$ === 'Just') { - var value = maybeValue.a; - return callback(value); - } else { - return $elm$core$Maybe$Nothing; - } - }); var $elm$json$Json$Encode$list = F2( function (func, entries) { return _Json_wrap( @@ -5963,14 +6058,6 @@ var $author$project$Pages$Reports$Utils$isWideScope = function (selectedEntity) _List_fromArray( [$author$project$Backend$Reports$Model$EntityGlobal, $author$project$Backend$Reports$Model$EntityProvince, $author$project$Backend$Reports$Model$EntityDistrict, $author$project$Backend$Reports$Model$EntityHealthCenter])); }; -var $elm_community$maybe_extra$Maybe$Extra$or = F2( - function (ma, mb) { - if (ma.$ === 'Nothing') { - return mb; - } else { - return ma; - } - }); var $author$project$Pages$Reports$Model$NutritionReportDataCalculationCompleted = function (a) { return {$: 'NutritionReportDataCalculationCompleted', a: a}; }; @@ -9762,6 +9849,9 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Commune', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Completed': return {english: 'Completed', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'CompletionReportType': + var reportType = transId.a; + return {english: 'Nutrition Individual', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'CBNP': return {english: 'CBNP', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Cell': @@ -10417,71 +10507,44 @@ var $author$project$Error$View$view = F2( }); var $author$project$Gizra$Html$emptyNode = $elm$html$Html$text(''); var $elm$core$Debug$toString = _Debug_toString; +var $author$project$Translate$CompletionReportType = function (a) { + return {$: 'CompletionReportType', a: a}; +}; var $author$project$Translate$NewScope = {$: 'NewScope'}; +var $author$project$Translate$ReportTypeLabel = {$: 'ReportTypeLabel'}; var $author$project$Translate$Scope = {$: 'Scope'}; -var $elm$html$Html$a = _VirtualDom_node('a'); -var $elm$html$Html$button = _VirtualDom_node('button'); -var $author$project$Translate$Activity = {$: 'Activity'}; -var $author$project$Translate$Completed = {$: 'Completed'}; -var $author$project$Translate$Expected = {$: 'Expected'}; -var $author$project$Translate$NutritionActivity = function (a) { - return {$: 'NutritionActivity', a: a}; +var $author$project$Translate$SelectLimitDate = {$: 'SelectLimitDate'}; +var $author$project$Translate$SelectStartDate = {$: 'SelectStartDate'}; +var $author$project$Pages$Completion$Model$SetLimitDate = function (a) { + return {$: 'SetLimitDate', a: a}; }; -var $author$project$Translate$NutritionIndividual = {$: 'NutritionIndividual'}; -var $author$project$Pages$Completion$Model$allNutritionActivities = _List_fromArray( - [$author$project$Backend$Completion$Model$NutritionHeight, $author$project$Backend$Completion$Model$NutritionNutrition, $author$project$Backend$Completion$Model$NutritionPhoto, $author$project$Backend$Completion$Model$NutritionWeight, $author$project$Backend$Completion$Model$NutritionMUAC, $author$project$Backend$Completion$Model$NutritionContributingFactors, $author$project$Backend$Completion$Model$NutritionFollowUp, $author$project$Backend$Completion$Model$NutritionHealthEducation, $author$project$Backend$Completion$Model$NutritionSendToHC, $author$project$Backend$Completion$Model$NutritionNCDA]); -var $elm$core$Basics$abs = function (n) { - return (n < 0) ? (-n) : n; +var $author$project$Pages$Completion$Model$SetLimitDateSelectorState = function (a) { + return {$: 'SetLimitDateSelectorState', a: a}; }; -var $elm$core$String$foldr = _String_foldr; -var $elm$core$String$toList = function (string) { - return A3($elm$core$String$foldr, $elm$core$List$cons, _List_Nil, string); +var $author$project$Pages$Completion$Model$SetReportType = function (a) { + return {$: 'SetReportType', a: a}; }; -var $myrho$elm_round$Round$addSign = F2( - function (signed, str) { - var isNotZero = A2( - $elm$core$List$any, - function (c) { - return (!_Utils_eq( - c, - _Utils_chr('0'))) && (!_Utils_eq( - c, - _Utils_chr('.'))); - }, - $elm$core$String$toList(str)); - return _Utils_ap( - (signed && isNotZero) ? '-' : '', - str); +var $author$project$Pages$Completion$Model$SetStartDate = function (a) { + return {$: 'SetStartDate', a: a}; +}; +var $author$project$Pages$Completion$Model$SetStartDateSelectorState = function (a) { + return {$: 'SetStartDateSelectorState', a: a}; +}; +var $elm$html$Html$a = _VirtualDom_node('a'); +var $elm$html$Html$button = _VirtualDom_node('button'); +var $justinmimbs$date$Date$day = A2( + $elm$core$Basics$composeR, + $justinmimbs$date$Date$toCalendarDate, + function ($) { + return $.day; + }); +var $justinmimbs$date$Date$ordinalDay = A2( + $elm$core$Basics$composeR, + $justinmimbs$date$Date$toOrdinalDate, + function ($) { + return $.ordinalDay; }); -var $elm$core$String$fromFloat = _String_fromNumber; var $elm$core$String$cons = _String_cons; -var $elm$core$Char$fromCode = _Char_fromCode; -var $myrho$elm_round$Round$increaseNum = function (_v0) { - var head = _v0.a; - var tail = _v0.b; - if (_Utils_eq( - head, - _Utils_chr('9'))) { - var _v1 = $elm$core$String$uncons(tail); - if (_v1.$ === 'Nothing') { - return '01'; - } else { - var headtail = _v1.a; - return A2( - $elm$core$String$cons, - _Utils_chr('0'), - $myrho$elm_round$Round$increaseNum(headtail)); - } - } else { - var c = $elm$core$Char$toCode(head); - return ((c >= 48) && (c < 57)) ? A2( - $elm$core$String$cons, - $elm$core$Char$fromCode(c + 1), - tail) : '0'; - } -}; -var $elm$core$Basics$isInfinite = _Basics_isInfinite; -var $elm$core$Basics$isNaN = _Basics_isNaN; var $elm$core$String$fromChar = function (_char) { return A2($elm$core$String$cons, _char, ''); }; @@ -10499,2544 +10562,2765 @@ var $elm$core$String$repeat = F2( function (n, chunk) { return A3($elm$core$String$repeatHelp, n, chunk, ''); }); -var $elm$core$String$padRight = F3( +var $elm$core$String$padLeft = F3( function (n, _char, string) { return _Utils_ap( - string, A2( $elm$core$String$repeat, n - $elm$core$String$length(string), - $elm$core$String$fromChar(_char))); + $elm$core$String$fromChar(_char)), + string); }); -var $elm$core$String$reverse = _String_reverse; -var $myrho$elm_round$Round$splitComma = function (str) { - var _v0 = A2($elm$core$String$split, '.', str); - if (_v0.b) { - if (_v0.b.b) { - var before = _v0.a; - var _v1 = _v0.b; - var after = _v1.a; - return _Utils_Tuple2(before, after); - } else { - var before = _v0.a; - return _Utils_Tuple2(before, '0'); - } - } else { - return _Utils_Tuple2('0', '0'); - } +var $elm$core$Basics$abs = function (n) { + return (n < 0) ? (-n) : n; }; -var $elm$core$Tuple$mapFirst = F2( - function (func, _v0) { - var x = _v0.a; - var y = _v0.b; - return _Utils_Tuple2( - func(x), - y); +var $justinmimbs$date$Date$padSignedInt = F2( + function (length, _int) { + return _Utils_ap( + (_int < 0) ? '-' : '', + A3( + $elm$core$String$padLeft, + length, + _Utils_chr('0'), + $elm$core$String$fromInt( + $elm$core$Basics$abs(_int)))); }); -var $myrho$elm_round$Round$toDecimal = function (fl) { - var _v0 = A2( - $elm$core$String$split, - 'e', - $elm$core$String$fromFloat( - $elm$core$Basics$abs(fl))); - if (_v0.b) { - if (_v0.b.b) { - var num = _v0.a; - var _v1 = _v0.b; - var exp = _v1.a; - var e = A2( - $elm$core$Maybe$withDefault, - 0, - $elm$core$String$toInt( - A2($elm$core$String$startsWith, '+', exp) ? A2($elm$core$String$dropLeft, 1, exp) : exp)); - var _v2 = $myrho$elm_round$Round$splitComma(num); - var before = _v2.a; - var after = _v2.b; - var total = _Utils_ap(before, after); - var zeroed = (e < 0) ? A2( - $elm$core$Maybe$withDefault, - '0', - A2( - $elm$core$Maybe$map, - function (_v3) { - var a = _v3.a; - var b = _v3.b; - return a + ('.' + b); - }, - A2( - $elm$core$Maybe$map, - $elm$core$Tuple$mapFirst($elm$core$String$fromChar), - $elm$core$String$uncons( - _Utils_ap( - A2( - $elm$core$String$repeat, - $elm$core$Basics$abs(e), - '0'), - total))))) : A3( - $elm$core$String$padRight, - e + 1, - _Utils_chr('0'), - total); - return _Utils_ap( - (fl < 0) ? '-' : '', - zeroed); - } else { - var num = _v0.a; - return _Utils_ap( - (fl < 0) ? '-' : '', - num); - } - } else { - return ''; - } +var $justinmimbs$date$Date$monthToQuarter = function (m) { + return (($justinmimbs$date$Date$monthToNumber(m) + 2) / 3) | 0; }; -var $myrho$elm_round$Round$roundFun = F3( - function (functor, s, fl) { - if ($elm$core$Basics$isInfinite(fl) || $elm$core$Basics$isNaN(fl)) { - return $elm$core$String$fromFloat(fl); - } else { - var signed = fl < 0; - var _v0 = $myrho$elm_round$Round$splitComma( - $myrho$elm_round$Round$toDecimal( - $elm$core$Basics$abs(fl))); - var before = _v0.a; - var after = _v0.b; - var r = $elm$core$String$length(before) + s; - var normalized = _Utils_ap( - A2($elm$core$String$repeat, (-r) + 1, '0'), - A3( - $elm$core$String$padRight, - r, - _Utils_chr('0'), - _Utils_ap(before, after))); - var totalLen = $elm$core$String$length(normalized); - var roundDigitIndex = A2($elm$core$Basics$max, 1, r); - var increase = A2( - functor, - signed, - A3($elm$core$String$slice, roundDigitIndex, totalLen, normalized)); - var remains = A3($elm$core$String$slice, 0, roundDigitIndex, normalized); - var num = increase ? $elm$core$String$reverse( - A2( - $elm$core$Maybe$withDefault, - '1', - A2( - $elm$core$Maybe$map, - $myrho$elm_round$Round$increaseNum, - $elm$core$String$uncons( - $elm$core$String$reverse(remains))))) : remains; - var numLen = $elm$core$String$length(num); - var numZeroed = (num === '0') ? num : ((s <= 0) ? _Utils_ap( - num, - A2( - $elm$core$String$repeat, - $elm$core$Basics$abs(s), - '0')) : ((_Utils_cmp( - s, - $elm$core$String$length(after)) < 0) ? (A3($elm$core$String$slice, 0, numLen - s, num) + ('.' + A3($elm$core$String$slice, numLen - s, numLen, num))) : _Utils_ap( - before + '.', - A3( - $elm$core$String$padRight, - s, - _Utils_chr('0'), - after)))); - return A2($myrho$elm_round$Round$addSign, signed, numZeroed); - } - }); -var $myrho$elm_round$Round$round = $myrho$elm_round$Round$roundFun( - F2( - function (signed, str) { - var _v0 = $elm$core$String$uncons(str); - if (_v0.$ === 'Nothing') { - return false; - } else { - if ('5' === _v0.a.a.valueOf()) { - if (_v0.a.b === '') { - var _v1 = _v0.a; - return !signed; - } else { - var _v2 = _v0.a; - return true; - } - } else { - var _v3 = _v0.a; - var _int = _v3.a; - return function (i) { - return ((i > 53) && signed) || ((i >= 53) && (!signed)); - }( - $elm$core$Char$toCode(_int)); - } - } - })); -var $author$project$Pages$Completion$View$generateNutritionReportData = F2( - function (language, records) { - var count = F2( - function (resolveFunc, activity) { - return $elm$core$List$length( - A2( - $elm$core$List$filter, - A2( - $elm$core$Basics$composeR, - resolveFunc, - $elm$core$List$member(activity)), - records)); - }); - var calcualtePercentage = F2( - function (nominator, total) { - return (!total) ? '0' : (A2($myrho$elm_round$Round$round, 3, (nominator / total) * 100) + '%'); - }); - return { - captions: _List_fromArray( - [ - A2($author$project$Translate$translate, language, $author$project$Translate$Activity), - A2($author$project$Translate$translate, language, $author$project$Translate$Expected), - A2($author$project$Translate$translate, language, $author$project$Translate$Completed), - '%' - ]), - heading: A2($author$project$Translate$translate, language, $author$project$Translate$NutritionIndividual), - rows: A2( - $elm$core$List$map, - function (activity) { - var expected = A2( - count, - function ($) { - return $.expectedActivities; - }, - activity); - var completed = A2( - count, - function ($) { - return $.completedActivities; - }, - activity); - return _List_fromArray( - [ - A2( - $author$project$Translate$translate, - language, - $author$project$Translate$NutritionActivity(activity)), - $elm$core$String$fromInt(expected), - $elm$core$String$fromInt(completed), - A2(calcualtePercentage, completed, expected) - ]); - }, - $author$project$Pages$Completion$Model$allNutritionActivities) - }; +var $justinmimbs$date$Date$quarter = A2($elm$core$Basics$composeR, $justinmimbs$date$Date$month, $justinmimbs$date$Date$monthToQuarter); +var $elm$core$String$right = F2( + function (n, string) { + return (n < 1) ? '' : A3( + $elm$core$String$slice, + -n, + $elm$core$String$length(string), + string); }); -var $elm$html$Html$Attributes$href = function (url) { - return A2( - $elm$html$Html$Attributes$stringProperty, - 'href', - _VirtualDom_noJavaScriptUri(url)); +var $elm$time$Time$Fri = {$: 'Fri'}; +var $elm$time$Time$Mon = {$: 'Mon'}; +var $elm$time$Time$Sat = {$: 'Sat'}; +var $elm$time$Time$Sun = {$: 'Sun'}; +var $elm$time$Time$Thu = {$: 'Thu'}; +var $elm$time$Time$Tue = {$: 'Tue'}; +var $elm$time$Time$Wed = {$: 'Wed'}; +var $justinmimbs$date$Date$numberToWeekday = function (wdn) { + var _v0 = A2($elm$core$Basics$max, 1, wdn); + switch (_v0) { + case 1: + return $elm$time$Time$Mon; + case 2: + return $elm$time$Time$Tue; + case 3: + return $elm$time$Time$Wed; + case 4: + return $elm$time$Time$Thu; + case 5: + return $elm$time$Time$Fri; + case 6: + return $elm$time$Time$Sat; + default: + return $elm$time$Time$Sun; + } }; -var $elm$html$Html$Attributes$classList = function (classes) { - return $elm$html$Html$Attributes$class( - A2( - $elm$core$String$join, - ' ', - A2( - $elm$core$List$map, - $elm$core$Tuple$first, - A2($elm$core$List$filter, $elm$core$Tuple$second, classes)))); +var $justinmimbs$date$Date$toWeekDate = function (_v0) { + var rd = _v0.a; + var wdn = $justinmimbs$date$Date$weekdayNumber( + $justinmimbs$date$Date$RD(rd)); + var wy = $justinmimbs$date$Date$year( + $justinmimbs$date$Date$RD(rd + (4 - wdn))); + var week1Day1 = $justinmimbs$date$Date$daysBeforeWeekYear(wy) + 1; + return { + weekNumber: 1 + (((rd - week1Day1) / 7) | 0), + weekYear: wy, + weekday: $justinmimbs$date$Date$numberToWeekday(wdn) + }; }; -var $author$project$Pages$Utils$viewCustomCells = F2( - function (labelClass, valueClass) { - return $elm$core$List$indexedMap( - F2( - function (index, cellText) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$classList( - _List_fromArray( - [ - _Utils_Tuple2('item', true), - _Utils_Tuple2(labelClass, !index), - _Utils_Tuple2(valueClass, !(!index)) - ])) - ]), - _List_fromArray( - [ - $elm$html$Html$text(cellText) - ])); - })); - }); -var $author$project$Pages$Utils$viewStandardCells = A2($author$project$Pages$Utils$viewCustomCells, 'label', 'value'); -var $author$project$Pages$Utils$viewStandardRow = A2( +var $justinmimbs$date$Date$weekNumber = A2( $elm$core$Basics$composeR, - $author$project$Pages$Utils$viewStandardCells, - $elm$html$Html$div( - _List_fromArray( - [ - $elm$html$Html$Attributes$class('row') - ]))); -var $author$project$Pages$Completion$View$viewCompletionData = F5( - function (language, currentDate, themePath, data, model) { - var topBar = function () { - var scopeLabel = function () { - var _v0 = data.entityType; - if (_v0.$ === 'EntityGlobal') { - return A2($author$project$Translate$translate, language, $author$project$Translate$Global); - } else { - return data.entityName; - } - }(); - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('top-bar') - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('new-selection') - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$a, - _List_fromArray( - [ - $elm$html$Html$Attributes$href('/admin/reports/completion') - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$button, - _List_Nil, - _List_fromArray( - [ - $elm$html$Html$text( - A2($author$project$Translate$translate, language, $author$project$Translate$NewScope)) - ])) - ])) - ])), - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('scope') - ]), - _List_fromArray( - [ - $elm$html$Html$text( - A2($author$project$Translate$translate, language, $author$project$Translate$Scope) + (': ' + scopeLabel)) - ])) - ])); - }(); - var reportData = A2($author$project$Pages$Completion$View$generateNutritionReportData, language, data.nutritionIndividualData); - var captionsRow = A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('row captions') - ]), - $author$project$Pages$Utils$viewStandardCells(reportData.captions)); - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('page-content completion') - ]), - _List_fromArray( - [ - topBar, - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('inputs') - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('report') - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('table') - ]), - A2( - $elm$core$List$cons, - captionsRow, - A2($elm$core$List$map, $author$project$Pages$Utils$viewStandardRow, reportData.rows))) - ])) - ])) - ])); + $justinmimbs$date$Date$toWeekDate, + function ($) { + return $.weekNumber; }); -var $author$project$Pages$Completion$View$view = F5( - function (language, currentDate, themePath, modelBackend, model) { - var _v0 = modelBackend.completionData; - if (_v0.$ === 'Just') { - if (_v0.a.$ === 'Ok') { - var data = _v0.a.a; - return A5($author$project$Pages$Completion$View$viewCompletionData, language, currentDate, themePath, data, model); - } else { - var err = _v0.a.a; - return $elm$html$Html$text( - $elm$core$Debug$toString(err)); - } - } else { - return $author$project$Gizra$Html$emptyNode; - } +var $justinmimbs$date$Date$weekYear = A2( + $elm$core$Basics$composeR, + $justinmimbs$date$Date$toWeekDate, + function ($) { + return $.weekYear; }); -var $author$project$Translate$PleaseWaitMessage = {$: 'PleaseWaitMessage'}; -var $author$project$Translate$PopulationSelectionOption = function (a) { - return {$: 'PopulationSelectionOption', a: a}; -}; -var $author$project$Translate$SelectScope = {$: 'SelectScope'}; -var $author$project$Pages$CompletionMenu$Model$SelectionMade = {$: 'SelectionMade'}; -var $author$project$Pages$CompletionMenu$Model$SetHealthCenter = function (a) { - return {$: 'SetHealthCenter', a: a}; -}; -var $author$project$Pages$CompletionMenu$Model$SetPopulationSelection = function (a) { - return {$: 'SetPopulationSelection', a: a}; -}; -var $author$project$Pages$Components$Utils$populationSelectionOptionToString = function (selectionOption) { - switch (selectionOption.$) { - case 'SelectionOptionGlobal': - return 'all'; - case 'SelectionOptionDemographics': - return 'demographics'; +var $justinmimbs$date$Date$weekday = A2($elm$core$Basics$composeR, $justinmimbs$date$Date$weekdayNumber, $justinmimbs$date$Date$numberToWeekday); +var $elm$core$Basics$min = F2( + function (x, y) { + return (_Utils_cmp(x, y) < 0) ? x : y; + }); +var $justinmimbs$date$Date$ordinalSuffix = function (n) { + var nn = A2($elm$core$Basics$modBy, 100, n); + var _v0 = A2( + $elm$core$Basics$min, + (nn < 20) ? nn : A2($elm$core$Basics$modBy, 10, nn), + 4); + switch (_v0) { + case 1: + return 'st'; + case 2: + return 'nd'; + case 3: + return 'rd'; default: - return 'hc'; + return 'th'; } }; -var $elm$core$List$sortBy = _List_sortBy; -var $author$project$Pages$Utils$viewCustomLabel = F4( - function (language, translationId, suffix, class_) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class(class_) - ]), - _List_fromArray( - [ - $elm$html$Html$text( - _Utils_ap( - A2($author$project$Translate$translate, language, translationId), - suffix)) - ])); - }); -var $elm$html$Html$option = _VirtualDom_node('option'); -var $elm$json$Json$Encode$bool = _Json_wrap; -var $elm$html$Html$Attributes$boolProperty = F2( - function (key, bool) { - return A2( - _VirtualDom_property, - key, - $elm$json$Json$Encode$bool(bool)); - }); -var $elm$html$Html$Attributes$selected = $elm$html$Html$Attributes$boolProperty('selected'); -var $elm$html$Html$Attributes$value = $elm$html$Html$Attributes$stringProperty('value'); -var $author$project$Pages$Utils$emptySelectOption = function (isSelected) { - return A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value(''), - $elm$html$Html$Attributes$selected(isSelected) - ]), - _List_fromArray( - [ - $elm$html$Html$text('') - ])); -}; -var $elm$html$Html$Events$alwaysStop = function (x) { - return _Utils_Tuple2(x, true); -}; -var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { - return {$: 'MayStopPropagation', a: a}; -}; -var $elm$virtual_dom$VirtualDom$on = _VirtualDom_on; -var $elm$html$Html$Events$stopPropagationOn = F2( - function (event, decoder) { - return A2( - $elm$virtual_dom$VirtualDom$on, - event, - $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); - }); -var $elm$html$Html$Events$targetValue = A2( - $elm$json$Json$Decode$at, - _List_fromArray( - ['target', 'value']), - $elm$json$Json$Decode$string); -var $elm$html$Html$Events$onInput = function (tagger) { - return A2( - $elm$html$Html$Events$stopPropagationOn, - 'input', - A2( - $elm$json$Json$Decode$map, - $elm$html$Html$Events$alwaysStop, - A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); +var $justinmimbs$date$Date$withOrdinalSuffix = function (n) { + return _Utils_ap( + $elm$core$String$fromInt(n), + $justinmimbs$date$Date$ordinalSuffix(n)); }; -var $elm$html$Html$select = _VirtualDom_node('select'); -var $author$project$Pages$Utils$viewCustomSelectListInput = F6( - function (currentValue, options, toStringFunc, setMsg, inputClass, withEmptyOption) { - var emptyOption = withEmptyOption ? $author$project$Pages$Utils$emptySelectOption( - _Utils_eq(currentValue, $elm$core$Maybe$Nothing)) : $author$project$Gizra$Html$emptyNode; - return A2( - $elm$html$Html$select, - _List_fromArray( - [ - $elm$html$Html$Events$onInput(setMsg), - $elm$html$Html$Attributes$class(inputClass) - ]), - A2( - $elm$core$List$cons, - emptyOption, - A2( - $elm$core$List$map, - function (_v0) { - var label = _v0.a; - var value_ = _v0.b; - return A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value( - toStringFunc(value_)), - $elm$html$Html$Attributes$selected( - _Utils_eq( - currentValue, - $elm$core$Maybe$Just(value_))) - ]), - _List_fromArray( - [ - $elm$html$Html$text(label) - ])); - }, - options))); - }); -var $author$project$Translate$LoadData = {$: 'LoadData'}; -var $elm$virtual_dom$VirtualDom$Normal = function (a) { - return {$: 'Normal', a: a}; -}; -var $elm$html$Html$Events$on = F2( - function (event, decoder) { - return A2( - $elm$virtual_dom$VirtualDom$on, - event, - $elm$virtual_dom$VirtualDom$Normal(decoder)); - }); -var $elm$html$Html$Events$onClick = function (msg) { - return A2( - $elm$html$Html$Events$on, - 'click', - $elm$json$Json$Decode$succeed(msg)); -}; -var $author$project$Pages$Utils$viewMenuActionButton = F4( - function (language, path, label, selectionMadeMsg) { - return A2( - $elm$html$Html$a, - _List_fromArray( - [ - $elm$html$Html$Attributes$href(path) - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$button, - _List_fromArray( - [ - $elm$html$Html$Events$onClick(selectionMadeMsg) - ]), - _List_fromArray( - [ - $elm$html$Html$text( - A2($author$project$Translate$translate, language, label)) - ])) - ])); - }); -var $author$project$Pages$Utils$viewLoadDataButton = F3( - function (language, path, selectionMadeMsg) { - return A4($author$project$Pages$Utils$viewMenuActionButton, language, path, $author$project$Translate$LoadData, selectionMadeMsg); - }); -var $author$project$Pages$Utils$viewSelectListInput = F7( - function (language, currentValue, options, toStringFunc, setMsg, transId, inputClass) { - var transFunc = A2( - $elm$core$Basics$composeR, - transId, - $author$project$Translate$translate(language)); - var optionsPairs = A2( - $elm$core$List$map, - function (option) { - return _Utils_Tuple2( - transFunc(option), - option); - }, - options); - return A6($author$project$Pages$Utils$viewCustomSelectListInput, currentValue, optionsPairs, toStringFunc, setMsg, inputClass, true); - }); -var $author$project$Pages$Utils$viewLabel = F2( - function (language, translationId) { - return A4($author$project$Pages$Utils$viewCustomLabel, language, translationId, ':', 'label'); - }); -var $author$project$Pages$Utils$wrapSelectListInput = F4( - function (language, labelTransId, disabled, selectList) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$classList( - _List_fromArray( - [ - _Utils_Tuple2('select-input-wrapper', true), - _Utils_Tuple2('disabled', disabled) - ])) - ]), - _List_fromArray( - [ - A2($author$project$Pages$Utils$viewLabel, language, labelTransId), - selectList - ])); - }); -var $author$project$Pages$CompletionMenu$View$viewMenu = F4( - function (language, themePath, data, model) { - var populationSelectionInput = A4( - $author$project$Pages$Utils$wrapSelectListInput, - language, - $author$project$Translate$Scope, - false, - A7( - $author$project$Pages$Utils$viewSelectListInput, - language, - model.populationSelection, - _List_fromArray( - [$author$project$Pages$Components$Types$SelectionOptionGlobal, $author$project$Pages$Components$Types$SelectionOptionHealthCenter]), - $author$project$Pages$Components$Utils$populationSelectionOptionToString, - $author$project$Pages$CompletionMenu$Model$SetPopulationSelection, - $author$project$Translate$PopulationSelectionOption, - 'select-input')); - var _v0 = A2( - $elm$core$Maybe$withDefault, - _Utils_Tuple2(_List_Nil, $author$project$Gizra$Html$emptyNode), - A2( - $elm$core$Maybe$map, - function (populationSelection) { - switch (populationSelection.$) { - case 'SelectionOptionGlobal': - return _Utils_Tuple2( - _List_Nil, - A3($author$project$Pages$Utils$viewLoadDataButton, language, '/admin/reports/completion/all', $author$project$Pages$CompletionMenu$Model$SelectionMade)); - case 'SelectionOptionHealthCenter': - var options = A2( - $elm$core$List$map, - function (healthCenter) { - return _Utils_Tuple2(healthCenter.name, healthCenter.id); - }, - A2( - $elm$core$List$sortBy, - function ($) { - return $.name; - }, - data.healthCenters)); - return _Utils_Tuple2( - _List_fromArray( - [ - A4( - $author$project$Pages$Utils$wrapSelectListInput, - language, - $author$project$Translate$HealthCenter, - false, - A6($author$project$Pages$Utils$viewCustomSelectListInput, model.selectedHealthCenter, options, $elm$core$String$fromInt, $author$project$Pages$CompletionMenu$Model$SetHealthCenter, 'select-input', true)) - ]), - A2( - $elm$core$Maybe$withDefault, - $author$project$Gizra$Html$emptyNode, - A2( - $elm$core$Maybe$map, - function (selectedHealthCenter) { - return A3( - $author$project$Pages$Utils$viewLoadDataButton, - language, - '/admin/reports/completion/health-center/' + $elm$core$String$fromInt(selectedHealthCenter), - $author$project$Pages$CompletionMenu$Model$SelectionMade); - }, - model.selectedHealthCenter))); - default: - return _Utils_Tuple2(_List_Nil, $author$project$Gizra$Html$emptyNode); - } - }, - model.populationSelection)); - var derivedInputs = _v0.a; - var actionButton_ = _v0.b; - var actionButton = model.selected ? $elm$html$Html$text( - A2($author$project$Translate$translate, language, $author$project$Translate$PleaseWaitMessage)) : actionButton_; - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('page-content completion-menu') - ]), - _List_fromArray( - [ - A4($author$project$Pages$Utils$viewCustomLabel, language, $author$project$Translate$SelectScope, ':', 'header'), - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('inputs') - ]), - A2($elm$core$List$cons, populationSelectionInput, derivedInputs)), - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('actions') - ]), - _List_fromArray( - [actionButton])) - ])); - }); -var $author$project$Pages$CompletionMenu$View$view = F4( - function (language, themePath, modelBackend, model) { - var _v0 = modelBackend.completionMenuData; - if (_v0.$ === 'Just') { - if (_v0.a.$ === 'Ok') { - var data = _v0.a.a; - return A4($author$project$Pages$CompletionMenu$View$viewMenu, language, themePath, data, model); - } else { - var err = _v0.a.a; - return $elm$html$Html$text( - $elm$core$Debug$toString(err)); - } - } else { - return $author$project$Gizra$Html$emptyNode; - } - }); -var $author$project$Translate$ReportType = function (a) { - return {$: 'ReportType', a: a}; -}; -var $author$project$Translate$ReportTypeLabel = {$: 'ReportTypeLabel'}; -var $author$project$Translate$SelectLimitDate = {$: 'SelectLimitDate'}; -var $author$project$Translate$SelectStartDate = {$: 'SelectStartDate'}; -var $author$project$Translate$SelectedScope = function (a) { - return {$: 'SelectedScope', a: a}; -}; -var $author$project$Pages$Reports$Model$SetLimitDate = function (a) { - return {$: 'SetLimitDate', a: a}; -}; -var $author$project$Pages$Reports$Model$SetLimitDateSelectorState = function (a) { - return {$: 'SetLimitDateSelectorState', a: a}; -}; -var $author$project$Pages$Reports$Model$SetReportType = function (a) { - return {$: 'SetReportType', a: a}; -}; -var $author$project$Pages$Reports$Model$SetStartDate = function (a) { - return {$: 'SetStartDate', a: a}; -}; -var $author$project$Pages$Reports$Model$SetStartDateSelectorState = function (a) { - return {$: 'SetStartDateSelectorState', a: a}; -}; -var $author$project$Translate$WideScopeNote = {$: 'WideScopeNote'}; -var $elm$core$Basics$min = F2( - function (x, y) { - return (_Utils_cmp(x, y) < 0) ? x : y; - }); -var $justinmimbs$date$Date$add = F3( - function (unit, n, _v0) { - var rd = _v0.a; - switch (unit.$) { - case 'Years': - return A3( - $justinmimbs$date$Date$add, - $justinmimbs$date$Date$Months, - 12 * n, - $justinmimbs$date$Date$RD(rd)); - case 'Months': - var date = $justinmimbs$date$Date$toCalendarDate( - $justinmimbs$date$Date$RD(rd)); - var wholeMonths = ((12 * (date.year - 1)) + ($justinmimbs$date$Date$monthToNumber(date.month) - 1)) + n; - var m = $justinmimbs$date$Date$numberToMonth( - A2($elm$core$Basics$modBy, 12, wholeMonths) + 1); - var y = A2($justinmimbs$date$Date$floorDiv, wholeMonths, 12) + 1; - return $justinmimbs$date$Date$RD( - ($justinmimbs$date$Date$daysBeforeYear(y) + A2($justinmimbs$date$Date$daysBeforeMonth, y, m)) + A2( - $elm$core$Basics$min, - date.day, - A2($justinmimbs$date$Date$daysInMonth, y, m))); - case 'Weeks': - return $justinmimbs$date$Date$RD(rd + (7 * n)); +var $justinmimbs$date$Date$formatField = F4( + function (language, _char, length, date) { + switch (_char.valueOf()) { + case 'y': + if (length === 2) { + return A2( + $elm$core$String$right, + 2, + A3( + $elm$core$String$padLeft, + 2, + _Utils_chr('0'), + $elm$core$String$fromInt( + $justinmimbs$date$Date$year(date)))); + } else { + return A2( + $justinmimbs$date$Date$padSignedInt, + length, + $justinmimbs$date$Date$year(date)); + } + case 'Y': + if (length === 2) { + return A2( + $elm$core$String$right, + 2, + A3( + $elm$core$String$padLeft, + 2, + _Utils_chr('0'), + $elm$core$String$fromInt( + $justinmimbs$date$Date$weekYear(date)))); + } else { + return A2( + $justinmimbs$date$Date$padSignedInt, + length, + $justinmimbs$date$Date$weekYear(date)); + } + case 'Q': + switch (length) { + case 1: + return $elm$core$String$fromInt( + $justinmimbs$date$Date$quarter(date)); + case 2: + return $elm$core$String$fromInt( + $justinmimbs$date$Date$quarter(date)); + case 3: + return 'Q' + $elm$core$String$fromInt( + $justinmimbs$date$Date$quarter(date)); + case 4: + return $justinmimbs$date$Date$withOrdinalSuffix( + $justinmimbs$date$Date$quarter(date)); + case 5: + return $elm$core$String$fromInt( + $justinmimbs$date$Date$quarter(date)); + default: + return ''; + } + case 'M': + switch (length) { + case 1: + return $elm$core$String$fromInt( + $justinmimbs$date$Date$monthNumber(date)); + case 2: + return A3( + $elm$core$String$padLeft, + 2, + _Utils_chr('0'), + $elm$core$String$fromInt( + $justinmimbs$date$Date$monthNumber(date))); + case 3: + return language.monthNameShort( + $justinmimbs$date$Date$month(date)); + case 4: + return language.monthName( + $justinmimbs$date$Date$month(date)); + case 5: + return A2( + $elm$core$String$left, + 1, + language.monthNameShort( + $justinmimbs$date$Date$month(date))); + default: + return ''; + } + case 'w': + switch (length) { + case 1: + return $elm$core$String$fromInt( + $justinmimbs$date$Date$weekNumber(date)); + case 2: + return A3( + $elm$core$String$padLeft, + 2, + _Utils_chr('0'), + $elm$core$String$fromInt( + $justinmimbs$date$Date$weekNumber(date))); + default: + return ''; + } + case 'd': + switch (length) { + case 1: + return $elm$core$String$fromInt( + $justinmimbs$date$Date$day(date)); + case 2: + return A3( + $elm$core$String$padLeft, + 2, + _Utils_chr('0'), + $elm$core$String$fromInt( + $justinmimbs$date$Date$day(date))); + case 3: + return language.dayWithSuffix( + $justinmimbs$date$Date$day(date)); + default: + return ''; + } + case 'D': + switch (length) { + case 1: + return $elm$core$String$fromInt( + $justinmimbs$date$Date$ordinalDay(date)); + case 2: + return A3( + $elm$core$String$padLeft, + 2, + _Utils_chr('0'), + $elm$core$String$fromInt( + $justinmimbs$date$Date$ordinalDay(date))); + case 3: + return A3( + $elm$core$String$padLeft, + 3, + _Utils_chr('0'), + $elm$core$String$fromInt( + $justinmimbs$date$Date$ordinalDay(date))); + default: + return ''; + } + case 'E': + switch (length) { + case 1: + return language.weekdayNameShort( + $justinmimbs$date$Date$weekday(date)); + case 2: + return language.weekdayNameShort( + $justinmimbs$date$Date$weekday(date)); + case 3: + return language.weekdayNameShort( + $justinmimbs$date$Date$weekday(date)); + case 4: + return language.weekdayName( + $justinmimbs$date$Date$weekday(date)); + case 5: + return A2( + $elm$core$String$left, + 1, + language.weekdayNameShort( + $justinmimbs$date$Date$weekday(date))); + case 6: + return A2( + $elm$core$String$left, + 2, + language.weekdayNameShort( + $justinmimbs$date$Date$weekday(date))); + default: + return ''; + } + case 'e': + switch (length) { + case 1: + return $elm$core$String$fromInt( + $justinmimbs$date$Date$weekdayNumber(date)); + case 2: + return $elm$core$String$fromInt( + $justinmimbs$date$Date$weekdayNumber(date)); + default: + return A4( + $justinmimbs$date$Date$formatField, + language, + _Utils_chr('E'), + length, + date); + } default: - return $justinmimbs$date$Date$RD(rd + n); + return ''; } }); -var $justinmimbs$date$Date$day = A2( - $elm$core$Basics$composeR, - $justinmimbs$date$Date$toCalendarDate, - function ($) { - return $.day; - }); -var $justinmimbs$date$Date$ordinalDay = A2( - $elm$core$Basics$composeR, - $justinmimbs$date$Date$toOrdinalDate, - function ($) { - return $.ordinalDay; +var $justinmimbs$date$Date$formatWithTokens = F3( + function (language, tokens, date) { + return A3( + $elm$core$List$foldl, + F2( + function (token, formatted) { + if (token.$ === 'Field') { + var _char = token.a; + var length = token.b; + return _Utils_ap( + A4($justinmimbs$date$Date$formatField, language, _char, length, date), + formatted); + } else { + var str = token.a; + return _Utils_ap(str, formatted); + } + }), + '', + tokens); }); -var $elm$core$String$padLeft = F3( - function (n, _char, string) { - return _Utils_ap( - A2( - $elm$core$String$repeat, - n - $elm$core$String$length(string), - $elm$core$String$fromChar(_char)), - string); +var $justinmimbs$date$Pattern$Literal = function (a) { + return {$: 'Literal', a: a}; +}; +var $justinmimbs$date$Pattern$escapedQuote = A2( + $elm$parser$Parser$ignorer, + $elm$parser$Parser$succeed( + $justinmimbs$date$Pattern$Literal('\'')), + $elm$parser$Parser$token('\'\'')); +var $justinmimbs$date$Pattern$Field = F2( + function (a, b) { + return {$: 'Field', a: a, b: b}; }); -var $justinmimbs$date$Date$padSignedInt = F2( - function (length, _int) { - return _Utils_ap( - (_int < 0) ? '-' : '', - A3( - $elm$core$String$padLeft, - length, - _Utils_chr('0'), - $elm$core$String$fromInt( - $elm$core$Basics$abs(_int)))); +var $elm$parser$Parser$Advanced$chompWhileHelp = F5( + function (isGood, offset, row, col, s0) { + chompWhileHelp: + while (true) { + var newOffset = A3($elm$parser$Parser$Advanced$isSubChar, isGood, offset, s0.src); + if (_Utils_eq(newOffset, -1)) { + return A3( + $elm$parser$Parser$Advanced$Good, + _Utils_cmp(s0.offset, offset) < 0, + _Utils_Tuple0, + {col: col, context: s0.context, indent: s0.indent, offset: offset, row: row, src: s0.src}); + } else { + if (_Utils_eq(newOffset, -2)) { + var $temp$isGood = isGood, + $temp$offset = offset + 1, + $temp$row = row + 1, + $temp$col = 1, + $temp$s0 = s0; + isGood = $temp$isGood; + offset = $temp$offset; + row = $temp$row; + col = $temp$col; + s0 = $temp$s0; + continue chompWhileHelp; + } else { + var $temp$isGood = isGood, + $temp$offset = newOffset, + $temp$row = row, + $temp$col = col + 1, + $temp$s0 = s0; + isGood = $temp$isGood; + offset = $temp$offset; + row = $temp$row; + col = $temp$col; + s0 = $temp$s0; + continue chompWhileHelp; + } + } + } }); -var $justinmimbs$date$Date$monthToQuarter = function (m) { - return (($justinmimbs$date$Date$monthToNumber(m) + 2) / 3) | 0; +var $elm$parser$Parser$Advanced$chompWhile = function (isGood) { + return $elm$parser$Parser$Advanced$Parser( + function (s) { + return A5($elm$parser$Parser$Advanced$chompWhileHelp, isGood, s.offset, s.row, s.col, s); + }); }; -var $justinmimbs$date$Date$quarter = A2($elm$core$Basics$composeR, $justinmimbs$date$Date$month, $justinmimbs$date$Date$monthToQuarter); -var $elm$core$String$right = F2( - function (n, string) { - return (n < 1) ? '' : A3( - $elm$core$String$slice, - -n, - $elm$core$String$length(string), - string); +var $elm$parser$Parser$chompWhile = $elm$parser$Parser$Advanced$chompWhile; +var $elm$parser$Parser$Advanced$getOffset = $elm$parser$Parser$Advanced$Parser( + function (s) { + return A3($elm$parser$Parser$Advanced$Good, false, s.offset, s); }); -var $elm$time$Time$Fri = {$: 'Fri'}; -var $elm$time$Time$Mon = {$: 'Mon'}; -var $elm$time$Time$Sat = {$: 'Sat'}; -var $elm$time$Time$Sun = {$: 'Sun'}; -var $elm$time$Time$Thu = {$: 'Thu'}; -var $elm$time$Time$Tue = {$: 'Tue'}; -var $elm$time$Time$Wed = {$: 'Wed'}; -var $justinmimbs$date$Date$numberToWeekday = function (wdn) { - var _v0 = A2($elm$core$Basics$max, 1, wdn); - switch (_v0) { - case 1: - return $elm$time$Time$Mon; - case 2: - return $elm$time$Time$Tue; - case 3: - return $elm$time$Time$Wed; - case 4: - return $elm$time$Time$Thu; - case 5: - return $elm$time$Time$Fri; - case 6: - return $elm$time$Time$Sat; - default: - return $elm$time$Time$Sun; +var $elm$parser$Parser$getOffset = $elm$parser$Parser$Advanced$getOffset; +var $elm$core$String$foldr = _String_foldr; +var $elm$core$String$toList = function (string) { + return A3($elm$core$String$foldr, $elm$core$List$cons, _List_Nil, string); +}; +var $justinmimbs$date$Pattern$fieldRepeats = function (str) { + var _v0 = $elm$core$String$toList(str); + if (_v0.b && (!_v0.b.b)) { + var _char = _v0.a; + return A2( + $elm$parser$Parser$keeper, + A2( + $elm$parser$Parser$keeper, + $elm$parser$Parser$succeed( + F2( + function (x, y) { + return A2($justinmimbs$date$Pattern$Field, _char, 1 + (y - x)); + })), + A2( + $elm$parser$Parser$ignorer, + $elm$parser$Parser$getOffset, + $elm$parser$Parser$chompWhile( + $elm$core$Basics$eq(_char)))), + $elm$parser$Parser$getOffset); + } else { + return $elm$parser$Parser$problem('expected exactly one char'); } }; -var $justinmimbs$date$Date$toWeekDate = function (_v0) { - var rd = _v0.a; - var wdn = $justinmimbs$date$Date$weekdayNumber( - $justinmimbs$date$Date$RD(rd)); - var wy = $justinmimbs$date$Date$year( - $justinmimbs$date$Date$RD(rd + (4 - wdn))); - var week1Day1 = $justinmimbs$date$Date$daysBeforeWeekYear(wy) + 1; - return { - weekNumber: 1 + (((rd - week1Day1) / 7) | 0), - weekYear: wy, - weekday: $justinmimbs$date$Date$numberToWeekday(wdn) - }; +var $elm$parser$Parser$Advanced$getChompedString = function (parser) { + return A2($elm$parser$Parser$Advanced$mapChompedString, $elm$core$Basics$always, parser); }; -var $justinmimbs$date$Date$weekNumber = A2( - $elm$core$Basics$composeR, - $justinmimbs$date$Date$toWeekDate, - function ($) { - return $.weekNumber; +var $elm$parser$Parser$getChompedString = $elm$parser$Parser$Advanced$getChompedString; +var $justinmimbs$date$Pattern$field = A2( + $elm$parser$Parser$andThen, + $justinmimbs$date$Pattern$fieldRepeats, + $elm$parser$Parser$getChompedString( + $elm$parser$Parser$chompIf($elm$core$Char$isAlpha))); +var $justinmimbs$date$Pattern$finalize = A2( + $elm$core$List$foldl, + F2( + function (token, tokens) { + var _v0 = _Utils_Tuple2(token, tokens); + if (((_v0.a.$ === 'Literal') && _v0.b.b) && (_v0.b.a.$ === 'Literal')) { + var x = _v0.a.a; + var _v1 = _v0.b; + var y = _v1.a.a; + var rest = _v1.b; + return A2( + $elm$core$List$cons, + $justinmimbs$date$Pattern$Literal( + _Utils_ap(x, y)), + rest); + } else { + return A2($elm$core$List$cons, token, tokens); + } + }), + _List_Nil); +var $elm$parser$Parser$Advanced$lazy = function (thunk) { + return $elm$parser$Parser$Advanced$Parser( + function (s) { + var _v0 = thunk(_Utils_Tuple0); + var parse = _v0.a; + return parse(s); + }); +}; +var $elm$parser$Parser$lazy = $elm$parser$Parser$Advanced$lazy; +var $justinmimbs$date$Pattern$isLiteralChar = function (_char) { + return (!_Utils_eq( + _char, + _Utils_chr('\''))) && (!$elm$core$Char$isAlpha(_char)); +}; +var $justinmimbs$date$Pattern$literal = A2( + $elm$parser$Parser$map, + $justinmimbs$date$Pattern$Literal, + $elm$parser$Parser$getChompedString( + A2( + $elm$parser$Parser$ignorer, + A2( + $elm$parser$Parser$ignorer, + $elm$parser$Parser$succeed(_Utils_Tuple0), + $elm$parser$Parser$chompIf($justinmimbs$date$Pattern$isLiteralChar)), + $elm$parser$Parser$chompWhile($justinmimbs$date$Pattern$isLiteralChar)))); +var $justinmimbs$date$Pattern$quotedHelp = function (result) { + return $elm$parser$Parser$oneOf( + _List_fromArray( + [ + A2( + $elm$parser$Parser$andThen, + function (str) { + return $justinmimbs$date$Pattern$quotedHelp( + _Utils_ap(result, str)); + }, + $elm$parser$Parser$getChompedString( + A2( + $elm$parser$Parser$ignorer, + A2( + $elm$parser$Parser$ignorer, + $elm$parser$Parser$succeed(_Utils_Tuple0), + $elm$parser$Parser$chompIf( + $elm$core$Basics$neq( + _Utils_chr('\'')))), + $elm$parser$Parser$chompWhile( + $elm$core$Basics$neq( + _Utils_chr('\'')))))), + A2( + $elm$parser$Parser$andThen, + function (_v0) { + return $justinmimbs$date$Pattern$quotedHelp(result + '\''); + }, + $elm$parser$Parser$token('\'\'')), + $elm$parser$Parser$succeed(result) + ])); +}; +var $justinmimbs$date$Pattern$quoted = A2( + $elm$parser$Parser$keeper, + A2( + $elm$parser$Parser$ignorer, + $elm$parser$Parser$succeed($justinmimbs$date$Pattern$Literal), + $elm$parser$Parser$chompIf( + $elm$core$Basics$eq( + _Utils_chr('\'')))), + A2( + $elm$parser$Parser$ignorer, + $justinmimbs$date$Pattern$quotedHelp(''), + $elm$parser$Parser$oneOf( + _List_fromArray( + [ + $elm$parser$Parser$chompIf( + $elm$core$Basics$eq( + _Utils_chr('\''))), + $elm$parser$Parser$end + ])))); +var $justinmimbs$date$Pattern$patternHelp = function (tokens) { + return $elm$parser$Parser$oneOf( + _List_fromArray( + [ + A2( + $elm$parser$Parser$andThen, + function (token) { + return $justinmimbs$date$Pattern$patternHelp( + A2($elm$core$List$cons, token, tokens)); + }, + $elm$parser$Parser$oneOf( + _List_fromArray( + [$justinmimbs$date$Pattern$field, $justinmimbs$date$Pattern$literal, $justinmimbs$date$Pattern$escapedQuote, $justinmimbs$date$Pattern$quoted]))), + $elm$parser$Parser$lazy( + function (_v0) { + return $elm$parser$Parser$succeed( + $justinmimbs$date$Pattern$finalize(tokens)); + }) + ])); +}; +var $elm$core$Result$withDefault = F2( + function (def, result) { + if (result.$ === 'Ok') { + var a = result.a; + return a; + } else { + return def; + } }); -var $justinmimbs$date$Date$weekYear = A2( - $elm$core$Basics$composeR, - $justinmimbs$date$Date$toWeekDate, - function ($) { - return $.weekYear; +var $justinmimbs$date$Pattern$fromString = function (str) { + return A2( + $elm$core$Result$withDefault, + _List_fromArray( + [ + $justinmimbs$date$Pattern$Literal(str) + ]), + A2( + $elm$parser$Parser$run, + $justinmimbs$date$Pattern$patternHelp(_List_Nil), + str)); +}; +var $justinmimbs$date$Date$formatWithLanguage = F2( + function (language, pattern) { + var tokens = $elm$core$List$reverse( + $justinmimbs$date$Pattern$fromString(pattern)); + return A2($justinmimbs$date$Date$formatWithTokens, language, tokens); }); -var $justinmimbs$date$Date$weekday = A2($elm$core$Basics$composeR, $justinmimbs$date$Date$weekdayNumber, $justinmimbs$date$Date$numberToWeekday); -var $justinmimbs$date$Date$ordinalSuffix = function (n) { - var nn = A2($elm$core$Basics$modBy, 100, n); - var _v0 = A2( - $elm$core$Basics$min, - (nn < 20) ? nn : A2($elm$core$Basics$modBy, 10, nn), - 4); - switch (_v0) { - case 1: - return 'st'; - case 2: - return 'nd'; - case 3: - return 'rd'; +var $justinmimbs$date$Date$weekdayToName = function (wd) { + switch (wd.$) { + case 'Mon': + return 'Monday'; + case 'Tue': + return 'Tuesday'; + case 'Wed': + return 'Wednesday'; + case 'Thu': + return 'Thursday'; + case 'Fri': + return 'Friday'; + case 'Sat': + return 'Saturday'; default: - return 'th'; + return 'Sunday'; } }; -var $justinmimbs$date$Date$withOrdinalSuffix = function (n) { - return _Utils_ap( - $elm$core$String$fromInt(n), - $justinmimbs$date$Date$ordinalSuffix(n)); -}; -var $justinmimbs$date$Date$formatField = F4( - function (language, _char, length, date) { - switch (_char.valueOf()) { - case 'y': - if (length === 2) { - return A2( - $elm$core$String$right, - 2, - A3( - $elm$core$String$padLeft, - 2, - _Utils_chr('0'), - $elm$core$String$fromInt( - $justinmimbs$date$Date$year(date)))); - } else { - return A2( - $justinmimbs$date$Date$padSignedInt, - length, - $justinmimbs$date$Date$year(date)); - } - case 'Y': - if (length === 2) { - return A2( - $elm$core$String$right, - 2, - A3( - $elm$core$String$padLeft, - 2, - _Utils_chr('0'), - $elm$core$String$fromInt( - $justinmimbs$date$Date$weekYear(date)))); - } else { - return A2( - $justinmimbs$date$Date$padSignedInt, - length, - $justinmimbs$date$Date$weekYear(date)); - } - case 'Q': - switch (length) { - case 1: - return $elm$core$String$fromInt( - $justinmimbs$date$Date$quarter(date)); - case 2: - return $elm$core$String$fromInt( - $justinmimbs$date$Date$quarter(date)); - case 3: - return 'Q' + $elm$core$String$fromInt( - $justinmimbs$date$Date$quarter(date)); - case 4: - return $justinmimbs$date$Date$withOrdinalSuffix( - $justinmimbs$date$Date$quarter(date)); - case 5: - return $elm$core$String$fromInt( - $justinmimbs$date$Date$quarter(date)); - default: - return ''; - } - case 'M': - switch (length) { - case 1: - return $elm$core$String$fromInt( - $justinmimbs$date$Date$monthNumber(date)); - case 2: - return A3( - $elm$core$String$padLeft, - 2, - _Utils_chr('0'), - $elm$core$String$fromInt( - $justinmimbs$date$Date$monthNumber(date))); - case 3: - return language.monthNameShort( - $justinmimbs$date$Date$month(date)); - case 4: - return language.monthName( - $justinmimbs$date$Date$month(date)); - case 5: - return A2( - $elm$core$String$left, - 1, - language.monthNameShort( - $justinmimbs$date$Date$month(date))); - default: - return ''; - } - case 'w': - switch (length) { - case 1: - return $elm$core$String$fromInt( - $justinmimbs$date$Date$weekNumber(date)); - case 2: - return A3( - $elm$core$String$padLeft, - 2, - _Utils_chr('0'), - $elm$core$String$fromInt( - $justinmimbs$date$Date$weekNumber(date))); - default: - return ''; - } - case 'd': - switch (length) { - case 1: - return $elm$core$String$fromInt( - $justinmimbs$date$Date$day(date)); - case 2: - return A3( - $elm$core$String$padLeft, - 2, - _Utils_chr('0'), - $elm$core$String$fromInt( - $justinmimbs$date$Date$day(date))); - case 3: - return language.dayWithSuffix( - $justinmimbs$date$Date$day(date)); - default: - return ''; - } - case 'D': - switch (length) { - case 1: - return $elm$core$String$fromInt( - $justinmimbs$date$Date$ordinalDay(date)); - case 2: - return A3( - $elm$core$String$padLeft, - 2, - _Utils_chr('0'), - $elm$core$String$fromInt( - $justinmimbs$date$Date$ordinalDay(date))); - case 3: - return A3( - $elm$core$String$padLeft, - 3, - _Utils_chr('0'), - $elm$core$String$fromInt( - $justinmimbs$date$Date$ordinalDay(date))); - default: - return ''; - } - case 'E': - switch (length) { - case 1: - return language.weekdayNameShort( - $justinmimbs$date$Date$weekday(date)); - case 2: - return language.weekdayNameShort( - $justinmimbs$date$Date$weekday(date)); - case 3: - return language.weekdayNameShort( - $justinmimbs$date$Date$weekday(date)); - case 4: - return language.weekdayName( - $justinmimbs$date$Date$weekday(date)); - case 5: - return A2( - $elm$core$String$left, - 1, - language.weekdayNameShort( - $justinmimbs$date$Date$weekday(date))); - case 6: - return A2( - $elm$core$String$left, - 2, - language.weekdayNameShort( - $justinmimbs$date$Date$weekday(date))); - default: - return ''; - } - case 'e': - switch (length) { - case 1: - return $elm$core$String$fromInt( - $justinmimbs$date$Date$weekdayNumber(date)); - case 2: - return $elm$core$String$fromInt( - $justinmimbs$date$Date$weekdayNumber(date)); - default: - return A4( - $justinmimbs$date$Date$formatField, - language, - _Utils_chr('E'), - length, - date); +var $justinmimbs$date$Date$language_en = { + dayWithSuffix: $justinmimbs$date$Date$withOrdinalSuffix, + monthName: $justinmimbs$date$Date$monthToName, + monthNameShort: A2( + $elm$core$Basics$composeR, + $justinmimbs$date$Date$monthToName, + $elm$core$String$left(3)), + weekdayName: $justinmimbs$date$Date$weekdayToName, + weekdayNameShort: A2( + $elm$core$Basics$composeR, + $justinmimbs$date$Date$weekdayToName, + $elm$core$String$left(3)) +}; +var $justinmimbs$date$Date$format = function (pattern) { + return A2($justinmimbs$date$Date$formatWithLanguage, $justinmimbs$date$Date$language_en, pattern); +}; +var $author$project$Gizra$NominalDate$customFormatDDMMYYYY = function (delimiter) { + return $justinmimbs$date$Date$format('dd' + (delimiter + ('MM' + (delimiter + 'yyyy')))); +}; +var $author$project$Gizra$NominalDate$formatDDMMYYYY = $author$project$Gizra$NominalDate$customFormatDDMMYYYY('/'); +var $elm$html$Html$Attributes$href = function (url) { + return A2( + $elm$html$Html$Attributes$stringProperty, + 'href', + _VirtualDom_noJavaScriptUri(url)); +}; +var $elm_community$maybe_extra$Maybe$Extra$isJust = function (m) { + if (m.$ === 'Nothing') { + return false; + } else { + return true; + } +}; +var $author$project$Pages$Utils$launchDate = A3($justinmimbs$date$Date$fromCalendarDate, 2018, $elm$time$Time$Jan, 1); +var $elm$core$Maybe$map3 = F4( + function (func, ma, mb, mc) { + if (ma.$ === 'Nothing') { + return $elm$core$Maybe$Nothing; + } else { + var a = ma.a; + if (mb.$ === 'Nothing') { + return $elm$core$Maybe$Nothing; + } else { + var b = mb.a; + if (mc.$ === 'Nothing') { + return $elm$core$Maybe$Nothing; + } else { + var c = mc.a; + return $elm$core$Maybe$Just( + A3(func, a, b, c)); } - default: - return ''; + } } }); -var $justinmimbs$date$Date$formatWithTokens = F3( - function (language, tokens, date) { - return A3( - $elm$core$List$foldl, - F2( - function (token, formatted) { - if (token.$ === 'Field') { - var _char = token.a; - var length = token.b; - return _Utils_ap( - A4($justinmimbs$date$Date$formatField, language, _char, length, date), - formatted); - } else { - var str = token.a; - return _Utils_ap(str, formatted); - } - }), - '', - tokens); +var $elm$virtual_dom$VirtualDom$Normal = function (a) { + return {$: 'Normal', a: a}; +}; +var $elm$virtual_dom$VirtualDom$on = _VirtualDom_on; +var $elm$html$Html$Events$on = F2( + function (event, decoder) { + return A2( + $elm$virtual_dom$VirtualDom$on, + event, + $elm$virtual_dom$VirtualDom$Normal(decoder)); }); -var $justinmimbs$date$Pattern$Literal = function (a) { - return {$: 'Literal', a: a}; +var $elm$html$Html$Events$onClick = function (msg) { + return A2( + $elm$html$Html$Events$on, + 'click', + $elm$json$Json$Decode$succeed(msg)); }; -var $justinmimbs$date$Pattern$escapedQuote = A2( - $elm$parser$Parser$ignorer, - $elm$parser$Parser$succeed( - $justinmimbs$date$Pattern$Literal('\'')), - $elm$parser$Parser$token('\'\'')); -var $justinmimbs$date$Pattern$Field = F2( - function (a, b) { - return {$: 'Field', a: a, b: b}; +var $author$project$Pages$Completion$Utils$reportTypeToString = function (reportType) { + return 'nutrition-individual'; +}; +var $author$project$Translate$Save = {$: 'Save'}; +var $author$project$Translate$MonthLabel = {$: 'MonthLabel'}; +var $author$project$Translate$YearLabel = {$: 'YearLabel'}; +var $justinmimbs$date$Date$clamp = F3( + function (dateA, dateB, dateX) { + var a = dateA.a; + var b = dateB.a; + var x = dateX.a; + return (_Utils_cmp(x, a) < 0) ? dateA : ((_Utils_cmp(b, x) < 0) ? dateB : dateX); }); -var $elm$parser$Parser$Advanced$chompWhileHelp = F5( - function (isGood, offset, row, col, s0) { - chompWhileHelp: +var $elm$html$Html$p = _VirtualDom_node('p'); +var $author$project$DateSelector$Selector$Dimmed = {$: 'Dimmed'}; +var $author$project$DateSelector$Selector$Disabled = {$: 'Disabled'}; +var $author$project$DateSelector$Selector$Normal = {$: 'Normal'}; +var $author$project$DateSelector$Selector$Selected = {$: 'Selected'}; +var $author$project$DateSelector$Selector$classNameFromState = function (state) { + switch (state.$) { + case 'Normal': + return ''; + case 'Dimmed': + return 'date-selector--dimmed'; + case 'Disabled': + return 'date-selector--disabled'; + default: + return 'date-selector--selected'; + } +}; +var $justinmimbs$date$Date$fromRataDie = function (rd) { + return $justinmimbs$date$Date$RD(rd); +}; +var $elm$core$List$drop = F2( + function (n, list) { + drop: while (true) { - var newOffset = A3($elm$parser$Parser$Advanced$isSubChar, isGood, offset, s0.src); - if (_Utils_eq(newOffset, -1)) { - return A3( - $elm$parser$Parser$Advanced$Good, - _Utils_cmp(s0.offset, offset) < 0, - _Utils_Tuple0, - {col: col, context: s0.context, indent: s0.indent, offset: offset, row: row, src: s0.src}); + if (n <= 0) { + return list; } else { - if (_Utils_eq(newOffset, -2)) { - var $temp$isGood = isGood, - $temp$offset = offset + 1, - $temp$row = row + 1, - $temp$col = 1, - $temp$s0 = s0; - isGood = $temp$isGood; - offset = $temp$offset; - row = $temp$row; - col = $temp$col; - s0 = $temp$s0; - continue chompWhileHelp; + if (!list.b) { + return list; } else { - var $temp$isGood = isGood, - $temp$offset = newOffset, - $temp$row = row, - $temp$col = col + 1, - $temp$s0 = s0; - isGood = $temp$isGood; - offset = $temp$offset; - row = $temp$row; - col = $temp$col; - s0 = $temp$s0; - continue chompWhileHelp; + var x = list.a; + var xs = list.b; + var $temp$n = n - 1, + $temp$list = xs; + n = $temp$n; + list = $temp$list; + continue drop; + } + } + } + }); +var $elm$core$List$takeReverse = F3( + function (n, list, kept) { + takeReverse: + while (true) { + if (n <= 0) { + return kept; + } else { + if (!list.b) { + return kept; + } else { + var x = list.a; + var xs = list.b; + var $temp$n = n - 1, + $temp$list = xs, + $temp$kept = A2($elm$core$List$cons, x, kept); + n = $temp$n; + list = $temp$list; + kept = $temp$kept; + continue takeReverse; + } + } + } + }); +var $elm$core$List$takeTailRec = F2( + function (n, list) { + return $elm$core$List$reverse( + A3($elm$core$List$takeReverse, n, list, _List_Nil)); + }); +var $elm$core$List$takeFast = F3( + function (ctr, n, list) { + if (n <= 0) { + return _List_Nil; + } else { + var _v0 = _Utils_Tuple2(n, list); + _v0$1: + while (true) { + _v0$5: + while (true) { + if (!_v0.b.b) { + return list; + } else { + if (_v0.b.b.b) { + switch (_v0.a) { + case 1: + break _v0$1; + case 2: + var _v2 = _v0.b; + var x = _v2.a; + var _v3 = _v2.b; + var y = _v3.a; + return _List_fromArray( + [x, y]); + case 3: + if (_v0.b.b.b.b) { + var _v4 = _v0.b; + var x = _v4.a; + var _v5 = _v4.b; + var y = _v5.a; + var _v6 = _v5.b; + var z = _v6.a; + return _List_fromArray( + [x, y, z]); + } else { + break _v0$5; + } + default: + if (_v0.b.b.b.b && _v0.b.b.b.b.b) { + var _v7 = _v0.b; + var x = _v7.a; + var _v8 = _v7.b; + var y = _v8.a; + var _v9 = _v8.b; + var z = _v9.a; + var _v10 = _v9.b; + var w = _v10.a; + var tl = _v10.b; + return (ctr > 1000) ? A2( + $elm$core$List$cons, + x, + A2( + $elm$core$List$cons, + y, + A2( + $elm$core$List$cons, + z, + A2( + $elm$core$List$cons, + w, + A2($elm$core$List$takeTailRec, n - 4, tl))))) : A2( + $elm$core$List$cons, + x, + A2( + $elm$core$List$cons, + y, + A2( + $elm$core$List$cons, + z, + A2( + $elm$core$List$cons, + w, + A3($elm$core$List$takeFast, ctr + 1, n - 4, tl))))); + } else { + break _v0$5; + } + } + } else { + if (_v0.a === 1) { + break _v0$1; + } else { + break _v0$5; + } + } + } } + return list; } + var _v1 = _v0.b; + var x = _v1.a; + return _List_fromArray( + [x]); } }); -var $elm$parser$Parser$Advanced$chompWhile = function (isGood) { - return $elm$parser$Parser$Advanced$Parser( - function (s) { - return A5($elm$parser$Parser$Advanced$chompWhileHelp, isGood, s.offset, s.row, s.col, s); - }); -}; -var $elm$parser$Parser$chompWhile = $elm$parser$Parser$Advanced$chompWhile; -var $elm$parser$Parser$Advanced$getOffset = $elm$parser$Parser$Advanced$Parser( - function (s) { - return A3($elm$parser$Parser$Advanced$Good, false, s.offset, s); +var $elm$core$List$take = F2( + function (n, list) { + return A3($elm$core$List$takeFast, 0, n, list); }); -var $elm$parser$Parser$getOffset = $elm$parser$Parser$Advanced$getOffset; -var $justinmimbs$date$Pattern$fieldRepeats = function (str) { - var _v0 = $elm$core$String$toList(str); - if (_v0.b && (!_v0.b.b)) { - var _char = _v0.a; - return A2( - $elm$parser$Parser$keeper, +var $author$project$DateSelector$Selector$groupsOf = F2( + function (n, list) { + return $elm$core$List$isEmpty(list) ? _List_Nil : A2( + $elm$core$List$cons, + A2($elm$core$List$take, n, list), A2( - $elm$parser$Parser$keeper, - $elm$parser$Parser$succeed( - F2( - function (x, y) { - return A2($justinmimbs$date$Pattern$Field, _char, 1 + (y - x)); - })), - A2( - $elm$parser$Parser$ignorer, - $elm$parser$Parser$getOffset, - $elm$parser$Parser$chompWhile( - $elm$core$Basics$eq(_char)))), - $elm$parser$Parser$getOffset); - } else { - return $elm$parser$Parser$problem('expected exactly one char'); + $author$project$DateSelector$Selector$groupsOf, + n, + A2($elm$core$List$drop, n, list))); + }); +var $elm$json$Json$Encode$int = _Json_wrap; +var $justinmimbs$date$Date$isBetween = F3( + function (_v0, _v1, _v2) { + var a = _v0.a; + var b = _v1.a; + var x = _v2.a; + return A3($justinmimbs$date$Date$isBetweenInt, a, b, x); + }); +var $author$project$DateSelector$Selector$isSelectable = function (state) { + return _Utils_eq(state, $author$project$DateSelector$Selector$Normal) || _Utils_eq(state, $author$project$DateSelector$Selector$Dimmed); +}; +var $justinmimbs$date$Date$Day = {$: 'Day'}; +var $justinmimbs$date$Date$Days = {$: 'Days'}; +var $justinmimbs$date$Date$Monday = {$: 'Monday'}; +var $justinmimbs$date$Date$add = F3( + function (unit, n, _v0) { + var rd = _v0.a; + switch (unit.$) { + case 'Years': + return A3( + $justinmimbs$date$Date$add, + $justinmimbs$date$Date$Months, + 12 * n, + $justinmimbs$date$Date$RD(rd)); + case 'Months': + var date = $justinmimbs$date$Date$toCalendarDate( + $justinmimbs$date$Date$RD(rd)); + var wholeMonths = ((12 * (date.year - 1)) + ($justinmimbs$date$Date$monthToNumber(date.month) - 1)) + n; + var m = $justinmimbs$date$Date$numberToMonth( + A2($elm$core$Basics$modBy, 12, wholeMonths) + 1); + var y = A2($justinmimbs$date$Date$floorDiv, wholeMonths, 12) + 1; + return $justinmimbs$date$Date$RD( + ($justinmimbs$date$Date$daysBeforeYear(y) + A2($justinmimbs$date$Date$daysBeforeMonth, y, m)) + A2( + $elm$core$Basics$min, + date.day, + A2($justinmimbs$date$Date$daysInMonth, y, m))); + case 'Weeks': + return $justinmimbs$date$Date$RD(rd + (7 * n)); + default: + return $justinmimbs$date$Date$RD(rd + n); + } + }); +var $justinmimbs$date$Date$weekdayToNumber = function (wd) { + switch (wd.$) { + case 'Mon': + return 1; + case 'Tue': + return 2; + case 'Wed': + return 3; + case 'Thu': + return 4; + case 'Fri': + return 5; + case 'Sat': + return 6; + default: + return 7; } }; -var $elm$parser$Parser$Advanced$getChompedString = function (parser) { - return A2($elm$parser$Parser$Advanced$mapChompedString, $elm$core$Basics$always, parser); +var $justinmimbs$date$Date$daysSincePreviousWeekday = F2( + function (wd, date) { + return A2( + $elm$core$Basics$modBy, + 7, + ($justinmimbs$date$Date$weekdayNumber(date) + 7) - $justinmimbs$date$Date$weekdayToNumber(wd)); + }); +var $justinmimbs$date$Date$firstOfMonth = F2( + function (y, m) { + return $justinmimbs$date$Date$RD( + ($justinmimbs$date$Date$daysBeforeYear(y) + A2($justinmimbs$date$Date$daysBeforeMonth, y, m)) + 1); + }); +var $justinmimbs$date$Date$quarterToMonth = function (q) { + return $justinmimbs$date$Date$numberToMonth((q * 3) - 2); }; -var $elm$parser$Parser$getChompedString = $elm$parser$Parser$Advanced$getChompedString; -var $justinmimbs$date$Pattern$field = A2( - $elm$parser$Parser$andThen, - $justinmimbs$date$Pattern$fieldRepeats, - $elm$parser$Parser$getChompedString( - $elm$parser$Parser$chompIf($elm$core$Char$isAlpha))); -var $justinmimbs$date$Pattern$finalize = A2( - $elm$core$List$foldl, - F2( - function (token, tokens) { - var _v0 = _Utils_Tuple2(token, tokens); - if (((_v0.a.$ === 'Literal') && _v0.b.b) && (_v0.b.a.$ === 'Literal')) { - var x = _v0.a.a; - var _v1 = _v0.b; - var y = _v1.a.a; - var rest = _v1.b; +var $justinmimbs$date$Date$floor = F2( + function (interval, date) { + var rd = date.a; + switch (interval.$) { + case 'Year': + return $justinmimbs$date$Date$firstOfYear( + $justinmimbs$date$Date$year(date)); + case 'Quarter': return A2( + $justinmimbs$date$Date$firstOfMonth, + $justinmimbs$date$Date$year(date), + $justinmimbs$date$Date$quarterToMonth( + $justinmimbs$date$Date$quarter(date))); + case 'Month': + return A2( + $justinmimbs$date$Date$firstOfMonth, + $justinmimbs$date$Date$year(date), + $justinmimbs$date$Date$month(date)); + case 'Week': + return $justinmimbs$date$Date$RD( + rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Mon, date)); + case 'Monday': + return $justinmimbs$date$Date$RD( + rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Mon, date)); + case 'Tuesday': + return $justinmimbs$date$Date$RD( + rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Tue, date)); + case 'Wednesday': + return $justinmimbs$date$Date$RD( + rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Wed, date)); + case 'Thursday': + return $justinmimbs$date$Date$RD( + rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Thu, date)); + case 'Friday': + return $justinmimbs$date$Date$RD( + rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Fri, date)); + case 'Saturday': + return $justinmimbs$date$Date$RD( + rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Sat, date)); + case 'Sunday': + return $justinmimbs$date$Date$RD( + rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Sun, date)); + default: + return date; + } + }); +var $justinmimbs$date$Date$Weeks = {$: 'Weeks'}; +var $justinmimbs$date$Date$intervalToUnits = function (interval) { + switch (interval.$) { + case 'Year': + return _Utils_Tuple2(1, $justinmimbs$date$Date$Years); + case 'Quarter': + return _Utils_Tuple2(3, $justinmimbs$date$Date$Months); + case 'Month': + return _Utils_Tuple2(1, $justinmimbs$date$Date$Months); + case 'Day': + return _Utils_Tuple2(1, $justinmimbs$date$Date$Days); + default: + var week = interval; + return _Utils_Tuple2(1, $justinmimbs$date$Date$Weeks); + } +}; +var $justinmimbs$date$Date$ceiling = F2( + function (interval, date) { + var floored = A2($justinmimbs$date$Date$floor, interval, date); + if (_Utils_eq(date, floored)) { + return date; + } else { + var _v0 = $justinmimbs$date$Date$intervalToUnits(interval); + var n = _v0.a; + var unit = _v0.b; + return A3($justinmimbs$date$Date$add, unit, n, floored); + } + }); +var $justinmimbs$date$Date$rangeHelp = F5( + function (unit, step, until, revList, current) { + rangeHelp: + while (true) { + if (_Utils_cmp(current, until) < 0) { + var _v0 = A3( + $justinmimbs$date$Date$add, + unit, + step, + $justinmimbs$date$Date$RD(current)); + var next = _v0.a; + var $temp$unit = unit, + $temp$step = step, + $temp$until = until, + $temp$revList = A2( $elm$core$List$cons, - $justinmimbs$date$Pattern$Literal( - _Utils_ap(x, y)), - rest); + $justinmimbs$date$Date$RD(current), + revList), + $temp$current = next; + unit = $temp$unit; + step = $temp$step; + until = $temp$until; + revList = $temp$revList; + current = $temp$current; + continue rangeHelp; } else { - return A2($elm$core$List$cons, token, tokens); + return $elm$core$List$reverse(revList); } - }), - _List_Nil); -var $elm$parser$Parser$Advanced$lazy = function (thunk) { - return $elm$parser$Parser$Advanced$Parser( - function (s) { - var _v0 = thunk(_Utils_Tuple0); - var parse = _v0.a; - return parse(s); - }); -}; -var $elm$parser$Parser$lazy = $elm$parser$Parser$Advanced$lazy; -var $justinmimbs$date$Pattern$isLiteralChar = function (_char) { - return (!_Utils_eq( - _char, - _Utils_chr('\''))) && (!$elm$core$Char$isAlpha(_char)); + } + }); +var $justinmimbs$date$Date$range = F4( + function (interval, step, _v0, _v1) { + var start = _v0.a; + var until = _v1.a; + var _v2 = $justinmimbs$date$Date$intervalToUnits(interval); + var n = _v2.a; + var unit = _v2.b; + var _v3 = A2( + $justinmimbs$date$Date$ceiling, + interval, + $justinmimbs$date$Date$RD(start)); + var first = _v3.a; + return (_Utils_cmp(first, until) < 0) ? A5( + $justinmimbs$date$Date$rangeHelp, + unit, + A2($elm$core$Basics$max, 1, step) * n, + until, + _List_Nil, + first) : _List_Nil; + }); +var $author$project$DateSelector$Selector$monthDates = F2( + function (y, m) { + var start = A2( + $justinmimbs$date$Date$floor, + $justinmimbs$date$Date$Monday, + A3($justinmimbs$date$Date$fromCalendarDate, y, m, 1)); + return A4( + $justinmimbs$date$Date$range, + $justinmimbs$date$Date$Day, + 1, + start, + A3($justinmimbs$date$Date$add, $justinmimbs$date$Date$Days, 42, start)); + }); +var $elm$json$Json$Encode$null = _Json_encodeNull; +var $elm$virtual_dom$VirtualDom$property = F2( + function (key, value) { + return A2( + _VirtualDom_property, + _VirtualDom_noInnerHtmlOrFormAction(key), + _VirtualDom_noJavaScriptOrHtmlUri(value)); + }); +var $elm$html$Html$Attributes$property = $elm$virtual_dom$VirtualDom$property; +var $elm$html$Html$table = _VirtualDom_node('table'); +var $elm$html$Html$tbody = _VirtualDom_node('tbody'); +var $elm$html$Html$td = _VirtualDom_node('td'); +var $justinmimbs$date$Date$toRataDie = function (_v0) { + var rd = _v0.a; + return rd; }; -var $justinmimbs$date$Pattern$literal = A2( - $elm$parser$Parser$map, - $justinmimbs$date$Pattern$Literal, - $elm$parser$Parser$getChompedString( - A2( - $elm$parser$Parser$ignorer, +var $elm$html$Html$tr = _VirtualDom_node('tr'); +var $author$project$DateSelector$Selector$dayOfWeekNames = _List_fromArray( + ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']); +var $elm$html$Html$th = _VirtualDom_node('th'); +var $elm$html$Html$thead = _VirtualDom_node('thead'); +var $author$project$DateSelector$Selector$viewDayOfWeekHeader = A2( + $elm$html$Html$thead, + _List_Nil, + _List_fromArray( + [ A2( - $elm$parser$Parser$ignorer, - $elm$parser$Parser$succeed(_Utils_Tuple0), - $elm$parser$Parser$chompIf($justinmimbs$date$Pattern$isLiteralChar)), - $elm$parser$Parser$chompWhile($justinmimbs$date$Pattern$isLiteralChar)))); -var $justinmimbs$date$Pattern$quotedHelp = function (result) { - return $elm$parser$Parser$oneOf( - _List_fromArray( - [ - A2( - $elm$parser$Parser$andThen, - function (str) { - return $justinmimbs$date$Pattern$quotedHelp( - _Utils_ap(result, str)); - }, - $elm$parser$Parser$getChompedString( - A2( - $elm$parser$Parser$ignorer, - A2( - $elm$parser$Parser$ignorer, - $elm$parser$Parser$succeed(_Utils_Tuple0), - $elm$parser$Parser$chompIf( - $elm$core$Basics$neq( - _Utils_chr('\'')))), - $elm$parser$Parser$chompWhile( - $elm$core$Basics$neq( - _Utils_chr('\'')))))), - A2( - $elm$parser$Parser$andThen, - function (_v0) { - return $justinmimbs$date$Pattern$quotedHelp(result + '\''); + $elm$html$Html$tr, + _List_Nil, + A2( + $elm$core$List$map, + function (name) { + return A2( + $elm$html$Html$th, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text(name) + ])); }, - $elm$parser$Parser$token('\'\'')), - $elm$parser$Parser$succeed(result) - ])); -}; -var $justinmimbs$date$Pattern$quoted = A2( - $elm$parser$Parser$keeper, - A2( - $elm$parser$Parser$ignorer, - $elm$parser$Parser$succeed($justinmimbs$date$Pattern$Literal), - $elm$parser$Parser$chompIf( - $elm$core$Basics$eq( - _Utils_chr('\'')))), - A2( - $elm$parser$Parser$ignorer, - $justinmimbs$date$Pattern$quotedHelp(''), - $elm$parser$Parser$oneOf( + $author$project$DateSelector$Selector$dayOfWeekNames)) + ])); +var $author$project$DateSelector$Selector$viewDateTable = F3( + function (minimum, maximum, selected) { + var weeks = A2( + $author$project$DateSelector$Selector$groupsOf, + 7, + A2( + $author$project$DateSelector$Selector$monthDates, + $justinmimbs$date$Date$year(selected), + $justinmimbs$date$Date$month(selected))); + var isInvertedMinMax = _Utils_eq( + A2($justinmimbs$date$Date$compare, minimum, maximum), + $elm$core$Basics$GT); + return A2( + $elm$html$Html$table, + _List_Nil, _List_fromArray( [ - $elm$parser$Parser$chompIf( - $elm$core$Basics$eq( - _Utils_chr('\''))), - $elm$parser$Parser$end - ])))); -var $justinmimbs$date$Pattern$patternHelp = function (tokens) { - return $elm$parser$Parser$oneOf( - _List_fromArray( - [ - A2( - $elm$parser$Parser$andThen, - function (token) { - return $justinmimbs$date$Pattern$patternHelp( - A2($elm$core$List$cons, token, tokens)); - }, - $elm$parser$Parser$oneOf( + $author$project$DateSelector$Selector$viewDayOfWeekHeader, + A2( + $elm$html$Html$tbody, _List_fromArray( - [$justinmimbs$date$Pattern$field, $justinmimbs$date$Pattern$literal, $justinmimbs$date$Pattern$escapedQuote, $justinmimbs$date$Pattern$quoted]))), - $elm$parser$Parser$lazy( - function (_v0) { - return $elm$parser$Parser$succeed( - $justinmimbs$date$Pattern$finalize(tokens)); - }) - ])); -}; -var $elm$core$Result$withDefault = F2( - function (def, result) { - if (result.$ === 'Ok') { - var a = result.a; - return a; - } else { - return def; - } + [ + A2( + $elm$html$Html$Events$on, + 'click', + A2( + $elm$json$Json$Decode$map, + $justinmimbs$date$Date$fromRataDie, + A2( + $elm$json$Json$Decode$at, + _List_fromArray( + ['target', 'time']), + $elm$json$Json$Decode$int))) + ]), + A2( + $elm$core$List$map, + function (week) { + return A2( + $elm$html$Html$tr, + _List_Nil, + A2( + $elm$core$List$map, + function (date) { + var equalByDay = F2( + function (date1, date2) { + return _Utils_eq( + $justinmimbs$date$Date$day(date1), + $justinmimbs$date$Date$day(date2)) && (_Utils_eq( + $justinmimbs$date$Date$month(date1), + $justinmimbs$date$Date$month(date2)) && _Utils_eq( + $justinmimbs$date$Date$year(date1), + $justinmimbs$date$Date$year(date2))); + }); + var state = A2(equalByDay, date, selected) ? $author$project$DateSelector$Selector$Selected : (((!A3($justinmimbs$date$Date$isBetween, minimum, maximum, date)) || isInvertedMinMax) ? $author$project$DateSelector$Selector$Disabled : ((!_Utils_eq( + $justinmimbs$date$Date$month(date), + $justinmimbs$date$Date$month(selected))) ? $author$project$DateSelector$Selector$Dimmed : $author$project$DateSelector$Selector$Normal)); + var cell = _Utils_eq(state, $author$project$DateSelector$Selector$Selected) ? A2( + $elm$html$Html$p, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text( + $elm$core$String$fromInt( + $justinmimbs$date$Date$day(date))) + ])) : $elm$html$Html$text( + $elm$core$String$fromInt( + $justinmimbs$date$Date$day(date))); + return A2( + $elm$html$Html$td, + _List_fromArray( + [ + $elm$html$Html$Attributes$class( + $author$project$DateSelector$Selector$classNameFromState(state)), + A2( + $elm$html$Html$Attributes$property, + 'time', + $author$project$DateSelector$Selector$isSelectable(state) ? $elm$json$Json$Encode$int( + $justinmimbs$date$Date$toRataDie(date)) : $elm$json$Json$Encode$null) + ]), + _List_fromArray( + [cell])); + }, + week)); + }, + weeks)) + ])); }); -var $justinmimbs$date$Pattern$fromString = function (str) { - return A2( - $elm$core$Result$withDefault, - _List_fromArray( - [ - $justinmimbs$date$Pattern$Literal(str) - ]), +var $author$project$DateSelector$Selector$viewDateTableDisabled = function (date) { + var weeks = A2( + $author$project$DateSelector$Selector$groupsOf, + 7, A2( - $elm$parser$Parser$run, - $justinmimbs$date$Pattern$patternHelp(_List_Nil), - str)); -}; -var $justinmimbs$date$Date$formatWithLanguage = F2( - function (language, pattern) { - var tokens = $elm$core$List$reverse( - $justinmimbs$date$Pattern$fromString(pattern)); - return A2($justinmimbs$date$Date$formatWithTokens, language, tokens); - }); -var $justinmimbs$date$Date$weekdayToName = function (wd) { - switch (wd.$) { - case 'Mon': - return 'Monday'; - case 'Tue': - return 'Tuesday'; - case 'Wed': - return 'Wednesday'; - case 'Thu': - return 'Thursday'; - case 'Fri': - return 'Friday'; - case 'Sat': - return 'Saturday'; - default: - return 'Sunday'; - } -}; -var $justinmimbs$date$Date$language_en = { - dayWithSuffix: $justinmimbs$date$Date$withOrdinalSuffix, - monthName: $justinmimbs$date$Date$monthToName, - monthNameShort: A2( - $elm$core$Basics$composeR, - $justinmimbs$date$Date$monthToName, - $elm$core$String$left(3)), - weekdayName: $justinmimbs$date$Date$weekdayToName, - weekdayNameShort: A2( - $elm$core$Basics$composeR, - $justinmimbs$date$Date$weekdayToName, - $elm$core$String$left(3)) -}; -var $justinmimbs$date$Date$format = function (pattern) { - return A2($justinmimbs$date$Date$formatWithLanguage, $justinmimbs$date$Date$language_en, pattern); -}; -var $author$project$Gizra$NominalDate$customFormatDDMMYYYY = function (delimiter) { - return $justinmimbs$date$Date$format('dd' + (delimiter + ('MM' + (delimiter + 'yyyy')))); -}; -var $author$project$Gizra$NominalDate$formatDDMMYYYY = $author$project$Gizra$NominalDate$customFormatDDMMYYYY('/'); -var $elm$html$Html$img = _VirtualDom_node('img'); -var $elm$html$Html$Attributes$src = function (url) { - return A2( - $elm$html$Html$Attributes$stringProperty, - 'src', - _VirtualDom_noJavaScriptOrHtmlUri(url)); -}; -var $author$project$Pages$Utils$generateReportsHeaderImage = function (themePath) { + $author$project$DateSelector$Selector$monthDates, + $justinmimbs$date$Date$year(date), + $justinmimbs$date$Date$month(date))); + var disabled = $author$project$DateSelector$Selector$classNameFromState($author$project$DateSelector$Selector$Disabled); return A2( - $elm$html$Html$img, + $elm$html$Html$table, + _List_Nil, _List_fromArray( [ - $elm$html$Html$Attributes$src('/' + (themePath + '/icons/statistical-queries.png')) - ]), - _List_Nil); -}; -var $elm_community$maybe_extra$Maybe$Extra$isJust = function (m) { - if (m.$ === 'Nothing') { - return false; - } else { - return true; - } + $author$project$DateSelector$Selector$viewDayOfWeekHeader, + A2( + $elm$html$Html$tbody, + _List_Nil, + A2( + $elm$core$List$map, + function (week) { + return A2( + $elm$html$Html$tr, + _List_Nil, + A2( + $elm$core$List$map, + function (date_) { + return A2( + $elm$html$Html$td, + _List_fromArray( + [ + $elm$html$Html$Attributes$class(disabled) + ]), + _List_fromArray( + [ + $elm$html$Html$text( + $elm$core$String$fromInt( + $justinmimbs$date$Date$day(date_))) + ])); + }, + week)); + }, + weeks)) + ])); }; -var $elm$core$Maybe$map3 = F4( - function (func, ma, mb, mc) { - if (ma.$ === 'Nothing') { - return $elm$core$Maybe$Nothing; - } else { - var a = ma.a; - if (mb.$ === 'Nothing') { - return $elm$core$Maybe$Nothing; - } else { - var b = mb.a; - if (mc.$ === 'Nothing') { - return $elm$core$Maybe$Nothing; - } else { - var c = mc.a; - return $elm$core$Maybe$Just( - A3(func, a, b, c)); - } - } - } +var $author$project$Translate$ResolveMonth = F2( + function (a, b) { + return {$: 'ResolveMonth', a: a, b: b}; }); -var $author$project$Pages$Reports$Utils$reportTypeToString = function (reportType) { - switch (reportType.$) { - case 'ReportAcuteIllness': - return 'acute-illness'; - case 'ReportDemographics': - return 'demographics'; - case 'ReportNutrition': - return 'nutrition'; - default: - return 'prenatal'; - } -}; -var $author$project$Translate$AcuteIllnessDiagnosis = function (a) { - return {$: 'AcuteIllnessDiagnosis', a: a}; +var $author$project$Gizra$NominalDate$allMonths = _List_fromArray( + [$elm$time$Time$Jan, $elm$time$Time$Feb, $elm$time$Time$Mar, $elm$time$Time$Apr, $elm$time$Time$May, $elm$time$Time$Jun, $elm$time$Time$Jul, $elm$time$Time$Aug, $elm$time$Time$Sep, $elm$time$Time$Oct, $elm$time$Time$Nov, $elm$time$Time$Dec]); +var $author$project$DateSelector$Selector$isLeapYear = function (y) { + return ((!A2($elm$core$Basics$modBy, 4, y)) && (!(!A2($elm$core$Basics$modBy, 100, y)))) || (!A2($elm$core$Basics$modBy, 400, y)); }; -var $author$project$Translate$Diagnosis = {$: 'Diagnosis'}; -var $author$project$Translate$NoDiagnosis = {$: 'NoDiagnosis'}; -var $author$project$Translate$Total = {$: 'Total'}; -var $author$project$Backend$Reports$Utils$allAcuteIllnessDiagnoses = _List_fromArray( - [$author$project$Backend$Reports$Model$DiagnosisCovid19Suspect, $author$project$Backend$Reports$Model$DiagnosisSevereCovid19, $author$project$Backend$Reports$Model$DiagnosisPneuminialCovid19, $author$project$Backend$Reports$Model$DiagnosisLowRiskCovid19, $author$project$Backend$Reports$Model$DiagnosisMalariaComplicated, $author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicated, $author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicatedAndPregnant, $author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionComplicated, $author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionUncomplicated, $author$project$Backend$Reports$Model$DiagnosisSimpleColdAndCough, $author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionComplicated, $author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionUncomplicated, $author$project$Backend$Reports$Model$DiagnosisFeverOfUnknownOrigin, $author$project$Backend$Reports$Model$DiagnosisUndeterminedMoreEvaluationNeeded, $author$project$Backend$Reports$Model$DiagnosisTuberculosisSuspect]); -var $author$project$Gizra$NominalDate$sortByDateDesc = F3( - function (getDateFunc, entity1, entity2) { - return A2( - $justinmimbs$date$Date$compare, - getDateFunc(entity2), - getDateFunc(entity1)); +var $author$project$DateSelector$Selector$daysInMonth = F2( + function (y, m) { + switch (m.$) { + case 'Jan': + return 31; + case 'Feb': + return $author$project$DateSelector$Selector$isLeapYear(y) ? 29 : 28; + case 'Mar': + return 31; + case 'Apr': + return 30; + case 'May': + return 31; + case 'Jun': + return 30; + case 'Jul': + return 31; + case 'Aug': + return 31; + case 'Sep': + return 30; + case 'Oct': + return 31; + case 'Nov': + return 30; + default: + return 31; + } }); -var $author$project$Pages$Reports$View$generateAcuteIllnessReportData = F3( - function (language, startDate, records) { - var generateRow = F2( - function (label, value) { - return _List_fromArray( - [ - A2($author$project$Translate$translate, language, label), - $elm$core$String$fromInt(value) - ]); - }); - var acuteIllnessParticipantRecords = $elm$core$List$concat( - $elm_community$maybe_extra$Maybe$Extra$values( - A2( - $elm$core$List$map, - function ($) { - return $.acuteIllnessData; - }, - records))); - var diagnosesCountDict = A3( - $elm$core$List$foldl, - F2( - function (diagnosis, accum) { - return A2( - $elm$core$Maybe$withDefault, - A3($pzp1997$assoc_list$AssocList$insert, diagnosis, 1, accum), - A2( - $elm$core$Maybe$map, - function (value) { - return A3($pzp1997$assoc_list$AssocList$insert, diagnosis, value + 1, accum); - }, - A2($pzp1997$assoc_list$AssocList$get, diagnosis, accum))); - }), - $pzp1997$assoc_list$AssocList$empty, - $elm_community$maybe_extra$Maybe$Extra$values( - A2( - $elm$core$List$map, - function ($) { - return $.diagnosis; +var $author$project$DateSelector$Selector$dateWithMonth = F2( + function (date, m) { + var y = $justinmimbs$date$Date$year(date); + var d = $justinmimbs$date$Date$day(date); + return A3( + $justinmimbs$date$Date$fromCalendarDate, + y, + m, + A2( + $elm$core$Basics$min, + d, + A2($author$project$DateSelector$Selector$daysInMonth, y, m))); + }); +var $elm$html$Html$option = _VirtualDom_node('option'); +var $elm$html$Html$select = _VirtualDom_node('select'); +var $elm$json$Json$Encode$bool = _Json_wrap; +var $elm$html$Html$Attributes$boolProperty = F2( + function (key, bool) { + return A2( + _VirtualDom_property, + key, + $elm$json$Json$Encode$bool(bool)); + }); +var $elm$html$Html$Attributes$selected = $elm$html$Html$Attributes$boolProperty('selected'); +var $elm$html$Html$Attributes$value = $elm$html$Html$Attributes$stringProperty('value'); +var $author$project$DateSelector$Selector$viewMonthSelectList = F4( + function (language, minimum, maximum, selectedDate) { + var isInvertedMinMax = _Utils_eq( + A2($justinmimbs$date$Date$compare, minimum, maximum), + $elm$core$Basics$GT); + var months = function () { + if (isInvertedMinMax) { + return _List_Nil; + } else { + var last = _Utils_eq( + $justinmimbs$date$Date$year(selectedDate), + $justinmimbs$date$Date$year(maximum)) ? $justinmimbs$date$Date$monthNumber(maximum) : 12; + var first = _Utils_eq( + $justinmimbs$date$Date$year(selectedDate), + $justinmimbs$date$Date$year(minimum)) ? $justinmimbs$date$Date$monthNumber(minimum) : 1; + return A2( + $elm$core$List$filter, + function (month) { + var monthNumber = $justinmimbs$date$Date$monthToNumber(month); + return (_Utils_cmp(monthNumber, first) > -1) && (_Utils_cmp(monthNumber, last) < 1); }, - $elm$core$List$concat(acuteIllnessParticipantRecords)))); - var rows = A2( + $author$project$Gizra$NominalDate$allMonths); + } + }(); + var options = A2( $elm$core$List$map, - function (diagnosis) { + function (month) { + var monthNumber = $justinmimbs$date$Date$monthToNumber(month); return A2( - generateRow, - $author$project$Translate$AcuteIllnessDiagnosis(diagnosis), - A2( - $elm$core$Maybe$withDefault, - 0, - A2($pzp1997$assoc_list$AssocList$get, diagnosis, diagnosesCountDict))); + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value( + $elm$core$String$fromInt(monthNumber)), + $elm$html$Html$Attributes$selected( + _Utils_eq( + $justinmimbs$date$Date$monthNumber(selectedDate), + monthNumber)) + ]), + _List_fromArray( + [ + $elm$html$Html$text( + A2( + $author$project$Translate$translate, + language, + A2($author$project$Translate$ResolveMonth, false, month))) + ])); }, - $author$project$Backend$Reports$Utils$allAcuteIllnessDiagnoses); - var totalsRow = A2( - generateRow, - $author$project$Translate$Total, - $elm$core$List$sum( - $pzp1997$assoc_list$AssocList$values(diagnosesCountDict))); - var illnessesWithNoDiagnosis = $elm$core$List$length( - A2( - $elm$core$List$filter, - function (encountersList) { - return A2( - $elm$core$Maybe$withDefault, - false, + months); + return A2( + $elm$html$Html$select, + _List_fromArray( + [ + A2( + $elm$html$Html$Events$on, + 'input', + A2( + $elm$json$Json$Decode$map, + function (s) { + var selectedMonths = A2( + $elm$core$Maybe$withDefault, + 1, + $elm$core$String$toInt(s)); + return A2( + $author$project$DateSelector$Selector$dateWithMonth, + selectedDate, + $justinmimbs$date$Date$numberToMonth(selectedMonths)); + }, A2( - $elm$core$Maybe$map, - function (encounter) { - return (!_Utils_eq( - A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), - $elm$core$Basics$LT)) && $elm_community$maybe_extra$Maybe$Extra$isNothing(encounter.diagnosis); - }, - $elm$core$List$head( - A2( - $elm$core$List$sortWith, - $author$project$Gizra$NominalDate$sortByDateDesc( - function ($) { - return $.startDate; - }), - encountersList)))); - }, - acuteIllnessParticipantRecords)); - var noneRow = A2(generateRow, $author$project$Translate$NoDiagnosis, illnessesWithNoDiagnosis); - return { - captions: _List_fromArray( + $elm$json$Json$Decode$at, + _List_fromArray( + ['target', 'value']), + $elm$json$Json$Decode$string))) + ]), + options); + }); +var $author$project$DateSelector$Selector$viewMonthSelectListDisabled = A2( + $elm$html$Html$select, + _List_Nil, + _List_fromArray( + [ + A2( + $elm$html$Html$option, + _List_fromArray( [ - A2($author$project$Translate$translate, language, $author$project$Translate$Diagnosis), - A2($author$project$Translate$translate, language, $author$project$Translate$Total) + $elm$html$Html$Attributes$value('') ]), - heading: '', - rows: _Utils_ap( - rows, - _Utils_ap( + _List_fromArray( + [ + $elm$html$Html$text('') + ])) + ])); +var $author$project$DateSelector$Selector$dateWithYear = F2( + function (date, y) { + var m = $justinmimbs$date$Date$month(date); + var d = $justinmimbs$date$Date$day(date); + return (_Utils_eq(m, $elm$time$Time$Feb) && ((d === 29) && (!$author$project$DateSelector$Selector$isLeapYear(y)))) ? A3($justinmimbs$date$Date$fromCalendarDate, y, $elm$time$Time$Feb, 28) : A3($justinmimbs$date$Date$fromCalendarDate, y, m, d); + }); +var $author$project$DateSelector$Selector$viewYearSelectList = F3( + function (minimum, maximum, maybeSelected) { + var isSelectedYear = A2( + $elm$core$Maybe$withDefault, + $elm$core$Basics$always(false), + A2( + $elm$core$Maybe$map, + function (selected) { + return $elm$core$Basics$eq( + $justinmimbs$date$Date$year(selected)); + }, + maybeSelected)); + var isInvertedMinMax = _Utils_eq( + A2($justinmimbs$date$Date$compare, minimum, maximum), + $elm$core$Basics$GT); + var years = isInvertedMinMax ? _List_fromArray( + [ + $justinmimbs$date$Date$year( + A2($elm$core$Maybe$withDefault, minimum, maybeSelected)) + ]) : A2( + $elm$core$List$range, + $justinmimbs$date$Date$year(minimum), + $justinmimbs$date$Date$year(maximum)); + var options_ = A2( + $elm$core$List$map, + function (year) { + return A2( + $elm$html$Html$option, _List_fromArray( - [totalsRow]), + [ + $elm$html$Html$Attributes$value( + $elm$core$String$fromInt(year)), + $elm$html$Html$Attributes$selected( + isSelectedYear(year)) + ]), _List_fromArray( - [noneRow]))) - }; - }); -var $elm$core$String$replace = F3( - function (before, after, string) { + [ + $elm$html$Html$text( + $elm$core$String$fromInt(year)) + ])); + }, + $elm$core$List$reverse(years)); + var options = $elm_community$maybe_extra$Maybe$Extra$isNothing(maybeSelected) ? A2( + $elm$core$List$cons, + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('') + ]), + _List_fromArray( + [ + $elm$html$Html$text('') + ])), + options_) : options_; return A2( - $elm$core$String$join, - after, - A2($elm$core$String$split, before, string)); - }); -var $author$project$Pages$Reports$View$reportTableDataToCSV = function (tableData) { - return A2( - $elm$core$String$join, - '\n', - _List_fromArray( - [ - tableData.heading, - A2($elm$core$String$join, ',', tableData.captions), - A2( - $elm$core$String$join, - '\n', - A2( - $elm$core$List$map, - $elm$core$String$join(','), - tableData.rows)) - ])); -}; -var $author$project$Pages$Reports$Model$DownloadCSV = F2( - function (a, b) { - return {$: 'DownloadCSV', a: a, b: b}; + $elm$html$Html$select, + _List_fromArray( + [ + A2( + $elm$html$Html$Events$on, + 'input', + A2( + $elm$json$Json$Decode$map, + function (s) { + var selectedYear = A2( + $elm$core$Maybe$withDefault, + 2000, + $elm$core$String$toInt(s)); + return A2( + $author$project$DateSelector$Selector$dateWithYear, + A2( + $elm$core$Maybe$withDefault, + A3( + $justinmimbs$date$Date$fromCalendarDate, + $justinmimbs$date$Date$year(minimum), + $elm$time$Time$Jan, + 1), + maybeSelected), + selectedYear); + }, + A2( + $elm$json$Json$Decode$at, + _List_fromArray( + ['target', 'value']), + $elm$json$Json$Decode$string))) + ]), + options); }); -var $author$project$Translate$DownloadCSV = {$: 'DownloadCSV'}; -var $author$project$Pages$Reports$View$viewDownloadCSVButton = F3( - function (language, csvFileName, csvContent) { - return A2( +var $author$project$DateSelector$Selector$viewPopup = F4( + function (language, minimum, maximum, maybeSelected) { + var yearSection = A2( $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$Attributes$class('download-csv-wrapper') + $elm$html$Html$Attributes$class('year') ]), _List_fromArray( [ A2( - $elm$html$Html$button, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('download-csv'), - $elm$html$Html$Events$onClick( - A2($author$project$Pages$Reports$Model$DownloadCSV, csvFileName, csvContent)) - ]), + $elm$html$Html$p, + _List_Nil, _List_fromArray( [ $elm$html$Html$text( - A2($author$project$Translate$translate, language, $author$project$Translate$DownloadCSV)) - ])) + A2($author$project$Translate$translate, language, $author$project$Translate$YearLabel)) + ])), + A3($author$project$DateSelector$Selector$viewYearSelectList, minimum, maximum, maybeSelected) ])); - }); -var $author$project$Pages$Reports$View$viewAcuteIllnessReport = F5( - function (language, limitDate, startDate, scopeLabel, records) { - var data = A3($author$project$Pages$Reports$View$generateAcuteIllnessReportData, language, startDate, records); - var csvFileName = 'acute-illness-report-' + ($elm$core$String$toLower( - A3($elm$core$String$replace, ' ', '-', scopeLabel)) + ('-' + (A2($author$project$Gizra$NominalDate$customFormatDDMMYYYY, '-', startDate) + ('-to-' + (A2($author$project$Gizra$NominalDate$customFormatDDMMYYYY, '-', limitDate) + '.csv'))))); - var csvContent = $author$project$Pages$Reports$View$reportTableDataToCSV(data); - var captionsRow = A2( + var monthSection = A2( $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$Attributes$class('row captions') + $elm$html$Html$Attributes$class('month') ]), - $author$project$Pages$Utils$viewStandardCells(data.captions)); - return A2( - $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$Attributes$class('report acute-illness') - ]), - _Utils_ap( - _List_fromArray( - [ - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('table') - ]), - A2( - $elm$core$List$cons, - captionsRow, - A2($elm$core$List$map, $author$project$Pages$Utils$viewStandardRow, data.rows))) - ]), - _List_fromArray( - [ - A3($author$project$Pages$Reports$View$viewDownloadCSVButton, language, csvFileName, csvContent) - ]))); - }); -var $author$project$Translate$Save = {$: 'Save'}; -var $author$project$Translate$MonthLabel = {$: 'MonthLabel'}; -var $author$project$Translate$YearLabel = {$: 'YearLabel'}; -var $justinmimbs$date$Date$clamp = F3( - function (dateA, dateB, dateX) { - var a = dateA.a; - var b = dateB.a; - var x = dateX.a; - return (_Utils_cmp(x, a) < 0) ? dateA : ((_Utils_cmp(b, x) < 0) ? dateB : dateX); - }); -var $elm$html$Html$p = _VirtualDom_node('p'); -var $author$project$DateSelector$Selector$Dimmed = {$: 'Dimmed'}; -var $author$project$DateSelector$Selector$Disabled = {$: 'Disabled'}; -var $author$project$DateSelector$Selector$Normal = {$: 'Normal'}; -var $author$project$DateSelector$Selector$Selected = {$: 'Selected'}; -var $author$project$DateSelector$Selector$classNameFromState = function (state) { - switch (state.$) { - case 'Normal': - return ''; - case 'Dimmed': - return 'date-selector--dimmed'; - case 'Disabled': - return 'date-selector--disabled'; - default: - return 'date-selector--selected'; - } -}; -var $justinmimbs$date$Date$fromRataDie = function (rd) { - return $justinmimbs$date$Date$RD(rd); -}; -var $elm$core$List$drop = F2( - function (n, list) { - drop: - while (true) { - if (n <= 0) { - return list; - } else { - if (!list.b) { - return list; - } else { - var x = list.a; - var xs = list.b; - var $temp$n = n - 1, - $temp$list = xs; - n = $temp$n; - list = $temp$list; - continue drop; - } - } - } - }); -var $elm$core$List$takeReverse = F3( - function (n, list, kept) { - takeReverse: - while (true) { - if (n <= 0) { - return kept; - } else { - if (!list.b) { - return kept; - } else { - var x = list.a; - var xs = list.b; - var $temp$n = n - 1, - $temp$list = xs, - $temp$kept = A2($elm$core$List$cons, x, kept); - n = $temp$n; - list = $temp$list; - kept = $temp$kept; - continue takeReverse; - } - } - } - }); -var $elm$core$List$takeTailRec = F2( - function (n, list) { - return $elm$core$List$reverse( - A3($elm$core$List$takeReverse, n, list, _List_Nil)); - }); -var $elm$core$List$takeFast = F3( - function (ctr, n, list) { - if (n <= 0) { - return _List_Nil; - } else { - var _v0 = _Utils_Tuple2(n, list); - _v0$1: - while (true) { - _v0$5: - while (true) { - if (!_v0.b.b) { - return list; - } else { - if (_v0.b.b.b) { - switch (_v0.a) { - case 1: - break _v0$1; - case 2: - var _v2 = _v0.b; - var x = _v2.a; - var _v3 = _v2.b; - var y = _v3.a; - return _List_fromArray( - [x, y]); - case 3: - if (_v0.b.b.b.b) { - var _v4 = _v0.b; - var x = _v4.a; - var _v5 = _v4.b; - var y = _v5.a; - var _v6 = _v5.b; - var z = _v6.a; - return _List_fromArray( - [x, y, z]); - } else { - break _v0$5; - } - default: - if (_v0.b.b.b.b && _v0.b.b.b.b.b) { - var _v7 = _v0.b; - var x = _v7.a; - var _v8 = _v7.b; - var y = _v8.a; - var _v9 = _v8.b; - var z = _v9.a; - var _v10 = _v9.b; - var w = _v10.a; - var tl = _v10.b; - return (ctr > 1000) ? A2( - $elm$core$List$cons, - x, - A2( - $elm$core$List$cons, - y, - A2( - $elm$core$List$cons, - z, - A2( - $elm$core$List$cons, - w, - A2($elm$core$List$takeTailRec, n - 4, tl))))) : A2( - $elm$core$List$cons, - x, - A2( - $elm$core$List$cons, - y, - A2( - $elm$core$List$cons, - z, - A2( - $elm$core$List$cons, - w, - A3($elm$core$List$takeFast, ctr + 1, n - 4, tl))))); - } else { - break _v0$5; - } - } - } else { - if (_v0.a === 1) { - break _v0$1; - } else { - break _v0$5; - } - } - } - } - return list; - } - var _v1 = _v0.b; - var x = _v1.a; - return _List_fromArray( - [x]); - } - }); -var $elm$core$List$take = F2( - function (n, list) { - return A3($elm$core$List$takeFast, 0, n, list); - }); -var $author$project$DateSelector$Selector$groupsOf = F2( - function (n, list) { - return $elm$core$List$isEmpty(list) ? _List_Nil : A2( - $elm$core$List$cons, - A2($elm$core$List$take, n, list), + A2( + $elm$html$Html$p, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text( + A2($author$project$Translate$translate, language, $author$project$Translate$MonthLabel)) + ])), + A2( + $elm$core$Maybe$withDefault, + $author$project$DateSelector$Selector$viewMonthSelectListDisabled, + A2( + $elm$core$Maybe$map, + A3($author$project$DateSelector$Selector$viewMonthSelectList, language, minimum, maximum), + maybeSelected)) + ])); + var daysSection = A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('days') + ]), + _List_fromArray( + [ + A2( + $elm$core$Maybe$withDefault, + $author$project$DateSelector$Selector$viewDateTableDisabled(minimum), + A2( + $elm$core$Maybe$map, + A2($author$project$DateSelector$Selector$viewDateTable, minimum, maximum), + maybeSelected)) + ])); + return A2( + $elm$html$Html$map, + A2($justinmimbs$date$Date$clamp, minimum, maximum), A2( - $author$project$DateSelector$Selector$groupsOf, - n, - A2($elm$core$List$drop, n, list))); + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('calendar') + ]), + _List_fromArray( + [yearSection, monthSection, daysSection]))); }); -var $elm$json$Json$Encode$int = _Json_wrap; -var $justinmimbs$date$Date$isBetween = F3( - function (_v0, _v1, _v2) { - var a = _v0.a; - var b = _v1.a; - var x = _v2.a; - return A3($justinmimbs$date$Date$isBetweenInt, a, b, x); +var $author$project$DateSelector$SelectorPopup$view = F6( + function (language, toSelect, toClose, minimum, maximum, selected) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('date-selector-popup') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$map, + toSelect, + A4($author$project$DateSelector$Selector$viewPopup, language, minimum, maximum, selected)), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('ui button save'), + $elm$html$Html$Events$onClick(toClose) + ]), + _List_fromArray( + [ + $elm$html$Html$text( + A2($author$project$Translate$translate, language, $author$project$Translate$Save)) + ])) + ])); }); -var $author$project$DateSelector$Selector$isSelectable = function (state) { - return _Utils_eq(state, $author$project$DateSelector$Selector$Normal) || _Utils_eq(state, $author$project$DateSelector$Selector$Dimmed); -}; -var $justinmimbs$date$Date$Day = {$: 'Day'}; -var $justinmimbs$date$Date$Days = {$: 'Days'}; -var $justinmimbs$date$Date$Monday = {$: 'Monday'}; -var $justinmimbs$date$Date$weekdayToNumber = function (wd) { - switch (wd.$) { - case 'Mon': - return 1; - case 'Tue': - return 2; - case 'Wed': - return 3; - case 'Thu': - return 4; - case 'Fri': - return 5; - case 'Sat': - return 6; - default: - return 7; - } -}; -var $justinmimbs$date$Date$daysSincePreviousWeekday = F2( - function (wd, date) { +var $author$project$DateSelector$SelectorPopup$viewCalendarPopup = F3( + function (language, popupState, selected) { return A2( - $elm$core$Basics$modBy, - 7, - ($justinmimbs$date$Date$weekdayNumber(date) + 7) - $justinmimbs$date$Date$weekdayToNumber(wd)); + $elm$core$Maybe$map, + function (config) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('ui active modal calendar-popup') + ]), + _List_fromArray( + [ + A6($author$project$DateSelector$SelectorPopup$view, language, config.select, config.close, config.dateFrom, config.dateTo, selected) + ])); + }, + popupState); }); -var $justinmimbs$date$Date$firstOfMonth = F2( - function (y, m) { - return $justinmimbs$date$Date$RD( - ($justinmimbs$date$Date$daysBeforeYear(y) + A2($justinmimbs$date$Date$daysBeforeMonth, y, m)) + 1); +var $author$project$Gizra$Html$showMaybe = $elm$core$Maybe$withDefault($author$project$Gizra$Html$emptyNode); +var $author$project$Utils$Html$viewCustomModal = function (extraClasses) { + var classes = A2( + $elm$core$String$join, + ' ', + A2($elm$core$List$cons, 'overlay', extraClasses)); + return A2( + $elm$core$Basics$composeL, + $author$project$Gizra$Html$showMaybe, + $elm$core$Maybe$map( + function (modal) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class(classes) + ]), + _List_fromArray( + [modal])); + })); +}; +var $author$project$Utils$Html$viewModal = $author$project$Utils$Html$viewCustomModal(_List_Nil); +var $author$project$Translate$Activity = {$: 'Activity'}; +var $author$project$Translate$Completed = {$: 'Completed'}; +var $author$project$Translate$Expected = {$: 'Expected'}; +var $author$project$Translate$NutritionActivity = function (a) { + return {$: 'NutritionActivity', a: a}; +}; +var $author$project$Translate$NutritionIndividual = {$: 'NutritionIndividual'}; +var $author$project$Pages$Completion$Model$allNutritionActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$NutritionHeight, $author$project$Backend$Completion$Model$NutritionNutrition, $author$project$Backend$Completion$Model$NutritionPhoto, $author$project$Backend$Completion$Model$NutritionWeight, $author$project$Backend$Completion$Model$NutritionMUAC, $author$project$Backend$Completion$Model$NutritionContributingFactors, $author$project$Backend$Completion$Model$NutritionFollowUp, $author$project$Backend$Completion$Model$NutritionHealthEducation, $author$project$Backend$Completion$Model$NutritionSendToHC, $author$project$Backend$Completion$Model$NutritionNCDA]); +var $myrho$elm_round$Round$addSign = F2( + function (signed, str) { + var isNotZero = A2( + $elm$core$List$any, + function (c) { + return (!_Utils_eq( + c, + _Utils_chr('0'))) && (!_Utils_eq( + c, + _Utils_chr('.'))); + }, + $elm$core$String$toList(str)); + return _Utils_ap( + (signed && isNotZero) ? '-' : '', + str); }); -var $justinmimbs$date$Date$quarterToMonth = function (q) { - return $justinmimbs$date$Date$numberToMonth((q * 3) - 2); +var $elm$core$String$fromFloat = _String_fromNumber; +var $elm$core$Char$fromCode = _Char_fromCode; +var $myrho$elm_round$Round$increaseNum = function (_v0) { + var head = _v0.a; + var tail = _v0.b; + if (_Utils_eq( + head, + _Utils_chr('9'))) { + var _v1 = $elm$core$String$uncons(tail); + if (_v1.$ === 'Nothing') { + return '01'; + } else { + var headtail = _v1.a; + return A2( + $elm$core$String$cons, + _Utils_chr('0'), + $myrho$elm_round$Round$increaseNum(headtail)); + } + } else { + var c = $elm$core$Char$toCode(head); + return ((c >= 48) && (c < 57)) ? A2( + $elm$core$String$cons, + $elm$core$Char$fromCode(c + 1), + tail) : '0'; + } }; -var $justinmimbs$date$Date$floor = F2( - function (interval, date) { - var rd = date.a; - switch (interval.$) { - case 'Year': - return $justinmimbs$date$Date$firstOfYear( - $justinmimbs$date$Date$year(date)); - case 'Quarter': - return A2( - $justinmimbs$date$Date$firstOfMonth, - $justinmimbs$date$Date$year(date), - $justinmimbs$date$Date$quarterToMonth( - $justinmimbs$date$Date$quarter(date))); - case 'Month': - return A2( - $justinmimbs$date$Date$firstOfMonth, - $justinmimbs$date$Date$year(date), - $justinmimbs$date$Date$month(date)); - case 'Week': - return $justinmimbs$date$Date$RD( - rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Mon, date)); - case 'Monday': - return $justinmimbs$date$Date$RD( - rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Mon, date)); - case 'Tuesday': - return $justinmimbs$date$Date$RD( - rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Tue, date)); - case 'Wednesday': - return $justinmimbs$date$Date$RD( - rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Wed, date)); - case 'Thursday': - return $justinmimbs$date$Date$RD( - rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Thu, date)); - case 'Friday': - return $justinmimbs$date$Date$RD( - rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Fri, date)); - case 'Saturday': - return $justinmimbs$date$Date$RD( - rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Sat, date)); - case 'Sunday': - return $justinmimbs$date$Date$RD( - rd - A2($justinmimbs$date$Date$daysSincePreviousWeekday, $elm$time$Time$Sun, date)); - default: - return date; +var $elm$core$Basics$isInfinite = _Basics_isInfinite; +var $elm$core$Basics$isNaN = _Basics_isNaN; +var $elm$core$String$padRight = F3( + function (n, _char, string) { + return _Utils_ap( + string, + A2( + $elm$core$String$repeat, + n - $elm$core$String$length(string), + $elm$core$String$fromChar(_char))); + }); +var $elm$core$String$reverse = _String_reverse; +var $myrho$elm_round$Round$splitComma = function (str) { + var _v0 = A2($elm$core$String$split, '.', str); + if (_v0.b) { + if (_v0.b.b) { + var before = _v0.a; + var _v1 = _v0.b; + var after = _v1.a; + return _Utils_Tuple2(before, after); + } else { + var before = _v0.a; + return _Utils_Tuple2(before, '0'); } + } else { + return _Utils_Tuple2('0', '0'); + } +}; +var $elm$core$Tuple$mapFirst = F2( + function (func, _v0) { + var x = _v0.a; + var y = _v0.b; + return _Utils_Tuple2( + func(x), + y); }); -var $justinmimbs$date$Date$Weeks = {$: 'Weeks'}; -var $justinmimbs$date$Date$intervalToUnits = function (interval) { - switch (interval.$) { - case 'Year': - return _Utils_Tuple2(1, $justinmimbs$date$Date$Years); - case 'Quarter': - return _Utils_Tuple2(3, $justinmimbs$date$Date$Months); - case 'Month': - return _Utils_Tuple2(1, $justinmimbs$date$Date$Months); - case 'Day': - return _Utils_Tuple2(1, $justinmimbs$date$Date$Days); - default: - var week = interval; - return _Utils_Tuple2(1, $justinmimbs$date$Date$Weeks); +var $myrho$elm_round$Round$toDecimal = function (fl) { + var _v0 = A2( + $elm$core$String$split, + 'e', + $elm$core$String$fromFloat( + $elm$core$Basics$abs(fl))); + if (_v0.b) { + if (_v0.b.b) { + var num = _v0.a; + var _v1 = _v0.b; + var exp = _v1.a; + var e = A2( + $elm$core$Maybe$withDefault, + 0, + $elm$core$String$toInt( + A2($elm$core$String$startsWith, '+', exp) ? A2($elm$core$String$dropLeft, 1, exp) : exp)); + var _v2 = $myrho$elm_round$Round$splitComma(num); + var before = _v2.a; + var after = _v2.b; + var total = _Utils_ap(before, after); + var zeroed = (e < 0) ? A2( + $elm$core$Maybe$withDefault, + '0', + A2( + $elm$core$Maybe$map, + function (_v3) { + var a = _v3.a; + var b = _v3.b; + return a + ('.' + b); + }, + A2( + $elm$core$Maybe$map, + $elm$core$Tuple$mapFirst($elm$core$String$fromChar), + $elm$core$String$uncons( + _Utils_ap( + A2( + $elm$core$String$repeat, + $elm$core$Basics$abs(e), + '0'), + total))))) : A3( + $elm$core$String$padRight, + e + 1, + _Utils_chr('0'), + total); + return _Utils_ap( + (fl < 0) ? '-' : '', + zeroed); + } else { + var num = _v0.a; + return _Utils_ap( + (fl < 0) ? '-' : '', + num); + } + } else { + return ''; } }; -var $justinmimbs$date$Date$ceiling = F2( - function (interval, date) { - var floored = A2($justinmimbs$date$Date$floor, interval, date); - if (_Utils_eq(date, floored)) { - return date; +var $myrho$elm_round$Round$roundFun = F3( + function (functor, s, fl) { + if ($elm$core$Basics$isInfinite(fl) || $elm$core$Basics$isNaN(fl)) { + return $elm$core$String$fromFloat(fl); } else { - var _v0 = $justinmimbs$date$Date$intervalToUnits(interval); - var n = _v0.a; - var unit = _v0.b; - return A3($justinmimbs$date$Date$add, unit, n, floored); + var signed = fl < 0; + var _v0 = $myrho$elm_round$Round$splitComma( + $myrho$elm_round$Round$toDecimal( + $elm$core$Basics$abs(fl))); + var before = _v0.a; + var after = _v0.b; + var r = $elm$core$String$length(before) + s; + var normalized = _Utils_ap( + A2($elm$core$String$repeat, (-r) + 1, '0'), + A3( + $elm$core$String$padRight, + r, + _Utils_chr('0'), + _Utils_ap(before, after))); + var totalLen = $elm$core$String$length(normalized); + var roundDigitIndex = A2($elm$core$Basics$max, 1, r); + var increase = A2( + functor, + signed, + A3($elm$core$String$slice, roundDigitIndex, totalLen, normalized)); + var remains = A3($elm$core$String$slice, 0, roundDigitIndex, normalized); + var num = increase ? $elm$core$String$reverse( + A2( + $elm$core$Maybe$withDefault, + '1', + A2( + $elm$core$Maybe$map, + $myrho$elm_round$Round$increaseNum, + $elm$core$String$uncons( + $elm$core$String$reverse(remains))))) : remains; + var numLen = $elm$core$String$length(num); + var numZeroed = (num === '0') ? num : ((s <= 0) ? _Utils_ap( + num, + A2( + $elm$core$String$repeat, + $elm$core$Basics$abs(s), + '0')) : ((_Utils_cmp( + s, + $elm$core$String$length(after)) < 0) ? (A3($elm$core$String$slice, 0, numLen - s, num) + ('.' + A3($elm$core$String$slice, numLen - s, numLen, num))) : _Utils_ap( + before + '.', + A3( + $elm$core$String$padRight, + s, + _Utils_chr('0'), + after)))); + return A2($myrho$elm_round$Round$addSign, signed, numZeroed); } }); -var $justinmimbs$date$Date$rangeHelp = F5( - function (unit, step, until, revList, current) { - rangeHelp: - while (true) { - if (_Utils_cmp(current, until) < 0) { - var _v0 = A3( - $justinmimbs$date$Date$add, - unit, - step, - $justinmimbs$date$Date$RD(current)); - var next = _v0.a; - var $temp$unit = unit, - $temp$step = step, - $temp$until = until, - $temp$revList = A2( - $elm$core$List$cons, - $justinmimbs$date$Date$RD(current), - revList), - $temp$current = next; - unit = $temp$unit; - step = $temp$step; - until = $temp$until; - revList = $temp$revList; - current = $temp$current; - continue rangeHelp; +var $myrho$elm_round$Round$round = $myrho$elm_round$Round$roundFun( + F2( + function (signed, str) { + var _v0 = $elm$core$String$uncons(str); + if (_v0.$ === 'Nothing') { + return false; } else { - return $elm$core$List$reverse(revList); + if ('5' === _v0.a.a.valueOf()) { + if (_v0.a.b === '') { + var _v1 = _v0.a; + return !signed; + } else { + var _v2 = _v0.a; + return true; + } + } else { + var _v3 = _v0.a; + var _int = _v3.a; + return function (i) { + return ((i > 53) && signed) || ((i >= 53) && (!signed)); + }( + $elm$core$Char$toCode(_int)); + } } - } - }); -var $justinmimbs$date$Date$range = F4( - function (interval, step, _v0, _v1) { - var start = _v0.a; - var until = _v1.a; - var _v2 = $justinmimbs$date$Date$intervalToUnits(interval); - var n = _v2.a; - var unit = _v2.b; - var _v3 = A2( - $justinmimbs$date$Date$ceiling, - interval, - $justinmimbs$date$Date$RD(start)); - var first = _v3.a; - return (_Utils_cmp(first, until) < 0) ? A5( - $justinmimbs$date$Date$rangeHelp, - unit, - A2($elm$core$Basics$max, 1, step) * n, - until, - _List_Nil, - first) : _List_Nil; - }); -var $author$project$DateSelector$Selector$monthDates = F2( - function (y, m) { - var start = A2( - $justinmimbs$date$Date$floor, - $justinmimbs$date$Date$Monday, - A3($justinmimbs$date$Date$fromCalendarDate, y, m, 1)); - return A4( - $justinmimbs$date$Date$range, - $justinmimbs$date$Date$Day, - 1, - start, - A3($justinmimbs$date$Date$add, $justinmimbs$date$Date$Days, 42, start)); - }); -var $elm$json$Json$Encode$null = _Json_encodeNull; -var $elm$virtual_dom$VirtualDom$property = F2( - function (key, value) { - return A2( - _VirtualDom_property, - _VirtualDom_noInnerHtmlOrFormAction(key), - _VirtualDom_noJavaScriptOrHtmlUri(value)); + })); +var $author$project$Pages$Completion$View$generateNutritionReportData = F2( + function (language, records) { + var count = F2( + function (resolveFunc, activity) { + return $elm$core$List$length( + A2( + $elm$core$List$filter, + A2( + $elm$core$Basics$composeR, + resolveFunc, + $elm$core$List$member(activity)), + records)); + }); + var calcualtePercentage = F2( + function (nominator, total) { + return (!total) ? '0' : (A2($myrho$elm_round$Round$round, 3, (nominator / total) * 100) + '%'); + }); + return { + captions: _List_fromArray( + [ + A2($author$project$Translate$translate, language, $author$project$Translate$Activity), + A2($author$project$Translate$translate, language, $author$project$Translate$Expected), + A2($author$project$Translate$translate, language, $author$project$Translate$Completed), + '%' + ]), + heading: A2($author$project$Translate$translate, language, $author$project$Translate$NutritionIndividual), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A2( + count, + function ($) { + return $.expectedActivities; + }, + activity); + var completed = A2( + count, + function ($) { + return $.completedActivities; + }, + activity); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$NutritionActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2(calcualtePercentage, completed, expected) + ]); + }, + $author$project$Pages$Completion$Model$allNutritionActivities) + }; }); -var $elm$html$Html$Attributes$property = $elm$virtual_dom$VirtualDom$property; -var $elm$html$Html$table = _VirtualDom_node('table'); -var $elm$html$Html$tbody = _VirtualDom_node('tbody'); -var $elm$html$Html$td = _VirtualDom_node('td'); -var $justinmimbs$date$Date$toRataDie = function (_v0) { - var rd = _v0.a; - return rd; -}; -var $elm$html$Html$tr = _VirtualDom_node('tr'); -var $author$project$DateSelector$Selector$dayOfWeekNames = _List_fromArray( - ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']); -var $elm$html$Html$th = _VirtualDom_node('th'); -var $elm$html$Html$thead = _VirtualDom_node('thead'); -var $author$project$DateSelector$Selector$viewDayOfWeekHeader = A2( - $elm$html$Html$thead, - _List_Nil, - _List_fromArray( - [ - A2( - $elm$html$Html$tr, - _List_Nil, +var $elm$html$Html$Attributes$classList = function (classes) { + return $elm$html$Html$Attributes$class( + A2( + $elm$core$String$join, + ' ', A2( $elm$core$List$map, - function (name) { + $elm$core$Tuple$first, + A2($elm$core$List$filter, $elm$core$Tuple$second, classes)))); +}; +var $author$project$Pages$Components$View$viewCustomCells = F2( + function (labelClass, valueClass) { + return $elm$core$List$indexedMap( + F2( + function (index, cellText) { return A2( - $elm$html$Html$th, - _List_Nil, + $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$text(name) + $elm$html$Html$Attributes$classList( + _List_fromArray( + [ + _Utils_Tuple2('item', true), + _Utils_Tuple2(labelClass, !index), + _Utils_Tuple2(valueClass, !(!index)) + ])) + ]), + _List_fromArray( + [ + $elm$html$Html$text(cellText) ])); + })); + }); +var $author$project$Pages$Components$View$viewNutritionMetricsResultsTable = function (data) { + var viewRow = function (cells) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('row') + ]), + A3($author$project$Pages$Components$View$viewCustomCells, 'row-label', 'value', cells)); + }; + var captionsRow = A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('row') + ]), + A3($author$project$Pages$Components$View$viewCustomCells, 'row-label', 'heading', data.captions)); + return _List_fromArray( + [ + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('section heading') + ]), + _List_fromArray( + [ + $elm$html$Html$text(data.heading) + ])), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('table wide') + ]), + A2( + $elm$core$List$cons, + captionsRow, + A2($elm$core$List$map, viewRow, data.rows))) + ]); +}; +var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F4( + function (language, startDate, limitDate, reportData) { + var filteredData = A2( + $author$project$Pages$Completion$View$generateNutritionReportData, + language, + A2( + $elm$core$List$filter, + function (encounter) { + return (!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), + $elm$core$Basics$LT)) && (!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, limitDate), + $elm$core$Basics$GT)); }, - $author$project$DateSelector$Selector$dayOfWeekNames)) - ])); -var $author$project$DateSelector$Selector$viewDateTable = F3( - function (minimum, maximum, selected) { - var weeks = A2( - $author$project$DateSelector$Selector$groupsOf, - 7, + reportData)); + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report nutrition-individual') + ]), + $author$project$Pages$Components$View$viewNutritionMetricsResultsTable(filteredData)); + }); +var $author$project$Pages$Utils$emptySelectOption = function (isSelected) { + return A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value(''), + $elm$html$Html$Attributes$selected(isSelected) + ]), + _List_fromArray( + [ + $elm$html$Html$text('') + ])); +}; +var $elm$html$Html$Events$alwaysStop = function (x) { + return _Utils_Tuple2(x, true); +}; +var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { + return {$: 'MayStopPropagation', a: a}; +}; +var $elm$html$Html$Events$stopPropagationOn = F2( + function (event, decoder) { + return A2( + $elm$virtual_dom$VirtualDom$on, + event, + $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); + }); +var $elm$html$Html$Events$targetValue = A2( + $elm$json$Json$Decode$at, + _List_fromArray( + ['target', 'value']), + $elm$json$Json$Decode$string); +var $elm$html$Html$Events$onInput = function (tagger) { + return A2( + $elm$html$Html$Events$stopPropagationOn, + 'input', + A2( + $elm$json$Json$Decode$map, + $elm$html$Html$Events$alwaysStop, + A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); +}; +var $author$project$Pages$Utils$viewCustomSelectListInput = F6( + function (currentValue, options, toStringFunc, setMsg, inputClass, withEmptyOption) { + var emptyOption = withEmptyOption ? $author$project$Pages$Utils$emptySelectOption( + _Utils_eq(currentValue, $elm$core$Maybe$Nothing)) : $author$project$Gizra$Html$emptyNode; + return A2( + $elm$html$Html$select, + _List_fromArray( + [ + $elm$html$Html$Events$onInput(setMsg), + $elm$html$Html$Attributes$class(inputClass) + ]), A2( - $author$project$DateSelector$Selector$monthDates, - $justinmimbs$date$Date$year(selected), - $justinmimbs$date$Date$month(selected))); - var isInvertedMinMax = _Utils_eq( - A2($justinmimbs$date$Date$compare, minimum, maximum), - $elm$core$Basics$GT); + $elm$core$List$cons, + emptyOption, + A2( + $elm$core$List$map, + function (_v0) { + var label = _v0.a; + var value_ = _v0.b; + return A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value( + toStringFunc(value_)), + $elm$html$Html$Attributes$selected( + _Utils_eq( + currentValue, + $elm$core$Maybe$Just(value_))) + ]), + _List_fromArray( + [ + $elm$html$Html$text(label) + ])); + }, + options))); + }); +var $author$project$Pages$Utils$viewSelectListInput = F7( + function (language, currentValue, options, toStringFunc, setMsg, transId, inputClass) { + var transFunc = A2( + $elm$core$Basics$composeR, + transId, + $author$project$Translate$translate(language)); + var optionsPairs = A2( + $elm$core$List$map, + function (option) { + return _Utils_Tuple2( + transFunc(option), + option); + }, + options); + return A6($author$project$Pages$Utils$viewCustomSelectListInput, currentValue, optionsPairs, toStringFunc, setMsg, inputClass, true); + }); +var $author$project$Pages$Utils$viewCustomLabel = F4( + function (language, translationId, suffix, class_) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class(class_) + ]), + _List_fromArray( + [ + $elm$html$Html$text( + _Utils_ap( + A2($author$project$Translate$translate, language, translationId), + suffix)) + ])); + }); +var $author$project$Pages$Utils$viewLabel = F2( + function (language, translationId) { + return A4($author$project$Pages$Utils$viewCustomLabel, language, translationId, ':', 'label'); + }); +var $author$project$Pages$Utils$wrapSelectListInput = F4( + function (language, labelTransId, disabled, selectList) { return A2( - $elm$html$Html$table, - _List_Nil, + $elm$html$Html$div, _List_fromArray( [ - $author$project$DateSelector$Selector$viewDayOfWeekHeader, - A2( - $elm$html$Html$tbody, + $elm$html$Html$Attributes$classList( _List_fromArray( [ - A2( - $elm$html$Html$Events$on, - 'click', - A2( - $elm$json$Json$Decode$map, - $justinmimbs$date$Date$fromRataDie, - A2( - $elm$json$Json$Decode$at, - _List_fromArray( - ['target', 'time']), - $elm$json$Json$Decode$int))) - ]), - A2( - $elm$core$List$map, - function (week) { - return A2( - $elm$html$Html$tr, - _List_Nil, - A2( - $elm$core$List$map, - function (date) { - var equalByDay = F2( - function (date1, date2) { - return _Utils_eq( - $justinmimbs$date$Date$day(date1), - $justinmimbs$date$Date$day(date2)) && (_Utils_eq( - $justinmimbs$date$Date$month(date1), - $justinmimbs$date$Date$month(date2)) && _Utils_eq( - $justinmimbs$date$Date$year(date1), - $justinmimbs$date$Date$year(date2))); - }); - var state = A2(equalByDay, date, selected) ? $author$project$DateSelector$Selector$Selected : (((!A3($justinmimbs$date$Date$isBetween, minimum, maximum, date)) || isInvertedMinMax) ? $author$project$DateSelector$Selector$Disabled : ((!_Utils_eq( - $justinmimbs$date$Date$month(date), - $justinmimbs$date$Date$month(selected))) ? $author$project$DateSelector$Selector$Dimmed : $author$project$DateSelector$Selector$Normal)); - var cell = _Utils_eq(state, $author$project$DateSelector$Selector$Selected) ? A2( - $elm$html$Html$p, - _List_Nil, - _List_fromArray( - [ - $elm$html$Html$text( - $elm$core$String$fromInt( - $justinmimbs$date$Date$day(date))) - ])) : $elm$html$Html$text( - $elm$core$String$fromInt( - $justinmimbs$date$Date$day(date))); - return A2( - $elm$html$Html$td, - _List_fromArray( - [ - $elm$html$Html$Attributes$class( - $author$project$DateSelector$Selector$classNameFromState(state)), - A2( - $elm$html$Html$Attributes$property, - 'time', - $author$project$DateSelector$Selector$isSelectable(state) ? $elm$json$Json$Encode$int( - $justinmimbs$date$Date$toRataDie(date)) : $elm$json$Json$Encode$null) - ]), - _List_fromArray( - [cell])); - }, - week)); - }, - weeks)) + _Utils_Tuple2('select-input-wrapper', true), + _Utils_Tuple2('disabled', disabled) + ])) + ]), + _List_fromArray( + [ + A2($author$project$Pages$Utils$viewLabel, language, labelTransId), + selectList ])); }); -var $author$project$DateSelector$Selector$viewDateTableDisabled = function (date) { - var weeks = A2( - $author$project$DateSelector$Selector$groupsOf, - 7, - A2( - $author$project$DateSelector$Selector$monthDates, - $justinmimbs$date$Date$year(date), - $justinmimbs$date$Date$month(date))); - var disabled = $author$project$DateSelector$Selector$classNameFromState($author$project$DateSelector$Selector$Disabled); - return A2( - $elm$html$Html$table, - _List_Nil, - _List_fromArray( - [ - $author$project$DateSelector$Selector$viewDayOfWeekHeader, - A2( - $elm$html$Html$tbody, - _List_Nil, - A2( - $elm$core$List$map, - function (week) { - return A2( - $elm$html$Html$tr, - _List_Nil, - A2( - $elm$core$List$map, - function (date_) { - return A2( - $elm$html$Html$td, - _List_fromArray( - [ - $elm$html$Html$Attributes$class(disabled) - ]), +var $author$project$Pages$Completion$View$viewCompletionData = F5( + function (language, currentDate, themePath, data, model) { + var topBar = function () { + var scopeLabel = function () { + var _v1 = data.entityType; + if (_v1.$ === 'EntityGlobal') { + return A2($author$project$Translate$translate, language, $author$project$Translate$Global); + } else { + return data.entityName; + } + }(); + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('top-bar') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('new-selection') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$a, + _List_fromArray( + [ + $elm$html$Html$Attributes$href('/admin/reports/completion') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$button, + _List_Nil, _List_fromArray( [ $elm$html$Html$text( - $elm$core$String$fromInt( - $justinmimbs$date$Date$day(date_))) - ])); - }, - week)); - }, - weeks)) - ])); -}; -var $author$project$Translate$ResolveMonth = F2( - function (a, b) { - return {$: 'ResolveMonth', a: a, b: b}; - }); -var $author$project$Gizra$NominalDate$allMonths = _List_fromArray( - [$elm$time$Time$Jan, $elm$time$Time$Feb, $elm$time$Time$Mar, $elm$time$Time$Apr, $elm$time$Time$May, $elm$time$Time$Jun, $elm$time$Time$Jul, $elm$time$Time$Aug, $elm$time$Time$Sep, $elm$time$Time$Oct, $elm$time$Time$Nov, $elm$time$Time$Dec]); -var $author$project$DateSelector$Selector$isLeapYear = function (y) { - return ((!A2($elm$core$Basics$modBy, 4, y)) && (!(!A2($elm$core$Basics$modBy, 100, y)))) || (!A2($elm$core$Basics$modBy, 400, y)); -}; -var $author$project$DateSelector$Selector$daysInMonth = F2( - function (y, m) { - switch (m.$) { - case 'Jan': - return 31; - case 'Feb': - return $author$project$DateSelector$Selector$isLeapYear(y) ? 29 : 28; - case 'Mar': - return 31; - case 'Apr': - return 30; - case 'May': - return 31; - case 'Jun': - return 30; - case 'Jul': - return 31; - case 'Aug': - return 31; - case 'Sep': - return 30; - case 'Oct': - return 31; - case 'Nov': - return 30; - default: - return 31; - } - }); -var $author$project$DateSelector$Selector$dateWithMonth = F2( - function (date, m) { - var y = $justinmimbs$date$Date$year(date); - var d = $justinmimbs$date$Date$day(date); - return A3( - $justinmimbs$date$Date$fromCalendarDate, - y, - m, + A2($author$project$Translate$translate, language, $author$project$Translate$NewScope)) + ])) + ])) + ])), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('scope') + ]), + _List_fromArray( + [ + $elm$html$Html$text( + A2($author$project$Translate$translate, language, $author$project$Translate$Scope) + (': ' + scopeLabel)) + ])) + ])); + }(); + var dateInputs = A2( + $elm$core$Maybe$withDefault, + _List_Nil, A2( - $elm$core$Basics$min, - d, - A2($author$project$DateSelector$Selector$daysInMonth, y, m))); + $elm$core$Maybe$map, + function (reportType) { + var startDateInput = function () { + var dateSelectorConfig = { + close: $author$project$Pages$Completion$Model$SetStartDateSelectorState($elm$core$Maybe$Nothing), + dateDefault: $elm$core$Maybe$Just($author$project$Pages$Utils$launchDate), + dateFrom: $author$project$Pages$Utils$launchDate, + dateTo: currentDate, + select: $author$project$Pages$Completion$Model$SetStartDate + }; + var dateForView = A2( + $elm$core$Maybe$withDefault, + '', + A2($elm$core$Maybe$map, $author$project$Gizra$NominalDate$formatDDMMYYYY, model.startDate)); + return A4( + $author$project$Pages$Utils$wrapSelectListInput, + language, + $author$project$Translate$SelectStartDate, + false, + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('form-input date'), + $elm$html$Html$Events$onClick( + $author$project$Pages$Completion$Model$SetStartDateSelectorState( + $elm$core$Maybe$Just(dateSelectorConfig))) + ]), + _List_fromArray( + [ + $elm$html$Html$text(dateForView) + ]))); + }(); + var limitDateInput = function () { + if ($elm_community$maybe_extra$Maybe$Extra$isNothing(model.startDate)) { + return $author$project$Gizra$Html$emptyNode; + } else { + var limitDateForView = A2( + $elm$core$Maybe$withDefault, + '', + A2($elm$core$Maybe$map, $author$project$Gizra$NominalDate$formatDDMMYYYY, model.limitDate)); + var dateFrom = A2($elm$core$Maybe$withDefault, $author$project$Pages$Utils$launchDate, model.startDate); + var dateSelectorConfig = { + close: $author$project$Pages$Completion$Model$SetLimitDateSelectorState($elm$core$Maybe$Nothing), + dateDefault: $elm$core$Maybe$Just(currentDate), + dateFrom: dateFrom, + dateTo: currentDate, + select: $author$project$Pages$Completion$Model$SetLimitDate + }; + return A4( + $author$project$Pages$Utils$wrapSelectListInput, + language, + $author$project$Translate$SelectLimitDate, + false, + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('form-input date'), + $elm$html$Html$Events$onClick( + $author$project$Pages$Completion$Model$SetLimitDateSelectorState( + $elm$core$Maybe$Just(dateSelectorConfig))) + ]), + _List_fromArray( + [ + $elm$html$Html$text(limitDateForView) + ]))); + } + }(); + return _List_fromArray( + [startDateInput, limitDateInput]); + }, + model.reportType)); + var content = ($elm_community$maybe_extra$Maybe$Extra$isJust(model.startDateSelectorPopupState) || $elm_community$maybe_extra$Maybe$Extra$isJust(model.limitDateSelectorPopupState)) ? $author$project$Gizra$Html$emptyNode : A2( + $elm$core$Maybe$withDefault, + $author$project$Gizra$Html$emptyNode, + A4( + $elm$core$Maybe$map3, + F3( + function (reportType, startDate, limitDate) { + return A4($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, data.nutritionIndividualData); + }), + model.reportType, + model.startDate, + model.limitDate)); + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('page-content completion') + ]), + _List_fromArray( + [ + topBar, + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('inputs') + ]), + _Utils_ap( + _List_fromArray( + [ + A4( + $author$project$Pages$Utils$wrapSelectListInput, + language, + $author$project$Translate$ReportTypeLabel, + false, + A7( + $author$project$Pages$Utils$viewSelectListInput, + language, + model.reportType, + _List_fromArray( + [$author$project$Pages$Completion$Model$ReportNutritionIndividual]), + $author$project$Pages$Completion$Utils$reportTypeToString, + $author$project$Pages$Completion$Model$SetReportType, + $author$project$Translate$CompletionReportType, + 'select-input')) + ]), + _Utils_ap( + dateInputs, + _List_fromArray( + [content])))), + $author$project$Utils$Html$viewModal( + A3($author$project$DateSelector$SelectorPopup$viewCalendarPopup, language, model.startDateSelectorPopupState, model.startDate)), + $author$project$Utils$Html$viewModal( + A3($author$project$DateSelector$SelectorPopup$viewCalendarPopup, language, model.limitDateSelectorPopupState, model.limitDate)) + ])); }); -var $author$project$DateSelector$Selector$viewMonthSelectList = F4( - function (language, minimum, maximum, selectedDate) { - var isInvertedMinMax = _Utils_eq( - A2($justinmimbs$date$Date$compare, minimum, maximum), - $elm$core$Basics$GT); - var months = function () { - if (isInvertedMinMax) { - return _List_Nil; +var $author$project$Pages$Completion$View$view = F5( + function (language, currentDate, themePath, modelBackend, model) { + var _v0 = modelBackend.completionData; + if (_v0.$ === 'Just') { + if (_v0.a.$ === 'Ok') { + var data = _v0.a.a; + return A5($author$project$Pages$Completion$View$viewCompletionData, language, currentDate, themePath, data, model); } else { - var last = _Utils_eq( - $justinmimbs$date$Date$year(selectedDate), - $justinmimbs$date$Date$year(maximum)) ? $justinmimbs$date$Date$monthNumber(maximum) : 12; - var first = _Utils_eq( - $justinmimbs$date$Date$year(selectedDate), - $justinmimbs$date$Date$year(minimum)) ? $justinmimbs$date$Date$monthNumber(minimum) : 1; - return A2( - $elm$core$List$filter, - function (month) { - var monthNumber = $justinmimbs$date$Date$monthToNumber(month); - return (_Utils_cmp(monthNumber, first) > -1) && (_Utils_cmp(monthNumber, last) < 1); - }, - $author$project$Gizra$NominalDate$allMonths); + var err = _v0.a.a; + return $elm$html$Html$text( + $elm$core$Debug$toString(err)); } - }(); - var options = A2( - $elm$core$List$map, - function (month) { - var monthNumber = $justinmimbs$date$Date$monthToNumber(month); - return A2( - $elm$html$Html$option, + } else { + return $author$project$Gizra$Html$emptyNode; + } + }); +var $author$project$Translate$PleaseWaitMessage = {$: 'PleaseWaitMessage'}; +var $author$project$Translate$PopulationSelectionOption = function (a) { + return {$: 'PopulationSelectionOption', a: a}; +}; +var $author$project$Translate$SelectScope = {$: 'SelectScope'}; +var $author$project$Pages$CompletionMenu$Model$SelectionMade = {$: 'SelectionMade'}; +var $author$project$Pages$CompletionMenu$Model$SetHealthCenter = function (a) { + return {$: 'SetHealthCenter', a: a}; +}; +var $author$project$Pages$CompletionMenu$Model$SetPopulationSelection = function (a) { + return {$: 'SetPopulationSelection', a: a}; +}; +var $author$project$Pages$Components$Utils$populationSelectionOptionToString = function (selectionOption) { + switch (selectionOption.$) { + case 'SelectionOptionGlobal': + return 'all'; + case 'SelectionOptionDemographics': + return 'demographics'; + default: + return 'hc'; + } +}; +var $elm$core$List$sortBy = _List_sortBy; +var $author$project$Translate$LoadData = {$: 'LoadData'}; +var $author$project$Pages$Utils$viewMenuActionButton = F4( + function (language, path, label, selectionMadeMsg) { + return A2( + $elm$html$Html$a, + _List_fromArray( + [ + $elm$html$Html$Attributes$href(path) + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$button, _List_fromArray( [ - $elm$html$Html$Attributes$value( - $elm$core$String$fromInt(monthNumber)), - $elm$html$Html$Attributes$selected( - _Utils_eq( - $justinmimbs$date$Date$monthNumber(selectedDate), - monthNumber)) + $elm$html$Html$Events$onClick(selectionMadeMsg) ]), _List_fromArray( [ $elm$html$Html$text( - A2( - $author$project$Translate$translate, - language, - A2($author$project$Translate$ResolveMonth, false, month))) - ])); - }, - months); - return A2( - $elm$html$Html$select, - _List_fromArray( - [ - A2( - $elm$html$Html$Events$on, - 'input', - A2( - $elm$json$Json$Decode$map, - function (s) { - var selectedMonths = A2( - $elm$core$Maybe$withDefault, - 1, - $elm$core$String$toInt(s)); - return A2( - $author$project$DateSelector$Selector$dateWithMonth, - selectedDate, - $justinmimbs$date$Date$numberToMonth(selectedMonths)); - }, - A2( - $elm$json$Json$Decode$at, - _List_fromArray( - ['target', 'value']), - $elm$json$Json$Decode$string))) - ]), - options); + A2($author$project$Translate$translate, language, label)) + ])) + ])); }); -var $author$project$DateSelector$Selector$viewMonthSelectListDisabled = A2( - $elm$html$Html$select, - _List_Nil, - _List_fromArray( - [ +var $author$project$Pages$Utils$viewLoadDataButton = F3( + function (language, path, selectionMadeMsg) { + return A4($author$project$Pages$Utils$viewMenuActionButton, language, path, $author$project$Translate$LoadData, selectionMadeMsg); + }); +var $author$project$Pages$CompletionMenu$View$viewMenu = F4( + function (language, themePath, data, model) { + var populationSelectionInput = A4( + $author$project$Pages$Utils$wrapSelectListInput, + language, + $author$project$Translate$Scope, + false, + A7( + $author$project$Pages$Utils$viewSelectListInput, + language, + model.populationSelection, + _List_fromArray( + [$author$project$Pages$Components$Types$SelectionOptionGlobal, $author$project$Pages$Components$Types$SelectionOptionHealthCenter]), + $author$project$Pages$Components$Utils$populationSelectionOptionToString, + $author$project$Pages$CompletionMenu$Model$SetPopulationSelection, + $author$project$Translate$PopulationSelectionOption, + 'select-input')); + var _v0 = A2( + $elm$core$Maybe$withDefault, + _Utils_Tuple2(_List_Nil, $author$project$Gizra$Html$emptyNode), A2( - $elm$html$Html$option, + $elm$core$Maybe$map, + function (populationSelection) { + switch (populationSelection.$) { + case 'SelectionOptionGlobal': + return _Utils_Tuple2( + _List_Nil, + A3($author$project$Pages$Utils$viewLoadDataButton, language, '/admin/reports/completion/all', $author$project$Pages$CompletionMenu$Model$SelectionMade)); + case 'SelectionOptionHealthCenter': + var options = A2( + $elm$core$List$map, + function (healthCenter) { + return _Utils_Tuple2(healthCenter.name, healthCenter.id); + }, + A2( + $elm$core$List$sortBy, + function ($) { + return $.name; + }, + data.healthCenters)); + return _Utils_Tuple2( + _List_fromArray( + [ + A4( + $author$project$Pages$Utils$wrapSelectListInput, + language, + $author$project$Translate$HealthCenter, + false, + A6($author$project$Pages$Utils$viewCustomSelectListInput, model.selectedHealthCenter, options, $elm$core$String$fromInt, $author$project$Pages$CompletionMenu$Model$SetHealthCenter, 'select-input', true)) + ]), + A2( + $elm$core$Maybe$withDefault, + $author$project$Gizra$Html$emptyNode, + A2( + $elm$core$Maybe$map, + function (selectedHealthCenter) { + return A3( + $author$project$Pages$Utils$viewLoadDataButton, + language, + '/admin/reports/completion/health-center/' + $elm$core$String$fromInt(selectedHealthCenter), + $author$project$Pages$CompletionMenu$Model$SelectionMade); + }, + model.selectedHealthCenter))); + default: + return _Utils_Tuple2(_List_Nil, $author$project$Gizra$Html$emptyNode); + } + }, + model.populationSelection)); + var derivedInputs = _v0.a; + var actionButton_ = _v0.b; + var actionButton = model.selected ? $elm$html$Html$text( + A2($author$project$Translate$translate, language, $author$project$Translate$PleaseWaitMessage)) : actionButton_; + return A2( + $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$Attributes$value('') + $elm$html$Html$Attributes$class('page-content completion-menu') ]), _List_fromArray( [ - $elm$html$Html$text('') - ])) - ])); -var $author$project$DateSelector$Selector$dateWithYear = F2( - function (date, y) { - var m = $justinmimbs$date$Date$month(date); - var d = $justinmimbs$date$Date$day(date); - return (_Utils_eq(m, $elm$time$Time$Feb) && ((d === 29) && (!$author$project$DateSelector$Selector$isLeapYear(y)))) ? A3($justinmimbs$date$Date$fromCalendarDate, y, $elm$time$Time$Feb, 28) : A3($justinmimbs$date$Date$fromCalendarDate, y, m, d); - }); -var $author$project$DateSelector$Selector$viewYearSelectList = F3( - function (minimum, maximum, maybeSelected) { - var isSelectedYear = A2( - $elm$core$Maybe$withDefault, - $elm$core$Basics$always(false), - A2( - $elm$core$Maybe$map, - function (selected) { - return $elm$core$Basics$eq( - $justinmimbs$date$Date$year(selected)); - }, - maybeSelected)); - var isInvertedMinMax = _Utils_eq( - A2($justinmimbs$date$Date$compare, minimum, maximum), - $elm$core$Basics$GT); - var years = isInvertedMinMax ? _List_fromArray( - [ - $justinmimbs$date$Date$year( - A2($elm$core$Maybe$withDefault, minimum, maybeSelected)) - ]) : A2( - $elm$core$List$range, - $justinmimbs$date$Date$year(minimum), - $justinmimbs$date$Date$year(maximum)); - var options_ = A2( - $elm$core$List$map, - function (year) { - return A2( - $elm$html$Html$option, + A4($author$project$Pages$Utils$viewCustomLabel, language, $author$project$Translate$SelectScope, ':', 'header'), + A2( + $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$Attributes$value( - $elm$core$String$fromInt(year)), - $elm$html$Html$Attributes$selected( - isSelectedYear(year)) + $elm$html$Html$Attributes$class('inputs') ]), + A2($elm$core$List$cons, populationSelectionInput, derivedInputs)), + A2( + $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$text( - $elm$core$String$fromInt(year)) - ])); - }, - $elm$core$List$reverse(years)); - var options = $elm_community$maybe_extra$Maybe$Extra$isNothing(maybeSelected) ? A2( - $elm$core$List$cons, - A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value('') - ]), - _List_fromArray( - [ - $elm$html$Html$text('') - ])), - options_) : options_; + $elm$html$Html$Attributes$class('actions') + ]), + _List_fromArray( + [actionButton])) + ])); + }); +var $author$project$Pages$CompletionMenu$View$view = F4( + function (language, themePath, modelBackend, model) { + var _v0 = modelBackend.completionMenuData; + if (_v0.$ === 'Just') { + if (_v0.a.$ === 'Ok') { + var data = _v0.a.a; + return A4($author$project$Pages$CompletionMenu$View$viewMenu, language, themePath, data, model); + } else { + var err = _v0.a.a; + return $elm$html$Html$text( + $elm$core$Debug$toString(err)); + } + } else { + return $author$project$Gizra$Html$emptyNode; + } + }); +var $author$project$Translate$ReportType = function (a) { + return {$: 'ReportType', a: a}; +}; +var $author$project$Translate$SelectedScope = function (a) { + return {$: 'SelectedScope', a: a}; +}; +var $author$project$Pages$Reports$Model$SetLimitDate = function (a) { + return {$: 'SetLimitDate', a: a}; +}; +var $author$project$Pages$Reports$Model$SetLimitDateSelectorState = function (a) { + return {$: 'SetLimitDateSelectorState', a: a}; +}; +var $author$project$Pages$Reports$Model$SetReportType = function (a) { + return {$: 'SetReportType', a: a}; +}; +var $author$project$Pages$Reports$Model$SetStartDate = function (a) { + return {$: 'SetStartDate', a: a}; +}; +var $author$project$Pages$Reports$Model$SetStartDateSelectorState = function (a) { + return {$: 'SetStartDateSelectorState', a: a}; +}; +var $author$project$Translate$WideScopeNote = {$: 'WideScopeNote'}; +var $elm$html$Html$img = _VirtualDom_node('img'); +var $elm$html$Html$Attributes$src = function (url) { + return A2( + $elm$html$Html$Attributes$stringProperty, + 'src', + _VirtualDom_noJavaScriptOrHtmlUri(url)); +}; +var $author$project$Pages$Utils$generateReportsHeaderImage = function (themePath) { + return A2( + $elm$html$Html$img, + _List_fromArray( + [ + $elm$html$Html$Attributes$src('/' + (themePath + '/icons/statistical-queries.png')) + ]), + _List_Nil); +}; +var $author$project$Pages$Reports$Utils$reportTypeToString = function (reportType) { + switch (reportType.$) { + case 'ReportAcuteIllness': + return 'acute-illness'; + case 'ReportDemographics': + return 'demographics'; + case 'ReportNutrition': + return 'nutrition'; + default: + return 'prenatal'; + } +}; +var $author$project$Translate$AcuteIllnessDiagnosis = function (a) { + return {$: 'AcuteIllnessDiagnosis', a: a}; +}; +var $author$project$Translate$Diagnosis = {$: 'Diagnosis'}; +var $author$project$Translate$NoDiagnosis = {$: 'NoDiagnosis'}; +var $author$project$Translate$Total = {$: 'Total'}; +var $author$project$Backend$Reports$Utils$allAcuteIllnessDiagnoses = _List_fromArray( + [$author$project$Backend$Reports$Model$DiagnosisCovid19Suspect, $author$project$Backend$Reports$Model$DiagnosisSevereCovid19, $author$project$Backend$Reports$Model$DiagnosisPneuminialCovid19, $author$project$Backend$Reports$Model$DiagnosisLowRiskCovid19, $author$project$Backend$Reports$Model$DiagnosisMalariaComplicated, $author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicated, $author$project$Backend$Reports$Model$DiagnosisMalariaUncomplicatedAndPregnant, $author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionComplicated, $author$project$Backend$Reports$Model$DiagnosisGastrointestinalInfectionUncomplicated, $author$project$Backend$Reports$Model$DiagnosisSimpleColdAndCough, $author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionComplicated, $author$project$Backend$Reports$Model$DiagnosisRespiratoryInfectionUncomplicated, $author$project$Backend$Reports$Model$DiagnosisFeverOfUnknownOrigin, $author$project$Backend$Reports$Model$DiagnosisUndeterminedMoreEvaluationNeeded, $author$project$Backend$Reports$Model$DiagnosisTuberculosisSuspect]); +var $author$project$Gizra$NominalDate$sortByDateDesc = F3( + function (getDateFunc, entity1, entity2) { return A2( - $elm$html$Html$select, - _List_fromArray( - [ - A2( - $elm$html$Html$Events$on, - 'input', + $justinmimbs$date$Date$compare, + getDateFunc(entity2), + getDateFunc(entity1)); + }); +var $author$project$Pages$Reports$View$generateAcuteIllnessReportData = F3( + function (language, startDate, records) { + var generateRow = F2( + function (label, value) { + return _List_fromArray( + [ + A2($author$project$Translate$translate, language, label), + $elm$core$String$fromInt(value) + ]); + }); + var acuteIllnessParticipantRecords = $elm$core$List$concat( + $elm_community$maybe_extra$Maybe$Extra$values( + A2( + $elm$core$List$map, + function ($) { + return $.acuteIllnessData; + }, + records))); + var diagnosesCountDict = A3( + $elm$core$List$foldl, + F2( + function (diagnosis, accum) { + return A2( + $elm$core$Maybe$withDefault, + A3($pzp1997$assoc_list$AssocList$insert, diagnosis, 1, accum), + A2( + $elm$core$Maybe$map, + function (value) { + return A3($pzp1997$assoc_list$AssocList$insert, diagnosis, value + 1, accum); + }, + A2($pzp1997$assoc_list$AssocList$get, diagnosis, accum))); + }), + $pzp1997$assoc_list$AssocList$empty, + $elm_community$maybe_extra$Maybe$Extra$values( + A2( + $elm$core$List$map, + function ($) { + return $.diagnosis; + }, + $elm$core$List$concat(acuteIllnessParticipantRecords)))); + var rows = A2( + $elm$core$List$map, + function (diagnosis) { + return A2( + generateRow, + $author$project$Translate$AcuteIllnessDiagnosis(diagnosis), A2( - $elm$json$Json$Decode$map, - function (s) { - var selectedYear = A2( - $elm$core$Maybe$withDefault, - 2000, - $elm$core$String$toInt(s)); - return A2( - $author$project$DateSelector$Selector$dateWithYear, - A2( - $elm$core$Maybe$withDefault, - A3( - $justinmimbs$date$Date$fromCalendarDate, - $justinmimbs$date$Date$year(minimum), - $elm$time$Time$Jan, - 1), - maybeSelected), - selectedYear); - }, + $elm$core$Maybe$withDefault, + 0, + A2($pzp1997$assoc_list$AssocList$get, diagnosis, diagnosesCountDict))); + }, + $author$project$Backend$Reports$Utils$allAcuteIllnessDiagnoses); + var totalsRow = A2( + generateRow, + $author$project$Translate$Total, + $elm$core$List$sum( + $pzp1997$assoc_list$AssocList$values(diagnosesCountDict))); + var illnessesWithNoDiagnosis = $elm$core$List$length( + A2( + $elm$core$List$filter, + function (encountersList) { + return A2( + $elm$core$Maybe$withDefault, + false, A2( - $elm$json$Json$Decode$at, - _List_fromArray( - ['target', 'value']), - $elm$json$Json$Decode$string))) + $elm$core$Maybe$map, + function (encounter) { + return (!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), + $elm$core$Basics$LT)) && $elm_community$maybe_extra$Maybe$Extra$isNothing(encounter.diagnosis); + }, + $elm$core$List$head( + A2( + $elm$core$List$sortWith, + $author$project$Gizra$NominalDate$sortByDateDesc( + function ($) { + return $.startDate; + }), + encountersList)))); + }, + acuteIllnessParticipantRecords)); + var noneRow = A2(generateRow, $author$project$Translate$NoDiagnosis, illnessesWithNoDiagnosis); + return { + captions: _List_fromArray( + [ + A2($author$project$Translate$translate, language, $author$project$Translate$Diagnosis), + A2($author$project$Translate$translate, language, $author$project$Translate$Total) ]), - options); + heading: '', + rows: _Utils_ap( + rows, + _Utils_ap( + _List_fromArray( + [totalsRow]), + _List_fromArray( + [noneRow]))) + }; }); -var $author$project$DateSelector$Selector$viewPopup = F4( - function (language, minimum, maximum, maybeSelected) { - var yearSection = A2( +var $elm$core$String$replace = F3( + function (before, after, string) { + return A2( + $elm$core$String$join, + after, + A2($elm$core$String$split, before, string)); + }); +var $author$project$Pages$Reports$View$reportTableDataToCSV = function (tableData) { + return A2( + $elm$core$String$join, + '\n', + _List_fromArray( + [ + tableData.heading, + A2($elm$core$String$join, ',', tableData.captions), + A2( + $elm$core$String$join, + '\n', + A2( + $elm$core$List$map, + $elm$core$String$join(','), + tableData.rows)) + ])); +}; +var $author$project$Pages$Reports$Model$DownloadCSV = F2( + function (a, b) { + return {$: 'DownloadCSV', a: a, b: b}; + }); +var $author$project$Translate$DownloadCSV = {$: 'DownloadCSV'}; +var $author$project$Pages$Reports$View$viewDownloadCSVButton = F3( + function (language, csvFileName, csvContent) { + return A2( $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$Attributes$class('year') + $elm$html$Html$Attributes$class('download-csv-wrapper') ]), _List_fromArray( [ A2( - $elm$html$Html$p, - _List_Nil, + $elm$html$Html$button, _List_fromArray( [ - $elm$html$Html$text( - A2($author$project$Translate$translate, language, $author$project$Translate$YearLabel)) - ])), - A3($author$project$DateSelector$Selector$viewYearSelectList, minimum, maximum, maybeSelected) - ])); - var monthSection = A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('month') - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$p, - _List_Nil, + $elm$html$Html$Attributes$class('download-csv'), + $elm$html$Html$Events$onClick( + A2($author$project$Pages$Reports$Model$DownloadCSV, csvFileName, csvContent)) + ]), _List_fromArray( [ $elm$html$Html$text( - A2($author$project$Translate$translate, language, $author$project$Translate$MonthLabel)) - ])), - A2( - $elm$core$Maybe$withDefault, - $author$project$DateSelector$Selector$viewMonthSelectListDisabled, - A2( - $elm$core$Maybe$map, - A3($author$project$DateSelector$Selector$viewMonthSelectList, language, minimum, maximum), - maybeSelected)) + A2($author$project$Translate$translate, language, $author$project$Translate$DownloadCSV)) + ])) ])); - var daysSection = A2( + }); +var $author$project$Pages$Components$View$viewStandardCells = A2($author$project$Pages$Components$View$viewCustomCells, 'label', 'value'); +var $author$project$Pages$Components$View$viewStandardRow = A2( + $elm$core$Basics$composeR, + $author$project$Pages$Components$View$viewStandardCells, + $elm$html$Html$div( + _List_fromArray( + [ + $elm$html$Html$Attributes$class('row') + ]))); +var $author$project$Pages$Reports$View$viewAcuteIllnessReport = F5( + function (language, limitDate, startDate, scopeLabel, records) { + var data = A3($author$project$Pages$Reports$View$generateAcuteIllnessReportData, language, startDate, records); + var csvFileName = 'acute-illness-report-' + ($elm$core$String$toLower( + A3($elm$core$String$replace, ' ', '-', scopeLabel)) + ('-' + (A2($author$project$Gizra$NominalDate$customFormatDDMMYYYY, '-', startDate) + ('-to-' + (A2($author$project$Gizra$NominalDate$customFormatDDMMYYYY, '-', limitDate) + '.csv'))))); + var csvContent = $author$project$Pages$Reports$View$reportTableDataToCSV(data); + var captionsRow = A2( $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$Attributes$class('days') + $elm$html$Html$Attributes$class('row captions') ]), + $author$project$Pages$Components$View$viewStandardCells(data.captions)); + return A2( + $elm$html$Html$div, _List_fromArray( [ - A2( - $elm$core$Maybe$withDefault, - $author$project$DateSelector$Selector$viewDateTableDisabled(minimum), - A2( - $elm$core$Maybe$map, - A2($author$project$DateSelector$Selector$viewDateTable, minimum, maximum), - maybeSelected)) - ])); - return A2( - $elm$html$Html$map, - A2($justinmimbs$date$Date$clamp, minimum, maximum), - A2( - $elm$html$Html$div, + $elm$html$Html$Attributes$class('report acute-illness') + ]), + _Utils_ap( _List_fromArray( [ - $elm$html$Html$Attributes$class('calendar') + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('table') + ]), + A2( + $elm$core$List$cons, + captionsRow, + A2($elm$core$List$map, $author$project$Pages$Components$View$viewStandardRow, data.rows))) ]), _List_fromArray( - [yearSection, monthSection, daysSection]))); - }); -var $author$project$DateSelector$SelectorPopup$view = F6( - function (language, toSelect, toClose, minimum, maximum, selected) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('date-selector-popup') - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$map, - toSelect, - A4($author$project$DateSelector$Selector$viewPopup, language, minimum, maximum, selected)), - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('ui button save'), - $elm$html$Html$Events$onClick(toClose) - ]), - _List_fromArray( - [ - $elm$html$Html$text( - A2($author$project$Translate$translate, language, $author$project$Translate$Save)) - ])) - ])); - }); -var $author$project$DateSelector$SelectorPopup$viewCalendarPopup = F3( - function (language, popupState, selected) { - return A2( - $elm$core$Maybe$map, - function (config) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('ui active modal calendar-popup') - ]), - _List_fromArray( - [ - A6($author$project$DateSelector$SelectorPopup$view, language, config.select, config.close, config.dateFrom, config.dateTo, selected) - ])); - }, - popupState); + [ + A3($author$project$Pages$Reports$View$viewDownloadCSVButton, language, csvFileName, csvContent) + ]))); }); var $author$project$Pages$Reports$View$demographicsReportEncountersDataToCSV = function (data) { return A2( @@ -13717,7 +14001,7 @@ var $author$project$Pages$Reports$View$viewDemographicsReportEncounters = F2( [ $elm$html$Html$Attributes$class('row captions') ]), - $author$project$Pages$Utils$viewStandardCells(data.captions)) + $author$project$Pages$Components$View$viewStandardCells(data.captions)) ]), _Utils_ap( A2($elm$core$List$map, viewRow, data.rows), @@ -13729,7 +14013,7 @@ var $author$project$Pages$Reports$View$viewDemographicsReportEncounters = F2( [ $elm$html$Html$Attributes$class('row encounters-totals') ]), - $author$project$Pages$Utils$viewStandardCells( + $author$project$Pages$Components$View$viewStandardCells( _List_fromArray( [data.totals.label, data.totals.total, data.totals.unique]))) ])))) @@ -13753,9 +14037,9 @@ var $author$project$Pages$Reports$View$viewDemographicsReportPatients = F3( [ $elm$html$Html$Attributes$class('row captions') ]), - $author$project$Pages$Utils$viewStandardCells(tableData.captions)) + $author$project$Pages$Components$View$viewStandardCells(tableData.captions)) ]), - A2($elm$core$List$map, $author$project$Pages$Utils$viewStandardRow, tableData.rows))); + A2($elm$core$List$map, $author$project$Pages$Components$View$viewStandardRow, tableData.rows))); }; return A2( $elm$core$List$cons, @@ -13793,28 +14077,6 @@ var $author$project$Pages$Reports$View$viewDemographicsReport = F4( A3($author$project$Pages$Reports$View$viewDownloadCSVButton, language, csvFileName, csvContent) ])))); }); -var $author$project$Gizra$Html$showMaybe = $elm$core$Maybe$withDefault($author$project$Gizra$Html$emptyNode); -var $author$project$Utils$Html$viewCustomModal = function (extraClasses) { - var classes = A2( - $elm$core$String$join, - ' ', - A2($elm$core$List$cons, 'overlay', extraClasses)); - return A2( - $elm$core$Basics$composeL, - $author$project$Gizra$Html$showMaybe, - $elm$core$Maybe$map( - function (modal) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class(classes) - ]), - _List_fromArray( - [modal])); - })); -}; -var $author$project$Utils$Html$viewModal = $author$project$Utils$Html$viewCustomModal(_List_Nil); var $author$project$Translate$MonthYear = F3( function (a, b, c) { return {$: 'MonthYear', a: a, b: b, c: c}; @@ -15165,47 +15427,6 @@ var $author$project$Pages$Reports$View$reportTablesDataToCSV = A2( $elm$core$Basics$composeR, $elm$core$List$map($author$project$Pages$Reports$View$reportTableDataToCSV), $elm$core$String$join('\n\n')); -var $author$project$Pages$Reports$View$viewNutritionMetricsResultsTable = function (data) { - var viewRow = function (cells) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('row') - ]), - A3($author$project$Pages$Utils$viewCustomCells, 'row-label', 'value', cells)); - }; - var captionsRow = A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('row') - ]), - A3($author$project$Pages$Utils$viewCustomCells, 'row-label', 'heading', data.captions)); - return _List_fromArray( - [ - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('section heading') - ]), - _List_fromArray( - [ - $elm$html$Html$text(data.heading) - ])), - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('table wide') - ]), - A2( - $elm$core$List$cons, - captionsRow, - A2($elm$core$List$map, viewRow, data.rows))) - ]); -}; var $author$project$Pages$Reports$View$viewNutritionReport = F5( function (language, currentDate, scopeLabel, mBackendGeneratedData, reportData) { var generatedData = A2( @@ -15226,7 +15447,7 @@ var $author$project$Pages$Reports$View$viewNutritionReport = F5( ]), _Utils_ap( $elm$core$List$concat( - A2($elm$core$List$map, $author$project$Pages$Reports$View$viewNutritionMetricsResultsTable, generatedData)), + A2($elm$core$List$map, $author$project$Pages$Components$View$viewNutritionMetricsResultsTable, generatedData)), _List_fromArray( [ A3($author$project$Pages$Reports$View$viewDownloadCSVButton, language, csvFileName, csvContent) @@ -15484,8 +15705,8 @@ var $author$project$Pages$Reports$View$viewPrenatalReport = F4( [ $elm$html$Html$Attributes$class('row captions') ]), - $author$project$Pages$Utils$viewStandardCells(tableData.captions)), - A2($elm$core$List$map, $author$project$Pages$Utils$viewStandardRow, tableData.rows))) + $author$project$Pages$Components$View$viewStandardCells(tableData.captions)), + A2($elm$core$List$map, $author$project$Pages$Components$View$viewStandardRow, tableData.rows))) ]); }; var data = A3($author$project$Pages$Reports$View$generatePrenatalReportData, language, limitDate, records); @@ -15569,7 +15790,6 @@ var $author$project$Pages$Reports$View$viewReportsData = F5( A2($author$project$Translate$translate, language, $author$project$Translate$Scope) + (': ' + scopeLabel)) ])) ])); - var launchDate = A3($justinmimbs$date$Date$fromCalendarDate, 2018, $elm$time$Time$Jan, 1); var dateInputs = A2( $elm$core$Maybe$withDefault, _List_Nil, @@ -15582,8 +15802,8 @@ var $author$project$Pages$Reports$View$viewReportsData = F5( var startDateInput = function () { var dateSelectorConfig = { close: $author$project$Pages$Reports$Model$SetStartDateSelectorState($elm$core$Maybe$Nothing), - dateDefault: $elm$core$Maybe$Just(launchDate), - dateFrom: launchDate, + dateDefault: $elm$core$Maybe$Just($author$project$Pages$Utils$launchDate), + dateFrom: $author$project$Pages$Utils$launchDate, dateTo: currentDate, select: $author$project$Pages$Reports$Model$SetStartDate }; @@ -15618,10 +15838,7 @@ var $author$project$Pages$Reports$View$viewReportsData = F5( $elm$core$Maybe$withDefault, '', A2($elm$core$Maybe$map, $author$project$Gizra$NominalDate$formatDDMMYYYY, model.limitDate)); - var dateFrom = A2( - $elm$core$Maybe$withDefault, - A3($justinmimbs$date$Date$add, $justinmimbs$date$Date$Years, -6, currentDate), - model.startDate); + var dateFrom = A2($elm$core$Maybe$withDefault, $author$project$Pages$Utils$launchDate, model.startDate); var dateSelectorConfig = { close: $author$project$Pages$Reports$Model$SetLimitDateSelectorState($elm$core$Maybe$Nothing), dateDefault: $elm$core$Maybe$Just(currentDate), @@ -15657,7 +15874,7 @@ var $author$project$Pages$Reports$View$viewReportsData = F5( var _v0 = _Utils_eq( model.reportType, $elm$core$Maybe$Just($author$project$Pages$Reports$Model$ReportNutrition)) ? _Utils_Tuple2( - $elm$core$Maybe$Just(launchDate), + $elm$core$Maybe$Just($author$project$Pages$Utils$launchDate), $elm$core$Maybe$Just(currentDate)) : _Utils_Tuple2(model.startDate, model.limitDate); var startDateByReportType = _v0.a; var limitDateByReportType = _v0.b; @@ -15669,7 +15886,7 @@ var $author$project$Pages$Reports$View$viewReportsData = F5( F3( function (reportType, startDate, limitDate) { var recordsTillLimitDate = (_Utils_eq( - A2($justinmimbs$date$Date$compare, startDate, launchDate), + A2($justinmimbs$date$Date$compare, startDate, $author$project$Pages$Utils$launchDate), $elm$core$Basics$EQ) && _Utils_eq( A2($justinmimbs$date$Date$compare, limitDate, currentDate), $elm$core$Basics$EQ)) ? data.records : A2( From c36647ccabca25be06e0d63c49b67b6e9b69c931 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sat, 17 Aug 2024 21:32:19 +0300 Subject: [PATCH 012/185] Add missing file [ci skip] --- server/elm/src/Pages/Completion/Utils.elm | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 server/elm/src/Pages/Completion/Utils.elm diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm new file mode 100644 index 0000000000..1b514559a9 --- /dev/null +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -0,0 +1,20 @@ +module Pages.Completion.Utils exposing (..) + +import Pages.Completion.Model exposing (ReportType(..)) + + +reportTypeToString : ReportType -> String +reportTypeToString reportType = + case reportType of + ReportNutritionIndividual -> + "nutrition-individual" + + +reportTypeFromString : String -> Maybe ReportType +reportTypeFromString reportType = + case reportType of + "nutrition-individual" -> + Just ReportNutritionIndividual + + _ -> + Nothing From a403b6c949f6b150e690d9e94ec94f187fe3d8d1 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sat, 17 Aug 2024 22:10:11 +0300 Subject: [PATCH 013/185] Add 'taken by' filter [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 53 +-- server/elm/src/Backend/Completion/Utils.elm | 69 ++++ server/elm/src/Pages/Completion/Model.elm | 5 +- server/elm/src/Pages/Completion/Update.elm | 9 + server/elm/src/Pages/Completion/Utils.elm | 1 + server/elm/src/Pages/Completion/View.elm | 44 ++- server/elm/src/Pages/CompletionMenu/View.elm | 2 +- server/elm/src/Pages/Components/View.elm | 1 - server/elm/src/Pages/ReportsMenu/View.elm | 2 +- server/elm/src/Pages/Utils.elm | 26 +- server/elm/src/Translate.elm | 37 +- .../custom/hedley_general/js/elm-main.js | 333 ++++++++++++------ 12 files changed, 410 insertions(+), 172 deletions(-) create mode 100644 server/elm/src/Backend/Completion/Utils.elm diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index e5c27bdc32..05c801d69a 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -2,6 +2,7 @@ module Backend.Completion.Decoder exposing (decodeCompletionData) import AssocList as Dict import Backend.Completion.Model exposing (..) +import Backend.Completion.Utils exposing (..) import Backend.Decoder exposing (decodeSite, decodeWithFallback) import Date import EverySet exposing (EverySet) @@ -58,58 +59,12 @@ decodeNutritionActivities = ) -nutritionActivityFromMapping : String -> Maybe NutritionActivity -nutritionActivityFromMapping mapped = - case mapped of - "a" -> - Just NutritionHeight - - "b" -> - Just NutritionNutrition - - "c" -> - Just NutritionPhoto - - "d" -> - Just NutritionWeight - - "e" -> - Just NutritionMUAC - - "f" -> - Just NutritionContributingFactors - - "g" -> - Just NutritionFollowUp - - "h" -> - Just NutritionHealthEducation - - "i" -> - Just NutritionSendToHC - - "j" -> - Just NutritionNCDA - - _ -> - Nothing - - decodeTakenBy : Decoder TakenBy decodeTakenBy = string |> andThen (\takenBy -> - case takenBy of - "nurse" -> - succeed TakenByNurse - - "chw" -> - succeed TakenByCHW - - "unknown" -> - succeed TakenByUnknown - - _ -> - fail <| takenBy ++ " is unknown TakenBy type" + takenByFromString takenBy + |> Maybe.map succeed + |> Maybe.withDefault (fail <| takenBy ++ " is unknown TakenBy type") ) diff --git a/server/elm/src/Backend/Completion/Utils.elm b/server/elm/src/Backend/Completion/Utils.elm new file mode 100644 index 0000000000..bdd42e3ba0 --- /dev/null +++ b/server/elm/src/Backend/Completion/Utils.elm @@ -0,0 +1,69 @@ +module Backend.Completion.Utils exposing (..) + +import Backend.Completion.Model exposing (..) + + +nutritionActivityFromMapping : String -> Maybe NutritionActivity +nutritionActivityFromMapping mapped = + case mapped of + "a" -> + Just NutritionHeight + + "b" -> + Just NutritionNutrition + + "c" -> + Just NutritionPhoto + + "d" -> + Just NutritionWeight + + "e" -> + Just NutritionMUAC + + "f" -> + Just NutritionContributingFactors + + "g" -> + Just NutritionFollowUp + + "h" -> + Just NutritionHealthEducation + + "i" -> + Just NutritionSendToHC + + "j" -> + Just NutritionNCDA + + _ -> + Nothing + + +takenByToString : TakenBy -> String +takenByToString value = + case value of + TakenByNurse -> + "nurse" + + TakenByCHW -> + "chw" + + TakenByUnknown -> + "unknown" + + +takenByFromString : String -> Maybe TakenBy +takenByFromString value = + case value of + "nurse" -> + Just TakenByNurse + + "chw" -> + Just TakenByCHW + + "unknown" -> + Just TakenByUnknown + + _ -> + Nothing diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index 28cba93541..fbf0b52ba5 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -1,12 +1,13 @@ module Pages.Completion.Model exposing (..) -import Backend.Completion.Model exposing (NutritionActivity(..)) +import Backend.Completion.Model exposing (NutritionActivity(..), TakenBy) import Date exposing (Date) import DateSelector.Model exposing (DateSelectorConfig) type alias Model = { reportType : Maybe ReportType + , takenBy : Maybe TakenBy , startDate : Maybe Date , startDateSelectorPopupState : Maybe (DateSelectorConfig Msg) , limitDate : Maybe Date @@ -17,6 +18,7 @@ type alias Model = emptyModel : Model emptyModel = { reportType = Nothing + , takenBy = Nothing , startDate = Nothing , startDateSelectorPopupState = Nothing , limitDate = Nothing @@ -31,6 +33,7 @@ type ReportType type Msg = NoOp | SetReportType String + | SetTakenBy String | SetStartDate Date | SetStartDateSelectorState (Maybe (DateSelectorConfig Msg)) | SetLimitDate Date diff --git a/server/elm/src/Pages/Completion/Update.elm b/server/elm/src/Pages/Completion/Update.elm index 94c8d1874f..577faa7eef 100644 --- a/server/elm/src/Pages/Completion/Update.elm +++ b/server/elm/src/Pages/Completion/Update.elm @@ -3,6 +3,7 @@ module Pages.Completion.Update exposing (update) import App.Model exposing (PagesReturn) import App.Ports import AssocList as Dict exposing (Dict) +import Backend.Completion.Utils exposing (takenByFromString) import Backend.Model exposing (ModelBackend) import Date exposing (Interval(..), Unit(..)) import Error.Utils exposing (noError) @@ -28,6 +29,7 @@ update currentDate modelBackend msg model = PagesReturn { model | reportType = reportTypeFromString value + , takenBy = Nothing , startDate = Nothing , limitDate = Nothing } @@ -35,6 +37,13 @@ update currentDate modelBackend msg model = noError [] + SetTakenBy value -> + PagesReturn + { model | takenBy = takenByFromString value } + Cmd.none + noError + [] + SetStartDate value -> PagesReturn { model | startDate = Just value } diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index 1b514559a9..cce2e55bc1 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -1,5 +1,6 @@ module Pages.Completion.Utils exposing (..) +import Backend.Completion.Model exposing (TakenBy(..)) import Pages.Completion.Model exposing (ReportType(..)) diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index a56a341433..33f2578635 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -2,7 +2,8 @@ module Pages.Completion.View exposing (view) import App.Types exposing (Language, Site) import AssocList as Dict exposing (Dict) -import Backend.Completion.Model exposing (CompletionData, EncounterData, NutritionActivity(..), SelectedEntity(..)) +import Backend.Completion.Model exposing (CompletionData, EncounterData, NutritionActivity(..), SelectedEntity(..), TakenBy(..)) +import Backend.Completion.Utils exposing (takenByToString) import Backend.Model exposing (ModelBackend) import Date exposing (Interval(..), Unit(..)) import DateSelector.SelectorPopup exposing (viewCalendarPopup) @@ -17,7 +18,7 @@ import Pages.Completion.Model exposing (..) import Pages.Completion.Utils exposing (reportTypeToString) import Pages.Components.View exposing (viewNutritionMetricsResultsTable) import Pages.Model exposing (MetricsResultsTableData) -import Pages.Utils exposing (launchDate, viewSelectListInput, wrapSelectListInput) +import Pages.Utils exposing (launchDate, viewCustomSelectListInput, viewSelectListInput, wrapSelectListInput) import RemoteData exposing (RemoteData(..)) import Round import Time exposing (Month(..)) @@ -62,6 +63,28 @@ viewCompletionData language currentDate themePath data model = [ text <| translate language Translate.Scope ++ ": " ++ scopeLabel ] ] + takenByInput = + let + options = + List.map + (\option -> + ( translate language <| Translate.TakenBy option, option ) + ) + [ TakenByNurse, TakenByCHW ] + in + if isJust model.reportType then + viewCustomSelectListInput + model.takenBy + options + takenByToString + SetTakenBy + "select-input" + (Just <| translate language Translate.Any) + |> wrapSelectListInput language Translate.TakenByLabel False + + else + emptyNode + dateInputs = Maybe.map (\reportType -> @@ -138,7 +161,7 @@ viewCompletionData language currentDate themePath data model = (\reportType startDate limitDate -> case reportType of ReportNutritionIndividual -> - viewNutritionIndividualReport language startDate limitDate data.nutritionIndividualData + viewNutritionIndividualReport language startDate limitDate model.takenBy data.nutritionIndividualData ) model.reportType model.startDate @@ -156,6 +179,7 @@ viewCompletionData language currentDate themePath data model = Translate.CompletionReportType "select-input" |> wrapSelectListInput language Translate.ReportTypeLabel False + , takenByInput ] ++ dateInputs ++ [ content ] @@ -164,14 +188,24 @@ viewCompletionData language currentDate themePath data model = ] -viewNutritionIndividualReport : Language -> NominalDate -> NominalDate -> List (EncounterData NutritionActivity) -> Html Msg -viewNutritionIndividualReport language startDate limitDate reportData = +viewNutritionIndividualReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData NutritionActivity) -> Html Msg +viewNutritionIndividualReport language startDate limitDate mTakenBy reportData = let filteredData = List.filter (\encounter -> + let + takenByCondition = + Maybe.map + (\takenBy -> + encounter.takenBy == Just takenBy + ) + mTakenBy + |> Maybe.withDefault True + in (not <| Date.compare encounter.startDate startDate == LT) && (not <| Date.compare encounter.startDate limitDate == GT) + && takenByCondition ) reportData |> generateNutritionReportData language diff --git a/server/elm/src/Pages/CompletionMenu/View.elm b/server/elm/src/Pages/CompletionMenu/View.elm index 22abc5c66c..fe1a9f6944 100644 --- a/server/elm/src/Pages/CompletionMenu/View.elm +++ b/server/elm/src/Pages/CompletionMenu/View.elm @@ -74,7 +74,7 @@ viewMenu language themePath data model = String.fromInt SetHealthCenter "select-input" - True + (Just "") |> wrapSelectListInput language Translate.HealthCenter False ] , Maybe.map diff --git a/server/elm/src/Pages/Components/View.elm b/server/elm/src/Pages/Components/View.elm index 58543f7979..5a5c61c8ca 100644 --- a/server/elm/src/Pages/Components/View.elm +++ b/server/elm/src/Pages/Components/View.elm @@ -15,7 +15,6 @@ import Pages.Model exposing (MetricsResultsTableData) import Pages.Utils exposing ( viewCustomLabel - , viewCustomSelectListInput , viewGeoLocationSelectListInput , viewMenuActionButton , viewSelectListInput diff --git a/server/elm/src/Pages/ReportsMenu/View.elm b/server/elm/src/Pages/ReportsMenu/View.elm index 6fec8032ae..1fec845e66 100644 --- a/server/elm/src/Pages/ReportsMenu/View.elm +++ b/server/elm/src/Pages/ReportsMenu/View.elm @@ -89,7 +89,7 @@ viewMenu language themePath data model = String.fromInt SetHealthCenter "select-input" - True + (Just "") |> wrapSelectListInput language Translate.HealthCenter False ] , Maybe.map diff --git a/server/elm/src/Pages/Utils.elm b/server/elm/src/Pages/Utils.elm index d6ac99bff2..f76069fe60 100644 --- a/server/elm/src/Pages/Utils.elm +++ b/server/elm/src/Pages/Utils.elm @@ -102,7 +102,7 @@ viewSelectListInput language currentValue options toStringFunc setMsg transId in toStringFunc setMsg inputClass - True + (Just "") viewCustomSelectListInput : @@ -111,16 +111,17 @@ viewCustomSelectListInput : -> (a -> String) -> (String -> msg) -> String - -> Bool + -> Maybe String -> Html msg -viewCustomSelectListInput currentValue options toStringFunc setMsg inputClass withEmptyOption = +viewCustomSelectListInput currentValue options toStringFunc setMsg inputClass emptyOptionLabel = let emptyOption = - if withEmptyOption then - emptySelectOption (currentValue == Nothing) - - else - emptyNode + Maybe.map + (\label -> + customEmptySelectOption label (currentValue == Nothing) + ) + emptyOptionLabel + |> Maybe.withDefault emptyNode in emptyOption :: List.map @@ -195,12 +196,17 @@ wrapSelectListInput language labelTransId disabled selectList = emptySelectOption : Bool -> Html any -emptySelectOption isSelected = +emptySelectOption = + customEmptySelectOption "" + + +customEmptySelectOption : String -> Bool -> Html any +customEmptySelectOption label isSelected = option [ value "" , selected isSelected ] - [ text "" ] + [ text label ] diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 138d6169b2..eaf87e58d4 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -5,7 +5,7 @@ module Translate exposing ) import App.Types exposing (Language(..)) -import Backend.Completion.Model exposing (NutritionActivity(..)) +import Backend.Completion.Model exposing (NutritionActivity(..), TakenBy(..)) import Backend.Reports.Model exposing (AcuteIllnessDiagnosis(..), NutritionReportTableType(..)) import Backend.Scoreboard.Model import Date @@ -62,6 +62,7 @@ type TranslationId | All | ANCNewborn | ANCTotal + | Any | CBNP | Cell | ChildScorecard @@ -153,6 +154,8 @@ type TranslationId | StuntingModerate | StuntingSevere | Status + | TakenBy TakenBy + | TakenByLabel | TargetedInterventions | Total | Tuberculosis @@ -313,6 +316,12 @@ translationSet transId = , kirundi = Nothing } + Any -> + { english = "Any" + , kinyarwanda = Nothing + , kirundi = Nothing + } + Colline -> { english = "Colline" , kinyarwanda = Nothing @@ -1151,6 +1160,32 @@ translationSet transId = , kirundi = Nothing } + TakenBy value -> + case value of + TakenByNurse -> + { english = "Nurse" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + TakenByCHW -> + { english = "CHW" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + TakenByUnknown -> + { english = "Unknown" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + TakenByLabel -> + { english = "Taken By" + , kinyarwanda = Nothing + , kirundi = Nothing + } + TargetedInterventions -> { english = "Targeted Interventions" , kinyarwanda = Nothing diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 01082e05e5..e9d010f8d0 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5505,7 +5505,7 @@ var $elm$core$Basics$composeR = F3( }); var $author$project$App$Types$English = {$: 'English'}; var $author$project$App$Types$NotFound = {$: 'NotFound'}; -var $author$project$Pages$Completion$Model$emptyModel = {limitDate: $elm$core$Maybe$Nothing, limitDateSelectorPopupState: $elm$core$Maybe$Nothing, reportType: $elm$core$Maybe$Nothing, startDate: $elm$core$Maybe$Nothing, startDateSelectorPopupState: $elm$core$Maybe$Nothing}; +var $author$project$Pages$Completion$Model$emptyModel = {limitDate: $elm$core$Maybe$Nothing, limitDateSelectorPopupState: $elm$core$Maybe$Nothing, reportType: $elm$core$Maybe$Nothing, startDate: $elm$core$Maybe$Nothing, startDateSelectorPopupState: $elm$core$Maybe$Nothing, takenBy: $elm$core$Maybe$Nothing}; var $author$project$Pages$CompletionMenu$Model$emptyModel = {populationSelection: $elm$core$Maybe$Nothing, selected: false, selectedHealthCenter: $elm$core$Maybe$Nothing}; var $krisajenkins$remotedata$RemoteData$NotAsked = {$: 'NotAsked'}; var $author$project$Pages$Reports$Model$emptyModel = {limitDate: $elm$core$Maybe$Nothing, limitDateSelectorPopupState: $elm$core$Maybe$Nothing, nutritionReportData: $krisajenkins$remotedata$RemoteData$NotAsked, reportType: $elm$core$Maybe$Nothing, startDate: $elm$core$Maybe$Nothing, startDateSelectorPopupState: $elm$core$Maybe$Nothing}; @@ -5833,6 +5833,21 @@ var $author$project$Pages$Completion$Utils$reportTypeFromString = function (repo return $elm$core$Maybe$Nothing; } }; +var $author$project$Backend$Completion$Model$TakenByCHW = {$: 'TakenByCHW'}; +var $author$project$Backend$Completion$Model$TakenByNurse = {$: 'TakenByNurse'}; +var $author$project$Backend$Completion$Model$TakenByUnknown = {$: 'TakenByUnknown'}; +var $author$project$Backend$Completion$Utils$takenByFromString = function (value) { + switch (value) { + case 'nurse': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$TakenByNurse); + case 'chw': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$TakenByCHW); + case 'unknown': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$TakenByUnknown); + default: + return $elm$core$Maybe$Nothing; + } +}; var $author$project$Pages$Completion$Update$update = F4( function (currentDate, modelBackend, msg, model) { switch (msg.$) { @@ -5847,7 +5862,20 @@ var $author$project$Pages$Completion$Update$update = F4( { limitDate: $elm$core$Maybe$Nothing, reportType: $author$project$Pages$Completion$Utils$reportTypeFromString(value), - startDate: $elm$core$Maybe$Nothing + startDate: $elm$core$Maybe$Nothing, + takenBy: $elm$core$Maybe$Nothing + }), + $elm$core$Platform$Cmd$none, + $author$project$Error$Utils$noError, + _List_Nil); + case 'SetTakenBy': + var value = msg.a; + return A4( + $author$project$App$Model$PagesReturn, + _Utils_update( + model, + { + takenBy: $author$project$Backend$Completion$Utils$takenByFromString(value) }), $elm$core$Platform$Cmd$none, $author$project$Error$Utils$noError, @@ -6815,24 +6843,18 @@ var $author$project$Backend$Completion$Model$EncounterData = F4( function (startDate, expectedActivities, completedActivities, takenBy) { return {completedActivities: completedActivities, expectedActivities: expectedActivities, startDate: startDate, takenBy: takenBy}; }); -var $author$project$Backend$Completion$Model$TakenByUnknown = {$: 'TakenByUnknown'}; -var $author$project$Backend$Completion$Model$TakenByCHW = {$: 'TakenByCHW'}; -var $author$project$Backend$Completion$Model$TakenByNurse = {$: 'TakenByNurse'}; var $elm$json$Json$Decode$fail = _Json_fail; var $elm$json$Json$Decode$string = _Json_decodeString; var $author$project$Backend$Completion$Decoder$decodeTakenBy = A2( $elm$json$Json$Decode$andThen, function (takenBy) { - switch (takenBy) { - case 'nurse': - return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$TakenByNurse); - case 'chw': - return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$TakenByCHW); - case 'unknown': - return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$TakenByUnknown); - default: - return $elm$json$Json$Decode$fail(takenBy + ' is unknown TakenBy type'); - } + return A2( + $elm$core$Maybe$withDefault, + $elm$json$Json$Decode$fail(takenBy + ' is unknown TakenBy type'), + A2( + $elm$core$Maybe$map, + $elm$json$Json$Decode$succeed, + $author$project$Backend$Completion$Utils$takenByFromString(takenBy))); }, $elm$json$Json$Decode$string); var $elm$json$Json$Decode$oneOf = _Json_oneOf; @@ -7651,7 +7673,7 @@ var $author$project$Backend$Completion$Model$NutritionNutrition = {$: 'Nutrition var $author$project$Backend$Completion$Model$NutritionPhoto = {$: 'NutritionPhoto'}; var $author$project$Backend$Completion$Model$NutritionSendToHC = {$: 'NutritionSendToHC'}; var $author$project$Backend$Completion$Model$NutritionWeight = {$: 'NutritionWeight'}; -var $author$project$Backend$Completion$Decoder$nutritionActivityFromMapping = function (mapped) { +var $author$project$Backend$Completion$Utils$nutritionActivityFromMapping = function (mapped) { switch (mapped) { case 'a': return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHeight); @@ -7684,7 +7706,7 @@ var $author$project$Backend$Completion$Decoder$decodeNutritionActivities = A2( $elm$core$String$split(','), A2( $elm$core$Basics$composeR, - $elm$core$List$map($author$project$Backend$Completion$Decoder$nutritionActivityFromMapping), + $elm$core$List$map($author$project$Backend$Completion$Utils$nutritionActivityFromMapping), A2($elm$core$Basics$composeR, $elm_community$maybe_extra$Maybe$Extra$values, $elm$json$Json$Decode$succeed))), $elm$json$Json$Decode$string); var $author$project$Backend$Completion$Model$EntityGlobal = {$: 'EntityGlobal'}; @@ -9835,6 +9857,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'ANC + Newborn', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'ANCTotal': return {english: 'ANC (total)', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Any': + return {english: 'Any', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Colline': return {english: 'Colline', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'CollineSub': @@ -10327,6 +10351,18 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Stunting Severe', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Status': return {english: 'Status', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'TakenBy': + var value = transId.a; + switch (value.$) { + case 'TakenByNurse': + return {english: 'Nurse', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'TakenByCHW': + return {english: 'CHW', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + default: + return {english: 'Unknown', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + } + case 'TakenByLabel': + return {english: 'Taken By', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'TargetedInterventions': return {english: 'Targeted Interventions', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Total': @@ -10507,6 +10543,7 @@ var $author$project$Error$View$view = F2( }); var $author$project$Gizra$Html$emptyNode = $elm$html$Html$text(''); var $elm$core$Debug$toString = _Debug_toString; +var $author$project$Translate$Any = {$: 'Any'}; var $author$project$Translate$CompletionReportType = function (a) { return {$: 'CompletionReportType', a: a}; }; @@ -10530,6 +10567,13 @@ var $author$project$Pages$Completion$Model$SetStartDate = function (a) { var $author$project$Pages$Completion$Model$SetStartDateSelectorState = function (a) { return {$: 'SetStartDateSelectorState', a: a}; }; +var $author$project$Pages$Completion$Model$SetTakenBy = function (a) { + return {$: 'SetTakenBy', a: a}; +}; +var $author$project$Translate$TakenBy = function (a) { + return {$: 'TakenBy', a: a}; +}; +var $author$project$Translate$TakenByLabel = {$: 'TakenByLabel'}; var $elm$html$Html$a = _VirtualDom_node('a'); var $elm$html$Html$button = _VirtualDom_node('button'); var $justinmimbs$date$Date$day = A2( @@ -11217,6 +11261,16 @@ var $elm$html$Html$Events$onClick = function (msg) { var $author$project$Pages$Completion$Utils$reportTypeToString = function (reportType) { return 'nutrition-individual'; }; +var $author$project$Backend$Completion$Utils$takenByToString = function (value) { + switch (value.$) { + case 'TakenByNurse': + return 'nurse'; + case 'TakenByCHW': + return 'chw'; + default: + return 'unknown'; + } +}; var $author$project$Translate$Save = {$: 'Save'}; var $author$project$Translate$MonthLabel = {$: 'MonthLabel'}; var $author$project$Translate$YearLabel = {$: 'YearLabel'}; @@ -12158,6 +12212,94 @@ var $author$project$DateSelector$SelectorPopup$viewCalendarPopup = F3( }, popupState); }); +var $author$project$Pages$Utils$customEmptySelectOption = F2( + function (label, isSelected) { + return A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value(''), + $elm$html$Html$Attributes$selected(isSelected) + ]), + _List_fromArray( + [ + $elm$html$Html$text(label) + ])); + }); +var $elm$html$Html$Events$alwaysStop = function (x) { + return _Utils_Tuple2(x, true); +}; +var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { + return {$: 'MayStopPropagation', a: a}; +}; +var $elm$html$Html$Events$stopPropagationOn = F2( + function (event, decoder) { + return A2( + $elm$virtual_dom$VirtualDom$on, + event, + $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); + }); +var $elm$html$Html$Events$targetValue = A2( + $elm$json$Json$Decode$at, + _List_fromArray( + ['target', 'value']), + $elm$json$Json$Decode$string); +var $elm$html$Html$Events$onInput = function (tagger) { + return A2( + $elm$html$Html$Events$stopPropagationOn, + 'input', + A2( + $elm$json$Json$Decode$map, + $elm$html$Html$Events$alwaysStop, + A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); +}; +var $author$project$Pages$Utils$viewCustomSelectListInput = F6( + function (currentValue, options, toStringFunc, setMsg, inputClass, emptyOptionLabel) { + var emptyOption = A2( + $elm$core$Maybe$withDefault, + $author$project$Gizra$Html$emptyNode, + A2( + $elm$core$Maybe$map, + function (label) { + return A2( + $author$project$Pages$Utils$customEmptySelectOption, + label, + _Utils_eq(currentValue, $elm$core$Maybe$Nothing)); + }, + emptyOptionLabel)); + return A2( + $elm$html$Html$select, + _List_fromArray( + [ + $elm$html$Html$Events$onInput(setMsg), + $elm$html$Html$Attributes$class(inputClass) + ]), + A2( + $elm$core$List$cons, + emptyOption, + A2( + $elm$core$List$map, + function (_v0) { + var label = _v0.a; + var value_ = _v0.b; + return A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value( + toStringFunc(value_)), + $elm$html$Html$Attributes$selected( + _Utils_eq( + currentValue, + $elm$core$Maybe$Just(value_))) + ]), + _List_fromArray( + [ + $elm$html$Html$text(label) + ])); + }, + options))); + }); var $author$project$Gizra$Html$showMaybe = $elm$core$Maybe$withDefault($author$project$Gizra$Html$emptyNode); var $author$project$Utils$Html$viewCustomModal = function (extraClasses) { var classes = A2( @@ -12531,19 +12673,30 @@ var $author$project$Pages$Components$View$viewNutritionMetricsResultsTable = fun A2($elm$core$List$map, viewRow, data.rows))) ]); }; -var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F4( - function (language, startDate, limitDate, reportData) { +var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F5( + function (language, startDate, limitDate, mTakenBy, reportData) { var filteredData = A2( $author$project$Pages$Completion$View$generateNutritionReportData, language, A2( $elm$core$List$filter, function (encounter) { + var takenByCondition = A2( + $elm$core$Maybe$withDefault, + true, + A2( + $elm$core$Maybe$map, + function (takenBy) { + return _Utils_eq( + encounter.takenBy, + $elm$core$Maybe$Just(takenBy)); + }, + mTakenBy)); return (!_Utils_eq( A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), - $elm$core$Basics$LT)) && (!_Utils_eq( + $elm$core$Basics$LT)) && ((!_Utils_eq( A2($justinmimbs$date$Date$compare, encounter.startDate, limitDate), - $elm$core$Basics$GT)); + $elm$core$Basics$GT)) && takenByCondition); }, reportData)); return A2( @@ -12554,83 +12707,6 @@ var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F4( ]), $author$project$Pages$Components$View$viewNutritionMetricsResultsTable(filteredData)); }); -var $author$project$Pages$Utils$emptySelectOption = function (isSelected) { - return A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value(''), - $elm$html$Html$Attributes$selected(isSelected) - ]), - _List_fromArray( - [ - $elm$html$Html$text('') - ])); -}; -var $elm$html$Html$Events$alwaysStop = function (x) { - return _Utils_Tuple2(x, true); -}; -var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { - return {$: 'MayStopPropagation', a: a}; -}; -var $elm$html$Html$Events$stopPropagationOn = F2( - function (event, decoder) { - return A2( - $elm$virtual_dom$VirtualDom$on, - event, - $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); - }); -var $elm$html$Html$Events$targetValue = A2( - $elm$json$Json$Decode$at, - _List_fromArray( - ['target', 'value']), - $elm$json$Json$Decode$string); -var $elm$html$Html$Events$onInput = function (tagger) { - return A2( - $elm$html$Html$Events$stopPropagationOn, - 'input', - A2( - $elm$json$Json$Decode$map, - $elm$html$Html$Events$alwaysStop, - A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); -}; -var $author$project$Pages$Utils$viewCustomSelectListInput = F6( - function (currentValue, options, toStringFunc, setMsg, inputClass, withEmptyOption) { - var emptyOption = withEmptyOption ? $author$project$Pages$Utils$emptySelectOption( - _Utils_eq(currentValue, $elm$core$Maybe$Nothing)) : $author$project$Gizra$Html$emptyNode; - return A2( - $elm$html$Html$select, - _List_fromArray( - [ - $elm$html$Html$Events$onInput(setMsg), - $elm$html$Html$Attributes$class(inputClass) - ]), - A2( - $elm$core$List$cons, - emptyOption, - A2( - $elm$core$List$map, - function (_v0) { - var label = _v0.a; - var value_ = _v0.b; - return A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value( - toStringFunc(value_)), - $elm$html$Html$Attributes$selected( - _Utils_eq( - currentValue, - $elm$core$Maybe$Just(value_))) - ]), - _List_fromArray( - [ - $elm$html$Html$text(label) - ])); - }, - options))); - }); var $author$project$Pages$Utils$viewSelectListInput = F7( function (language, currentValue, options, toStringFunc, setMsg, transId, inputClass) { var transFunc = A2( @@ -12645,7 +12721,14 @@ var $author$project$Pages$Utils$viewSelectListInput = F7( option); }, options); - return A6($author$project$Pages$Utils$viewCustomSelectListInput, currentValue, optionsPairs, toStringFunc, setMsg, inputClass, true); + return A6( + $author$project$Pages$Utils$viewCustomSelectListInput, + currentValue, + optionsPairs, + toStringFunc, + setMsg, + inputClass, + $elm$core$Maybe$Just('')); }); var $author$project$Pages$Utils$viewCustomLabel = F4( function (language, translationId, suffix, class_) { @@ -12744,6 +12827,34 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( ])) ])); }(); + var takenByInput = function () { + var options = A2( + $elm$core$List$map, + function (option) { + return _Utils_Tuple2( + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$TakenBy(option)), + option); + }, + _List_fromArray( + [$author$project$Backend$Completion$Model$TakenByNurse, $author$project$Backend$Completion$Model$TakenByCHW])); + return $elm_community$maybe_extra$Maybe$Extra$isJust(model.reportType) ? A4( + $author$project$Pages$Utils$wrapSelectListInput, + language, + $author$project$Translate$TakenByLabel, + false, + A6( + $author$project$Pages$Utils$viewCustomSelectListInput, + model.takenBy, + options, + $author$project$Backend$Completion$Utils$takenByToString, + $author$project$Pages$Completion$Model$SetTakenBy, + 'select-input', + $elm$core$Maybe$Just( + A2($author$project$Translate$translate, language, $author$project$Translate$Any)))) : $author$project$Gizra$Html$emptyNode; + }(); var dateInputs = A2( $elm$core$Maybe$withDefault, _List_Nil, @@ -12828,7 +12939,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( $elm$core$Maybe$map3, F3( function (reportType, startDate, limitDate) { - return A4($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, data.nutritionIndividualData); + return A5($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, model.takenBy, data.nutritionIndividualData); }), model.reportType, model.startDate, @@ -12865,7 +12976,8 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( $author$project$Pages$Completion$Utils$reportTypeToString, $author$project$Pages$Completion$Model$SetReportType, $author$project$Translate$CompletionReportType, - 'select-input')) + 'select-input')), + takenByInput ]), _Utils_ap( dateInputs, @@ -12992,7 +13104,14 @@ var $author$project$Pages$CompletionMenu$View$viewMenu = F4( language, $author$project$Translate$HealthCenter, false, - A6($author$project$Pages$Utils$viewCustomSelectListInput, model.selectedHealthCenter, options, $elm$core$String$fromInt, $author$project$Pages$CompletionMenu$Model$SetHealthCenter, 'select-input', true)) + A6( + $author$project$Pages$Utils$viewCustomSelectListInput, + model.selectedHealthCenter, + options, + $elm$core$String$fromInt, + $author$project$Pages$CompletionMenu$Model$SetHealthCenter, + 'select-input', + $elm$core$Maybe$Just(''))) ]), A2( $elm$core$Maybe$withDefault, @@ -35382,6 +35501,7 @@ var $author$project$Utils$GeoLocation$resolveGeoSructureLabelLevel5 = function ( return $author$project$Translate$EmptyString; } }; +var $author$project$Pages$Utils$emptySelectOption = $author$project$Pages$Utils$customEmptySelectOption(''); var $author$project$Pages$Utils$viewGeoLocationSelectListInput = F6( function (language, currentValue, options, setMsg, labelTransId, disabled) { var emptyOption = $author$project$Pages$Utils$emptySelectOption( @@ -35715,7 +35835,14 @@ var $author$project$Pages$ReportsMenu$View$viewMenu = F4( language, $author$project$Translate$HealthCenter, false, - A6($author$project$Pages$Utils$viewCustomSelectListInput, model.selectedHealthCenter, options, $elm$core$String$fromInt, $author$project$Pages$ReportsMenu$Model$SetHealthCenter, 'select-input', true)) + A6( + $author$project$Pages$Utils$viewCustomSelectListInput, + model.selectedHealthCenter, + options, + $elm$core$String$fromInt, + $author$project$Pages$ReportsMenu$Model$SetHealthCenter, + 'select-input', + $elm$core$Maybe$Just(''))) ]), A2( $elm$core$Maybe$withDefault, From 2baaa56f49ab61c8b615feee18966acc262d5308 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 13:58:42 +0300 Subject: [PATCH 014/185] Logic for generatig data [ci skip] --- .../hedley_reports/hedley_reports.module | 172 +++++++++++++++++- .../scripts/generate-completion-data.php | 2 +- ...nerate-nutrition-group-completion-data.php | 94 ++++++++++ 3 files changed, 264 insertions(+), 4 deletions(-) create mode 100644 server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index aaa2433ab4..3eb5eec013 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2030,7 +2030,7 @@ function hedley_reports_generate_completion_results_data($health_center) { return $data; } -function hedley_reports_generate_completion_data_for_nutrition_encounter($encounter) { +function hedley_reports_generate_completion_data_for_nutrition_individual_encounter($encounter) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ 'nutrition_height' => 'a', @@ -2054,10 +2054,11 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun ]; $completed = []; - // Was encounter recorded by nurse or CHW? + // Was encounter recorded by nurse or CHW. $taken_by = $encounter->field_nutrition_encounter_type[LANGUAGE_NONE][0]['value']; // Resolve encounter start date. $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $start_date_obj = new DateTime($start_date); // Loading all measurements that belong to encounter. $query = db_select('field_data_field_nutrition_encounter', 'ne'); @@ -2084,7 +2085,6 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun // Calculate age in months. $birth_date_obj = new DateTime($birth_date); - $start_date_obj = new DateTime($start_date); $interval = $start_date_obj->diff($birth_date_obj); $age_in_months = ($interval->y * 12) + $interval->m; } catch (Exception $e) { @@ -2146,6 +2146,172 @@ function hedley_reports_generate_completion_data_for_nutrition_encounter($encoun return hedley_reports_generate_completion_result($expected, $completed, $start_date, $taken_by, $mapping); } +function hedley_reports_generate_completion_data_for_nutrition_group_encounter($attendance) { + // To reduce memory usage, mapping measurement types as single characters. + $mapping = [ + 'height' => 'a', + 'nutrition' => 'b', + 'photo' => 'c', + 'weight' => 'd', + 'muac' => 'e', + 'contributing_factors' => 'f', + 'follow_up' => 'g', + 'health_education' => 'h', + 'send_to_hc' => 'i', + 'ncda' => 'j', + ]; + + // Activities that are always taken during encounter. + $expected = [ + 'height', + 'nutrition', + 'photo', + 'weight', + ]; + $completed = []; + + // Attendance points to mother. We need to resolve the child (or children) + // that have participated in the session. + $children_ids = []; + $adult_id = $attendance->field_person[LANGUAGE_NONE][0]['target_id']; + $session_id = $attendance->field_session[LANGUAGE_NONE][0]['target_id']; + $session = node_load($session_id); + $clinic_id = $session->field_clinic[LANGUAGE_NONE][0]['target_id']; + + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'pmtct_participant') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_adult', 'target_id', $adult_id) + ->fieldCondition('field_clinic', 'target_id', $clinic_id) + ->addTag('exclude_deleted') + ->execute(); + + if (empty($result['node'])) { + return []; + } + + $participants_ids = array_keys($result['node']); + $participants = node_load_multiple($participants_ids); + foreach ($participants as $participant) { + $children_ids[] = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + } + + if (empty($children_ids)) { + return []; + } + + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', array_keys($mapping), 'IN') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_person', 'target_id', $children_ids, 'IN') + ->fieldCondition('field_session', 'target_id', $session_id) + ->addTag('exclude_deleted') + ->execute(); + + if (empty($result['node'])) { + return []; + } + + $session_start_date = $session->field_scheduled_date[LANGUAGE_NONE][0]['value']; + $start_date_obj = new DateTime($session_start_date); + $measurements_ids = array_keys($result['node']); + $measurements = node_load_multiple($measurements_ids); + $measurements_per_child = []; + foreach ($measurements as $measurement) { + $child_id = $measurement->field_person[LANGUAGE_NONE][0]['target_id']; + $measurements_per_child[$child_id][] = $measurement; + } + + $clinic = node_load($clinic_id); + $clinic_type = $clinic->field_group_type[LANGUAGE_NONE][0]['value']; + $taken_by = ($clinic_type === 'chw') ? 'chw' : 'nurse'; + + $return = []; + foreach ($measurements_per_child as $child_id => $measurements) { + $child = node_load($child_id); + + // Try to resolve age in months at a time encounter was performed. + try { + // Get birthdate and date measured. + $birth_date = explode(' ', $child->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; + + // Calculate age in months. + $birth_date_obj = new DateTime($birth_date); + $interval = $start_date_obj->diff($birth_date_obj); + $age_in_months = ($interval->y * 12) + $interval->m; + } catch (Exception $e) { + $age_in_months = NULL; + } + + // MUAC is taken starting age of 6 months. + if (isset($age_in_months) && $age_in_months >= 6) { + $expected[] = 'muac'; + } + + // Ordering measurements by type. + $measurements_by_type = []; + foreach ($measurements as $measurement) { + $measurements_by_type[$measurement->type] = $measurement; + } + + // Date on which 'Group Next Steps' feature was launched. + $group_next_steps_launch_date = '2021-03-30'; + $group_next_steps_launch_date_obj = new DateTime($group_next_steps_launch_date); + + // We may expect Next Steps activities on after + // 'Group Next Steps' feature was launched. + if ($start_date_obj >= $group_next_steps_launch_date_obj) { + $assessment = ''; + if (!empty($measurements_by_type['nutrition'])) { + $assessment = $measurements_by_type['nutrition']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; + } + else if (!empty($measurements_by_type['follow_up'])) { + $assessment = $measurements_by_type['follow_up']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; + } + + // If assessment was made, we expect all next steps activities. + if (!empty($assessment) && $assessment !== 'none') { + $expected = array_merge( + $expected, + [ + 'contributing_factors', + 'follow_up', + 'group_health_education', + 'group_send_to_hc', + ] + ); + } + } + + // NCDA activity is expected if: + // 1. NCDA feature is enabled. + // 2. Encounter was performed after NCDA launch date. + // 3. Encounter was recorded by nurse (and not by CHW). + // 4. Child was under age of 24 months. + $ncda_enabled = variable_get('hedley_admin_feature_ncda_enabled', FALSE); + $ncda_launch_date = '2023-11-20'; + $ncda_launch_date_obj = new DateTime($ncda_launch_date); + + if ($ncda_enabled && $start_date_obj >= $ncda_launch_date_obj && ($taken_by == 'nurse') && isset($age_in_months) && $age_in_months < 24) { + $expected[] = 'group_ncda'; + } + + foreach ($expected as $measurement_type) { + if (!empty($measurements_by_type[$measurement_type])) { + $completed[] = $measurement_type; + } + } + + $return[] = hedley_reports_generate_completion_result($expected, $completed, $session_start_date, $taken_by, $mapping); + } + + return $return; +} + function hedley_reports_generate_completion_result($expected, $completed, $start_date, $taken_by, $mapping) { foreach ($expected as $index => $measurement_type) { $expected[$index] = $mapping[$measurement_type]; diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php index 119aa749a4..52571f4c84 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php @@ -69,7 +69,7 @@ $ids = array_keys($result['node']); $nodes = node_load_multiple($ids); foreach ($nodes as $node) { - $completion_data = hedley_reports_generate_completion_data_for_nutrition_encounter($node); + $completion_data = hedley_reports_generate_completion_data_for_nutrition_individual_encounter($node); $node->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); node_save($node); $total++; diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php new file mode 100644 index 0000000000..392e715d36 --- /dev/null +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php @@ -0,0 +1,94 @@ +entityCondition('entity_type', 'node') + ->entityCondition('bundle', $type) + ->fieldCondition('field_attended', 'value', TRUE) + ->propertyCondition('status', NODE_PUBLISHED); + +if ($exclude_set) { + $base_query->addTag('exclude_set_reports_data'); +} + +$count_query = clone $base_query; +$count_query->propertyCondition('nid', $nid, '>'); +$count = $count_query->count()->execute(); + +if ($count == 0) { + drush_print("There are no nodes of type $type in DB."); + exit; +} + +// @todo: do we need this? +$nurses = hedley_ncda_resolve_nurses_ids(); + +$total = 0; +drush_print("$count nodes of type $type located."); + +while (TRUE) { + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + $completion_data = hedley_reports_generate_completion_data_for_nutrition_group_encounter($node); +// $node->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); +// node_save($node); + $total++; + + $memory = round(memory_get_usage() / 1048576); + if ($memory >= $memory_limit) { + drush_print(dt('Stopped before out of memory. Start process from the node ID @nid', ['@nid' => $nid])); + return; + } + } + + $memory = round(memory_get_usage() / 1048576); + drush_print("Calculated so far: $total, Memory: $memory"); + + // Free up memory. + drupal_static_reset(); + + $nid = end($ids); +} + +drush_print("Done! Completion data calculated for $total encounters."); From b2bea58b83bcf23c69f01576b085bd8f5a0f2d6c Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 14:02:31 +0300 Subject: [PATCH 015/185] Add field to store completion data on attendance CT [ci skip] --- ...edley_activity.features.field_instance.inc | 211 ++++++++++++- .../hedley_activity/hedley_activity.info | 1 + .../hedley_activity.strongarm.inc | 282 +++++++++--------- 3 files changed, 349 insertions(+), 145 deletions(-) diff --git a/server/hedley/modules/custom/hedley_activity/hedley_activity.features.field_instance.inc b/server/hedley/modules/custom/hedley_activity/hedley_activity.features.field_instance.inc index 9bfc5ac204..96b5c024ab 100644 --- a/server/hedley/modules/custom/hedley_activity/hedley_activity.features.field_instance.inc +++ b/server/hedley/modules/custom/hedley_activity/hedley_activity.features.field_instance.inc @@ -100,7 +100,7 @@ function hedley_activity_field_default_field_instances() { 'year_range' => '-3:+3', ), 'type' => 'date_select', - 'weight' => 4, + 'weight' => 3, ), ); @@ -139,12 +139,13 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => 5, + 'weight' => 4, ), ); @@ -183,12 +184,53 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => 3, + 'weight' => 2, + ), + ); + + // Exported field_instance: 'node-attendance-field_reports_data'. + $field_instances['node-attendance-field_reports_data'] = array( + 'bundle' => 'attendance', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 9, + ), + 'teaser' => array( + 'label' => 'above', + 'settings' => array(), + 'type' => 'hidden', + 'weight' => 0, + ), + ), + 'entity_type' => 'node', + 'field_name' => 'field_reports_data', + 'label' => 'Completion Data', + 'required' => 0, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'rows' => 5, + ), + 'type' => 'text_textarea', + 'weight' => 6, ), ); @@ -227,12 +269,13 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => 6, + 'weight' => 5, ), ); @@ -271,6 +314,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -485,6 +529,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -529,6 +574,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -573,6 +619,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -617,6 +664,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -868,6 +916,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -912,6 +961,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -956,6 +1006,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1000,6 +1051,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1223,6 +1275,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1267,6 +1320,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1311,6 +1365,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1355,6 +1410,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1533,6 +1589,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1577,6 +1634,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1621,6 +1679,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1665,6 +1724,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2142,6 +2202,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2186,6 +2247,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2231,6 +2293,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2275,6 +2338,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2452,6 +2516,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2496,6 +2561,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2614,6 +2680,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2658,6 +2725,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2836,6 +2904,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2880,6 +2949,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2924,6 +2994,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2968,6 +3039,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3012,6 +3084,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3244,6 +3317,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3362,6 +3436,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3406,6 +3481,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3450,6 +3526,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3628,6 +3705,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3672,6 +3750,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3754,6 +3833,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3798,6 +3878,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4123,6 +4204,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4167,6 +4249,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4248,6 +4331,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4292,6 +4376,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4515,6 +4600,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4559,6 +4645,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4678,6 +4765,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4721,6 +4809,7 @@ function hedley_activity_field_default_field_instances() { 'widget' => array( 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4805,6 +4894,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4951,6 +5041,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4995,6 +5086,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5039,6 +5131,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5083,6 +5176,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5305,6 +5399,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5349,6 +5444,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5393,6 +5489,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5437,6 +5534,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5753,6 +5851,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5797,6 +5896,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5842,6 +5942,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5886,6 +5987,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6063,6 +6165,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6107,6 +6210,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6151,6 +6255,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6195,6 +6300,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6520,6 +6626,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6564,6 +6671,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6608,6 +6716,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6652,6 +6761,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6912,6 +7022,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6956,6 +7067,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7000,6 +7112,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7044,6 +7157,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7128,6 +7242,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7274,6 +7389,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7318,6 +7434,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7362,6 +7479,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7406,6 +7524,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7489,6 +7608,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7589,6 +7709,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7707,6 +7828,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7751,6 +7873,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7795,6 +7918,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7981,6 +8105,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8025,6 +8150,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8069,6 +8195,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8113,6 +8240,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8345,6 +8473,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8389,6 +8518,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8433,6 +8563,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8477,6 +8608,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8802,6 +8934,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8846,6 +8979,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8890,6 +9024,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8971,6 +9106,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9194,6 +9330,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9277,6 +9414,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9358,6 +9496,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9402,6 +9541,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9542,6 +9682,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9586,6 +9727,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9630,6 +9772,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9724,6 +9867,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9910,6 +10054,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9954,6 +10099,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9998,6 +10144,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10042,6 +10189,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10495,6 +10643,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10539,6 +10688,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10583,6 +10733,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10673,6 +10824,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11038,6 +11190,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11120,6 +11273,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11165,6 +11319,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11285,6 +11440,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11665,6 +11821,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11709,6 +11866,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11753,6 +11911,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11797,6 +11956,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11881,6 +12041,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11981,6 +12142,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12025,6 +12187,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12119,6 +12282,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12163,6 +12327,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12303,6 +12468,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12347,6 +12513,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12391,6 +12558,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12435,6 +12603,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12652,6 +12821,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12696,6 +12866,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12741,6 +12912,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12785,6 +12957,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12964,6 +13137,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -13008,6 +13182,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -13053,6 +13228,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -13135,6 +13311,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -13367,6 +13544,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -13411,6 +13589,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -13456,6 +13635,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -13500,6 +13680,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -13686,6 +13867,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -13730,6 +13912,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -13824,6 +14007,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -13868,6 +14052,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -14012,6 +14197,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -14056,6 +14242,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -14137,6 +14324,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -14218,6 +14406,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -14358,6 +14547,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -14439,6 +14629,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -14483,6 +14674,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -14527,6 +14719,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -14842,6 +15035,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -14886,6 +15080,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -14930,6 +15125,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -15020,6 +15216,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -15195,6 +15392,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -15295,6 +15493,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -15339,6 +15538,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -15383,6 +15583,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -15427,6 +15628,7 @@ function hedley_activity_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -15677,6 +15879,7 @@ function hedley_activity_field_default_field_instances() { t('C Sections'); t('C-Section Scar'); t('Child'); + t('Completion Data'); t('Confident'); t('Confirmation'); t('Contributing Factors Signs'); diff --git a/server/hedley/modules/custom/hedley_activity/hedley_activity.info b/server/hedley/modules/custom/hedley_activity/hedley_activity.info index 23a28d77aa..b574053166 100644 --- a/server/hedley/modules/custom/hedley_activity/hedley_activity.info +++ b/server/hedley/modules/custom/hedley_activity/hedley_activity.info @@ -108,6 +108,7 @@ features[field_instance][] = node-attendance-field_attended features[field_instance][] = node-attendance-field_date_measured features[field_instance][] = node-attendance-field_nurse features[field_instance][] = node-attendance-field_person +features[field_instance][] = node-attendance-field_reports_data features[field_instance][] = node-attendance-field_session features[field_instance][] = node-attendance-field_shards features[field_instance][] = node-attendance-field_uuid diff --git a/server/hedley/modules/custom/hedley_activity/hedley_activity.strongarm.inc b/server/hedley/modules/custom/hedley_activity/hedley_activity.strongarm.inc index 9e4fda14c9..cd50310763 100644 --- a/server/hedley/modules/custom/hedley_activity/hedley_activity.strongarm.inc +++ b/server/hedley/modules/custom/hedley_activity/hedley_activity.strongarm.inc @@ -870,15 +870,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__attendance'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__attendance'] = $strongarm; @@ -887,15 +887,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__birth_plan'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__birth_plan'] = $strongarm; @@ -904,15 +904,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__breast_exam'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__breast_exam'] = $strongarm; @@ -921,15 +921,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__child_fbf'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__child_fbf'] = $strongarm; @@ -938,15 +938,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__contributing_factors'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__contributing_factors'] = $strongarm; @@ -955,15 +955,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__core_physical_exam'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__core_physical_exam'] = $strongarm; @@ -972,15 +972,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__danger_signs'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__danger_signs'] = $strongarm; @@ -989,28 +989,28 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__family_planning'; $strongarm->value = array( - 'view_modes' => array( - 'teaser' => array( - 'custom_settings' => TRUE, + 'extra_fields' => array( + 'display' => array(), + 'form' => array( + 'title' => array( + 'weight' => '0', + ), ), + ), + 'view_modes' => array( 'full' => array( 'custom_settings' => FALSE, ), 'rss' => array( 'custom_settings' => FALSE, ), + 'teaser' => array( + 'custom_settings' => TRUE, + ), 'token' => array( 'custom_settings' => FALSE, ), ), - 'extra_fields' => array( - 'form' => array( - 'title' => array( - 'weight' => '0', - ), - ), - 'display' => array(), - ), ); $export['field_bundle_settings_node__family_planning'] = $strongarm; @@ -1019,15 +1019,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__follow_up'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__follow_up'] = $strongarm; @@ -1036,15 +1036,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__group_health_education'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__group_health_education'] = $strongarm; @@ -1053,15 +1053,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__group_ncda'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__group_ncda'] = $strongarm; @@ -1070,15 +1070,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__group_send_to_hc'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__group_send_to_hc'] = $strongarm; @@ -1087,28 +1087,28 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__height'; $strongarm->value = array( - 'view_modes' => array( - 'teaser' => array( - 'custom_settings' => TRUE, + 'extra_fields' => array( + 'display' => array(), + 'form' => array( + 'title' => array( + 'weight' => '0', + ), ), + ), + 'view_modes' => array( 'full' => array( 'custom_settings' => FALSE, ), 'rss' => array( 'custom_settings' => FALSE, ), + 'teaser' => array( + 'custom_settings' => TRUE, + ), 'token' => array( 'custom_settings' => FALSE, ), ), - 'extra_fields' => array( - 'form' => array( - 'title' => array( - 'weight' => '0', - ), - ), - 'display' => array(), - ), ); $export['field_bundle_settings_node__height'] = $strongarm; @@ -1117,15 +1117,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__lactation'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__lactation'] = $strongarm; @@ -1134,28 +1134,28 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__last_menstrual_period'; $strongarm->value = array( - 'view_modes' => array( - 'teaser' => array( - 'custom_settings' => TRUE, + 'extra_fields' => array( + 'display' => array(), + 'form' => array( + 'title' => array( + 'weight' => '0', + ), ), + ), + 'view_modes' => array( 'full' => array( 'custom_settings' => FALSE, ), 'rss' => array( 'custom_settings' => FALSE, ), + 'teaser' => array( + 'custom_settings' => TRUE, + ), 'token' => array( 'custom_settings' => FALSE, ), ), - 'extra_fields' => array( - 'form' => array( - 'title' => array( - 'weight' => '0', - ), - ), - 'display' => array(), - ), ); $export['field_bundle_settings_node__last_menstrual_period'] = $strongarm; @@ -1164,15 +1164,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__medical_history'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__medical_history'] = $strongarm; @@ -1181,15 +1181,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__medication'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__medication'] = $strongarm; @@ -1198,15 +1198,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__mother_fbf'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__mother_fbf'] = $strongarm; @@ -1215,28 +1215,28 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__muac'; $strongarm->value = array( - 'view_modes' => array( - 'teaser' => array( - 'custom_settings' => TRUE, + 'extra_fields' => array( + 'display' => array(), + 'form' => array( + 'title' => array( + 'weight' => '0', + ), ), + ), + 'view_modes' => array( 'full' => array( 'custom_settings' => FALSE, ), 'rss' => array( 'custom_settings' => FALSE, ), + 'teaser' => array( + 'custom_settings' => TRUE, + ), 'token' => array( 'custom_settings' => FALSE, ), ), - 'extra_fields' => array( - 'form' => array( - 'title' => array( - 'weight' => '0', - ), - ), - 'display' => array(), - ), ); $export['field_bundle_settings_node__muac'] = $strongarm; @@ -1245,28 +1245,28 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__nutrition'; $strongarm->value = array( - 'view_modes' => array( - 'teaser' => array( - 'custom_settings' => TRUE, + 'extra_fields' => array( + 'display' => array(), + 'form' => array( + 'title' => array( + 'weight' => '0', + ), ), + ), + 'view_modes' => array( 'full' => array( 'custom_settings' => FALSE, ), 'rss' => array( 'custom_settings' => FALSE, ), + 'teaser' => array( + 'custom_settings' => TRUE, + ), 'token' => array( 'custom_settings' => FALSE, ), ), - 'extra_fields' => array( - 'form' => array( - 'title' => array( - 'weight' => '0', - ), - ), - 'display' => array(), - ), ); $export['field_bundle_settings_node__nutrition'] = $strongarm; @@ -1275,15 +1275,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__nutrition_height'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__nutrition_height'] = $strongarm; @@ -1292,15 +1292,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__nutrition_muac'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__nutrition_muac'] = $strongarm; @@ -1309,15 +1309,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__nutrition_ncda'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__nutrition_ncda'] = $strongarm; @@ -1326,15 +1326,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__nutrition_nutrition'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__nutrition_nutrition'] = $strongarm; @@ -1343,15 +1343,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__nutrition_photo'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__nutrition_photo'] = $strongarm; @@ -1360,15 +1360,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__nutrition_weight'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__nutrition_weight'] = $strongarm; @@ -1377,15 +1377,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__obstetrical_exam'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__obstetrical_exam'] = $strongarm; @@ -1394,15 +1394,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__obstetric_history'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__obstetric_history'] = $strongarm; @@ -1411,15 +1411,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__obstetric_history_step2'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__obstetric_history_step2'] = $strongarm; @@ -1428,28 +1428,28 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__photo'; $strongarm->value = array( - 'view_modes' => array( - 'teaser' => array( - 'custom_settings' => TRUE, + 'extra_fields' => array( + 'display' => array(), + 'form' => array( + 'title' => array( + 'weight' => '0', + ), ), + ), + 'view_modes' => array( 'full' => array( 'custom_settings' => FALSE, ), 'rss' => array( 'custom_settings' => FALSE, ), + 'teaser' => array( + 'custom_settings' => TRUE, + ), 'token' => array( 'custom_settings' => FALSE, ), ), - 'extra_fields' => array( - 'form' => array( - 'title' => array( - 'weight' => '0', - ), - ), - 'display' => array(), - ), ); $export['field_bundle_settings_node__photo'] = $strongarm; @@ -1458,15 +1458,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__pregnancy_testing'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__pregnancy_testing'] = $strongarm; @@ -1475,15 +1475,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__prenatal_family_planning'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__prenatal_family_planning'] = $strongarm; @@ -1492,15 +1492,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__prenatal_health_education'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__prenatal_health_education'] = $strongarm; @@ -1509,15 +1509,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__prenatal_nutrition'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__prenatal_nutrition'] = $strongarm; @@ -1526,15 +1526,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__prenatal_photo'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__prenatal_photo'] = $strongarm; @@ -1543,15 +1543,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__resource'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__resource'] = $strongarm; @@ -1560,15 +1560,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__social_history'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__social_history'] = $strongarm; @@ -1577,15 +1577,15 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__vitals'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__vitals'] = $strongarm; @@ -1594,28 +1594,28 @@ function hedley_activity_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__weight'; $strongarm->value = array( - 'view_modes' => array( - 'teaser' => array( - 'custom_settings' => TRUE, + 'extra_fields' => array( + 'display' => array(), + 'form' => array( + 'title' => array( + 'weight' => '0', + ), ), + ), + 'view_modes' => array( 'full' => array( 'custom_settings' => FALSE, ), 'rss' => array( 'custom_settings' => FALSE, ), + 'teaser' => array( + 'custom_settings' => TRUE, + ), 'token' => array( 'custom_settings' => FALSE, ), ), - 'extra_fields' => array( - 'form' => array( - 'title' => array( - 'weight' => '0', - ), - ), - 'display' => array(), - ), ); $export['field_bundle_settings_node__weight'] = $strongarm; From 6f84426e8625ad9373478c9292d5f7c4d023bd8c Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 14:03:19 +0300 Subject: [PATCH 016/185] A fix [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 3eb5eec013..b646614718 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2156,9 +2156,9 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ 'muac' => 'e', 'contributing_factors' => 'f', 'follow_up' => 'g', - 'health_education' => 'h', - 'send_to_hc' => 'i', - 'ncda' => 'j', + 'group_health_education' => 'h', + 'group_send_to_hc' => 'i', + 'group_ncda' => 'j', ]; // Activities that are always taken during encounter. From 001b0d7900d4adfd7c0afb6317aa0a3365b18ac8 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 14:05:20 +0300 Subject: [PATCH 017/185] Rename script [ci skip] --- ...ta.php => generate-nutrition-individual-completion-data.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename server/hedley/modules/custom/hedley_reports/scripts/{generate-completion-data.php => generate-nutrition-individual-completion-data.php} (98%) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php similarity index 98% rename from server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php rename to server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php index 52571f4c84..43adb34f61 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php @@ -5,7 +5,7 @@ * Generates completion data for different types of encounters. * * Execution: drush scr - * profiles/hedley/modules/custom/hedley_reports/scripts/generate-completion-data.php. + * profiles/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php. */ if (!drupal_is_cli()) { From cef1bd782536d111ccfed863eab9723218fe0588 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 14:05:41 +0300 Subject: [PATCH 018/185] Save generated data on Attendance node [ci skip] --- .../scripts/generate-nutrition-group-completion-data.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php index 392e715d36..5516446f87 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php @@ -71,8 +71,8 @@ $nodes = node_load_multiple($ids); foreach ($nodes as $node) { $completion_data = hedley_reports_generate_completion_data_for_nutrition_group_encounter($node); -// $node->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); -// node_save($node); + $node->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); + node_save($node); $total++; $memory = round(memory_get_usage() / 1048576); From 771ac0d40f04ec8444eae2831132160fbdb55333 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 14:10:53 +0300 Subject: [PATCH 019/185] A fix [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index b646614718..1b7afefabb 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2216,8 +2216,9 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ return []; } - $session_start_date = $session->field_scheduled_date[LANGUAGE_NONE][0]['value']; - $start_date_obj = new DateTime($session_start_date); + // Resolve session start date. + $start_date = explode(' ',$session->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $start_date_obj = new DateTime($start_date); $measurements_ids = array_keys($result['node']); $measurements = node_load_multiple($measurements_ids); $measurements_per_child = []; @@ -2306,7 +2307,7 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ } } - $return[] = hedley_reports_generate_completion_result($expected, $completed, $session_start_date, $taken_by, $mapping); + $return[] = hedley_reports_generate_completion_result($expected, $completed, $start_date, $taken_by, $mapping); } return $return; From 3c1376d1266b8e2ea02ad400a675226ca8cbda98 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 18:18:03 +0300 Subject: [PATCH 020/185] Add FBF and mother activities [ci skip] --- .../hedley_reports/hedley_reports.module | 274 +++++++++++------- ...nerate-nutrition-group-completion-data.php | 3 - 2 files changed, 175 insertions(+), 102 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 1b7afefabb..7e444ae52e 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2067,7 +2067,14 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun $measurements_ids = $query->execute()->fetchCol(); if (empty($measurements_ids)) { - return hedley_reports_generate_completion_result($expected, $completed, $start_date, $taken_by, $mapping); + list($expected_activities, $completed_activities) = hedley_reports_generate_completion_result($expected, $completed, $mapping); + + return [ + 'start_date' => $start_date, + 'expected' => $expected_activities, + 'completed' => $completed_activities, + 'taken_by' => $taken_by, + ]; } // Try to resolve age in months at a time encounter was performed. @@ -2143,12 +2150,19 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun } } - return hedley_reports_generate_completion_result($expected, $completed, $start_date, $taken_by, $mapping); + list($expected_activities, $completed_activities) = hedley_reports_generate_completion_result($expected, $completed, $mapping); + + return [ + 'start_date' => $start_date, + 'expected' => $expected_activities, + 'completed' => $completed_activities, + 'taken_by' => $taken_by, + ]; } function hedley_reports_generate_completion_data_for_nutrition_group_encounter($attendance) { // To reduce memory usage, mapping measurement types as single characters. - $mapping = [ + $mapping_child = [ 'height' => 'a', 'nutrition' => 'b', 'photo' => 'c', @@ -2159,20 +2173,17 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ 'group_health_education' => 'h', 'group_send_to_hc' => 'i', 'group_ncda' => 'j', + 'child_fbf' => 'k', ]; - // Activities that are always taken during encounter. - $expected = [ - 'height', - 'nutrition', - 'photo', - 'weight', + $mapping_mother = [ + 'family_planning' => 'a', + 'mother_fbf' => 'b', + 'lactation' =>'c', ]; - $completed = []; // Attendance points to mother. We need to resolve the child (or children) // that have participated in the session. - $children_ids = []; $adult_id = $attendance->field_person[LANGUAGE_NONE][0]['target_id']; $session_id = $attendance->field_session[LANGUAGE_NONE][0]['target_id']; $session = node_load($session_id); @@ -2188,132 +2199,202 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ ->addTag('exclude_deleted') ->execute(); - if (empty($result['node'])) { - return []; - } - + $session_participants_ids = [$adult_id]; $participants_ids = array_keys($result['node']); $participants = node_load_multiple($participants_ids); + // Flag that signals that adult is mother to a child (or children), + // and therefore, we expect to find mother activities. + $is_mother = FALSE; foreach ($participants as $participant) { - $children_ids[] = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + $session_participants_ids[] = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + // It's enough to determine that we found mother for one of the children. + if (!$is_mother) { + $is_mother = $participant->field_adult_activities[LANGUAGE_NONE][0]['value'] == 'mother'; + } } - if (empty($children_ids)) { - return []; - } + // Resolve session start date. + $start_date = explode(' ', $session->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $start_date_obj = new DateTime($start_date); + // Resolve data of clinic. + $clinic = node_load($clinic_id); + $clinic_type = $clinic->field_group_type[LANGUAGE_NONE][0]['value']; + $taken_by = ($clinic_type == 'chw') ? 'chw' : 'nurse'; + + // Initial return data. + $return = [ + 'start_date' => $start_date, + 'taken_by' => $taken_by, + 'children' => [], + ]; + // Loading all measurements that were taken for mother and children. + $session_measurements_types = array_merge(array_keys($mapping_mother), array_keys($mapping_child)); $query = new EntityFieldQuery(); $result = $query ->entityCondition('entity_type', 'node') - ->entityCondition('bundle', array_keys($mapping), 'IN') + ->entityCondition('bundle', $session_measurements_types, 'IN') ->propertyCondition('status', NODE_PUBLISHED) - ->fieldCondition('field_person', 'target_id', $children_ids, 'IN') + ->fieldCondition('field_person', 'target_id', $session_participants_ids, 'IN') ->fieldCondition('field_session', 'target_id', $session_id) ->addTag('exclude_deleted') ->execute(); if (empty($result['node'])) { - return []; + // No measurement loaded - no reason to proceed. + return $return; } - // Resolve session start date. - $start_date = explode(' ',$session->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; - $start_date_obj = new DateTime($start_date); $measurements_ids = array_keys($result['node']); $measurements = node_load_multiple($measurements_ids); - $measurements_per_child = []; + $measurements_by_participant = []; foreach ($measurements as $measurement) { $child_id = $measurement->field_person[LANGUAGE_NONE][0]['target_id']; - $measurements_per_child[$child_id][] = $measurement; + $measurements_by_participant[$child_id][] = $measurement; } - $clinic = node_load($clinic_id); - $clinic_type = $clinic->field_group_type[LANGUAGE_NONE][0]['value']; - $taken_by = ($clinic_type === 'chw') ? 'chw' : 'nurse'; - - $return = []; - foreach ($measurements_per_child as $child_id => $measurements) { - $child = node_load($child_id); - - // Try to resolve age in months at a time encounter was performed. - try { - // Get birthdate and date measured. - $birth_date = explode(' ', $child->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; - - // Calculate age in months. - $birth_date_obj = new DateTime($birth_date); - $interval = $start_date_obj->diff($birth_date_obj); - $age_in_months = ($interval->y * 12) + $interval->m; - } catch (Exception $e) { - $age_in_months = NULL; - } - - // MUAC is taken starting age of 6 months. - if (isset($age_in_months) && $age_in_months >= 6) { - $expected[] = 'muac'; - } + // Date on which 'Fbf' feature was launched. + $fbf_launch_date = '2020-06-15'; + $fbf_launch_date_obj = new DateTime($fbf_launch_date); + // Processing measurements by participant type. + foreach ($measurements_by_participant as $person_id => $measurements) { + $person = node_load($person_id); // Ordering measurements by type. $measurements_by_type = []; foreach ($measurements as $measurement) { $measurements_by_type[$measurement->type] = $measurement; } - // Date on which 'Group Next Steps' feature was launched. - $group_next_steps_launch_date = '2021-03-30'; - $group_next_steps_launch_date_obj = new DateTime($group_next_steps_launch_date); + // Handling adult (mother or caregiver). + if ($person_id == $adult_id) { + // We do not expect to see activities for caregiver. + if ($is_mother) { + $expected = ['family_planning']; + + // Lactation (and possibly Mother FBF) activity are shown + // for sessions taking place at FBF and ACHI clinics. + if ($start_date_obj >= $fbf_launch_date_obj && in_array($clinic_type, ['fbf', 'achi'])) { + $expected[] = 'lactation'; + + // Mother FBF activity is shown if Lactation activity indicated + // that mother is breastfeeding. + if (!empty($measurements_by_type['lactation'])) { + $lactation_signs = $measurements_by_type['lactation']->field_lactation_signs[LANGUAGE_NONE][0]['value']; + if (in_array('breastfeeding', $lactation_signs)) { + $expected[] = 'mother_fbf'; + } + } + } + + $completed = []; + foreach ($expected as $measurement_type) { + if (!empty($measurements_by_type[$measurement_type])) { + $completed[] = $measurement_type; + } + } + + list($expected_activities, $completed_activities) = hedley_reports_generate_completion_result($expected, $completed, $mapping_mother); - // We may expect Next Steps activities on after - // 'Group Next Steps' feature was launched. - if ($start_date_obj >= $group_next_steps_launch_date_obj) { - $assessment = ''; - if (!empty($measurements_by_type['nutrition'])) { - $assessment = $measurements_by_type['nutrition']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; + $return['mother'] = [ + 'expected' => $expected_activities, + 'completed' => $completed_activities, + ]; } - else if (!empty($measurements_by_type['follow_up'])) { - $assessment = $measurements_by_type['follow_up']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; + } + // Handling child. + else { + // Activities that are always taken during encounter. + $expected = [ + 'height', + 'nutrition', + 'photo', + 'weight', + ]; + + // Try to resolve age in months at a time encounter was performed. + try { + // Get birthdate and date measured. + $birth_date = explode(' ', $person->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; + + // Calculate age in months. + $birth_date_obj = new DateTime($birth_date); + $interval = $start_date_obj->diff($birth_date_obj); + $age_in_months = ($interval->y * 12) + $interval->m; + } catch (Exception $e) { + $age_in_months = NULL; } - // If assessment was made, we expect all next steps activities. - if (!empty($assessment) && $assessment !== 'none') { - $expected = array_merge( - $expected, - [ - 'contributing_factors', - 'follow_up', - 'group_health_education', - 'group_send_to_hc', - ] - ); + // MUAC is taken starting age of 6 months. + if (isset($age_in_months) && $age_in_months >= 6) { + $expected[] = 'muac'; } - } - // NCDA activity is expected if: - // 1. NCDA feature is enabled. - // 2. Encounter was performed after NCDA launch date. - // 3. Encounter was recorded by nurse (and not by CHW). - // 4. Child was under age of 24 months. - $ncda_enabled = variable_get('hedley_admin_feature_ncda_enabled', FALSE); - $ncda_launch_date = '2023-11-20'; - $ncda_launch_date_obj = new DateTime($ncda_launch_date); - - if ($ncda_enabled && $start_date_obj >= $ncda_launch_date_obj && ($taken_by == 'nurse') && isset($age_in_months) && $age_in_months < 24) { - $expected[] = 'group_ncda'; - } + // Date on which 'Group Next Steps' feature was launched. + $group_next_steps_launch_date = '2021-06-07'; + $group_next_steps_launch_date_obj = new DateTime($group_next_steps_launch_date); + // We may expect Next Steps activities on after + // 'Group Next Steps' feature was launched. + if ($start_date_obj >= $group_next_steps_launch_date_obj) { + $assessment = ''; + if (!empty($measurements_by_type['nutrition'])) { + $assessment = $measurements_by_type['nutrition']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; + } + else if (!empty($measurements_by_type['follow_up'])) { + $assessment = $measurements_by_type['follow_up']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; + } - foreach ($expected as $measurement_type) { - if (!empty($measurements_by_type[$measurement_type])) { - $completed[] = $measurement_type; + // If assessment was made, we expect all next steps activities. + if (!empty($assessment) && $assessment !== 'none') { + $expected = array_merge( + $expected, + [ + 'contributing_factors', + 'follow_up', + 'group_health_education', + 'group_send_to_hc', + ] + ); + } } - } - $return[] = hedley_reports_generate_completion_result($expected, $completed, $start_date, $taken_by, $mapping); + // Child FBF activity is shown for sessions taking place at FBF and ACHI clinics. + if ($start_date_obj >= $fbf_launch_date_obj && in_array($clinic_type, ['fbf', 'achi'])) { + $expected[] = 'child_fbf'; + } + + // NCDA activity is expected if: + // 1. NCDA feature is enabled. + // 2. Encounter was performed after NCDA launch date. + // 3. Encounter was recorded by nurse (and not by CHW). + // 4. Child was under age of 24 months. + $ncda_enabled = variable_get('hedley_admin_feature_ncda_enabled', FALSE); + $ncda_launch_date = '2023-11-20'; + $ncda_launch_date_obj = new DateTime($ncda_launch_date); + if ($ncda_enabled && $start_date_obj >= $ncda_launch_date_obj && ($taken_by == 'nurse') && isset($age_in_months) && $age_in_months < 24) { + $expected[] = 'group_ncda'; + } + + $completed = []; + foreach ($expected as $measurement_type) { + if (!empty($measurements_by_type[$measurement_type])) { + $completed[] = $measurement_type; + } + } + + list($expected_activities, $completed_activities) = hedley_reports_generate_completion_result($expected, $completed, $mapping_child); + + $return['children'][] = [ + 'expected' => $expected_activities, + 'completed' => $completed_activities, + ]; + } } return $return; } -function hedley_reports_generate_completion_result($expected, $completed, $start_date, $taken_by, $mapping) { +function hedley_reports_generate_completion_result($expected, $completed, $mapping) { foreach ($expected as $index => $measurement_type) { $expected[$index] = $mapping[$measurement_type]; } @@ -2322,10 +2403,5 @@ function hedley_reports_generate_completion_result($expected, $completed, $start $completed[$index] = $mapping[$measurement_type]; } - return [ - 'start_date' => $start_date, - 'expected' => implode(',', $expected), - 'completed' => implode(',', $completed), - 'taken_by' => $taken_by, - ]; + return [implode(',', $expected), implode(',', $completed)]; } diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php index 5516446f87..23528cad0d 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php @@ -46,9 +46,6 @@ exit; } -// @todo: do we need this? -$nurses = hedley_ncda_resolve_nurses_ids(); - $total = 0; drush_print("$count nodes of type $type located."); From 628681cb4b1c0974979337e65c266f1c61af5b76 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 18:25:00 +0300 Subject: [PATCH 021/185] A fix [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 7e444ae52e..c0ac51727b 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2280,8 +2280,8 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ // Mother FBF activity is shown if Lactation activity indicated // that mother is breastfeeding. if (!empty($measurements_by_type['lactation'])) { - $lactation_signs = $measurements_by_type['lactation']->field_lactation_signs[LANGUAGE_NONE][0]['value']; - if (in_array('breastfeeding', $lactation_signs)) { + $lactation_sign = $measurements_by_type['lactation']->field_lactation_signs[LANGUAGE_NONE][0]['value']; + if ($lactation_sign == 'breastfeeding') { $expected[] = 'mother_fbf'; } } From 896090a5c412f053fd054d4b76793af28f17eb62 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 18:55:40 +0300 Subject: [PATCH 022/185] Another fix [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index c0ac51727b..b1ca689cb1 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2278,10 +2278,11 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ $expected[] = 'lactation'; // Mother FBF activity is shown if Lactation activity indicated - // that mother is breastfeeding. + // that mother is breastfeeding, and mother Ubudehe is 1 or 2. if (!empty($measurements_by_type['lactation'])) { $lactation_sign = $measurements_by_type['lactation']->field_lactation_signs[LANGUAGE_NONE][0]['value']; - if ($lactation_sign == 'breastfeeding') { + $ubudehe = $person->field_ubudehe[LANGUAGE_NONE][0]['value']; + if ($lactation_sign == 'breastfeeding' && in_array($ubudehe, [1, 2])) { $expected[] = 'mother_fbf'; } } From 4803a805d1ede68f5e98e66f741507c9513175ae Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 19:21:50 +0300 Subject: [PATCH 023/185] Load, decode and store Group Nutrition completion data [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 42 +++- server/elm/src/Backend/Completion/Model.elm | 26 +- server/elm/src/Backend/Completion/Utils.elm | 23 +- server/elm/src/Pages/Completion/Model.elm | 4 +- server/elm/src/Pages/Completion/View.elm | 11 +- server/elm/src/Translate.elm | 12 +- .../custom/hedley_general/js/elm-main.js | 237 ++++++++++++------ .../hedley_reports/hedley_reports.module | 23 +- 8 files changed, 283 insertions(+), 95 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index 05c801d69a..56e0b625e4 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -9,7 +9,7 @@ import EverySet exposing (EverySet) import Gizra.Json exposing (decodeFloat, decodeInt) import Gizra.NominalDate exposing (NominalDate, decodeYYYYMMDD, diffMonths) import Json.Decode exposing (Decoder, andThen, bool, fail, list, map, maybe, nullable, oneOf, string, succeed) -import Json.Decode.Pipeline exposing (optional, optionalAt, required) +import Json.Decode.Pipeline exposing (optional, optionalAt, required, requiredAt) import Maybe.Extra exposing (isNothing) @@ -19,7 +19,9 @@ decodeCompletionData = |> required "site" decodeSite |> required "entity_name" string |> required "entity_type" decodeSelectedEntity - |> required "results" (list (decodeEncounterData decodeNutritionActivities)) + |> requiredAt [ "results", "nutrition_individual" ] (list (decodeEncounterData decodeNutritionChildActivities)) + |> requiredAt [ "results", "nutrition_group" ] + (list (decodeNutritionGroupEncounterData decodeNutritionMotherActivities decodeNutritionChildActivities)) decodeSelectedEntity : Decoder SelectedEntity @@ -48,12 +50,42 @@ decodeEncounterData activitiesDecoder = |> required "taken_by" (nullable (decodeWithFallback TakenByUnknown decodeTakenBy)) -decodeNutritionActivities : Decoder (List NutritionActivity) -decodeNutritionActivities = +decodeNutritionChildActivities : Decoder (List NutritionChildActivity) +decodeNutritionChildActivities = string |> andThen (String.split "," - >> List.map nutritionActivityFromMapping + >> List.map nutritionChildActivityFromMapping + >> Maybe.Extra.values + >> succeed + ) + + +decodeNutritionGroupEncounterData : + Decoder (List motherActivity) + -> Decoder (List childActivity) + -> Decoder (NutritionGroupEncounterData motherActivity childActivity) +decodeNutritionGroupEncounterData motherActivitiesDecoder childActivitiesDecoder = + succeed NutritionGroupEncounterData + |> required "start_date" decodeYYYYMMDD + |> optional "mother" (nullable (decodeActivitiesCompletionData motherActivitiesDecoder)) Nothing + |> required "children" (list (decodeActivitiesCompletionData childActivitiesDecoder)) + |> required "taken_by" (nullable (decodeWithFallback TakenByUnknown decodeTakenBy)) + + +decodeActivitiesCompletionData : Decoder (List activity) -> Decoder (ActivitiesCompletionData activity) +decodeActivitiesCompletionData activitiesDecoder = + succeed ActivitiesCompletionData + |> required "expected" activitiesDecoder + |> required "completed" activitiesDecoder + + +decodeNutritionMotherActivities : Decoder (List NutritionMotherActivity) +decodeNutritionMotherActivities = + string + |> andThen + (String.split "," + >> List.map nutritionMotherActivityFromMapping >> Maybe.Extra.values >> succeed ) diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index 571d37e166..e0a05426f5 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -11,7 +11,8 @@ type alias CompletionData = { site : Site , entityName : String , entityType : SelectedEntity - , nutritionIndividualData : List (EncounterData NutritionActivity) + , nutritionIndividualData : List (EncounterData NutritionChildActivity) + , nutritionGropData : List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) } @@ -28,7 +29,21 @@ type alias EncounterData activity = } -type NutritionActivity +type alias NutritionGroupEncounterData motherActivity childActivity = + { startDate : NominalDate + , motherData : Maybe (ActivitiesCompletionData motherActivity) + , childrenData : List (ActivitiesCompletionData childActivity) + , takenBy : Maybe TakenBy + } + + +type alias ActivitiesCompletionData activity = + { expectedActivities : List activity + , completedActivities : List activity + } + + +type NutritionChildActivity = NutritionHeight | NutritionNutrition | NutritionPhoto @@ -39,6 +54,13 @@ type NutritionActivity | NutritionHealthEducation | NutritionSendToHC | NutritionNCDA + | NutritionChildFbf + + +type NutritionMotherActivity + = NutritionFamilyPlanning + | NutritionLactation + | NutritionMotherFbf type TakenBy diff --git a/server/elm/src/Backend/Completion/Utils.elm b/server/elm/src/Backend/Completion/Utils.elm index bdd42e3ba0..c65065704e 100644 --- a/server/elm/src/Backend/Completion/Utils.elm +++ b/server/elm/src/Backend/Completion/Utils.elm @@ -3,8 +3,8 @@ module Backend.Completion.Utils exposing (..) import Backend.Completion.Model exposing (..) -nutritionActivityFromMapping : String -> Maybe NutritionActivity -nutritionActivityFromMapping mapped = +nutritionChildActivityFromMapping : String -> Maybe NutritionChildActivity +nutritionChildActivityFromMapping mapped = case mapped of "a" -> Just NutritionHeight @@ -36,6 +36,25 @@ nutritionActivityFromMapping mapped = "j" -> Just NutritionNCDA + "k" -> + Just NutritionChildFbf + + _ -> + Nothing + + +nutritionMotherActivityFromMapping : String -> Maybe NutritionMotherActivity +nutritionMotherActivityFromMapping mapped = + case mapped of + "a" -> + Just NutritionFamilyPlanning + + "b" -> + Just NutritionMotherFbf + + "c" -> + Just NutritionLactation + _ -> Nothing diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index fbf0b52ba5..fe98b4665a 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -1,6 +1,6 @@ module Pages.Completion.Model exposing (..) -import Backend.Completion.Model exposing (NutritionActivity(..), TakenBy) +import Backend.Completion.Model exposing (NutritionChildActivity(..), TakenBy) import Date exposing (Date) import DateSelector.Model exposing (DateSelectorConfig) @@ -40,7 +40,7 @@ type Msg | SetLimitDateSelectorState (Maybe (DateSelectorConfig Msg)) -allNutritionActivities : List NutritionActivity +allNutritionActivities : List NutritionChildActivity allNutritionActivities = [ NutritionHeight , NutritionNutrition diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index 33f2578635..ca5c224a09 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -2,7 +2,7 @@ module Pages.Completion.View exposing (view) import App.Types exposing (Language, Site) import AssocList as Dict exposing (Dict) -import Backend.Completion.Model exposing (CompletionData, EncounterData, NutritionActivity(..), SelectedEntity(..), TakenBy(..)) +import Backend.Completion.Model exposing (CompletionData, EncounterData, NutritionChildActivity(..), SelectedEntity(..), TakenBy(..)) import Backend.Completion.Utils exposing (takenByToString) import Backend.Model exposing (ModelBackend) import Date exposing (Interval(..), Unit(..)) @@ -42,6 +42,9 @@ view language currentDate themePath modelBackend model = viewCompletionData : Language -> NominalDate -> String -> CompletionData -> Model -> Html Msg viewCompletionData language currentDate themePath data model = let + _ = + Debug.log "" data.nutritionGropData + topBar = let scopeLabel = @@ -188,7 +191,7 @@ viewCompletionData language currentDate themePath data model = ] -viewNutritionIndividualReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData NutritionActivity) -> Html Msg +viewNutritionIndividualReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData NutritionChildActivity) -> Html Msg viewNutritionIndividualReport language startDate limitDate mTakenBy reportData = let filteredData = @@ -216,7 +219,7 @@ viewNutritionIndividualReport language startDate limitDate mTakenBy reportData = generateNutritionReportData : Language - -> List (EncounterData NutritionActivity) + -> List (EncounterData NutritionChildActivity) -> MetricsResultsTableData generateNutritionReportData language records = let @@ -248,7 +251,7 @@ generateNutritionReportData language records = completed = count .completedActivities activity in - [ translate language <| Translate.NutritionActivity activity + [ translate language <| Translate.NutritionChildActivity activity , String.fromInt expected , String.fromInt completed , calcualtePercentage completed expected diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index eaf87e58d4..0a7a4d95ff 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -5,7 +5,7 @@ module Translate exposing ) import App.Types exposing (Language(..)) -import Backend.Completion.Model exposing (NutritionActivity(..), TakenBy(..)) +import Backend.Completion.Model exposing (NutritionChildActivity(..), TakenBy(..)) import Backend.Reports.Model exposing (AcuteIllnessDiagnosis(..), NutritionReportTableType(..)) import Backend.Scoreboard.Model import Date @@ -118,7 +118,7 @@ type TranslationId | None | NumberOfVisits Int | NumberOfVisitsLabel - | NutritionActivity NutritionActivity + | NutritionChildActivity NutritionChildActivity | NutritionBehavior | NutritionIndividual | NutritionReportTableType NutritionReportTableType @@ -812,7 +812,7 @@ translationSet transId = , kirundi = Nothing } - NutritionActivity activity -> + NutritionChildActivity activity -> case activity of NutritionHeight -> { english = "Height" @@ -874,6 +874,12 @@ translationSet transId = , kirundi = Nothing } + NutritionChildFbf -> + { english = "Child FBF" + , kinyarwanda = Nothing + , kirundi = Nothing + } + NutritionBehavior -> { english = "Nutrition Behavior" , kinyarwanda = Nothing diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index e9d010f8d0..b8f7e98b8c 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -6835,9 +6835,9 @@ var $author$project$Backend$Types$BackendReturn = F4( function (model, cmd, error, appMsgs) { return {appMsgs: appMsgs, cmd: cmd, error: error, model: model}; }); -var $author$project$Backend$Completion$Model$CompletionData = F4( - function (site, entityName, entityType, nutritionIndividualData) { - return {entityName: entityName, entityType: entityType, nutritionIndividualData: nutritionIndividualData, site: site}; +var $author$project$Backend$Completion$Model$CompletionData = F5( + function (site, entityName, entityType, nutritionIndividualData, nutritionGropData) { + return {entityName: entityName, entityType: entityType, nutritionGropData: nutritionGropData, nutritionIndividualData: nutritionIndividualData, site: site}; }); var $author$project$Backend$Completion$Model$EncounterData = F4( function (startDate, expectedActivities, completedActivities, takenBy) { @@ -7663,6 +7663,7 @@ var $author$project$Backend$Completion$Decoder$decodeEncounterData = function (a $author$project$Gizra$NominalDate$decodeYYYYMMDD, $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EncounterData))))); }; +var $author$project$Backend$Completion$Model$NutritionChildFbf = {$: 'NutritionChildFbf'}; var $author$project$Backend$Completion$Model$NutritionContributingFactors = {$: 'NutritionContributingFactors'}; var $author$project$Backend$Completion$Model$NutritionFollowUp = {$: 'NutritionFollowUp'}; var $author$project$Backend$Completion$Model$NutritionHealthEducation = {$: 'NutritionHealthEducation'}; @@ -7673,7 +7674,7 @@ var $author$project$Backend$Completion$Model$NutritionNutrition = {$: 'Nutrition var $author$project$Backend$Completion$Model$NutritionPhoto = {$: 'NutritionPhoto'}; var $author$project$Backend$Completion$Model$NutritionSendToHC = {$: 'NutritionSendToHC'}; var $author$project$Backend$Completion$Model$NutritionWeight = {$: 'NutritionWeight'}; -var $author$project$Backend$Completion$Utils$nutritionActivityFromMapping = function (mapped) { +var $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping = function (mapped) { switch (mapped) { case 'a': return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHeight); @@ -7695,18 +7696,134 @@ var $author$project$Backend$Completion$Utils$nutritionActivityFromMapping = func return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionSendToHC); case 'j': return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionNCDA); + case 'k': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionChildFbf); + default: + return $elm$core$Maybe$Nothing; + } +}; +var $author$project$Backend$Completion$Decoder$decodeNutritionChildActivities = A2( + $elm$json$Json$Decode$andThen, + A2( + $elm$core$Basics$composeR, + $elm$core$String$split(','), + A2( + $elm$core$Basics$composeR, + $elm$core$List$map($author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping), + A2($elm$core$Basics$composeR, $elm_community$maybe_extra$Maybe$Extra$values, $elm$json$Json$Decode$succeed))), + $elm$json$Json$Decode$string); +var $author$project$Backend$Completion$Model$NutritionGroupEncounterData = F4( + function (startDate, motherData, childrenData, takenBy) { + return {childrenData: childrenData, motherData: motherData, startDate: startDate, takenBy: takenBy}; + }); +var $author$project$Backend$Completion$Model$ActivitiesCompletionData = F2( + function (expectedActivities, completedActivities) { + return {completedActivities: completedActivities, expectedActivities: expectedActivities}; + }); +var $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData = function (activitiesDecoder) { + return A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'completed', + activitiesDecoder, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'expected', + activitiesDecoder, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$ActivitiesCompletionData))); +}; +var $elm$json$Json$Decode$list = _Json_decodeList; +var $elm$json$Json$Decode$decodeValue = _Json_run; +var $elm$json$Json$Decode$value = _Json_decodeValue; +var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalDecoder = F3( + function (pathDecoder, valDecoder, fallback) { + var nullOr = function (decoder) { + return $elm$json$Json$Decode$oneOf( + _List_fromArray( + [ + decoder, + $elm$json$Json$Decode$null(fallback) + ])); + }; + var handleResult = function (input) { + var _v0 = A2($elm$json$Json$Decode$decodeValue, pathDecoder, input); + if (_v0.$ === 'Ok') { + var rawValue = _v0.a; + var _v1 = A2( + $elm$json$Json$Decode$decodeValue, + nullOr(valDecoder), + rawValue); + if (_v1.$ === 'Ok') { + var finalResult = _v1.a; + return $elm$json$Json$Decode$succeed(finalResult); + } else { + var finalErr = _v1.a; + return $elm$json$Json$Decode$fail( + $elm$json$Json$Decode$errorToString(finalErr)); + } + } else { + return $elm$json$Json$Decode$succeed(fallback); + } + }; + return A2($elm$json$Json$Decode$andThen, handleResult, $elm$json$Json$Decode$value); + }); +var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optional = F4( + function (key, valDecoder, fallback, decoder) { + return A2( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalDecoder, + A2($elm$json$Json$Decode$field, key, $elm$json$Json$Decode$value), + valDecoder, + fallback), + decoder); + }); +var $author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData = F2( + function (motherActivitiesDecoder, childActivitiesDecoder) { + return A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'taken_by', + $elm$json$Json$Decode$nullable( + A2($author$project$Backend$Decoder$decodeWithFallback, $author$project$Backend$Completion$Model$TakenByUnknown, $author$project$Backend$Completion$Decoder$decodeTakenBy)), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'children', + $elm$json$Json$Decode$list( + $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData(childActivitiesDecoder)), + A4( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optional, + 'mother', + $elm$json$Json$Decode$nullable( + $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData(motherActivitiesDecoder)), + $elm$core$Maybe$Nothing, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'start_date', + $author$project$Gizra$NominalDate$decodeYYYYMMDD, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$NutritionGroupEncounterData))))); + }); +var $author$project$Backend$Completion$Model$NutritionFamilyPlanning = {$: 'NutritionFamilyPlanning'}; +var $author$project$Backend$Completion$Model$NutritionLactation = {$: 'NutritionLactation'}; +var $author$project$Backend$Completion$Model$NutritionMotherFbf = {$: 'NutritionMotherFbf'}; +var $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionFamilyPlanning); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionMotherFbf); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionLactation); default: return $elm$core$Maybe$Nothing; } }; -var $author$project$Backend$Completion$Decoder$decodeNutritionActivities = A2( +var $author$project$Backend$Completion$Decoder$decodeNutritionMotherActivities = A2( $elm$json$Json$Decode$andThen, A2( $elm$core$Basics$composeR, $elm$core$String$split(','), A2( $elm$core$Basics$composeR, - $elm$core$List$map($author$project$Backend$Completion$Utils$nutritionActivityFromMapping), + $elm$core$List$map($author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping), A2($elm$core$Basics$composeR, $elm_community$maybe_extra$Maybe$Extra$values, $elm$json$Json$Decode$succeed))), $elm$json$Json$Decode$string); var $author$project$Backend$Completion$Model$EntityGlobal = {$: 'EntityGlobal'}; @@ -7743,26 +7860,42 @@ var $author$project$Backend$Decoder$decodeSite = A2( $elm$json$Json$Decode$andThen, A2($elm$core$Basics$composeR, $author$project$Backend$Decoder$siteFromString, $elm$json$Json$Decode$succeed), $elm$json$Json$Decode$string); -var $elm$json$Json$Decode$list = _Json_decodeList; +var $elm$json$Json$Decode$at = F2( + function (fields, decoder) { + return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields); + }); +var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt = F3( + function (path, valDecoder, decoder) { + return A2( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom, + A2($elm$json$Json$Decode$at, path, valDecoder), + decoder); + }); var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'results', + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, + _List_fromArray( + ['results', 'nutrition_group']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Decoder$decodeNutritionActivities)), + A2($author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData, $author$project$Backend$Completion$Decoder$decodeNutritionMotherActivities, $author$project$Backend$Completion$Decoder$decodeNutritionChildActivities)), A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_type', - $author$project$Backend$Completion$Decoder$decodeSelectedEntity, + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, + _List_fromArray( + ['results', 'nutrition_individual']), + $elm$json$Json$Decode$list( + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Decoder$decodeNutritionChildActivities)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_name', - $elm$json$Json$Decode$string, + 'entity_type', + $author$project$Backend$Completion$Decoder$decodeSelectedEntity, A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'site', - $author$project$Backend$Decoder$decodeSite, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData))))); -var $elm$json$Json$Decode$decodeValue = _Json_run; + 'entity_name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData)))))); var $author$project$Backend$Completion$Update$update = F3( function (currentDate, msg, model) { var value = msg.a; @@ -8256,50 +8389,6 @@ var $author$project$Backend$Reports$Decoder$decodePrenatalEncounterData = A2( return $elm$json$Json$Decode$fail('Failed to decode PrenatalEncounterData'); }, $elm$json$Json$Decode$string); -var $elm$json$Json$Decode$value = _Json_decodeValue; -var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalDecoder = F3( - function (pathDecoder, valDecoder, fallback) { - var nullOr = function (decoder) { - return $elm$json$Json$Decode$oneOf( - _List_fromArray( - [ - decoder, - $elm$json$Json$Decode$null(fallback) - ])); - }; - var handleResult = function (input) { - var _v0 = A2($elm$json$Json$Decode$decodeValue, pathDecoder, input); - if (_v0.$ === 'Ok') { - var rawValue = _v0.a; - var _v1 = A2( - $elm$json$Json$Decode$decodeValue, - nullOr(valDecoder), - rawValue); - if (_v1.$ === 'Ok') { - var finalResult = _v1.a; - return $elm$json$Json$Decode$succeed(finalResult); - } else { - var finalErr = _v1.a; - return $elm$json$Json$Decode$fail( - $elm$json$Json$Decode$errorToString(finalErr)); - } - } else { - return $elm$json$Json$Decode$succeed(fallback); - } - }; - return A2($elm$json$Json$Decode$andThen, handleResult, $elm$json$Json$Decode$value); - }); -var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optional = F4( - function (key, valDecoder, fallback, decoder) { - return A2( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom, - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalDecoder, - A2($elm$json$Json$Decode$field, key, $elm$json$Json$Decode$value), - valDecoder, - fallback), - decoder); - }); var $author$project$Backend$Reports$Decoder$decodePrenatalParticipantData = A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, 'encounters', @@ -8319,10 +8408,6 @@ var $author$project$Backend$Reports$Decoder$decodePrenatalParticipantData = A3( 'created', $author$project$Gizra$NominalDate$decodeYYYYMMDD, $elm$json$Json$Decode$succeed($author$project$Backend$Reports$Model$PrenatalParticipantData))))); -var $elm$json$Json$Decode$at = F2( - function (fields, decoder) { - return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields); - }); var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalAt = F4( function (path, valDecoder, fallback, decoder) { return A2( @@ -10145,7 +10230,7 @@ var $author$project$Translate$translationSet = function (transId) { }); case 'NumberOfVisitsLabel': return {english: '# Visits', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; - case 'NutritionActivity': + case 'NutritionChildActivity': var activity = transId.a; switch (activity.$) { case 'NutritionHeight': @@ -10166,8 +10251,10 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Health Education', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NutritionSendToHC': return {english: 'Referal', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; - default: + case 'NutritionNCDA': return {english: 'NCDA', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + default: + return {english: 'Child FBF', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; } case 'NutritionBehavior': return {english: 'Nutrition Behavior', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; @@ -11221,6 +11308,7 @@ var $elm_community$maybe_extra$Maybe$Extra$isJust = function (m) { } }; var $author$project$Pages$Utils$launchDate = A3($justinmimbs$date$Date$fromCalendarDate, 2018, $elm$time$Time$Jan, 1); +var $elm$core$Debug$log = _Debug_log; var $elm$core$Maybe$map3 = F4( function (func, ma, mb, mc) { if (ma.$ === 'Nothing') { @@ -12325,8 +12413,8 @@ var $author$project$Utils$Html$viewModal = $author$project$Utils$Html$viewCustom var $author$project$Translate$Activity = {$: 'Activity'}; var $author$project$Translate$Completed = {$: 'Completed'}; var $author$project$Translate$Expected = {$: 'Expected'}; -var $author$project$Translate$NutritionActivity = function (a) { - return {$: 'NutritionActivity', a: a}; +var $author$project$Translate$NutritionChildActivity = function (a) { + return {$: 'NutritionChildActivity', a: a}; }; var $author$project$Translate$NutritionIndividual = {$: 'NutritionIndividual'}; var $author$project$Pages$Completion$Model$allNutritionActivities = _List_fromArray( @@ -12590,7 +12678,7 @@ var $author$project$Pages$Completion$View$generateNutritionReportData = F2( A2( $author$project$Translate$translate, language, - $author$project$Translate$NutritionActivity(activity)), + $author$project$Translate$NutritionChildActivity(activity)), $elm$core$String$fromInt(expected), $elm$core$String$fromInt(completed), A2(calcualtePercentage, completed, expected) @@ -12773,8 +12861,8 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( function (language, currentDate, themePath, data, model) { var topBar = function () { var scopeLabel = function () { - var _v1 = data.entityType; - if (_v1.$ === 'EntityGlobal') { + var _v2 = data.entityType; + if (_v2.$ === 'EntityGlobal') { return A2($author$project$Translate$translate, language, $author$project$Translate$Global); } else { return data.entityName; @@ -12944,6 +13032,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( model.reportType, model.startDate, model.limitDate)); + var _v0 = A2($elm$core$Debug$log, '', data.nutritionGropData); return A2( $elm$html$Html$div, _List_fromArray( diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index b1ca689cb1..768b1cdc73 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -1976,10 +1976,15 @@ function hedley_reports_build_completion_results_app($health_center = NULL) { * An array of generated data. */ function hedley_reports_generate_completion_results_data($health_center) { + $bundles = [ + 'nutrition_encounter', // Nutrition Individual data. + 'attendance', // Nutrition Group data. + ]; + $base_query = new EntityFieldQuery(); $base_query ->entityCondition('entity_type', 'node') - ->entityCondition('bundle', 'nutrition_encounter') + ->entityCondition('bundle', $bundles, 'IN') ->propertyCondition('status', NODE_PUBLISHED) ->fieldCondition('field_reports_data', 'value', NULL, 'IS NOT NULL') ->propertyOrderBy('nid'); @@ -1988,7 +1993,11 @@ function hedley_reports_generate_completion_results_data($health_center) { $base_query->fieldCondition('field_shards', 'target_id', $health_center); } - $data = []; + $data = [ + 'nutrition_individual' => [], + 'nutrition_group' => [], + ]; + $nid = 0; $batch = 400; while (TRUE) { @@ -2017,7 +2026,15 @@ function hedley_reports_generate_completion_results_data($health_center) { continue; } - $data[] = json_decode($json_data); + switch ($node->type) { + case 'nutrition_encounter': + $data['nutrition_individual'][] = json_decode($json_data); + break; + + case 'attendance': + $data['nutrition_group'][] = json_decode($json_data); + } + // Explicitly unset large variables after use for memory optimization. unset($json_data); } From 1156e51c481290375d39fff787bb21bc29c68879 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 20:49:14 +0300 Subject: [PATCH 024/185] New report type - logic + view [ci skip] --- server/elm/src/Backend/Completion/Model.elm | 2 +- server/elm/src/Pages/Completion/Model.elm | 20 +- server/elm/src/Pages/Completion/Utils.elm | 6 + server/elm/src/Pages/Completion/View.elm | 117 ++++++++- server/elm/src/Translate.elm | 36 ++- .../custom/hedley_general/js/elm-main.js | 242 ++++++++++++++---- 6 files changed, 360 insertions(+), 63 deletions(-) diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index e0a05426f5..c6b7fd1219 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -12,7 +12,7 @@ type alias CompletionData = , entityName : String , entityType : SelectedEntity , nutritionIndividualData : List (EncounterData NutritionChildActivity) - , nutritionGropData : List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) + , nutritionGroupData : List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) } diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index fe98b4665a..1b4c67f094 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -1,6 +1,6 @@ module Pages.Completion.Model exposing (..) -import Backend.Completion.Model exposing (NutritionChildActivity(..), TakenBy) +import Backend.Completion.Model exposing (NutritionChildActivity(..), NutritionMotherActivity(..), TakenBy) import Date exposing (Date) import DateSelector.Model exposing (DateSelectorConfig) @@ -28,6 +28,7 @@ emptyModel = type ReportType = ReportNutritionIndividual + | ReportNutritionGroup type Msg @@ -40,8 +41,8 @@ type Msg | SetLimitDateSelectorState (Maybe (DateSelectorConfig Msg)) -allNutritionActivities : List NutritionChildActivity -allNutritionActivities = +allNutritionIndividualActivities : List NutritionChildActivity +allNutritionIndividualActivities = [ NutritionHeight , NutritionNutrition , NutritionPhoto @@ -53,3 +54,16 @@ allNutritionActivities = , NutritionSendToHC , NutritionNCDA ] + + +allNutritionChildGroupActivities : List NutritionChildActivity +allNutritionChildGroupActivities = + allNutritionIndividualActivities ++ [ NutritionChildFbf ] + + +allNutritionMotherGroupActivities : List NutritionMotherActivity +allNutritionMotherGroupActivities = + [ NutritionFamilyPlanning + , NutritionLactation + , NutritionMotherFbf + ] diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index cce2e55bc1..6073bb59aa 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -10,6 +10,9 @@ reportTypeToString reportType = ReportNutritionIndividual -> "nutrition-individual" + ReportNutritionGroup -> + "nutrition-group" + reportTypeFromString : String -> Maybe ReportType reportTypeFromString reportType = @@ -17,5 +20,8 @@ reportTypeFromString reportType = "nutrition-individual" -> Just ReportNutritionIndividual + "nutrition-group" -> + Just ReportNutritionGroup + _ -> Nothing diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index ca5c224a09..4d15485c9a 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -2,7 +2,16 @@ module Pages.Completion.View exposing (view) import App.Types exposing (Language, Site) import AssocList as Dict exposing (Dict) -import Backend.Completion.Model exposing (CompletionData, EncounterData, NutritionChildActivity(..), SelectedEntity(..), TakenBy(..)) +import Backend.Completion.Model + exposing + ( CompletionData + , EncounterData + , NutritionChildActivity(..) + , NutritionGroupEncounterData + , NutritionMotherActivity(..) + , SelectedEntity(..) + , TakenBy(..) + ) import Backend.Completion.Utils exposing (takenByToString) import Backend.Model exposing (ModelBackend) import Date exposing (Interval(..), Unit(..)) @@ -42,9 +51,6 @@ view language currentDate themePath modelBackend model = viewCompletionData : Language -> NominalDate -> String -> CompletionData -> Model -> Html Msg viewCompletionData language currentDate themePath data model = let - _ = - Debug.log "" data.nutritionGropData - topBar = let scopeLabel = @@ -165,6 +171,9 @@ viewCompletionData language currentDate themePath data model = case reportType of ReportNutritionIndividual -> viewNutritionIndividualReport language startDate limitDate model.takenBy data.nutritionIndividualData + + ReportNutritionGroup -> + viewNutritionGroupReport language startDate limitDate model.takenBy data.nutritionGroupData ) model.reportType model.startDate @@ -176,7 +185,7 @@ viewCompletionData language currentDate themePath data model = , div [ class "inputs" ] <| [ viewSelectListInput language model.reportType - [ ReportNutritionIndividual ] + [ ReportNutritionIndividual, ReportNutritionGroup ] reportTypeToString SetReportType Translate.CompletionReportType @@ -211,17 +220,17 @@ viewNutritionIndividualReport language startDate limitDate mTakenBy reportData = && takenByCondition ) reportData - |> generateNutritionReportData language + |> generateNutritionIndividualReportData language in div [ class "report nutrition-individual" ] <| viewNutritionMetricsResultsTable filteredData -generateNutritionReportData : +generateNutritionIndividualReportData : Language -> List (EncounterData NutritionChildActivity) -> MetricsResultsTableData -generateNutritionReportData language records = +generateNutritionIndividualReportData language records = let count resolveFunc activity = List.filter (resolveFunc >> List.member activity) records @@ -257,5 +266,95 @@ generateNutritionReportData language records = , calcualtePercentage completed expected ] ) - allNutritionActivities + allNutritionIndividualActivities + } + + +viewNutritionGroupReport : + Language + -> NominalDate + -> NominalDate + -> Maybe TakenBy + -> List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) + -> Html Msg +viewNutritionGroupReport language startDate limitDate mTakenBy reportData = + let + filteredData = + List.filter + (\encounter -> + let + takenByCondition = + Maybe.map + (\takenBy -> + encounter.takenBy == Just takenBy + ) + mTakenBy + |> Maybe.withDefault True + in + (not <| Date.compare encounter.startDate startDate == LT) + && (not <| Date.compare encounter.startDate limitDate == GT) + && takenByCondition + ) + reportData + |> generateNutritionGroupReportData language + in + div [ class "report nutrition-individual" ] <| + viewNutritionMetricsResultsTable filteredData + + +generateNutritionGroupReportData : + Language + -> List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) + -> MetricsResultsTableData +generateNutritionGroupReportData language records = + let + count resolveFunc activity data = + List.filter (resolveFunc >> List.member activity) data + |> List.length + + calcualtePercentage nominator total = + if total == 0 then + "0" + + else + Round.round 3 ((toFloat nominator / toFloat total) * 100) ++ "%" + + motherData = + List.filterMap .motherData records + + childrenData = + List.map .childrenData records + |> List.concat + + generateActivityRows activityTransId data = + List.map + (\activity -> + let + expected = + count .expectedActivities activity data + + completed = + count .completedActivities activity data + in + [ translate language <| activityTransId activity + , String.fromInt expected + , String.fromInt completed + , calcualtePercentage completed expected + ] + ) + + motherActivityRows = + generateActivityRows Translate.NutritionMotherActivity motherData allNutritionMotherGroupActivities + + childrenActivityRows = + generateActivityRows Translate.NutritionChildActivity childrenData allNutritionChildGroupActivities + in + { heading = translate language Translate.NutritionGroup + , captions = + [ translate language Translate.Activity + , translate language Translate.Expected + , translate language Translate.Completed + , "%" + ] + , rows = motherActivityRows ++ childrenActivityRows } diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 0a7a4d95ff..283487b0fb 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -5,7 +5,7 @@ module Translate exposing ) import App.Types exposing (Language(..)) -import Backend.Completion.Model exposing (NutritionChildActivity(..), TakenBy(..)) +import Backend.Completion.Model exposing (NutritionChildActivity(..), NutritionMotherActivity(..), TakenBy(..)) import Backend.Reports.Model exposing (AcuteIllnessDiagnosis(..), NutritionReportTableType(..)) import Backend.Scoreboard.Model import Date @@ -119,8 +119,10 @@ type TranslationId | NumberOfVisits Int | NumberOfVisitsLabel | NutritionChildActivity NutritionChildActivity + | NutritionMotherActivity NutritionMotherActivity | NutritionBehavior | NutritionIndividual + | NutritionGroup | NutritionReportTableType NutritionReportTableType | NutritionTotal | PleaseWaitMessage @@ -360,6 +362,12 @@ translationSet transId = , kirundi = Nothing } + Pages.Completion.Model.ReportNutritionGroup -> + { english = "Nutrition Group" + , kinyarwanda = Nothing + , kirundi = Nothing + } + CBNP -> { english = "CBNP" , kinyarwanda = Nothing @@ -880,6 +888,26 @@ translationSet transId = , kirundi = Nothing } + NutritionMotherActivity activity -> + case activity of + NutritionFamilyPlanning -> + { english = "Family Planning" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NutritionLactation -> + { english = "Lactation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NutritionMotherFbf -> + { english = "Mother FBF" + , kinyarwanda = Nothing + , kirundi = Nothing + } + NutritionBehavior -> { english = "Nutrition Behavior" , kinyarwanda = Nothing @@ -892,6 +920,12 @@ translationSet transId = , kirundi = Nothing } + NutritionGroup -> + { english = "Nutrition Group" + , kinyarwanda = Nothing + , kirundi = Nothing + } + NutritionReportTableType tableType -> case tableType of NutritionTablePrevalanceOneOrMore -> diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index b8f7e98b8c..eb5fd4b8b4 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5825,12 +5825,16 @@ var $elm_community$maybe_extra$Maybe$Extra$or = F2( return ma; } }); +var $author$project$Pages$Completion$Model$ReportNutritionGroup = {$: 'ReportNutritionGroup'}; var $author$project$Pages$Completion$Model$ReportNutritionIndividual = {$: 'ReportNutritionIndividual'}; var $author$project$Pages$Completion$Utils$reportTypeFromString = function (reportType) { - if (reportType === 'nutrition-individual') { - return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionIndividual); - } else { - return $elm$core$Maybe$Nothing; + switch (reportType) { + case 'nutrition-individual': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionIndividual); + case 'nutrition-group': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionGroup); + default: + return $elm$core$Maybe$Nothing; } }; var $author$project$Backend$Completion$Model$TakenByCHW = {$: 'TakenByCHW'}; @@ -6836,8 +6840,8 @@ var $author$project$Backend$Types$BackendReturn = F4( return {appMsgs: appMsgs, cmd: cmd, error: error, model: model}; }); var $author$project$Backend$Completion$Model$CompletionData = F5( - function (site, entityName, entityType, nutritionIndividualData, nutritionGropData) { - return {entityName: entityName, entityType: entityType, nutritionGropData: nutritionGropData, nutritionIndividualData: nutritionIndividualData, site: site}; + function (site, entityName, entityType, nutritionIndividualData, nutritionGroupData) { + return {entityName: entityName, entityType: entityType, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site}; }); var $author$project$Backend$Completion$Model$EncounterData = F4( function (startDate, expectedActivities, completedActivities, takenBy) { @@ -9960,7 +9964,11 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Completed', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'CompletionReportType': var reportType = transId.a; - return {english: 'Nutrition Individual', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + if (reportType.$ === 'ReportNutritionIndividual') { + return {english: 'Nutrition Individual', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + } else { + return {english: 'Nutrition Group', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + } case 'CBNP': return {english: 'CBNP', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Cell': @@ -10256,10 +10264,22 @@ var $author$project$Translate$translationSet = function (transId) { default: return {english: 'Child FBF', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; } + case 'NutritionMotherActivity': + var activity = transId.a; + switch (activity.$) { + case 'NutritionFamilyPlanning': + return {english: 'Family Planning', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionLactation': + return {english: 'Lactation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + default: + return {english: 'Mother FBF', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + } case 'NutritionBehavior': return {english: 'Nutrition Behavior', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NutritionIndividual': return {english: 'Nutrition Individual', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NutritionGroup': + return {english: 'Nutrition Group', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NutritionReportTableType': var tableType = transId.a; switch (tableType.$) { @@ -11308,7 +11328,6 @@ var $elm_community$maybe_extra$Maybe$Extra$isJust = function (m) { } }; var $author$project$Pages$Utils$launchDate = A3($justinmimbs$date$Date$fromCalendarDate, 2018, $elm$time$Time$Jan, 1); -var $elm$core$Debug$log = _Debug_log; var $elm$core$Maybe$map3 = F4( function (func, ma, mb, mc) { if (ma.$ === 'Nothing') { @@ -11347,7 +11366,11 @@ var $elm$html$Html$Events$onClick = function (msg) { $elm$json$Json$Decode$succeed(msg)); }; var $author$project$Pages$Completion$Utils$reportTypeToString = function (reportType) { - return 'nutrition-individual'; + if (reportType.$ === 'ReportNutritionIndividual') { + return 'nutrition-individual'; + } else { + return 'nutrition-group'; + } }; var $author$project$Backend$Completion$Utils$takenByToString = function (value) { switch (value.$) { @@ -12416,9 +12439,18 @@ var $author$project$Translate$Expected = {$: 'Expected'}; var $author$project$Translate$NutritionChildActivity = function (a) { return {$: 'NutritionChildActivity', a: a}; }; -var $author$project$Translate$NutritionIndividual = {$: 'NutritionIndividual'}; -var $author$project$Pages$Completion$Model$allNutritionActivities = _List_fromArray( +var $author$project$Translate$NutritionGroup = {$: 'NutritionGroup'}; +var $author$project$Translate$NutritionMotherActivity = function (a) { + return {$: 'NutritionMotherActivity', a: a}; +}; +var $author$project$Pages$Completion$Model$allNutritionIndividualActivities = _List_fromArray( [$author$project$Backend$Completion$Model$NutritionHeight, $author$project$Backend$Completion$Model$NutritionNutrition, $author$project$Backend$Completion$Model$NutritionPhoto, $author$project$Backend$Completion$Model$NutritionWeight, $author$project$Backend$Completion$Model$NutritionMUAC, $author$project$Backend$Completion$Model$NutritionContributingFactors, $author$project$Backend$Completion$Model$NutritionFollowUp, $author$project$Backend$Completion$Model$NutritionHealthEducation, $author$project$Backend$Completion$Model$NutritionSendToHC, $author$project$Backend$Completion$Model$NutritionNCDA]); +var $author$project$Pages$Completion$Model$allNutritionChildGroupActivities = _Utils_ap( + $author$project$Pages$Completion$Model$allNutritionIndividualActivities, + _List_fromArray( + [$author$project$Backend$Completion$Model$NutritionChildFbf])); +var $author$project$Pages$Completion$Model$allNutritionMotherGroupActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$NutritionFamilyPlanning, $author$project$Backend$Completion$Model$NutritionLactation, $author$project$Backend$Completion$Model$NutritionMotherFbf]); var $myrho$elm_round$Round$addSign = F2( function (signed, str) { var isNotZero = A2( @@ -12632,10 +12664,16 @@ var $myrho$elm_round$Round$round = $myrho$elm_round$Round$roundFun( } } })); -var $author$project$Pages$Completion$View$generateNutritionReportData = F2( +var $author$project$Pages$Completion$View$generateNutritionGroupReportData = F2( function (language, records) { - var count = F2( - function (resolveFunc, activity) { + var motherData = A2( + $elm$core$List$filterMap, + function ($) { + return $.motherData; + }, + records); + var count = F3( + function (resolveFunc, activity, data) { return $elm$core$List$length( A2( $elm$core$List$filter, @@ -12643,12 +12681,51 @@ var $author$project$Pages$Completion$View$generateNutritionReportData = F2( $elm$core$Basics$composeR, resolveFunc, $elm$core$List$member(activity)), - records)); + data)); }); + var childrenData = $elm$core$List$concat( + A2( + $elm$core$List$map, + function ($) { + return $.childrenData; + }, + records)); var calcualtePercentage = F2( function (nominator, total) { return (!total) ? '0' : (A2($myrho$elm_round$Round$round, 3, (nominator / total) * 100) + '%'); }); + var generateActivityRows = F2( + function (activityTransId, data) { + return $elm$core$List$map( + function (activity) { + var expected = A3( + count, + function ($) { + return $.expectedActivities; + }, + activity, + data); + var completed = A3( + count, + function ($) { + return $.completedActivities; + }, + activity, + data); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + activityTransId(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2(calcualtePercentage, completed, expected) + ]); + }); + }); + var childrenActivityRows = A3(generateActivityRows, $author$project$Translate$NutritionChildActivity, childrenData, $author$project$Pages$Completion$Model$allNutritionChildGroupActivities); + var motherActivityRows = A3(generateActivityRows, $author$project$Translate$NutritionMotherActivity, motherData, $author$project$Pages$Completion$Model$allNutritionMotherGroupActivities); return { captions: _List_fromArray( [ @@ -12657,34 +12734,8 @@ var $author$project$Pages$Completion$View$generateNutritionReportData = F2( A2($author$project$Translate$translate, language, $author$project$Translate$Completed), '%' ]), - heading: A2($author$project$Translate$translate, language, $author$project$Translate$NutritionIndividual), - rows: A2( - $elm$core$List$map, - function (activity) { - var expected = A2( - count, - function ($) { - return $.expectedActivities; - }, - activity); - var completed = A2( - count, - function ($) { - return $.completedActivities; - }, - activity); - return _List_fromArray( - [ - A2( - $author$project$Translate$translate, - language, - $author$project$Translate$NutritionChildActivity(activity)), - $elm$core$String$fromInt(expected), - $elm$core$String$fromInt(completed), - A2(calcualtePercentage, completed, expected) - ]); - }, - $author$project$Pages$Completion$Model$allNutritionActivities) + heading: A2($author$project$Translate$translate, language, $author$project$Translate$NutritionGroup), + rows: _Utils_ap(motherActivityRows, childrenActivityRows) }; }); var $elm$html$Html$Attributes$classList = function (classes) { @@ -12761,10 +12812,100 @@ var $author$project$Pages$Components$View$viewNutritionMetricsResultsTable = fun A2($elm$core$List$map, viewRow, data.rows))) ]); }; +var $author$project$Pages$Completion$View$viewNutritionGroupReport = F5( + function (language, startDate, limitDate, mTakenBy, reportData) { + var filteredData = A2( + $author$project$Pages$Completion$View$generateNutritionGroupReportData, + language, + A2( + $elm$core$List$filter, + function (encounter) { + var takenByCondition = A2( + $elm$core$Maybe$withDefault, + true, + A2( + $elm$core$Maybe$map, + function (takenBy) { + return _Utils_eq( + encounter.takenBy, + $elm$core$Maybe$Just(takenBy)); + }, + mTakenBy)); + return (!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), + $elm$core$Basics$LT)) && ((!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, limitDate), + $elm$core$Basics$GT)) && takenByCondition); + }, + reportData)); + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report nutrition-individual') + ]), + $author$project$Pages$Components$View$viewNutritionMetricsResultsTable(filteredData)); + }); +var $author$project$Translate$NutritionIndividual = {$: 'NutritionIndividual'}; +var $author$project$Pages$Completion$View$generateNutritionIndividualReportData = F2( + function (language, records) { + var count = F2( + function (resolveFunc, activity) { + return $elm$core$List$length( + A2( + $elm$core$List$filter, + A2( + $elm$core$Basics$composeR, + resolveFunc, + $elm$core$List$member(activity)), + records)); + }); + var calcualtePercentage = F2( + function (nominator, total) { + return (!total) ? '0' : (A2($myrho$elm_round$Round$round, 3, (nominator / total) * 100) + '%'); + }); + return { + captions: _List_fromArray( + [ + A2($author$project$Translate$translate, language, $author$project$Translate$Activity), + A2($author$project$Translate$translate, language, $author$project$Translate$Expected), + A2($author$project$Translate$translate, language, $author$project$Translate$Completed), + '%' + ]), + heading: A2($author$project$Translate$translate, language, $author$project$Translate$NutritionIndividual), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A2( + count, + function ($) { + return $.expectedActivities; + }, + activity); + var completed = A2( + count, + function ($) { + return $.completedActivities; + }, + activity); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$NutritionChildActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2(calcualtePercentage, completed, expected) + ]); + }, + $author$project$Pages$Completion$Model$allNutritionIndividualActivities) + }; + }); var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F5( function (language, startDate, limitDate, mTakenBy, reportData) { var filteredData = A2( - $author$project$Pages$Completion$View$generateNutritionReportData, + $author$project$Pages$Completion$View$generateNutritionIndividualReportData, language, A2( $elm$core$List$filter, @@ -12861,8 +13002,8 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( function (language, currentDate, themePath, data, model) { var topBar = function () { var scopeLabel = function () { - var _v2 = data.entityType; - if (_v2.$ === 'EntityGlobal') { + var _v1 = data.entityType; + if (_v1.$ === 'EntityGlobal') { return A2($author$project$Translate$translate, language, $author$project$Translate$Global); } else { return data.entityName; @@ -13027,12 +13168,15 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( $elm$core$Maybe$map3, F3( function (reportType, startDate, limitDate) { - return A5($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, model.takenBy, data.nutritionIndividualData); + if (reportType.$ === 'ReportNutritionIndividual') { + return A5($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, model.takenBy, data.nutritionIndividualData); + } else { + return A5($author$project$Pages$Completion$View$viewNutritionGroupReport, language, startDate, limitDate, model.takenBy, data.nutritionGroupData); + } }), model.reportType, model.startDate, model.limitDate)); - var _v0 = A2($elm$core$Debug$log, '', data.nutritionGropData); return A2( $elm$html$Html$div, _List_fromArray( @@ -13061,7 +13205,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( language, model.reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportNutritionIndividual]), + [$author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportNutritionGroup]), $author$project$Pages$Completion$Utils$reportTypeToString, $author$project$Pages$Completion$Model$SetReportType, $author$project$Translate$CompletionReportType, From e2660a07c1d3ee0f5f5f5f781edb7a5ab0252282 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 18 Aug 2024 21:44:15 +0300 Subject: [PATCH 025/185] A fix [ci skip] --- .../hedley_reports/hedley_reports.module | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 768b1cdc73..af23fffbf0 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2196,7 +2196,7 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ $mapping_mother = [ 'family_planning' => 'a', 'mother_fbf' => 'b', - 'lactation' =>'c', + 'lactation' => 'c', ]; // Attendance points to mother. We need to resolve the child (or children) @@ -2216,17 +2216,20 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ ->addTag('exclude_deleted') ->execute(); - $session_participants_ids = [$adult_id]; - $participants_ids = array_keys($result['node']); - $participants = node_load_multiple($participants_ids); // Flag that signals that adult is mother to a child (or children), // and therefore, we expect to find mother activities. $is_mother = FALSE; - foreach ($participants as $participant) { - $session_participants_ids[] = $participant->field_person[LANGUAGE_NONE][0]['target_id']; - // It's enough to determine that we found mother for one of the children. - if (!$is_mother) { - $is_mother = $participant->field_adult_activities[LANGUAGE_NONE][0]['value'] == 'mother'; + $session_participants_ids = [$adult_id]; + + if (!empty($result['node'])) { + $participants_ids = array_keys($result['node']); + $participants = node_load_multiple($participants_ids); + foreach ($participants as $participant) { + $session_participants_ids[] = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + // It's enough to determine that we found mother for one of the children. + if (!$is_mother) { + $is_mother = $participant->field_adult_activities[LANGUAGE_NONE][0]['value'] == 'mother'; + } } } From da6f2c6c3c2c813f1b6c8133da898d93830f1ce0 Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 19 Aug 2024 10:28:10 +0300 Subject: [PATCH 026/185] Store large sets data as content [ci skip] --- .../hedley_reports.features.field_base.inc | 1 + .../hedley_reports/hedley_reports.module | 2 +- .../recalculate-completion-large-datasets.php | 61 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 server/hedley/modules/custom/hedley_reports/scripts/recalculate-completion-large-datasets.php diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.features.field_base.inc b/server/hedley/modules/custom/hedley_reports/hedley_reports.features.field_base.inc index b22b4d65c5..5b369da4d1 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.features.field_base.inc +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.features.field_base.inc @@ -82,6 +82,7 @@ function hedley_reports_field_default_field_bases() { 'allowed_values' => array( 'aggregated-ncda' => 'Aggregated NCDA', 'statistical-query' => 'Statistical Query', + 'completion' => 'Completion', ), 'allowed_values_function' => '', ), diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 768b1cdc73..278752b57f 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -1961,7 +1961,7 @@ function hedley_reports_build_completion_results_app($health_center = NULL) { $data['site'] = variable_get('hedley_general_site_name', ''); - $data['results'] = hedley_reports_generate_completion_results_data($health_center); + list($data['results'], $data['additional']) = hedley_reports_load_results_data('completion', $data['entity_type'], NULL, NULL, $health_center); return hedley_general_build_elm_app('completion-results', $data); } diff --git a/server/hedley/modules/custom/hedley_reports/scripts/recalculate-completion-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/recalculate-completion-large-datasets.php new file mode 100644 index 0000000000..0ae954e7ce --- /dev/null +++ b/server/hedley/modules/custom/hedley_reports/scripts/recalculate-completion-large-datasets.php @@ -0,0 +1,61 @@ + Date: Mon, 19 Aug 2024 16:20:35 +0300 Subject: [PATCH 027/185] Try to reduce memory usage [ci skip] --- .../hedley_reports/hedley_reports.module | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 8bbb7edbb0..8528f4d680 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2084,13 +2084,12 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun $measurements_ids = $query->execute()->fetchCol(); if (empty($measurements_ids)) { - list($expected_activities, $completed_activities) = hedley_reports_generate_completion_result($expected, $completed, $mapping); + $completion = hedley_reports_generate_completion_result($expected, $completed, $mapping); return [ 'start_date' => $start_date, - 'expected' => $expected_activities, - 'completed' => $completed_activities, 'taken_by' => $taken_by, + 'completion' => $completion, ]; } @@ -2167,13 +2166,12 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun } } - list($expected_activities, $completed_activities) = hedley_reports_generate_completion_result($expected, $completed, $mapping); + $completion = hedley_reports_generate_completion_result($expected, $completed, $mapping); return [ 'start_date' => $start_date, - 'expected' => $expected_activities, - 'completed' => $completed_activities, 'taken_by' => $taken_by, + 'completion' => $completion, ]; } @@ -2233,8 +2231,9 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ } } - // Resolve session start date. - $start_date = explode(' ', $session->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + // Resolve encounter start date. We gp by the date of attendance + // measurement, since session may have lasted several days. + $start_date = explode(' ', $attendance->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; $start_date_obj = new DateTime($start_date); // Resolve data of clinic. $clinic = node_load($clinic_id); @@ -2315,12 +2314,7 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ } } - list($expected_activities, $completed_activities) = hedley_reports_generate_completion_result($expected, $completed, $mapping_mother); - - $return['mother'] = [ - 'expected' => $expected_activities, - 'completed' => $completed_activities, - ]; + $return['mother'] = hedley_reports_generate_completion_result($expected, $completed, $mapping_mother); } } // Handling child. @@ -2403,15 +2397,12 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ } } - list($expected_activities, $completed_activities) = hedley_reports_generate_completion_result($expected, $completed, $mapping_child); - - $return['children'][] = [ - 'expected' => $expected_activities, - 'completed' => $completed_activities, - ]; + $return['children'][] = hedley_reports_generate_completion_result($expected, $completed, $mapping_child); } } + $return['children'] = implode('$', $return['children']); + return $return; } @@ -2424,5 +2415,5 @@ function hedley_reports_generate_completion_result($expected, $completed, $mappi $completed[$index] = $mapping[$measurement_type]; } - return [implode(',', $expected), implode(',', $completed)]; + return implode(',', $expected) . '|' . implode(',', $completed); } From 0303ede114d9a32e6cb7795fe01d9c01f89628e1 Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 19 Aug 2024 16:21:25 +0300 Subject: [PATCH 028/185] Addapt client side [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 85 +++-- server/elm/src/Backend/Completion/Model.elm | 5 +- server/elm/src/Pages/Completion/View.elm | 4 +- .../custom/hedley_general/js/elm-main.js | 295 ++++++++++-------- 4 files changed, 222 insertions(+), 167 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index 56e0b625e4..130821a9a4 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -19,9 +19,9 @@ decodeCompletionData = |> required "site" decodeSite |> required "entity_name" string |> required "entity_type" decodeSelectedEntity - |> requiredAt [ "results", "nutrition_individual" ] (list (decodeEncounterData decodeNutritionChildActivities)) + |> requiredAt [ "results", "nutrition_individual" ] (list (decodeEncounterData nutritionChildActivityFromMapping)) |> requiredAt [ "results", "nutrition_group" ] - (list (decodeNutritionGroupEncounterData decodeNutritionMotherActivities decodeNutritionChildActivities)) + (list (decodeNutritionGroupEncounterData nutritionMotherActivityFromMapping nutritionChildActivityFromMapping)) decodeSelectedEntity : Decoder SelectedEntity @@ -41,56 +41,75 @@ decodeSelectedEntity = ) -decodeEncounterData : Decoder (List activity) -> Decoder (EncounterData activity) -decodeEncounterData activitiesDecoder = +decodeEncounterData : (String -> Maybe activity) -> Decoder (EncounterData activity) +decodeEncounterData activityFromString = succeed EncounterData |> required "start_date" decodeYYYYMMDD - |> required "expected" activitiesDecoder - |> required "completed" activitiesDecoder |> required "taken_by" (nullable (decodeWithFallback TakenByUnknown decodeTakenBy)) - - -decodeNutritionChildActivities : Decoder (List NutritionChildActivity) -decodeNutritionChildActivities = - string - |> andThen - (String.split "," - >> List.map nutritionChildActivityFromMapping - >> Maybe.Extra.values - >> succeed - ) + |> required "completion" (decodeActivitiesCompletionData activityFromString) decodeNutritionGroupEncounterData : - Decoder (List motherActivity) - -> Decoder (List childActivity) + (String -> Maybe motherActivity) + -> (String -> Maybe childActivity) -> Decoder (NutritionGroupEncounterData motherActivity childActivity) -decodeNutritionGroupEncounterData motherActivitiesDecoder childActivitiesDecoder = +decodeNutritionGroupEncounterData motherActivityFromString childActivityFromString = succeed NutritionGroupEncounterData |> required "start_date" decodeYYYYMMDD - |> optional "mother" (nullable (decodeActivitiesCompletionData motherActivitiesDecoder)) Nothing - |> required "children" (list (decodeActivitiesCompletionData childActivitiesDecoder)) |> required "taken_by" (nullable (decodeWithFallback TakenByUnknown decodeTakenBy)) + |> optional "mother" (nullable (decodeActivitiesCompletionData motherActivityFromString)) Nothing + |> required "children" (decodeActivitiesCompletionDataList childActivityFromString) -decodeActivitiesCompletionData : Decoder (List activity) -> Decoder (ActivitiesCompletionData activity) -decodeActivitiesCompletionData activitiesDecoder = - succeed ActivitiesCompletionData - |> required "expected" activitiesDecoder - |> required "completed" activitiesDecoder +decodeActivitiesCompletionData : (String -> Maybe activity) -> Decoder (ActivitiesCompletionData activity) +decodeActivitiesCompletionData activityFromString = + string + |> andThen + (\s -> + activitiesCompletionDataFromString activityFromString s + |> Maybe.map succeed + |> Maybe.withDefault (fail <| s ++ " is unknown ActivitiesCompletionData type") + ) -decodeNutritionMotherActivities : Decoder (List NutritionMotherActivity) -decodeNutritionMotherActivities = +decodeActivitiesCompletionDataList : (String -> Maybe activity) -> Decoder (List (ActivitiesCompletionData activity)) +decodeActivitiesCompletionDataList activityFromString = string |> andThen - (String.split "," - >> List.map nutritionMotherActivityFromMapping - >> Maybe.Extra.values - >> succeed + (\s -> + String.split "$" s + |> List.filterMap (activitiesCompletionDataFromString activityFromString) + |> succeed ) +activitiesCompletionDataFromString : (String -> Maybe activity) -> String -> Maybe (ActivitiesCompletionData activity) +activitiesCompletionDataFromString activityFromString s = + let + splitActivities = + String.split "," >> List.filterMap activityFromString + in + case String.split "|" (String.trim s) of + [ expected, completed ] -> + ActivitiesCompletionData + (splitActivities expected) + (splitActivities completed) + |> Just + + [ expected ] -> + ActivitiesCompletionData + (splitActivities expected) + [] + |> Just + + [] -> + ActivitiesCompletionData [] [] + |> Just + + _ -> + Nothing + + decodeTakenBy : Decoder TakenBy decodeTakenBy = string diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index c6b7fd1219..ef537a9df3 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -23,17 +23,16 @@ type SelectedEntity type alias EncounterData activity = { startDate : NominalDate - , expectedActivities : List activity - , completedActivities : List activity , takenBy : Maybe TakenBy + , completion : ActivitiesCompletionData activity } type alias NutritionGroupEncounterData motherActivity childActivity = { startDate : NominalDate + , takenBy : Maybe TakenBy , motherData : Maybe (ActivitiesCompletionData motherActivity) , childrenData : List (ActivitiesCompletionData childActivity) - , takenBy : Maybe TakenBy } diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index 4d15485c9a..db9c584183 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -255,10 +255,10 @@ generateNutritionIndividualReportData language records = (\activity -> let expected = - count .expectedActivities activity + count (.completion >> .expectedActivities) activity completed = - count .completedActivities activity + count (.completion >> .completedActivities) activity in [ translate language <| Translate.NutritionChildActivity activity , String.fromInt expected diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index eb5fd4b8b4..c0b8c27f6a 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -6843,12 +6843,68 @@ var $author$project$Backend$Completion$Model$CompletionData = F5( function (site, entityName, entityType, nutritionIndividualData, nutritionGroupData) { return {entityName: entityName, entityType: entityType, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site}; }); -var $author$project$Backend$Completion$Model$EncounterData = F4( - function (startDate, expectedActivities, completedActivities, takenBy) { - return {completedActivities: completedActivities, expectedActivities: expectedActivities, startDate: startDate, takenBy: takenBy}; +var $author$project$Backend$Completion$Model$EncounterData = F3( + function (startDate, takenBy, completion) { + return {completion: completion, startDate: startDate, takenBy: takenBy}; + }); +var $author$project$Backend$Completion$Model$ActivitiesCompletionData = F2( + function (expectedActivities, completedActivities) { + return {completedActivities: completedActivities, expectedActivities: expectedActivities}; + }); +var $elm$core$String$trim = _String_trim; +var $author$project$Backend$Completion$Decoder$activitiesCompletionDataFromString = F2( + function (activityFromString, s) { + var splitActivities = A2( + $elm$core$Basics$composeR, + $elm$core$String$split(','), + $elm$core$List$filterMap(activityFromString)); + var _v0 = A2( + $elm$core$String$split, + '|', + $elm$core$String$trim(s)); + if (_v0.b) { + if (_v0.b.b) { + if (!_v0.b.b.b) { + var expected = _v0.a; + var _v1 = _v0.b; + var completed = _v1.a; + return $elm$core$Maybe$Just( + A2( + $author$project$Backend$Completion$Model$ActivitiesCompletionData, + splitActivities(expected), + splitActivities(completed))); + } else { + return $elm$core$Maybe$Nothing; + } + } else { + var expected = _v0.a; + return $elm$core$Maybe$Just( + A2( + $author$project$Backend$Completion$Model$ActivitiesCompletionData, + splitActivities(expected), + _List_Nil)); + } + } else { + return $elm$core$Maybe$Just( + A2($author$project$Backend$Completion$Model$ActivitiesCompletionData, _List_Nil, _List_Nil)); + } }); var $elm$json$Json$Decode$fail = _Json_fail; var $elm$json$Json$Decode$string = _Json_decodeString; +var $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData = function (activityFromString) { + return A2( + $elm$json$Json$Decode$andThen, + function (s) { + return A2( + $elm$core$Maybe$withDefault, + $elm$json$Json$Decode$fail(s + ' is unknown ActivitiesCompletionData type'), + A2( + $elm$core$Maybe$map, + $elm$json$Json$Decode$succeed, + A2($author$project$Backend$Completion$Decoder$activitiesCompletionDataFromString, activityFromString, s))); + }, + $elm$json$Json$Decode$string); +}; var $author$project$Backend$Completion$Decoder$decodeTakenBy = A2( $elm$json$Json$Decode$andThen, function (takenBy) { @@ -7647,95 +7703,38 @@ var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required = F3( A2($elm$json$Json$Decode$field, key, valDecoder), decoder); }); -var $author$project$Backend$Completion$Decoder$decodeEncounterData = function (activitiesDecoder) { +var $author$project$Backend$Completion$Decoder$decodeEncounterData = function (activityFromString) { return A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'taken_by', - $elm$json$Json$Decode$nullable( - A2($author$project$Backend$Decoder$decodeWithFallback, $author$project$Backend$Completion$Model$TakenByUnknown, $author$project$Backend$Completion$Decoder$decodeTakenBy)), + 'completion', + $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData(activityFromString), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'completed', - activitiesDecoder, + 'taken_by', + $elm$json$Json$Decode$nullable( + A2($author$project$Backend$Decoder$decodeWithFallback, $author$project$Backend$Completion$Model$TakenByUnknown, $author$project$Backend$Completion$Decoder$decodeTakenBy)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'expected', - activitiesDecoder, - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'start_date', - $author$project$Gizra$NominalDate$decodeYYYYMMDD, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EncounterData))))); -}; -var $author$project$Backend$Completion$Model$NutritionChildFbf = {$: 'NutritionChildFbf'}; -var $author$project$Backend$Completion$Model$NutritionContributingFactors = {$: 'NutritionContributingFactors'}; -var $author$project$Backend$Completion$Model$NutritionFollowUp = {$: 'NutritionFollowUp'}; -var $author$project$Backend$Completion$Model$NutritionHealthEducation = {$: 'NutritionHealthEducation'}; -var $author$project$Backend$Completion$Model$NutritionHeight = {$: 'NutritionHeight'}; -var $author$project$Backend$Completion$Model$NutritionMUAC = {$: 'NutritionMUAC'}; -var $author$project$Backend$Completion$Model$NutritionNCDA = {$: 'NutritionNCDA'}; -var $author$project$Backend$Completion$Model$NutritionNutrition = {$: 'NutritionNutrition'}; -var $author$project$Backend$Completion$Model$NutritionPhoto = {$: 'NutritionPhoto'}; -var $author$project$Backend$Completion$Model$NutritionSendToHC = {$: 'NutritionSendToHC'}; -var $author$project$Backend$Completion$Model$NutritionWeight = {$: 'NutritionWeight'}; -var $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping = function (mapped) { - switch (mapped) { - case 'a': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHeight); - case 'b': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionNutrition); - case 'c': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionPhoto); - case 'd': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionWeight); - case 'e': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionMUAC); - case 'f': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionContributingFactors); - case 'g': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionFollowUp); - case 'h': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHealthEducation); - case 'i': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionSendToHC); - case 'j': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionNCDA); - case 'k': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionChildFbf); - default: - return $elm$core$Maybe$Nothing; - } + 'start_date', + $author$project$Gizra$NominalDate$decodeYYYYMMDD, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EncounterData)))); }; -var $author$project$Backend$Completion$Decoder$decodeNutritionChildActivities = A2( - $elm$json$Json$Decode$andThen, - A2( - $elm$core$Basics$composeR, - $elm$core$String$split(','), - A2( - $elm$core$Basics$composeR, - $elm$core$List$map($author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping), - A2($elm$core$Basics$composeR, $elm_community$maybe_extra$Maybe$Extra$values, $elm$json$Json$Decode$succeed))), - $elm$json$Json$Decode$string); var $author$project$Backend$Completion$Model$NutritionGroupEncounterData = F4( - function (startDate, motherData, childrenData, takenBy) { + function (startDate, takenBy, motherData, childrenData) { return {childrenData: childrenData, motherData: motherData, startDate: startDate, takenBy: takenBy}; }); -var $author$project$Backend$Completion$Model$ActivitiesCompletionData = F2( - function (expectedActivities, completedActivities) { - return {completedActivities: completedActivities, expectedActivities: expectedActivities}; - }); -var $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData = function (activitiesDecoder) { - return A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'completed', - activitiesDecoder, - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'expected', - activitiesDecoder, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$ActivitiesCompletionData))); +var $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionDataList = function (activityFromString) { + return A2( + $elm$json$Json$Decode$andThen, + function (s) { + return $elm$json$Json$Decode$succeed( + A2( + $elm$core$List$filterMap, + $author$project$Backend$Completion$Decoder$activitiesCompletionDataFromString(activityFromString), + A2($elm$core$String$split, '$', s))); + }, + $elm$json$Json$Decode$string); }; -var $elm$json$Json$Decode$list = _Json_decodeList; var $elm$json$Json$Decode$decodeValue = _Json_run; var $elm$json$Json$Decode$value = _Json_decodeValue; var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalDecoder = F3( @@ -7782,54 +7781,28 @@ var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optional = F4( decoder); }); var $author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData = F2( - function (motherActivitiesDecoder, childActivitiesDecoder) { + function (motherActivityFromString, childActivityFromString) { return A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'taken_by', - $elm$json$Json$Decode$nullable( - A2($author$project$Backend$Decoder$decodeWithFallback, $author$project$Backend$Completion$Model$TakenByUnknown, $author$project$Backend$Completion$Decoder$decodeTakenBy)), - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'children', - $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData(childActivitiesDecoder)), - A4( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optional, - 'mother', + 'children', + $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionDataList(childActivityFromString), + A4( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optional, + 'mother', + $elm$json$Json$Decode$nullable( + $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData(motherActivityFromString)), + $elm$core$Maybe$Nothing, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'taken_by', $elm$json$Json$Decode$nullable( - $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData(motherActivitiesDecoder)), - $elm$core$Maybe$Nothing, + A2($author$project$Backend$Decoder$decodeWithFallback, $author$project$Backend$Completion$Model$TakenByUnknown, $author$project$Backend$Completion$Decoder$decodeTakenBy)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, 'start_date', $author$project$Gizra$NominalDate$decodeYYYYMMDD, $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$NutritionGroupEncounterData))))); }); -var $author$project$Backend$Completion$Model$NutritionFamilyPlanning = {$: 'NutritionFamilyPlanning'}; -var $author$project$Backend$Completion$Model$NutritionLactation = {$: 'NutritionLactation'}; -var $author$project$Backend$Completion$Model$NutritionMotherFbf = {$: 'NutritionMotherFbf'}; -var $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping = function (mapped) { - switch (mapped) { - case 'a': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionFamilyPlanning); - case 'b': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionMotherFbf); - case 'c': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionLactation); - default: - return $elm$core$Maybe$Nothing; - } -}; -var $author$project$Backend$Completion$Decoder$decodeNutritionMotherActivities = A2( - $elm$json$Json$Decode$andThen, - A2( - $elm$core$Basics$composeR, - $elm$core$String$split(','), - A2( - $elm$core$Basics$composeR, - $elm$core$List$map($author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping), - A2($elm$core$Basics$composeR, $elm_community$maybe_extra$Maybe$Extra$values, $elm$json$Json$Decode$succeed))), - $elm$json$Json$Decode$string); var $author$project$Backend$Completion$Model$EntityGlobal = {$: 'EntityGlobal'}; var $author$project$Backend$Completion$Model$EntityHealthCenter = {$: 'EntityHealthCenter'}; var $author$project$Backend$Completion$Decoder$decodeSelectedEntity = A2( @@ -7864,6 +7837,61 @@ var $author$project$Backend$Decoder$decodeSite = A2( $elm$json$Json$Decode$andThen, A2($elm$core$Basics$composeR, $author$project$Backend$Decoder$siteFromString, $elm$json$Json$Decode$succeed), $elm$json$Json$Decode$string); +var $elm$json$Json$Decode$list = _Json_decodeList; +var $author$project$Backend$Completion$Model$NutritionChildFbf = {$: 'NutritionChildFbf'}; +var $author$project$Backend$Completion$Model$NutritionContributingFactors = {$: 'NutritionContributingFactors'}; +var $author$project$Backend$Completion$Model$NutritionFollowUp = {$: 'NutritionFollowUp'}; +var $author$project$Backend$Completion$Model$NutritionHealthEducation = {$: 'NutritionHealthEducation'}; +var $author$project$Backend$Completion$Model$NutritionHeight = {$: 'NutritionHeight'}; +var $author$project$Backend$Completion$Model$NutritionMUAC = {$: 'NutritionMUAC'}; +var $author$project$Backend$Completion$Model$NutritionNCDA = {$: 'NutritionNCDA'}; +var $author$project$Backend$Completion$Model$NutritionNutrition = {$: 'NutritionNutrition'}; +var $author$project$Backend$Completion$Model$NutritionPhoto = {$: 'NutritionPhoto'}; +var $author$project$Backend$Completion$Model$NutritionSendToHC = {$: 'NutritionSendToHC'}; +var $author$project$Backend$Completion$Model$NutritionWeight = {$: 'NutritionWeight'}; +var $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHeight); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionNutrition); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionPhoto); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionWeight); + case 'e': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionMUAC); + case 'f': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionContributingFactors); + case 'g': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionFollowUp); + case 'h': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHealthEducation); + case 'i': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionSendToHC); + case 'j': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionNCDA); + case 'k': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionChildFbf); + default: + return $elm$core$Maybe$Nothing; + } +}; +var $author$project$Backend$Completion$Model$NutritionFamilyPlanning = {$: 'NutritionFamilyPlanning'}; +var $author$project$Backend$Completion$Model$NutritionLactation = {$: 'NutritionLactation'}; +var $author$project$Backend$Completion$Model$NutritionMotherFbf = {$: 'NutritionMotherFbf'}; +var $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionFamilyPlanning); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionMotherFbf); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionLactation); + default: + return $elm$core$Maybe$Nothing; + } +}; var $elm$json$Json$Decode$at = F2( function (fields, decoder) { return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields); @@ -7880,13 +7908,13 @@ var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( _List_fromArray( ['results', 'nutrition_group']), $elm$json$Json$Decode$list( - A2($author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData, $author$project$Backend$Completion$Decoder$decodeNutritionMotherActivities, $author$project$Backend$Completion$Decoder$decodeNutritionChildActivities)), + A2($author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData, $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping, $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( ['results', 'nutrition_individual']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Decoder$decodeNutritionChildActivities)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, 'entity_type', @@ -8156,7 +8184,6 @@ var $elm$core$Result$toMaybe = function (result) { return $elm$core$Maybe$Nothing; } }; -var $elm$core$String$trim = _String_trim; var $author$project$Backend$Reports$Decoder$decodeAcuteIllnessEncounterData = A2( $elm$json$Json$Decode$andThen, function (s) { @@ -12878,15 +12905,25 @@ var $author$project$Pages$Completion$View$generateNutritionIndividualReportData function (activity) { var expected = A2( count, - function ($) { - return $.expectedActivities; - }, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.expectedActivities; + }), activity); var completed = A2( count, - function ($) { - return $.completedActivities; - }, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.completedActivities; + }), activity); return _List_fromArray( [ From 809fa35344f30e32f377242ffc8be8355f387d78 Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 19 Aug 2024 17:00:01 +0300 Subject: [PATCH 029/185] Improve code [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 17 +- server/elm/src/Pages/Completion/View.elm | 164 ++++++------- .../custom/hedley_general/js/elm-main.js | 219 ++++++++---------- 3 files changed, 176 insertions(+), 224 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index 130821a9a4..3e2d588435 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -74,13 +74,16 @@ decodeActivitiesCompletionData activityFromString = decodeActivitiesCompletionDataList : (String -> Maybe activity) -> Decoder (List (ActivitiesCompletionData activity)) decodeActivitiesCompletionDataList activityFromString = - string - |> andThen - (\s -> - String.split "$" s - |> List.filterMap (activitiesCompletionDataFromString activityFromString) - |> succeed - ) + oneOf + [ string + |> andThen + (\s -> + String.split "$" s + |> List.filterMap (activitiesCompletionDataFromString activityFromString) + |> succeed + ) + , succeed [] + ] activitiesCompletionDataFromString : (String -> Maybe activity) -> String -> Maybe (ActivitiesCompletionData activity) diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index db9c584183..97ce007a4f 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -202,28 +202,48 @@ viewCompletionData language currentDate themePath data model = viewNutritionIndividualReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData NutritionChildActivity) -> Html Msg viewNutritionIndividualReport language startDate limitDate mTakenBy reportData = - let - filteredData = - List.filter - (\encounter -> - let - takenByCondition = - Maybe.map - (\takenBy -> - encounter.takenBy == Just takenBy - ) - mTakenBy - |> Maybe.withDefault True - in - (not <| Date.compare encounter.startDate startDate == LT) - && (not <| Date.compare encounter.startDate limitDate == GT) - && takenByCondition - ) - reportData - |> generateNutritionIndividualReportData language - in - div [ class "report nutrition-individual" ] <| - viewNutritionMetricsResultsTable filteredData + applyFilters startDate limitDate mTakenBy reportData + |> generateNutritionIndividualReportData language + |> viewNutritionMetricsResultsTable + |> div [ class "report nutrition-individual" ] + + +viewNutritionGroupReport : + Language + -> NominalDate + -> NominalDate + -> Maybe TakenBy + -> List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) + -> Html Msg +viewNutritionGroupReport language startDate limitDate mTakenBy reportData = + applyFilters startDate limitDate mTakenBy reportData + |> generateNutritionGroupReportData language + |> viewNutritionMetricsResultsTable + |> div [ class "report nutrition-individual" ] + + +applyFilters : + NominalDate + -> NominalDate + -> Maybe TakenBy + -> List { a | startDate : Date.Date, takenBy : Maybe TakenBy } + -> List { a | startDate : Date.Date, takenBy : Maybe TakenBy } +applyFilters startDate limitDate mTakenBy = + List.filter + (\encounter -> + let + takenByCondition = + Maybe.map + (\takenBy -> + encounter.takenBy == Just takenBy + ) + mTakenBy + |> Maybe.withDefault True + in + (not <| Date.compare encounter.startDate startDate == LT) + && (not <| Date.compare encounter.startDate limitDate == GT) + && takenByCondition + ) generateNutritionIndividualReportData : @@ -231,34 +251,17 @@ generateNutritionIndividualReportData : -> List (EncounterData NutritionChildActivity) -> MetricsResultsTableData generateNutritionIndividualReportData language records = - let - count resolveFunc activity = - List.filter (resolveFunc >> List.member activity) records - |> List.length - - calcualtePercentage nominator total = - if total == 0 then - "0" - - else - Round.round 3 ((toFloat nominator / toFloat total) * 100) ++ "%" - in { heading = translate language Translate.NutritionIndividual - , captions = - [ translate language Translate.Activity - , translate language Translate.Expected - , translate language Translate.Completed - , "%" - ] + , captions = generateCaptionsList language , rows = List.map (\activity -> let expected = - count (.completion >> .expectedActivities) activity + countOccurrences (.completion >> .expectedActivities) activity records completed = - count (.completion >> .completedActivities) activity + countOccurrences (.completion >> .completedActivities) activity records in [ translate language <| Translate.NutritionChildActivity activity , String.fromInt expected @@ -270,55 +273,12 @@ generateNutritionIndividualReportData language records = } -viewNutritionGroupReport : - Language - -> NominalDate - -> NominalDate - -> Maybe TakenBy - -> List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) - -> Html Msg -viewNutritionGroupReport language startDate limitDate mTakenBy reportData = - let - filteredData = - List.filter - (\encounter -> - let - takenByCondition = - Maybe.map - (\takenBy -> - encounter.takenBy == Just takenBy - ) - mTakenBy - |> Maybe.withDefault True - in - (not <| Date.compare encounter.startDate startDate == LT) - && (not <| Date.compare encounter.startDate limitDate == GT) - && takenByCondition - ) - reportData - |> generateNutritionGroupReportData language - in - div [ class "report nutrition-individual" ] <| - viewNutritionMetricsResultsTable filteredData - - generateNutritionGroupReportData : Language -> List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) -> MetricsResultsTableData generateNutritionGroupReportData language records = let - count resolveFunc activity data = - List.filter (resolveFunc >> List.member activity) data - |> List.length - - calcualtePercentage nominator total = - if total == 0 then - "0" - - else - Round.round 3 ((toFloat nominator / toFloat total) * 100) ++ "%" - motherData = List.filterMap .motherData records @@ -331,10 +291,10 @@ generateNutritionGroupReportData language records = (\activity -> let expected = - count .expectedActivities activity data + countOccurrences .expectedActivities activity data completed = - count .completedActivities activity data + countOccurrences .completedActivities activity data in [ translate language <| activityTransId activity , String.fromInt expected @@ -350,11 +310,29 @@ generateNutritionGroupReportData language records = generateActivityRows Translate.NutritionChildActivity childrenData allNutritionChildGroupActivities in { heading = translate language Translate.NutritionGroup - , captions = - [ translate language Translate.Activity - , translate language Translate.Expected - , translate language Translate.Completed - , "%" - ] + , captions = generateCaptionsList language , rows = motherActivityRows ++ childrenActivityRows } + + +generateCaptionsList : Language -> List String +generateCaptionsList language = + [ translate language Translate.Activity + , translate language Translate.Expected + , translate language Translate.Completed + , "%" + ] + + +countOccurrences resolveFunc activity data = + List.filter (resolveFunc >> List.member activity) data + |> List.length + + +calcualtePercentage : Int -> Int -> String +calcualtePercentage nominator total = + if total == 0 then + "0" + + else + Round.round 2 ((toFloat nominator / toFloat total) * 100) ++ "%" diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index c0b8c27f6a..dda0a4e407 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -7724,16 +7724,21 @@ var $author$project$Backend$Completion$Model$NutritionGroupEncounterData = F4( return {childrenData: childrenData, motherData: motherData, startDate: startDate, takenBy: takenBy}; }); var $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionDataList = function (activityFromString) { - return A2( - $elm$json$Json$Decode$andThen, - function (s) { - return $elm$json$Json$Decode$succeed( + return $elm$json$Json$Decode$oneOf( + _List_fromArray( + [ A2( - $elm$core$List$filterMap, - $author$project$Backend$Completion$Decoder$activitiesCompletionDataFromString(activityFromString), - A2($elm$core$String$split, '$', s))); - }, - $elm$json$Json$Decode$string); + $elm$json$Json$Decode$andThen, + function (s) { + return $elm$json$Json$Decode$succeed( + A2( + $elm$core$List$filterMap, + $author$project$Backend$Completion$Decoder$activitiesCompletionDataFromString(activityFromString), + A2($elm$core$String$split, '$', s))); + }, + $elm$json$Json$Decode$string), + $elm$json$Json$Decode$succeed(_List_Nil) + ])); }; var $elm$json$Json$Decode$decodeValue = _Json_run; var $elm$json$Json$Decode$value = _Json_decodeValue; @@ -12460,9 +12465,28 @@ var $author$project$Utils$Html$viewCustomModal = function (extraClasses) { })); }; var $author$project$Utils$Html$viewModal = $author$project$Utils$Html$viewCustomModal(_List_Nil); -var $author$project$Translate$Activity = {$: 'Activity'}; -var $author$project$Translate$Completed = {$: 'Completed'}; -var $author$project$Translate$Expected = {$: 'Expected'}; +var $author$project$Pages$Completion$View$applyFilters = F3( + function (startDate, limitDate, mTakenBy) { + return $elm$core$List$filter( + function (encounter) { + var takenByCondition = A2( + $elm$core$Maybe$withDefault, + true, + A2( + $elm$core$Maybe$map, + function (takenBy) { + return _Utils_eq( + encounter.takenBy, + $elm$core$Maybe$Just(takenBy)); + }, + mTakenBy)); + return (!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), + $elm$core$Basics$LT)) && ((!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, limitDate), + $elm$core$Basics$GT)) && takenByCondition); + }); + }); var $author$project$Translate$NutritionChildActivity = function (a) { return {$: 'NutritionChildActivity', a: a}; }; @@ -12691,6 +12715,33 @@ var $myrho$elm_round$Round$round = $myrho$elm_round$Round$roundFun( } } })); +var $author$project$Pages$Completion$View$calcualtePercentage = F2( + function (nominator, total) { + return (!total) ? '0' : (A2($myrho$elm_round$Round$round, 2, (nominator / total) * 100) + '%'); + }); +var $author$project$Pages$Completion$View$countOccurrences = F3( + function (resolveFunc, activity, data) { + return $elm$core$List$length( + A2( + $elm$core$List$filter, + A2( + $elm$core$Basics$composeR, + resolveFunc, + $elm$core$List$member(activity)), + data)); + }); +var $author$project$Translate$Activity = {$: 'Activity'}; +var $author$project$Translate$Completed = {$: 'Completed'}; +var $author$project$Translate$Expected = {$: 'Expected'}; +var $author$project$Pages$Completion$View$generateCaptionsList = function (language) { + return _List_fromArray( + [ + A2($author$project$Translate$translate, language, $author$project$Translate$Activity), + A2($author$project$Translate$translate, language, $author$project$Translate$Expected), + A2($author$project$Translate$translate, language, $author$project$Translate$Completed), + '%' + ]); +}; var $author$project$Pages$Completion$View$generateNutritionGroupReportData = F2( function (language, records) { var motherData = A2( @@ -12699,41 +12750,19 @@ var $author$project$Pages$Completion$View$generateNutritionGroupReportData = F2( return $.motherData; }, records); - var count = F3( - function (resolveFunc, activity, data) { - return $elm$core$List$length( - A2( - $elm$core$List$filter, - A2( - $elm$core$Basics$composeR, - resolveFunc, - $elm$core$List$member(activity)), - data)); - }); - var childrenData = $elm$core$List$concat( - A2( - $elm$core$List$map, - function ($) { - return $.childrenData; - }, - records)); - var calcualtePercentage = F2( - function (nominator, total) { - return (!total) ? '0' : (A2($myrho$elm_round$Round$round, 3, (nominator / total) * 100) + '%'); - }); var generateActivityRows = F2( function (activityTransId, data) { return $elm$core$List$map( function (activity) { var expected = A3( - count, + $author$project$Pages$Completion$View$countOccurrences, function ($) { return $.expectedActivities; }, activity, data); var completed = A3( - count, + $author$project$Pages$Completion$View$countOccurrences, function ($) { return $.completedActivities; }, @@ -12747,20 +12776,21 @@ var $author$project$Pages$Completion$View$generateNutritionGroupReportData = F2( activityTransId(activity)), $elm$core$String$fromInt(expected), $elm$core$String$fromInt(completed), - A2(calcualtePercentage, completed, expected) + A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) ]); }); }); - var childrenActivityRows = A3(generateActivityRows, $author$project$Translate$NutritionChildActivity, childrenData, $author$project$Pages$Completion$Model$allNutritionChildGroupActivities); var motherActivityRows = A3(generateActivityRows, $author$project$Translate$NutritionMotherActivity, motherData, $author$project$Pages$Completion$Model$allNutritionMotherGroupActivities); + var childrenData = $elm$core$List$concat( + A2( + $elm$core$List$map, + function ($) { + return $.childrenData; + }, + records)); + var childrenActivityRows = A3(generateActivityRows, $author$project$Translate$NutritionChildActivity, childrenData, $author$project$Pages$Completion$Model$allNutritionChildGroupActivities); return { - captions: _List_fromArray( - [ - A2($author$project$Translate$translate, language, $author$project$Translate$Activity), - A2($author$project$Translate$translate, language, $author$project$Translate$Expected), - A2($author$project$Translate$translate, language, $author$project$Translate$Completed), - '%' - ]), + captions: $author$project$Pages$Completion$View$generateCaptionsList(language), heading: A2($author$project$Translate$translate, language, $author$project$Translate$NutritionGroup), rows: _Utils_ap(motherActivityRows, childrenActivityRows) }; @@ -12841,70 +12871,29 @@ var $author$project$Pages$Components$View$viewNutritionMetricsResultsTable = fun }; var $author$project$Pages$Completion$View$viewNutritionGroupReport = F5( function (language, startDate, limitDate, mTakenBy, reportData) { - var filteredData = A2( - $author$project$Pages$Completion$View$generateNutritionGroupReportData, - language, - A2( - $elm$core$List$filter, - function (encounter) { - var takenByCondition = A2( - $elm$core$Maybe$withDefault, - true, - A2( - $elm$core$Maybe$map, - function (takenBy) { - return _Utils_eq( - encounter.takenBy, - $elm$core$Maybe$Just(takenBy)); - }, - mTakenBy)); - return (!_Utils_eq( - A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), - $elm$core$Basics$LT)) && ((!_Utils_eq( - A2($justinmimbs$date$Date$compare, encounter.startDate, limitDate), - $elm$core$Basics$GT)) && takenByCondition); - }, - reportData)); return A2( $elm$html$Html$div, _List_fromArray( [ $elm$html$Html$Attributes$class('report nutrition-individual') ]), - $author$project$Pages$Components$View$viewNutritionMetricsResultsTable(filteredData)); + $author$project$Pages$Components$View$viewNutritionMetricsResultsTable( + A2( + $author$project$Pages$Completion$View$generateNutritionGroupReportData, + language, + A4($author$project$Pages$Completion$View$applyFilters, startDate, limitDate, mTakenBy, reportData)))); }); var $author$project$Translate$NutritionIndividual = {$: 'NutritionIndividual'}; var $author$project$Pages$Completion$View$generateNutritionIndividualReportData = F2( function (language, records) { - var count = F2( - function (resolveFunc, activity) { - return $elm$core$List$length( - A2( - $elm$core$List$filter, - A2( - $elm$core$Basics$composeR, - resolveFunc, - $elm$core$List$member(activity)), - records)); - }); - var calcualtePercentage = F2( - function (nominator, total) { - return (!total) ? '0' : (A2($myrho$elm_round$Round$round, 3, (nominator / total) * 100) + '%'); - }); return { - captions: _List_fromArray( - [ - A2($author$project$Translate$translate, language, $author$project$Translate$Activity), - A2($author$project$Translate$translate, language, $author$project$Translate$Expected), - A2($author$project$Translate$translate, language, $author$project$Translate$Completed), - '%' - ]), + captions: $author$project$Pages$Completion$View$generateCaptionsList(language), heading: A2($author$project$Translate$translate, language, $author$project$Translate$NutritionIndividual), rows: A2( $elm$core$List$map, function (activity) { - var expected = A2( - count, + var expected = A3( + $author$project$Pages$Completion$View$countOccurrences, A2( $elm$core$Basics$composeR, function ($) { @@ -12913,9 +12902,10 @@ var $author$project$Pages$Completion$View$generateNutritionIndividualReportData function ($) { return $.expectedActivities; }), - activity); - var completed = A2( - count, + activity, + records); + var completed = A3( + $author$project$Pages$Completion$View$countOccurrences, A2( $elm$core$Basics$composeR, function ($) { @@ -12924,7 +12914,8 @@ var $author$project$Pages$Completion$View$generateNutritionIndividualReportData function ($) { return $.completedActivities; }), - activity); + activity, + records); return _List_fromArray( [ A2( @@ -12933,7 +12924,7 @@ var $author$project$Pages$Completion$View$generateNutritionIndividualReportData $author$project$Translate$NutritionChildActivity(activity)), $elm$core$String$fromInt(expected), $elm$core$String$fromInt(completed), - A2(calcualtePercentage, completed, expected) + A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) ]); }, $author$project$Pages$Completion$Model$allNutritionIndividualActivities) @@ -12941,37 +12932,17 @@ var $author$project$Pages$Completion$View$generateNutritionIndividualReportData }); var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F5( function (language, startDate, limitDate, mTakenBy, reportData) { - var filteredData = A2( - $author$project$Pages$Completion$View$generateNutritionIndividualReportData, - language, - A2( - $elm$core$List$filter, - function (encounter) { - var takenByCondition = A2( - $elm$core$Maybe$withDefault, - true, - A2( - $elm$core$Maybe$map, - function (takenBy) { - return _Utils_eq( - encounter.takenBy, - $elm$core$Maybe$Just(takenBy)); - }, - mTakenBy)); - return (!_Utils_eq( - A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), - $elm$core$Basics$LT)) && ((!_Utils_eq( - A2($justinmimbs$date$Date$compare, encounter.startDate, limitDate), - $elm$core$Basics$GT)) && takenByCondition); - }, - reportData)); return A2( $elm$html$Html$div, _List_fromArray( [ $elm$html$Html$Attributes$class('report nutrition-individual') ]), - $author$project$Pages$Components$View$viewNutritionMetricsResultsTable(filteredData)); + $author$project$Pages$Components$View$viewNutritionMetricsResultsTable( + A2( + $author$project$Pages$Completion$View$generateNutritionIndividualReportData, + language, + A4($author$project$Pages$Completion$View$applyFilters, startDate, limitDate, mTakenBy, reportData)))); }); var $author$project$Pages$Utils$viewSelectListInput = F7( function (language, currentValue, options, toStringFunc, setMsg, transId, inputClass) { From fbd1a1f9828871106f92798fa5d7f5a1402884ce Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 19 Aug 2024 22:23:41 +0300 Subject: [PATCH 030/185] Define mapping [ci skip] --- .../hedley_reports/hedley_reports.module | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 8528f4d680..905257842e 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2406,6 +2406,36 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ return $return; } + +function hedley_reports_generate_completion_data_for_aculte_illness($attendance) { + // To reduce memory usage, mapping measurement types as single characters. + $mapping = [ + 'acute_findings' => 'a', + 'acute_illness_contacts_tracing' => 'b', + 'acute_illness_core_exam' => 'c', + 'acute_illness_danger_signs' => 'd', + 'acute_illness_follow_up' => 'e', + 'acute_illness_muac' => 'f', + 'acute_illness_nutrition' => 'g', + 'acute_illness_vitals' => 'h', + 'call_114' => 'i', + 'covid_testing' => 'j', + 'exposure' => 'k', + 'hc_contact' => 'l', + 'health_education' => 'm', + 'isolation' => 'n', + 'malaria_testing' => 'o', + 'medication_distribution' => 'p', + 'send_to_hc' => 'q', + 'symptoms_general' => 'r', + 'symptoms_gi' => 's', + 'symptoms_respiratory' => 't', + 'travel_history' => 'u', + 'treatment_history' => 'v', + 'treatment_ongoing' => 'w', + ]; +} + function hedley_reports_generate_completion_result($expected, $completed, $mapping) { foreach ($expected as $index => $measurement_type) { $expected[$index] = $mapping[$measurement_type]; From c24d68b153b65ed76a90f777a039a1e169595270 Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 19 Aug 2024 23:04:48 +0300 Subject: [PATCH 031/185] Load participant encounters and sort then ASC [ci skip] --- .../hedley_reports/hedley_reports.module | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 905257842e..82cb0eda6b 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2406,8 +2406,7 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ return $return; } - -function hedley_reports_generate_completion_data_for_aculte_illness($attendance) { +function hedley_reports_generate_completion_data_for_aculte_illness($participant) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ 'acute_findings' => 'a', @@ -2434,6 +2433,46 @@ function hedley_reports_generate_completion_data_for_aculte_illness($attendance) 'treatment_history' => 'v', 'treatment_ongoing' => 'w', ]; + + // Load all encounters of current participant. + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'acute_illness_encounter') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_individual_participant', 'target_id', $participant->nid) + ->execute(); + + if (empty($result['node'])) { + return; + } + + $encounters = node_load_multiple(array_keys($result['node'])); + // Sort encounters by field_scheduled_date and field_sequence_number in ascending order. + usort($encounters, function($a, $b) { + $date_a = strtotime($a->field_scheduled_date[LANGUAGE_NONE][0]['value']); + $date_b = strtotime($b->field_scheduled_date[LANGUAGE_NONE][0]['value']); + + // If dates are the same, compare by field_sequence_number + if ($date_a !== $date_b) { + return $date_a - $date_b; + } + + $seq_a = isset($a->field_sequence_number[LANGUAGE_NONE][0]['value']) ? $a->field_sequence_number[LANGUAGE_NONE][0]['value'] : 0; + $seq_b = isset($b->field_sequence_number[LANGUAGE_NONE][0]['value']) ? $b->field_sequence_number[LANGUAGE_NONE][0]['value'] : 0; + return $seq_a - $seq_b; + }); + + + + // If encounter type field is empty, we default to CHW, since + // CHW mode was developed before nurse mode. +// $taken_by = 'chw'; +// $encounter_type = $encounter->field_ai_encounter_type[LANGUAGE_NONE][0]['value']; +// if (!empty($encounter_type) && $encounter_type !== 'chw-encounter') { +// $taken_by = 'nurse'; +// } + } function hedley_reports_generate_completion_result($expected, $completed, $mapping) { From 75ded4d3099cb72254537785d4dfc4639d293706 Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 19 Aug 2024 23:10:28 +0300 Subject: [PATCH 032/185] Add script [ci skip] --- ...generate-acute-illness-completion-data.php | 90 +++++++++++++++++++ ...e-nutrition-individual-completion-data.php | 3 - 2 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php new file mode 100644 index 0000000000..37dc7e593f --- /dev/null +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php @@ -0,0 +1,90 @@ +entityCondition('entity_type', 'node') + ->entityCondition('bundle', $type) + ->fieldCondition('field_encounter_type', 'target_id', 'acute-illness') + ->propertyCondition('status', NODE_PUBLISHED); + +if ($exclude_set) { + $base_query->addTag('exclude_set_reports_data'); +} + +$count_query = clone $base_query; +$count_query->propertyCondition('nid', $nid, '>'); +$count = $count_query->count()->execute(); + +if ($count == 0) { + drush_print("There are no nodes of type $type for acute illness encounters in DB."); + exit; +} + +$total = 0; +drush_print("$count nodes of type $type for acute illness encounters located."); + +while (TRUE) { + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + hedley_reports_generate_completion_data_for_aculte_illness($node); + node_save($node); + $total++; + + $memory = round(memory_get_usage() / 1048576); + if ($memory >= $memory_limit) { + drush_print(dt('Stopped before out of memory. Start process from the node ID @nid', ['@nid' => $nid])); + return; + } + } + + $memory = round(memory_get_usage() / 1048576); + drush_print("Calculated so far: $total, Memory: $memory"); + + // Free up memory. + drupal_static_reset(); + + $nid = end($ids); +} + +drush_print("Done! Completion data calculated for $total participants."); diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php index 43adb34f61..386ebaecfe 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php @@ -45,9 +45,6 @@ exit; } -// @todo: do we need this? -$nurses = hedley_ncda_resolve_nurses_ids(); - $total = 0; drush_print("$count nodes of type $type located."); From a3baa7bf472dc97b2258caf14d652910a306663b Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 19 Aug 2024 23:18:00 +0300 Subject: [PATCH 033/185] Fixes [ci skip] --- .../custom/hedley_reports/hedley_reports.module | 16 ++-------------- .../generate-acute-illness-completion-data.php | 2 +- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 82cb0eda6b..eaab14e14c 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2441,27 +2441,15 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant ->entityCondition('bundle', 'acute_illness_encounter') ->propertyCondition('status', NODE_PUBLISHED) ->fieldCondition('field_individual_participant', 'target_id', $participant->nid) + ->propertyOrderBy('nid') ->execute(); if (empty($result['node'])) { return; } + // Encounters are sorted ASC. $encounters = node_load_multiple(array_keys($result['node'])); - // Sort encounters by field_scheduled_date and field_sequence_number in ascending order. - usort($encounters, function($a, $b) { - $date_a = strtotime($a->field_scheduled_date[LANGUAGE_NONE][0]['value']); - $date_b = strtotime($b->field_scheduled_date[LANGUAGE_NONE][0]['value']); - - // If dates are the same, compare by field_sequence_number - if ($date_a !== $date_b) { - return $date_a - $date_b; - } - - $seq_a = isset($a->field_sequence_number[LANGUAGE_NONE][0]['value']) ? $a->field_sequence_number[LANGUAGE_NONE][0]['value'] : 0; - $seq_b = isset($b->field_sequence_number[LANGUAGE_NONE][0]['value']) ? $b->field_sequence_number[LANGUAGE_NONE][0]['value'] : 0; - return $seq_a - $seq_b; - }); diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php index 37dc7e593f..71a72f541d 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php @@ -30,7 +30,7 @@ $base_query ->entityCondition('entity_type', 'node') ->entityCondition('bundle', $type) - ->fieldCondition('field_encounter_type', 'target_id', 'acute-illness') + ->fieldCondition('field_encounter_type', 'value', 'acute-illness') ->propertyCondition('status', NODE_PUBLISHED); if ($exclude_set) { From 216c587178ff6414a5d7bb67783185d67d0be770 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 20 Aug 2024 19:12:10 +0300 Subject: [PATCH 034/185] Acute Illness logic WIP [ci skip] --- .../hedley_reports/hedley_reports.module | 336 +++++++++++++++++- 1 file changed, 325 insertions(+), 11 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index eaab14e14c..e11a4264ff 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2078,10 +2078,7 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun $start_date_obj = new DateTime($start_date); // Loading all measurements that belong to encounter. - $query = db_select('field_data_field_nutrition_encounter', 'ne'); - $query->addField('ne', 'entity_id'); - $query->condition('ne.field_nutrition_encounter_target_id', $encounter->nid); - $measurements_ids = $query->execute()->fetchCol(); + $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); if (empty($measurements_ids)) { $completion = hedley_reports_generate_completion_result($expected, $completed, $mapping); @@ -2450,17 +2447,334 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant // Encounters are sorted ASC. $encounters = node_load_multiple(array_keys($result['node'])); + $encounters_data = []; + foreach ($encounters as $encounter) { + // Loading all measurements that belong to encounter. + $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); + $encounter_type = $encounter->field_ai_encounter_type[LANGUAGE_NONE][0]['value']; + // If encounter type field is empty, we default to CHW, since + // CHW mode was developed before nurse mode. + if (empty($encounter_type)) { + $encounter_type = 'chw-encounter'; + } + + $measurements = !empty($measurements_ids) ? node_load_multiple($measurements_ids) : []; + // Ordering measurements by type. + $measurements_by_type = []; + foreach ($measurements as $measurement) { + $measurements_by_type[$measurement->type] = $measurement; + } + + $encounters_data[] = [ + 'encounter' => $encounter, + 'encounter_type' => $encounter_type, + 'taken_by' => $encounter_type == 'chw-encounter' ? 'chw' : 'nurse', + 'measurements_by_type' => $measurements_by_type, + ]; + } + + foreach ($encounters_data as $index => $encounter_data) { + $encounter = $encounter_data['encounter']; + $encounter_type = $encounter_data['encounter_type']; + $measurements_by_type = $encounter_data['measurements_by_type']; + + // Resolve encounter start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $start_date_obj = new DateTime($start_date); + $encounter_data['start_date_obj'] = $start_date_obj; + + $previous_encounters_data = array_slice($encounters_data, 0, $index); + $is_initial = ($encounter_type == 'nurse-encounter') || (($encounter_type == 'chw-encounter') && empty($previous_encounters_data)); + $illness_diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; + if (!$is_initial && (empty($diagnosis) || $diagnosis == 'none')) { + // Reversing passed array, to have the encounters sorted DESC. + $illness_diagnosis = hedley_reports_get_acute_illness_diagnosis_by_previous_encounters(array_reverse($previous_encounters_data)); + } + $encounter_data['is_initial'] = $is_initial; + $encounter_data['illness_diagnosis'] = $illness_diagnosis; + + // Acute illness module defines following logic: + // If first encounter(s) were taken by CHW, but then + // nurse ran and encounter, we consider that encounter of + // nurse as initial. All data collected by CHWs until that + // encounter should be ignored. + $initial_nurse_encounter_index = -1; + foreach ($previous_encounters_data as $ind => $data) { + if ($data['encounter_type'] == 'nurse-encounter') { + $initial_nurse_encounter_index = $ind; + break; + } + } + + if ($initial_nurse_encounter_index == -1) { + $first_initial_with_subsequents = $previous_encounters_data; + $second_initial_with_subsequents = []; + } else { + $first_initial_with_subsequents = array_slice($previous_encounters_data, 0, $initial_nurse_encounter_index + 1); + $second_initial_with_subsequents = array_slice($previous_encounters_data, $initial_nurse_encounter_index + 1); + } + + $encounter_data['first_initial_with_subsequents'] = $first_initial_with_subsequents; + $encounter_data['second_initial_with_subsequents'] = $second_initial_with_subsequents; + + $fever_at_symptoms = FALSE; + if (!empty($measurements_by_type['symptoms_general'])) { + $fever_period = $measurements_by_type['symptoms_general']->field_fever_period[LANGUAGE_NONE][0]['value']; + if (!empty($fever_period)) { + $fever_at_symptoms = $fever_period > 0; + } + } + $fever_at_vitals = FALSE; + if (!empty($measurements_by_type['vitals'])) { + $body_temperature = $measurements_by_type['vitals']->field_body_temperature[LANGUAGE_NONE][0]['value']; + if (!empty($body_temperature)) { + $fever_at_vitals = $body_temperature >= 37.5; + } + } + $fever = $fever_at_symptoms || $fever_at_vitals; + $encounter_data['fever'] = $fever; + + // So far we were constructing data structures to resolve encounter data. + // Now we have enough info to determine which activities were expected. + + // Load all activities expected only by encounter start date. + $expected = hedley_reports_generate_acute_illness_expected_initial_activities($start_date_obj); + // If conditions match, add malaria_testing activity. + hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, $expected); + // If conditions match, add covid_testing activity. + hedley_reports_acute_illness_add_expected_covid_testing($encounter_data, $expected); + } +} + +function hedley_reports_generate_acute_illness_expected_initial_activities($start_date_obj) { + // Activities that are shown at any encounter unconditionally, + // as they existed with initial launch of the feature. + $expected = [ + 'acute_findings', + 'acute_illness_vitals', + 'exposure', + 'symptoms_general', + 'symptoms_gi', + 'symptoms_respiratory', + 'travel_history', + 'treatment_history', + ]; + + $launch_date = '2022-12-22'; + $launch_date_obj = new DateTime($launch_date); + if ($start_date_obj >= $launch_date_obj) { + $expected[] = 'acute_illness_core_exam'; + } + + $launch_date = '2021-04-21'; + $launch_date_obj = new DateTime($launch_date); + if ($start_date_obj >= $launch_date_obj) { + $expected[] = 'acute_illness_danger_signs'; + } + + $launch_date = '2020-12-10'; + $launch_date_obj = new DateTime($launch_date); + if ($start_date_obj >= $launch_date_obj) { + $expected[] = 'acute_illness_muac'; + $expected[] = 'acute_illness_nutrition'; + } + + return $expected; +} + +function hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, &$expected) { + $encounter = $encounter_data['encounter']; + $measurements_by_type = $encounter_data['measurements_by_type']; + $fever = $encounter_data['fever']; + $first_initial_with_subsequents = $encounter_data['first_initial_with_subsequents']; + $second_initial_with_subsequents = $encounter_data['second_initial_with_subsequents']; + + $current_encounter_diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; + $covid_diagnoses = ['covid19-severe', 'covid19-pneumonia', 'covid19-low-risk']; + $covid_diagnosed = FALSE; + if (!empty($current_encounter_diagnosis)) { + $covid_diagnosed = !in_array($current_encounter_diagnosis, $covid_diagnoses); + } + + if ($encounter_data['is_initial']) { + // If patient was not diagnosed with Covid, and fever is recorded + // on current encounter, and patient was suggested to take + // COVID test, but did not run it, we expect patient to take Malaria test. + $covid_rapid_test_suggested_but_not_run = FALSE; + if (!empty($measurements_by_type['covid_testing'])) { + $covid_rapid_test_result = $measurements_by_type['covid_testing']->field_rapid_test_result[LANGUAGE_NONE][0]['value']; + if (!empty($covid_rapid_test_result)) { + $not_run_values = ['unable-to-run', 'unable-to-run-and-pregnant']; + $covid_rapid_test_suggested_but_not_run = in_array($covid_rapid_test_result, $not_run_values); + } + + if (!$covid_diagnosed && $fever && $covid_rapid_test_suggested_but_not_run) { + $expected[] = 'malaria_testing'; + } + } + } + else { + // If patient was not diagnosed with Covid on current encounter, and fever + // is recorded on current encounter, and patient did not test positive + // to Malaria during one of previous encounters, we expect patient to take + // Malaria test. + $initial_with_subsequents = empty($second_initial_with_subsequents) ? $first_initial_with_subsequents : $second_initial_with_subsequents; + $diagnosed_with_malaria_previously = FALSE; + $rdt_positive_values = ['positive', 'positive-and-pregnant']; + foreach ($initial_with_subsequents as $prev_encounter_data) { + $prev_measurements_by_type = $prev_encounter_data['measurements_by_type']; + if (!empty($prev_measurements_by_type['malaria_testing'])) { + $malaria_rapid_test_result = $prev_measurements_by_type['malaria_testing']->field_rapid_test_result[LANGUAGE_NONE][0]['value']; + if (!empty($malaria_rapid_test_result)) { + if (in_array($malaria_rapid_test_result, $rdt_positive_values)) { + $diagnosed_with_malaria_previously = TRUE; + break; + } + } + } + } + if (!$covid_diagnosed && $fever && !$diagnosed_with_malaria_previously) { + $expected[] = 'malaria_testing'; + } + } +} + +function hedley_reports_acute_illness_add_expected_covid_testing($encounter_data, &$expected) { + if ($encounter_data['taken_by'] != 'nurse') { + // COVID lab check is available for nurse only. + return; + } + + $launch_date = '2022-02-06'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] < $launch_date_obj) { + // Feature was not yet launched. + return; + } + + $measurements_by_type = $encounter_data['measurements_by_type']; + $fever = $encounter_data['fever']; + + $total_symptoms_respiratory = hedley_reports_count_acute_illness_symptoms_respiratory($measurements_by_type['symptoms_respiratory']); + $total_symptoms_gi = hedley_reports_count_acute_illness_symptoms_gi($measurements_by_type['symptoms_gi']); + if ($total_symptoms_gi > 0) { + $symptoms_indicate_covid = $total_symptoms_respiratory > 0; + } + else { + $total_symptoms_general = hedley_reports_count_acute_illness_symptoms_general($measurements_by_type['symptoms_general']); + $symptoms_indicate_covid = ($total_symptoms_general + $total_symptoms_respiratory + $total_symptoms_gi) > 1; + } + + $total_exposure_signs = 0; + if (!empty($measurements_by_type['exposure'])) { + $total_exposure_signs = hedley_reports_count_acute_illness_signs($measurements_by_type['exposure']->field_exposure[LANGUAGE_NONE]); + } + $total_travel_history_signs = 0; + if (!empty($measurements_by_type['travel_history'])) { + $total_travel_history_signs = hedley_reports_count_acute_illness_signs($measurements_by_type['travel_history']->field_travel_history[LANGUAGE_NONE]); + } + $signs_indicate_covid = ($total_exposure_signs + $total_travel_history_signs) > 0; + + $malaria_rapid_test_result = FALSE; + if (!empty($measurements_by_type['malaria_testing'])) { + $malaria_rapid_test_result = $measurements_by_type['malaria_testing']->field_rapid_test_result[LANGUAGE_NONE][0]['value']; + } + + $rdt_positive_values = ['positive', 'positive-and-pregnant']; + $malaria_rdt_run_and_not_positive = !empty($malaria_rapid_test_result) && !in_array($malaria_rapid_test_result, $rdt_positive_values); + + if (($symptoms_indicate_covid && $signs_indicate_covid) || + ($signs_indicate_covid && $fever) || + (!$symptoms_indicate_covid && $fever && $malaria_rdt_run_and_not_positive && $total_symptoms_respiratory > 0) || + (!$symptoms_indicate_covid && $fever && $malaria_rdt_run_and_not_positive && $total_symptoms_general > 1)) { + $expected[] = 'covid_testing'; + } +} + +function hedley_reports_get_acute_illness_diagnosis_by_previous_encounters($encounters_data) { + foreach ($encounters_data as $encounter_data) { + $encounter = $encounter_data['encounter']; + $diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; + if (!empty($diagnosis) && $diagnosis !== 'none') { + return $diagnosis; + } + } + return NULL; +} + +function hedley_reports_count_acute_illness_symptoms_general($measurement) { + $fields = [ + 'field_chills_period', + 'field_night_sweats_period', + 'field_body_aches_period', + 'field_headache_period', + ]; + + return hedley_reports_count_acute_illness_symptoms($measurement, $fields); +} + +function hedley_reports_count_acute_illness_symptoms_respiratory($measurement) { + $fields = [ + 'field_shortness_of_breath_period', + 'field_nasal_congestion_period', + 'field_blood_in_sputum_period', + 'field_sore_throat_period', + 'field_loss_of_smell_period', + 'field_stabbing_chest_pain_period', + ]; + + return hedley_reports_count_acute_illness_symptoms($measurement, $fields); +} + +function hedley_reports_count_acute_illness_symptoms_gi($measurement) { + $fields = [ + 'field_bloody_diarrhea_period', + 'field_non_bloody_diarrhea_period', + 'field_nausea_period', + 'field_vomiting_period', + 'field_abdominal_pain_period', + ]; + + return hedley_reports_count_acute_illness_symptoms($measurement, $fields); +} - // If encounter type field is empty, we default to CHW, since - // CHW mode was developed before nurse mode. -// $taken_by = 'chw'; -// $encounter_type = $encounter->field_ai_encounter_type[LANGUAGE_NONE][0]['value']; -// if (!empty($encounter_type) && $encounter_type !== 'chw-encounter') { -// $taken_by = 'nurse'; -// } +function hedley_reports_count_acute_illness_symptoms($measurement, $fields) { + $count = 0; + if (empty($measurement)) { + return $count; + } + + foreach ($fields as $field) { + $value = $measurement->$field[LANGUAGE_NONE][0]['value']; + if (!empty($value) && $value > 0) { + $count++; + } + } + return $count; +} + +function hedley_reports_count_acute_illness_signs($values) { + $count = 0; + foreach ($values as $value) { + if ($value['value'] != 'none') { + $count++; + } + } + + return $count; +} + + +function hedley_reports_load_individual_encounter_measurements_ids($encounter) { + $bundle = $encounter->type; + $encounter_field ="field_$bundle"; + $query = db_select("field_data_$encounter_field", 'ef'); + $query->addField('ef', 'entity_id'); + $query->condition("ef.{$encounter_field}_target_id", $encounter->nid); + return $query->execute()->fetchCol(); } function hedley_reports_generate_completion_result($expected, $completed, $mapping) { From 04e4bd9a89708284604218dd39fcd13358ac49f3 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 20 Aug 2024 19:12:54 +0300 Subject: [PATCH 035/185] Client side adjustments [ci skip] --- .../src/elm/Pages/AcuteIllness/Activity/Utils.elm | 9 ++++++--- .../src/elm/Pages/AcuteIllness/Encounter/Utils.elm | 13 +++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm b/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm index d4d9a2bade..d55021ac9d 100644 --- a/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm +++ b/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm @@ -1753,7 +1753,7 @@ expectLaboratoryTask currentDate isChw assembled task = else assembled.secondInitialWithSubsequent in - -- If pשtient was not diagnosed with Covid, and fever is recorded + -- If patient was not diagnosed with Covid, and fever is recorded -- on current encounter, and patient did not test positive -- to Malaria during one of previous encounters, -- we want patient to take Malaria test. @@ -2323,7 +2323,7 @@ covid19SuspectDiagnosed measurements = generalSymptomsCount = let excludesGeneral = - [ SymptomGeneralFever, NoSymptomsGeneral ] ++ symptomsGeneralDangerSigns + [ SymptomGeneralFever ] ++ symptomsGeneralDangerSigns in countGeneralSymptoms measurements excludesGeneral @@ -2358,7 +2358,10 @@ covid19SuspectDiagnosed measurements = malariaRapidTestResult measurements feverAndRdtNotPositive = - feverOnRecord && isJust malariaRDTResult && malariaRDTResult /= Just RapidTestPositive + feverOnRecord + && isJust malariaRDTResult + && (malariaRDTResult /= Just RapidTestPositive) + && (malariaRDTResult /= Just RapidTestPositiveAndPregnant) in (signsIndicateCovid && symptomsIndicateCovid) || (signsIndicateCovid && feverOnRecord) diff --git a/client/src/elm/Pages/AcuteIllness/Encounter/Utils.elm b/client/src/elm/Pages/AcuteIllness/Encounter/Utils.elm index e2005acd69..687b6bf712 100644 --- a/client/src/elm/Pages/AcuteIllness/Encounter/Utils.elm +++ b/client/src/elm/Pages/AcuteIllness/Encounter/Utils.elm @@ -102,12 +102,9 @@ generateAssembledData currentDate features id isChw db = data.encounter.diagnosis data.measurements - allEncountersData = - data.previousEncountersData ++ [ currentEncounterData ] - nurseEncounterIndex = List.indexedMap (\index encounterData -> ( index, encounterData.encounterType )) - allEncountersData + data.previousEncountersData |> List.filter (Tuple.second >> (==) AcuteIllnessEncounterNurse) |> List.reverse |> List.head @@ -116,15 +113,15 @@ generateAssembledData currentDate features id isChw db = Maybe.map (\nurseIndex -> if nurseIndex == 0 then - ( allEncountersData, [] ) + ( data.previousEncountersData, [] ) else - ( List.take nurseIndex allEncountersData - , List.drop nurseIndex allEncountersData + ( List.take nurseIndex data.previousEncountersData + , List.drop nurseIndex data.previousEncountersData ) ) nurseEncounterIndex - |> Maybe.withDefault ( allEncountersData, [] ) + |> Maybe.withDefault ( data.previousEncountersData, [] ) in { data | initialEncounter = initialEncounter From 1c5f7f8794f5065b1b02cda3d7c7b6904d901a2c Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 11:12:21 +0300 Subject: [PATCH 036/185] Add physical exam activities [ci skip] --- .../hedley_reports/hedley_reports.module | 147 +++++++++++++----- 1 file changed, 107 insertions(+), 40 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index e11a4264ff..d8c6f8be4d 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2091,25 +2091,7 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun } // Try to resolve age in months at a time encounter was performed. - try { - // Get participant ID and node. - $participant_id = $encounter->field_individual_participant[LANGUAGE_NONE][0]['target_id']; - $participant = node_load($participant_id); - - // Get person ID and node - $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; - $person = node_load($person_id); - - // Get birthdate and date measured. - $birth_date = explode(' ', $person->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; - - // Calculate age in months. - $birth_date_obj = new DateTime($birth_date); - $interval = $start_date_obj->diff($birth_date_obj); - $age_in_months = ($interval->y * 12) + $interval->m; - } catch (Exception $e) { - $age_in_months = NULL; - } + $age_in_months = hedley_reports_resolve_age_in_months_for_individual_encounter($$encounter, $start_date_obj); // MUAC is taken starting age of 6 months. if (isset($age_in_months) && $age_in_months >= 6) { @@ -2483,6 +2465,10 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant $start_date_obj = new DateTime($start_date); $encounter_data['start_date_obj'] = $start_date_obj; + // Try to resolve age in months at a time encounter was performed. + $age_in_months = hedley_reports_resolve_age_in_months_for_individual_encounter($$encounter, $start_date_obj); + $encounter_data['age_in_months'] = $age_in_months; + $previous_encounters_data = array_slice($encounters_data, 0, $index); $is_initial = ($encounter_type == 'nurse-encounter') || (($encounter_type == 'chw-encounter') && empty($previous_encounters_data)); $illness_diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; @@ -2513,9 +2499,8 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant $first_initial_with_subsequents = array_slice($previous_encounters_data, 0, $initial_nurse_encounter_index + 1); $second_initial_with_subsequents = array_slice($previous_encounters_data, $initial_nurse_encounter_index + 1); } - - $encounter_data['first_initial_with_subsequents'] = $first_initial_with_subsequents; - $encounter_data['second_initial_with_subsequents'] = $second_initial_with_subsequents; + $initial_with_subsequents = empty($second_initial_with_subsequents) ? $first_initial_with_subsequents : $second_initial_with_subsequents; + $encounter_data['initial_with_subsequents'] = $initial_with_subsequents; $fever_at_symptoms = FALSE; if (!empty($measurements_by_type['symptoms_general'])) { @@ -2543,6 +2528,10 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, $expected); // If conditions match, add covid_testing activity. hedley_reports_acute_illness_add_expected_covid_testing($encounter_data, $expected); + // If conditions match, add treatment_ongoing activity. + hedley_reports_acute_illness_add_expected_treatment_ongoing($encounter_data, $expected); + // If conditions match, add physical exam activities. + hedley_reports_acute_illness_add_physical_exam_activities($encounter_data, $expected); } } @@ -2550,7 +2539,6 @@ function hedley_reports_generate_acute_illness_expected_initial_activities($star // Activities that are shown at any encounter unconditionally, // as they existed with initial launch of the feature. $expected = [ - 'acute_findings', 'acute_illness_vitals', 'exposure', 'symptoms_general', @@ -2560,25 +2548,12 @@ function hedley_reports_generate_acute_illness_expected_initial_activities($star 'treatment_history', ]; - $launch_date = '2022-12-22'; - $launch_date_obj = new DateTime($launch_date); - if ($start_date_obj >= $launch_date_obj) { - $expected[] = 'acute_illness_core_exam'; - } - - $launch_date = '2021-04-21'; + $launch_date = '2021-03-11'; $launch_date_obj = new DateTime($launch_date); if ($start_date_obj >= $launch_date_obj) { $expected[] = 'acute_illness_danger_signs'; } - $launch_date = '2020-12-10'; - $launch_date_obj = new DateTime($launch_date); - if ($start_date_obj >= $launch_date_obj) { - $expected[] = 'acute_illness_muac'; - $expected[] = 'acute_illness_nutrition'; - } - return $expected; } @@ -2586,8 +2561,6 @@ function hedley_reports_acute_illness_add_expected_malaria_testing($encounter_da $encounter = $encounter_data['encounter']; $measurements_by_type = $encounter_data['measurements_by_type']; $fever = $encounter_data['fever']; - $first_initial_with_subsequents = $encounter_data['first_initial_with_subsequents']; - $second_initial_with_subsequents = $encounter_data['second_initial_with_subsequents']; $current_encounter_diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; $covid_diagnoses = ['covid19-severe', 'covid19-pneumonia', 'covid19-low-risk']; @@ -2618,9 +2591,9 @@ function hedley_reports_acute_illness_add_expected_malaria_testing($encounter_da // is recorded on current encounter, and patient did not test positive // to Malaria during one of previous encounters, we expect patient to take // Malaria test. - $initial_with_subsequents = empty($second_initial_with_subsequents) ? $first_initial_with_subsequents : $second_initial_with_subsequents; $diagnosed_with_malaria_previously = FALSE; $rdt_positive_values = ['positive', 'positive-and-pregnant']; + $initial_with_subsequents = $encounter_data['initial_with_subsequents']; foreach ($initial_with_subsequents as $prev_encounter_data) { $prev_measurements_by_type = $prev_encounter_data['measurements_by_type']; if (!empty($prev_measurements_by_type['malaria_testing'])) { @@ -2692,6 +2665,79 @@ function hedley_reports_acute_illness_add_expected_covid_testing($encounter_data } } +function hedley_reports_acute_illness_add_expected_treatment_ongoing($encounter_data, &$expected) { + if ($encounter_data['is_initial']) { + // Ongoing treatment is available only for subsequent encounters. + return; + } + + $launch_date = '2021-03-11'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] < $launch_date_obj) { + // Feature was not yet launched. + return; + } + + // Activity is expected, if medication was prescribed at any of previous encounters. + $medication_prescribed = FALSE; + $initial_with_subsequents = $encounter_data['initial_with_subsequents']; + foreach ($initial_with_subsequents as $prev_encounter_data) { + $measurements_by_type = $prev_encounter_data['measurements_by_type']; + if (empty($measurements_by_type['medication_distribution'])) { + continue; + } + $prescribed_medication = $measurements_by_type['medication_distribution']->field_prescribed_medication[LANGUAGE_NONE]; + $total_prescribed = count($prescribed_medication); + + if ($total_prescribed == 0) { + continue; + }; + + if ($total_prescribed > 1) { + $medication_prescribed = TRUE; + break; + } + + // If we got so far, $total_prescribed == 1. + $medication = $prescribed_medication[0]['value']; + if (!in_array($medication, ['lemon-juice-or-honey', 'none'])) { + $medication_prescribed = TRUE; + break; + } + } + + if ($medication_prescribed) { + $expected[] = 'treatment_ongoing'; + } +} + +function hedley_reports_acute_illness_add_physical_exam_activities($encounter_data, &$expected) { + if ($encounter_data['is_initial']) { + // Acute findings is available only for initial encounter. + $expected[] = 'acute_findings'; + } + + $launch_date = '2022-12-22'; + $launch_date_obj = new DateTime($launch_date); + // Core exam is taken only by nurse. + if ($encounter_data['start_date_obj'] >= $launch_date_obj && $encounter_data['taken_by'] == 'nurse') { + $expected[] = 'acute_illness_core_exam'; + } + + $launch_date = '2020-12-10'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] >= $launch_date_obj) { + // MUAC is taken for children that are 6 months to 5 years old. + if ($encounter_data['age_in_months'] >= 6 && $encounter_data['age_in_months'] < 60) { + $expected[] = 'acute_illness_muac'; + } + // Nutrition is taken for children that bellow age of 5 years. + if ($encounter_data['age_in_months'] < 60) { + $expected[] = 'acute_illness_nutrition'; + } + } +} + function hedley_reports_get_acute_illness_diagnosis_by_previous_encounters($encounters_data) { foreach ($encounters_data as $encounter_data) { $encounter = $encounter_data['encounter']; @@ -2767,6 +2813,27 @@ function hedley_reports_count_acute_illness_signs($values) { return $count; } +function hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj) { + try { + // Get participant ID and node. + $participant_id = $encounter->field_individual_participant[LANGUAGE_NONE][0]['target_id']; + $participant = node_load($participant_id); + + // Get person ID and node + $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + $person = node_load($person_id); + + // Get birthdate and date measured. + $birth_date = explode(' ', $person->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; + + // Calculate age in months. + $birth_date_obj = new DateTime($birth_date); + $interval = $start_date_obj->diff($birth_date_obj); + return ($interval->y * 12) + $interval->m; + } catch (Exception $e) { + return NULL; + } +} function hedley_reports_load_individual_encounter_measurements_ids($encounter) { $bundle = $encounter->type; From 1eed780b344c041029bebc85157e54a7bf90c7ed Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 11:51:23 +0300 Subject: [PATCH 037/185] Improve client-side code [ci skip] --- .../elm/Backend/AcuteIllnessActivity/Utils.elm | 18 +++++++++++------- .../elm/Pages/AcuteIllness/Activity/Utils.elm | 12 ++++++++++++ .../elm/Pages/AcuteIllness/Encounter/View.elm | 3 +-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/client/src/elm/Backend/AcuteIllnessActivity/Utils.elm b/client/src/elm/Backend/AcuteIllnessActivity/Utils.elm index 7cbff8308d..1be6de5cfc 100644 --- a/client/src/elm/Backend/AcuteIllnessActivity/Utils.elm +++ b/client/src/elm/Backend/AcuteIllnessActivity/Utils.elm @@ -85,10 +85,14 @@ getActivityIcon activity = encodeActivityAsString activity -getAllActivities : Bool -> List AcuteIllnessActivity -getAllActivities isFirstEncounter = - if isFirstEncounter then - [ AcuteIllnessSymptoms, AcuteIllnessExposure, AcuteIllnessPriorTreatment, AcuteIllnessPhysicalExam, AcuteIllnessLaboratory, AcuteIllnessNextSteps ] - - else - [ AcuteIllnessDangerSigns, AcuteIllnessPhysicalExam, AcuteIllnessOngoingTreatment, AcuteIllnessLaboratory, AcuteIllnessNextSteps ] +getAllActivities : List AcuteIllnessActivity +getAllActivities = + [ AcuteIllnessSymptoms + , AcuteIllnessExposure + , AcuteIllnessPriorTreatment + , AcuteIllnessPhysicalExam + , AcuteIllnessLaboratory + , AcuteIllnessDangerSigns + , AcuteIllnessOngoingTreatment + , AcuteIllnessNextSteps + ] diff --git a/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm b/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm index d55021ac9d..66252e88c5 100644 --- a/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm +++ b/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm @@ -43,6 +43,18 @@ import Translate exposing (Language, TranslationId) expectActivity : NominalDate -> Bool -> AssembledData -> AcuteIllnessActivity -> Bool expectActivity currentDate isChw assembled activity = case activity of + AcuteIllnessSymptoms -> + assembled.initialEncounter + + AcuteIllnessExposure -> + assembled.initialEncounter + + AcuteIllnessPriorTreatment -> + assembled.initialEncounter + + AcuteIllnessDangerSigns -> + not assembled.initialEncounter + AcuteIllnessLaboratory -> List.filter (expectLaboratoryTask currentDate isChw assembled) laboratoryTasks |> List.isEmpty diff --git a/client/src/elm/Pages/AcuteIllness/Encounter/View.elm b/client/src/elm/Pages/AcuteIllness/Encounter/View.elm index 8a703e88c8..3ec87d8df7 100644 --- a/client/src/elm/Pages/AcuteIllness/Encounter/View.elm +++ b/client/src/elm/Pages/AcuteIllness/Encounter/View.elm @@ -377,8 +377,7 @@ viewMainPageContent language currentDate id isChw assembled model = partitionActivities : NominalDate -> Bool -> AssembledData -> ( List AcuteIllnessActivity, List AcuteIllnessActivity ) partitionActivities currentDate isChw assembled = - getAllActivities assembled.initialEncounter - |> List.filter (expectActivity currentDate isChw assembled) + List.filter (expectActivity currentDate isChw assembled) getAllActivities |> List.partition (activityCompleted currentDate isChw assembled) From 6645dd1e0ccd8e11785998f7844569db34170897 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 11:52:34 +0300 Subject: [PATCH 038/185] More WIP [ci skip] --- .../hedley_reports/hedley_reports.module | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index d8c6f8be4d..6ec64b3faf 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2522,8 +2522,8 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. - // Load all activities expected only by encounter start date. - $expected = hedley_reports_generate_acute_illness_expected_initial_activities($start_date_obj); + // Load all activities expected only by encounter type and start date. + $expected = hedley_reports_generate_acute_illness_expected_initial_activities($encounter_data); // If conditions match, add malaria_testing activity. hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, $expected); // If conditions match, add covid_testing activity. @@ -2535,23 +2535,33 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant } } -function hedley_reports_generate_acute_illness_expected_initial_activities($start_date_obj) { - // Activities that are shown at any encounter unconditionally, - // as they existed with initial launch of the feature. +function hedley_reports_generate_acute_illness_expected_initial_activities($encounter_data, $start_date_obj) { + // Activities that are shown at any type of encounter, + // unconditionally. Existed with initial launch of the feature. $expected = [ 'acute_illness_vitals', - 'exposure', - 'symptoms_general', - 'symptoms_gi', - 'symptoms_respiratory', - 'travel_history', - 'treatment_history', ]; - $launch_date = '2021-03-11'; - $launch_date_obj = new DateTime($launch_date); - if ($start_date_obj >= $launch_date_obj) { - $expected[] = 'acute_illness_danger_signs'; + // Activities that are only shown at initial encounter. + if ($encounter_data['is_initial']) { + // Exposure activity. + $expected[] = 'exposure'; + $expected[] = 'travel_history'; + // Symptoms activity. + $expected[] = 'symptoms_general'; + $expected[] = 'symptoms_gi'; + $expected[] = 'symptoms_respiratory'; + // Treatment review activity. + $expected[] = 'treatment_history'; + } + + // Activities that are only shown at subsequent encounters. + if (!$encounter_data['is_initial']) { + $launch_date = '2021-03-11'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] >= $launch_date_obj) { + $expected[] = 'acute_illness_danger_signs'; + } } return $expected; From fc71208287cee3dbd019807d3001fba425fb921b Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 11:59:29 +0300 Subject: [PATCH 039/185] More improvements [ci skip] --- .../elm/Pages/AcuteIllness/Activity/Utils.elm | 18 +++++++++++++++--- .../elm/Pages/AcuteIllness/Activity/View.elm | 3 +-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm b/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm index 66252e88c5..aedd859ae5 100644 --- a/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm +++ b/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm @@ -55,6 +55,11 @@ expectActivity currentDate isChw assembled activity = AcuteIllnessDangerSigns -> not assembled.initialEncounter + AcuteIllnessPhysicalExam -> + List.filter (expectPhysicalExamTask currentDate assembled.person isChw assembled.initialEncounter) physicalExamTasks + |> List.isEmpty + |> not + AcuteIllnessLaboratory -> List.filter (expectLaboratoryTask currentDate isChw assembled) laboratoryTasks |> List.isEmpty @@ -103,9 +108,6 @@ expectActivity currentDate isChw assembled activity = |> List.isEmpty |> not - _ -> - True - activityCompleted : NominalDate -> Bool -> AssembledData -> AcuteIllnessActivity -> Bool activityCompleted currentDate isChw assembled activity = @@ -153,6 +155,16 @@ activityCompleted currentDate isChw assembled activity = mandatoryActivityCompletedSubsequentVisit currentDate isChw assembled AcuteIllnessOngoingTreatment +physicalExamTasks : List PhysicalExamTask +physicalExamTasks = + [ PhysicalExamVitals + , PhysicalExamCoreExam + , PhysicalExamMuac + , PhysicalExamNutrition + , PhysicalExamAcuteFindings + ] + + symptomsGeneralDangerSigns : List SymptomsGeneralSign symptomsGeneralDangerSigns = [ Lethargy diff --git a/client/src/elm/Pages/AcuteIllness/Activity/View.elm b/client/src/elm/Pages/AcuteIllness/Activity/View.elm index 763ca6acc1..ef295be1d3 100644 --- a/client/src/elm/Pages/AcuteIllness/Activity/View.elm +++ b/client/src/elm/Pages/AcuteIllness/Activity/View.elm @@ -718,8 +718,7 @@ viewAcuteIllnessPhysicalExam language currentDate site id isChw assembled data = assembled.measurements tasks = - [ PhysicalExamVitals, PhysicalExamCoreExam, PhysicalExamMuac, PhysicalExamNutrition, PhysicalExamAcuteFindings ] - |> List.filter (expectPhysicalExamTask currentDate person isChw assembled.initialEncounter) + List.filter (expectPhysicalExamTask currentDate person isChw assembled.initialEncounter) physicalExamTasks activeTask = resolveActiveTask tasks data.activeTask From 14f4d63f8b9b522b327495dd64c2476c6cb1e8c1 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 17:07:20 +0300 Subject: [PATCH 040/185] Compelete Next Steps activities [ci skip] --- .../hedley_reports/hedley_reports.module | 330 +++++++++++++++++- 1 file changed, 325 insertions(+), 5 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 6ec64b3faf..08a778b60d 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -14,6 +14,8 @@ include_once 'hedley_reports.features.inc'; define('HEDLEY_REPORTS_CALCULATE_AGGREGATED_DATA', 'hedley_reports_calculate_reports_data'); +const RDT_POSITIVE_VALUES = ['positive', 'positive-and-pregnant']; + /** * Implements hook_menu(). */ @@ -2532,6 +2534,8 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant hedley_reports_acute_illness_add_expected_treatment_ongoing($encounter_data, $expected); // If conditions match, add physical exam activities. hedley_reports_acute_illness_add_physical_exam_activities($encounter_data, $expected); + // If conditions match, add next steps activities. + hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); } } @@ -2602,14 +2606,13 @@ function hedley_reports_acute_illness_add_expected_malaria_testing($encounter_da // to Malaria during one of previous encounters, we expect patient to take // Malaria test. $diagnosed_with_malaria_previously = FALSE; - $rdt_positive_values = ['positive', 'positive-and-pregnant']; $initial_with_subsequents = $encounter_data['initial_with_subsequents']; foreach ($initial_with_subsequents as $prev_encounter_data) { $prev_measurements_by_type = $prev_encounter_data['measurements_by_type']; if (!empty($prev_measurements_by_type['malaria_testing'])) { $malaria_rapid_test_result = $prev_measurements_by_type['malaria_testing']->field_rapid_test_result[LANGUAGE_NONE][0]['value']; if (!empty($malaria_rapid_test_result)) { - if (in_array($malaria_rapid_test_result, $rdt_positive_values)) { + if (in_array($malaria_rapid_test_result, RDT_POSITIVE_VALUES)) { $diagnosed_with_malaria_previously = TRUE; break; } @@ -2661,11 +2664,10 @@ function hedley_reports_acute_illness_add_expected_covid_testing($encounter_data $malaria_rapid_test_result = FALSE; if (!empty($measurements_by_type['malaria_testing'])) { - $malaria_rapid_test_result = $measurements_by_type['malaria_testing']->field_rapid_test_result[LANGUAGE_NONE][0]['value']; + $malaria_rapid_test_result = $measurements_by_type['malaria_testing']->field_malaria_rapid_test[LANGUAGE_NONE][0]['value']; } - $rdt_positive_values = ['positive', 'positive-and-pregnant']; - $malaria_rdt_run_and_not_positive = !empty($malaria_rapid_test_result) && !in_array($malaria_rapid_test_result, $rdt_positive_values); + $malaria_rdt_run_and_not_positive = !empty($malaria_rapid_test_result) && !in_array($malaria_rapid_test_result, RDT_POSITIVE_VALUES); if (($symptoms_indicate_covid && $signs_indicate_covid) || ($signs_indicate_covid && $fever) || @@ -2748,6 +2750,324 @@ function hedley_reports_acute_illness_add_physical_exam_activities($encounter_da } } +function hedley_reports_acute_illness_add_next_steps_activities($encounter_data, &$expected) { + if ($encounter_data['is_initial']) { + hedley_reports_acute_illness_add_next_steps_activities_initial_encounter($encounter_data, $expected); + } + else { + hedley_reports_acute_illness_add_next_steps_activities_subsequent_encounter($encounter_data, $expected); + } +} + +function hedley_reports_acute_illness_add_next_steps_activities_initial_encounter($encounter_data, &$expected) { + $age_in_months = $encounter_data['age_in_months']; + $diagnosis = $encounter_data['illness_diagnosis']; + $measurements_by_type = $encounter_data['measurements_by_type']; + $is_chw = $encounter_data['taken_by'] == 'chw'; + + $medication_prescribed = FALSE; + if ((($diagnosis == 'malaria-uncomplicated') && $age_in_months >= 6) || + (in_array($diagnosis, ['cough-and-cold', 'ri-uncomplicated']) && ($age_in_months >= 2 && $age_in_months < 60)) || + (in_array($diagnosis, ['gi-uncomplicated', 'covid19-pneumonia']))) { + $medication_prescribed = TRUE; + } + + // Adding Isolation activity. + if (($is_chw && $diagnosis == 'covid19') || in_array($diagnosis, ['covid19-pneumonia', 'covid19-low-risk'])) { + $expected[] = 'isolation'; + } + + // Adding Call 114 activity. + if (($is_chw && $diagnosis == 'covid19')) { + $expected[] = 'call_114'; + } + + // Adding Contact HC activity. + if ($is_chw && $diagnosis == 'covid19' && !empty($measurements_by_type['call_114']) ) { + $signs = $measurements_by_type['call_114']->field_114_contact[LANGUAGE_NONE]; + foreach ($signs as $sign) { + if ($sign['value'] == 'call-114') { + $expected[] = 'hc_contact'; + break; + } + } + } + + // Adding Medication Distribution activity. + if ($medication_prescribed) { + $expected[] = 'medication_distribution'; + } + + // Adding Health Education activity. + // At initial encounter, it's mapped to Symptoms Relief Guidance. + if ($diagnosis == 'covid19-low-risk') { + $expected[] = 'health_education'; + } + + // Adding Contacts Tracing activity. + $launch_date = '2022-02-06'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] >= $launch_date_obj) { + if (in_array($diagnosis, ['covid19-pneumonia', 'covid19-low-risk'])) { + $expected[] = 'acute_illness_contacts_tracing'; + } + } + + // Adding Send to HC activity. + hedley_reports_acute_illness_add_send_to_hc_initial_encounter($encounter_data, $medication_prescribed, $expected); + + // Adding Follow Up activity. + // This activity must be last one checked, as it depends on previous checks. + $launch_date = '2021-06-07'; + $launch_date_obj = new DateTime($launch_date); + if (($encounter_data['start_date_obj'] >= $launch_date_obj) && !in_array($diagnosis, ['covid19-severe', 'fever-of-unknown-origin'])) { + if (($diagnosis == 'tuberculosis-suspect') || + !empty($expected['isolation']) || + !empty($expected['call_114']) || + !empty($expected['hc_contact']) || + !empty($expected['medication_distribution']) || + !empty($expected['send_to_hc'])) { + $expected[] = 'acute_illness_follow_up'; + } + } +} + +function hedley_reports_acute_illness_add_send_to_hc_initial_encounter($encounter_data, $medication_prescribed, &$expected) { + $age_in_months = $encounter_data['age_in_months']; + $diagnosis = $encounter_data['illness_diagnosis']; + + if ( + hedley_reports_acute_illness_send_to_hc_by_malaria_testing($encounter_data) || + (in_array($diagnosis, ['cough-and-cold', 'ri-uncomplicated']) && $age_in_months < 2) || + in_array($diagnosis, ['gi-complicated', 'ri-complicated', 'fever-of-unknown-origin', 'undetermined', 'covid19-severe']) || + ($medication_prescribed && $diagnosis != 'covid19-pneumonia' && + hedley_reports_acute_illness_send_to_hc_due_to_medication_non_administration($encounter_data)) || + ($encounter_data['taken_by'] == 'chw' && $diagnosis != 'tuberculosis-suspect') + ) { + $expected[] = 'send_to_hc'; + } +} + +function hedley_reports_acute_illness_send_to_hc_by_malaria_testing($encounter_data) { + $age_in_months = $encounter_data['age_in_months']; + $diagnosis = $encounter_data['illness_diagnosis']; + + return + ($diagnosis == 'malaria-uncomplicated' && $age_in_months < 6) || + in_array($diagnosis, ['malaria-complicated', 'malaria-uncomplicated-pregnant']); +} + +function hedley_reports_acute_illness_send_to_hc_due_to_medication_non_administration($encounter_data) { + $measurements_by_type = $encounter_data['measurements_by_type']; + if (empty($measurements_by_type['medication_distribution'])) { + return FALSE; + } + + $signs = $measurements_by_type['medication_distribution']->field_non_administration_reason[LANGUAGE_NONE]; + foreach ($signs as $sign) { + if (hedley_reports_ends_with($sign['value'], 'lack-of-stock') || hedley_reports_ends_with($sign['value'], 'known-allergy')) { + return TRUE; + } + } + + return FALSE; +} + +function hedley_reports_ends_with($haystack, $needle) { + $length = strlen($needle); + if(!$length) { + return TRUE; + } + return substr($haystack, -$length) === $needle; +} + +function hedley_reports_acute_illness_add_next_steps_activities_subsequent_encounter($encounter_data, &$expected) { + $diagnosis = $encounter_data['illness_diagnosis']; + $measurements_by_type = $encounter_data['measurements_by_type']; + + $malaria_diagnosed_at_current_encounter = FALSE; + if (!empty($measurements_by_type['malaria_testing'])) { + $malaria_rapid_test_result = $measurements_by_type['malaria_testing']->field_malaria_rapid_test[LANGUAGE_NONE][0]['value']; + $malaria_diagnosed_at_current_encounter = in_array($malaria_rapid_test_result, RDT_POSITIVE_VALUES); + } + + // Adding Medication Distribution activity. + $send_to_hc_by_malaria_testing = hedley_reports_acute_illness_send_to_hc_by_malaria_testing($encounter_data); + if ($malaria_diagnosed_at_current_encounter && !$send_to_hc_by_malaria_testing) { + $expected[] = 'medication_distribution'; + } + + // Adding Health Education activity. + if (!$malaria_diagnosed_at_current_encounter) { + $expected[] = 'health_education'; + } + + // Adding Contact HC activity. + $danger_sign_present_on_subsequent_visit = hedley_reports_acute_illness_danger_sign_present_on_subsequent_visit($encounter_data); + if (!$malaria_diagnosed_at_current_encounter && + ($danger_sign_present_on_subsequent_visit && $diagnosis == 'covid19')) { + $expected[] = 'hc_contact'; + } + + // Adding Send to HC activity. + hedley_reports_acute_illness_add_send_to_hc_subsequent_encounter( + $encounter_data, + $malaria_diagnosed_at_current_encounter, + $send_to_hc_by_malaria_testing, + $danger_sign_present_on_subsequent_visit, + $expected); + + // Adding Follow Up activity. + // This activity must be last one checked, as it depends on previous checks. + $launch_date = '2021-06-07'; + $launch_date_obj = new DateTime($launch_date); + if (($encounter_data['start_date_obj'] >= $launch_date_obj)) { + if (!empty($expected['hc_contact']) || + !empty($expected['medication_distribution']) || + !empty($expected['send_to_hc'])) { + $expected[] = 'acute_illness_follow_up'; + } + } +} + +function hedley_reports_acute_illness_danger_sign_present_on_subsequent_visit($encounter_data) { + $measurements_by_type = $encounter_data['measurements_by_type']; + + if (empty($measurements_by_type['acute_illness_danger_signs'])) { + return FALSE; + } + + $danger_signs = [ + 'unable-drink-suck', + 'vomiting', + 'convulsions', + 'lethargy-unconsciousness', + 'respiratory-distress', + 'spontaneous-bleeding', + 'bloody-diarrhea', + 'new-skip-rash', + ]; + $recorder_signs = $measurements_by_type['acute_illness_danger_signs']->field_acute_illness_danger_signs[LANGUAGE_NONE]; + + foreach ($recorder_signs as $recorder_sign) { + if (in_array($recorder_sign['value'], $danger_signs)) { + return TRUE; + } + } + + return FALSE; +} + +function hedley_reports_acute_illness_add_send_to_hc_subsequent_encounter +( + $encounter_data, + $malaria_diagnosed_at_current_encounter, + $send_to_hc_by_malaria_testing, + $danger_sign_present_on_subsequent_visit, + &$expected +) { + $diagnosis = $encounter_data['illness_diagnosis']; + $measurements_by_type = $encounter_data['measurements_by_type']; + $age_in_months = $encounter_data['age_in_months']; + + if ($malaria_diagnosed_at_current_encounter) { + if ($send_to_hc_by_malaria_testing || + hedley_reports_acute_illness_send_to_hc_due_to_medication_non_administration($encounter_data) + ) { + $expected[] = 'send_to_hc'; + return; + } + } + + $respiratory_rate_elevated = FALSE; + if (!empty($measurements_by_type['acute_illness_vitals'])) { + $respiratory_rate = $measurements_by_type['acute_illness_vitals']->field_respiratory_rate[LANGUAGE_NONE][0]['value']; + if ($age_in_months < 12) { + $respiratory_rate_elevated = $respiratory_rate >= 50; + } + else if ($age_in_months < 60) { + $respiratory_rate_elevated = $respiratory_rate >= 40; + } + else { + $respiratory_rate_elevated = $respiratory_rate >= 30; + } + } + $send_to_hc_by_vitals = $encounter_data['fever'] || $respiratory_rate_elevated; + + $send_to_hc_by_muac = FALSE; + if (!empty($measurements_by_type['acute_illness_muac'])) { + $muac = $measurements_by_type['acute_illness_muac']->field_muac[LANGUAGE_NONE][0]['value']; + $send_to_hc_by_muac = $muac <= 11.5; + } + + $send_to_hc_by_nutrition = FALSE; + if (!empty($measurements_by_type['acute_illness_nutrition'])) { + $signs = $measurements_by_type['acute_illness_nutrition']->field_nutrition_signs[LANGUAGE_NONE]; + + $triggers = ['abdominal-distension', 'apathy', 'edema', 'poor-appetite']; + $brittle_hair = $dry_skin = FALSE; + foreach ($signs as $sign) { + if (in_array($sign['value'], $triggers)) { + $send_to_hc_by_nutrition = TRUE; + break; + } + + if ($sign['value'] == 'brittle-hair') { + $brittle_hair = TRUE; + } + else if ($sign['value'] == 'dry-skin') { + $dry_skin = TRUE; + } + + if ($brittle_hair && $dry_skin) { + $send_to_hc_by_nutrition = TRUE; + break; + } + } + } + + $no_improvement_without_danger_signs = !$danger_sign_present_on_subsequent_visit && + (hedley_reports_acute_illness_conditions_not_improving_on_subsequent_visit($encounter_data) || + $send_to_hc_by_vitals || $send_to_hc_by_muac || $send_to_hc_by_nutrition + ); + + $hc_recommended_to_come = FALSE; + if (!empty($measurements_by_type['hc_contact'])) { + $recommendations = $measurements_by_type['hc_contact'] ->field_hc_recommendation[LANGUAGE_NONE]; + foreach ($recommendations as $recommendation) { + if ($recommendation['value'] == 'come-to-hc') { + $hc_recommended_to_come = TRUE; + break; + } + } + } + + if ($no_improvement_without_danger_signs || + ($danger_sign_present_on_subsequent_visit && $diagnosis != 'covid19') || + ($danger_sign_present_on_subsequent_visit && $diagnosis == 'covid19' && $hc_recommended_to_come) + ) { + $expected[] = 'send_to_hc'; + } +} + +function hedley_reports_acute_illness_conditions_not_improving_on_subsequent_visit($encounter_data) { + $measurements_by_type = $encounter_data['measurements_by_type']; + + if (empty($measurements_by_type['acute_illness_danger_signs'])) { + return FALSE; + } + + $recorder_signs = $measurements_by_type['acute_illness_danger_signs']->field_acute_illness_danger_signs[LANGUAGE_NONE]; + + foreach ($recorder_signs as $recorder_sign) { + if ($recorder_sign['value'] == 'condition-not-improving') { + return TRUE; + } + } + + return FALSE; +} + function hedley_reports_get_acute_illness_diagnosis_by_previous_encounters($encounters_data) { foreach ($encounters_data as $encounter_data) { $encounter = $encounter_data['encounter']; From 3f5e7aee8899a93012d48dbf6609205e5a8870af Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 17:07:46 +0300 Subject: [PATCH 041/185] More adjustments [ci skip] --- .../elm/Pages/AcuteIllness/Activity/Utils.elm | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm b/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm index aedd859ae5..16bd8be25f 100644 --- a/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm +++ b/client/src/elm/Pages/AcuteIllness/Activity/Utils.elm @@ -1891,7 +1891,10 @@ expectNextStepsTaskFirstEncounter currentDate isChw person diagnosis measurement isChw && (diagnosis == Just DiagnosisCovid19Suspect) NextStepsContactHC -> - isChw && (diagnosis == Just DiagnosisCovid19Suspect) && isJust measurements.call114 && (not <| talkedTo114 measurements) + isChw + && (diagnosis == Just DiagnosisCovid19Suspect) + && isJust measurements.call114 + && (not <| talkedTo114 measurements) NextStepsMedicationDistribution -> medicationPrescribed @@ -1972,9 +1975,11 @@ expectNextStepsTaskSubsequentEncounter currentDate person diagnosis measurements -- No improvement, without danger signs. noImprovementOnSubsequentVisitWithoutDangerSigns currentDate person measurements || -- No improvement, with danger signs, and diagnosis is not Covid19 suspect. - (noImprovementOnSubsequentVisitWithDangerSigns currentDate person measurements && diagnosis /= Just DiagnosisCovid19Suspect) + (dangerSignPresentOnSubsequentVisit measurements + && (diagnosis /= Just DiagnosisCovid19Suspect) + ) || -- No improvement, with danger signs, diagnosis is Covid19, and HC recomended to send patient over. - (noImprovementOnSubsequentVisitWithDangerSigns currentDate person measurements + (dangerSignPresentOnSubsequentVisit measurements && (diagnosis == Just DiagnosisCovid19Suspect) && healthCenterRecommendedToCome measurements ) @@ -1982,7 +1987,7 @@ expectNextStepsTaskSubsequentEncounter currentDate person diagnosis measurements NextStepsContactHC -> not malariaDiagnosedAtCurrentEncounter && -- No improvement, with danger signs, and diagnosis is Covid19. - (noImprovementOnSubsequentVisitWithDangerSigns currentDate person measurements && diagnosis == Just DiagnosisCovid19Suspect) + (dangerSignPresentOnSubsequentVisit measurements && diagnosis == Just DiagnosisCovid19Suspect) NextStepsHealthEducation -> not malariaDiagnosedAtCurrentEncounter @@ -2083,7 +2088,7 @@ sendToHCByMalariaTesting ageMonths0To6 diagnosis = noImprovementOnSubsequentVisit : NominalDate -> Person -> AcuteIllnessMeasurements -> Bool noImprovementOnSubsequentVisit currentDate person measurements = noImprovementOnSubsequentVisitWithoutDangerSigns currentDate person measurements - || noImprovementOnSubsequentVisitWithDangerSigns currentDate person measurements + || dangerSignPresentOnSubsequentVisit measurements noImprovementOnSubsequentVisitWithoutDangerSigns : NominalDate -> Person -> AcuteIllnessMeasurements -> Bool @@ -2096,11 +2101,6 @@ noImprovementOnSubsequentVisitWithoutDangerSigns currentDate person measurements ) -noImprovementOnSubsequentVisitWithDangerSigns : NominalDate -> Person -> AcuteIllnessMeasurements -> Bool -noImprovementOnSubsequentVisitWithDangerSigns currentDate person measurements = - dangerSignPresentOnSubsequentVisit measurements - - conditionNotImprovingOnSubsequentVisit : AcuteIllnessMeasurements -> Bool conditionNotImprovingOnSubsequentVisit measurements = measurements.dangerSigns @@ -2756,15 +2756,13 @@ covidCaseConfirmed measurements = covidRapidTestResult : AcuteIllnessMeasurements -> Maybe RapidTestResult covidRapidTestResult measurements = - measurements.covidTesting - |> getMeasurementValueFunc + getMeasurementValueFunc measurements.covidTesting |> Maybe.map .result malariaRapidTestResult : AcuteIllnessMeasurements -> Maybe RapidTestResult malariaRapidTestResult measurements = - measurements.malariaTesting - |> getMeasurementValueFunc + getMeasurementValueFunc measurements.malariaTesting malariaDangerSignsPresent : AcuteIllnessMeasurements -> Bool From b97c453e9d145ca0f0aa417f4ccc27ec0bbe0967 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 17:15:05 +0300 Subject: [PATCH 042/185] Generate and store completion data [ci skip] --- .../custom/hedley_reports/hedley_reports.module | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 08a778b60d..72fdc8a98f 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2536,6 +2536,22 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant hedley_reports_acute_illness_add_physical_exam_activities($encounter_data, $expected); // If conditions match, add next steps activities. hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); + + $completed = []; + foreach ($expected as $measurement_type) { + if (!empty($measurements_by_type[$measurement_type])) { + $completed[] = $measurement_type; + } + } + + $completion_data = [ + 'start_date' => $start_date, + 'taken_by' => $encounter_data['taken_by'], + 'completion' => hedley_reports_generate_completion_result($expected, $completed, $mapping), + ]; + + $encounter->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); + node_save($encounter); } } From 32a2b194d0aaeb9c14bdedfc26194ab10e090f55 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 17:16:49 +0300 Subject: [PATCH 043/185] A fix [ci skip] --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 72fdc8a98f..e3ebbc9dd5 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2468,7 +2468,7 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant $encounter_data['start_date_obj'] = $start_date_obj; // Try to resolve age in months at a time encounter was performed. - $age_in_months = hedley_reports_resolve_age_in_months_for_individual_encounter($$encounter, $start_date_obj); + $age_in_months = hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj); $encounter_data['age_in_months'] = $age_in_months; $previous_encounters_data = array_slice($encounters_data, 0, $index); From 38f67b9507a09044aed937f39ea1fda032cfa92c Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 17:19:02 +0300 Subject: [PATCH 044/185] Another fox [ci skip] --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index e3ebbc9dd5..b526b5a6b7 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2555,7 +2555,7 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant } } -function hedley_reports_generate_acute_illness_expected_initial_activities($encounter_data, $start_date_obj) { +function hedley_reports_generate_acute_illness_expected_initial_activities($encounter_data) { // Activities that are shown at any type of encounter, // unconditionally. Existed with initial launch of the feature. $expected = [ From 113596c6d3f6095b65d2903b5cbc015f7d5e402b Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 17:32:41 +0300 Subject: [PATCH 045/185] Add data field to Acute Illness Encounter CT [ci skip] --- ..._acute_illness.features.field_instance.inc | 138 ++++++++++++++++++ .../hedley_acute_illness.info | 1 + .../hedley_acute_illness.strongarm.inc | 80 +++++----- 3 files changed, 179 insertions(+), 40 deletions(-) diff --git a/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.features.field_instance.inc b/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.features.field_instance.inc index 45a4f438d9..4d6f0a41ce 100644 --- a/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.features.field_instance.inc +++ b/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.features.field_instance.inc @@ -47,6 +47,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -223,6 +224,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -267,6 +269,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -311,6 +314,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -396,6 +400,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -538,6 +543,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -583,6 +589,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -628,6 +635,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -713,6 +721,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -888,6 +897,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -932,6 +942,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -976,6 +987,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1099,6 +1111,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1200,6 +1213,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1244,6 +1258,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1288,6 +1303,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1337,6 +1353,46 @@ function hedley_acute_illness_field_default_field_instances() { ), ); + // Exported field_instance: 'node-acute_illness_encounter-field_reports_data'. + $field_instances['node-acute_illness_encounter-field_reports_data'] = array( + 'bundle' => 'acute_illness_encounter', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 6, + ), + 'teaser' => array( + 'label' => 'above', + 'settings' => array(), + 'type' => 'hidden', + 'weight' => 0, + ), + ), + 'entity_type' => 'node', + 'field_name' => 'field_reports_data', + 'label' => 'Completion Data', + 'required' => 0, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'rows' => 5, + ), + 'type' => 'text_textarea', + 'weight' => 6, + ), + ); + // Exported field_instance: // 'node-acute_illness_encounter-field_sequence_number'. $field_instances['node-acute_illness_encounter-field_sequence_number'] = array( @@ -1458,6 +1514,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1654,6 +1711,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1698,6 +1756,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1742,6 +1801,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1827,6 +1887,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1973,6 +2034,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2017,6 +2079,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2061,6 +2124,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2146,6 +2210,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2247,6 +2312,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2329,6 +2395,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2373,6 +2440,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2458,6 +2526,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2808,6 +2877,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2852,6 +2922,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2938,6 +3009,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3023,6 +3095,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3260,6 +3333,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3499,6 +3573,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3543,6 +3618,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3634,6 +3710,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3838,6 +3915,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3938,6 +4016,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3982,6 +4061,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4026,6 +4106,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4148,6 +4229,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4285,6 +4367,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4329,6 +4412,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4410,6 +4494,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4494,6 +4579,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4631,6 +4717,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4675,6 +4762,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4719,6 +4807,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4803,6 +4892,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5051,6 +5141,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5095,6 +5186,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5139,6 +5231,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5224,6 +5317,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5362,6 +5456,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5406,6 +5501,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5488,6 +5584,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5572,6 +5669,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5709,6 +5807,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5753,6 +5852,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5834,6 +5934,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5919,6 +6020,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6056,6 +6158,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6100,6 +6203,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6144,6 +6248,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6229,6 +6334,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6368,6 +6474,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6412,6 +6519,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6494,6 +6602,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6578,6 +6687,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6678,6 +6788,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6722,6 +6833,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6840,6 +6952,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6925,6 +7038,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7487,6 +7601,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7531,6 +7646,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7668,6 +7784,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7985,6 +8102,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8224,6 +8342,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8268,6 +8387,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8312,6 +8432,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8481,6 +8602,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8768,6 +8890,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8812,6 +8935,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8856,6 +8980,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9082,6 +9207,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9182,6 +9308,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9226,6 +9353,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9270,6 +9398,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9392,6 +9521,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9492,6 +9622,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9536,6 +9667,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9580,6 +9712,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9702,6 +9835,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9885,6 +10019,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9929,6 +10064,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10011,6 +10147,7 @@ function hedley_acute_illness_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10116,6 +10253,7 @@ function hedley_acute_illness_field_default_field_instances() { t('Body temperature'); t('Chills Period'); t('Coke Colored Urine Period'); + t('Completion Data'); t('Contact date'); t('Contacts Trace Data'); t('Convulsions Period'); diff --git a/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.info b/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.info index bef452f450..b45f40a288 100644 --- a/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.info +++ b/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.info @@ -116,6 +116,7 @@ features[field_instance][] = node-acute_illness_danger_signs-field_nurse features[field_instance][] = node-acute_illness_danger_signs-field_person features[field_instance][] = node-acute_illness_danger_signs-field_shards features[field_instance][] = node-acute_illness_danger_signs-field_uuid +features[field_instance][] = node-acute_illness_encounter-field_reports_data features[field_instance][] = node-acute_illness_encounter-field_sequence_number features[field_instance][] = node-acute_illness_follow_up-field_acute_illness_diagnosis features[field_instance][] = node-acute_illness_follow_up-field_acute_illness_encounter diff --git a/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.strongarm.inc b/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.strongarm.inc index 42bbbd3559..4c877322fb 100644 --- a/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.strongarm.inc +++ b/server/hedley/modules/custom/hedley_acute_illness/hedley_acute_illness.strongarm.inc @@ -520,15 +520,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__acute_findings'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__acute_findings'] = $strongarm; @@ -537,15 +537,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__acute_illness_contacts_tracing'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__acute_illness_contacts_tracing'] = $strongarm; @@ -554,15 +554,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__acute_illness_core_exam'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__acute_illness_core_exam'] = $strongarm; @@ -571,15 +571,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__acute_illness_danger_signs'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__acute_illness_danger_signs'] = $strongarm; @@ -588,15 +588,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__acute_illness_follow_up'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__acute_illness_follow_up'] = $strongarm; @@ -605,15 +605,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__acute_illness_muac'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__acute_illness_muac'] = $strongarm; @@ -622,15 +622,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__acute_illness_nutrition'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__acute_illness_nutrition'] = $strongarm; @@ -639,15 +639,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__acute_illness_trace_contact'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__acute_illness_trace_contact'] = $strongarm; @@ -656,15 +656,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__acute_illness_vitals'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__acute_illness_vitals'] = $strongarm; @@ -673,15 +673,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__call_114'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__call_114'] = $strongarm; @@ -690,15 +690,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__covid_testing'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__covid_testing'] = $strongarm; @@ -707,15 +707,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__hc_contact'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__hc_contact'] = $strongarm; @@ -724,15 +724,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__health_education'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__health_education'] = $strongarm; @@ -741,15 +741,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__malaria_testing'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__malaria_testing'] = $strongarm; @@ -758,15 +758,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__medication_distribution'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__medication_distribution'] = $strongarm; @@ -775,15 +775,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__send_to_hc'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__send_to_hc'] = $strongarm; @@ -792,15 +792,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__symptoms_general'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__symptoms_general'] = $strongarm; @@ -809,15 +809,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__symptoms_respiratory'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__symptoms_respiratory'] = $strongarm; @@ -826,15 +826,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__treatment_history'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__treatment_history'] = $strongarm; @@ -843,15 +843,15 @@ function hedley_acute_illness_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__treatment_ongoing'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__treatment_ongoing'] = $strongarm; From 6dbaade48c73ff5140fe3da8a3997072de6f261a Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 18:32:47 +0300 Subject: [PATCH 046/185] Add acute illness into 'large data sets' script [ci skip] --- .../custom/hedley_reports/hedley_reports.module | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index b526b5a6b7..e48761b4c1 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -1979,8 +1979,9 @@ function hedley_reports_build_completion_results_app($health_center = NULL) { */ function hedley_reports_generate_completion_results_data($health_center) { $bundles = [ - 'nutrition_encounter', // Nutrition Individual data. + 'acute_illness_encounter', // Acute Illness data. 'attendance', // Nutrition Group data. + 'nutrition_encounter', // Nutrition Individual data. ]; $base_query = new EntityFieldQuery(); @@ -1996,6 +1997,7 @@ function hedley_reports_generate_completion_results_data($health_center) { } $data = [ + 'acute_illness' => [], 'nutrition_individual' => [], 'nutrition_group' => [], ]; @@ -2029,12 +2031,17 @@ function hedley_reports_generate_completion_results_data($health_center) { } switch ($node->type) { - case 'nutrition_encounter': - $data['nutrition_individual'][] = json_decode($json_data); + case 'acute_illness_encounter': + $data['acute_illness'][] = json_decode($json_data); break; case 'attendance': $data['nutrition_group'][] = json_decode($json_data); + break; + + case 'nutrition_encounter': + $data['nutrition_individual'][] = json_decode($json_data); + break; } // Explicitly unset large variables after use for memory optimization. From 1778a8d317a6105354ffa623074625137ed98494 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 18:57:17 +0300 Subject: [PATCH 047/185] View report on client [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 1 + server/elm/src/Backend/Completion/Model.elm | 27 + server/elm/src/Backend/Completion/Utils.elm | 76 + server/elm/src/Pages/Completion/Model.elm | 33 +- server/elm/src/Pages/Completion/Utils.elm | 78 +- server/elm/src/Pages/Completion/View.elm | 53 +- server/elm/src/Translate.elm | 172 +- .../custom/hedley_general/js/elm-main.js | 1553 ++++++++++------- 8 files changed, 1275 insertions(+), 718 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index 3e2d588435..b7c1dcc809 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -19,6 +19,7 @@ decodeCompletionData = |> required "site" decodeSite |> required "entity_name" string |> required "entity_type" decodeSelectedEntity + |> requiredAt [ "results", "acute_illness" ] (list (decodeEncounterData acuteIllnessActivityFromMapping)) |> requiredAt [ "results", "nutrition_individual" ] (list (decodeEncounterData nutritionChildActivityFromMapping)) |> requiredAt [ "results", "nutrition_group" ] (list (decodeNutritionGroupEncounterData nutritionMotherActivityFromMapping nutritionChildActivityFromMapping)) diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index ef537a9df3..779d725bd6 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -11,6 +11,7 @@ type alias CompletionData = { site : Site , entityName : String , entityType : SelectedEntity + , acuteIllnessData : List (EncounterData AcuteIllnessActivity) , nutritionIndividualData : List (EncounterData NutritionChildActivity) , nutritionGroupData : List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) } @@ -42,6 +43,32 @@ type alias ActivitiesCompletionData activity = } +type AcuteIllnessActivity + = AcuteIllnessAcuteFindings + | AcuteIllnessContactsTracing + | AcuteIllnessCoreExam + | AcuteIllnessDangerSigns + | AcuteIllnessFollowUp + | AcuteIllnessMUAC + | AcuteIllnessNutrition + | AcuteIllnessVitals + | AcuteIllnessCall114 + | AcuteIllnessCOVIDTesting + | AcuteIllnessExposure + | AcuteIllnessContactHC + | AcuteIllnessHealthEducation + | AcuteIllnessIsolation + | AcuteIllnessMalariaTesting + | AcuteIllnessMedicationDistribution + | AcuteIllnessSendToHC + | AcuteIllnessSymptomsGeneral + | AcuteIllnessSymptomsGI + | AcuteIllnessSymptomsRespiratory + | AcuteIllnessTravelHistory + | AcuteIllnessPriorTreatment + | AcuteIllnessOngoingTreatment + + type NutritionChildActivity = NutritionHeight | NutritionNutrition diff --git a/server/elm/src/Backend/Completion/Utils.elm b/server/elm/src/Backend/Completion/Utils.elm index c65065704e..961c191611 100644 --- a/server/elm/src/Backend/Completion/Utils.elm +++ b/server/elm/src/Backend/Completion/Utils.elm @@ -59,6 +59,82 @@ nutritionMotherActivityFromMapping mapped = Nothing +acuteIllnessActivityFromMapping : String -> Maybe AcuteIllnessActivity +acuteIllnessActivityFromMapping mapped = + case mapped of + "a" -> + Just AcuteIllnessAcuteFindings + + "b" -> + Just AcuteIllnessContactsTracing + + "c" -> + Just AcuteIllnessCoreExam + + "d" -> + Just AcuteIllnessDangerSigns + + "e" -> + Just AcuteIllnessFollowUp + + "f" -> + Just AcuteIllnessMUAC + + "g" -> + Just AcuteIllnessNutrition + + "h" -> + Just AcuteIllnessVitals + + "i" -> + Just AcuteIllnessCall114 + + "j" -> + Just AcuteIllnessCOVIDTesting + + "k" -> + Just AcuteIllnessExposure + + "l" -> + Just AcuteIllnessContactHC + + "m" -> + Just AcuteIllnessHealthEducation + + "n" -> + Just AcuteIllnessIsolation + + "o" -> + Just AcuteIllnessMalariaTesting + + "p" -> + Just AcuteIllnessMedicationDistribution + + "q" -> + Just AcuteIllnessSendToHC + + "r" -> + Just AcuteIllnessSymptomsGeneral + + "s" -> + Just AcuteIllnessSymptomsGI + + "t" -> + Just AcuteIllnessSymptomsRespiratory + + "u" -> + Just AcuteIllnessTravelHistory + + "v" -> + Just AcuteIllnessPriorTreatment + + "w" -> + Just AcuteIllnessOngoingTreatment + + _ -> + Nothing + + takenByToString : TakenBy -> String takenByToString value = case value of diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index 1b4c67f094..d1a486ed05 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -1,6 +1,6 @@ module Pages.Completion.Model exposing (..) -import Backend.Completion.Model exposing (NutritionChildActivity(..), NutritionMotherActivity(..), TakenBy) +import Backend.Completion.Model exposing (TakenBy) import Date exposing (Date) import DateSelector.Model exposing (DateSelectorConfig) @@ -27,8 +27,9 @@ emptyModel = type ReportType - = ReportNutritionIndividual + = ReportAcuteIllness | ReportNutritionGroup + | ReportNutritionIndividual type Msg @@ -39,31 +40,3 @@ type Msg | SetStartDateSelectorState (Maybe (DateSelectorConfig Msg)) | SetLimitDate Date | SetLimitDateSelectorState (Maybe (DateSelectorConfig Msg)) - - -allNutritionIndividualActivities : List NutritionChildActivity -allNutritionIndividualActivities = - [ NutritionHeight - , NutritionNutrition - , NutritionPhoto - , NutritionWeight - , NutritionMUAC - , NutritionContributingFactors - , NutritionFollowUp - , NutritionHealthEducation - , NutritionSendToHC - , NutritionNCDA - ] - - -allNutritionChildGroupActivities : List NutritionChildActivity -allNutritionChildGroupActivities = - allNutritionIndividualActivities ++ [ NutritionChildFbf ] - - -allNutritionMotherGroupActivities : List NutritionMotherActivity -allNutritionMotherGroupActivities = - [ NutritionFamilyPlanning - , NutritionLactation - , NutritionMotherFbf - ] diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index 6073bb59aa..9c6cabad54 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -1,27 +1,95 @@ module Pages.Completion.Utils exposing (..) -import Backend.Completion.Model exposing (TakenBy(..)) +import Backend.Completion.Model + exposing + ( AcuteIllnessActivity(..) + , NutritionChildActivity(..) + , NutritionMotherActivity(..) + , TakenBy(..) + ) import Pages.Completion.Model exposing (ReportType(..)) reportTypeToString : ReportType -> String reportTypeToString reportType = case reportType of - ReportNutritionIndividual -> - "nutrition-individual" + ReportAcuteIllness -> + "acute-illness" ReportNutritionGroup -> "nutrition-group" + ReportNutritionIndividual -> + "nutrition-individual" + reportTypeFromString : String -> Maybe ReportType reportTypeFromString reportType = case reportType of - "nutrition-individual" -> - Just ReportNutritionIndividual + "acute-illness" -> + Just ReportAcuteIllness "nutrition-group" -> Just ReportNutritionGroup + "nutrition-individual" -> + Just ReportNutritionIndividual + _ -> Nothing + + +allAcuteIllnessActivities : List AcuteIllnessActivity +allAcuteIllnessActivities = + [ AcuteIllnessAcuteFindings + , AcuteIllnessContactsTracing + , AcuteIllnessCoreExam + , AcuteIllnessDangerSigns + , AcuteIllnessFollowUp + , AcuteIllnessMUAC + , AcuteIllnessNutrition + , AcuteIllnessVitals + , AcuteIllnessCall114 + , AcuteIllnessCOVIDTesting + , AcuteIllnessExposure + , AcuteIllnessContactHC + , AcuteIllnessHealthEducation + , AcuteIllnessIsolation + , AcuteIllnessMalariaTesting + , AcuteIllnessMedicationDistribution + , AcuteIllnessSendToHC + , AcuteIllnessSymptomsGeneral + , AcuteIllnessSymptomsGI + , AcuteIllnessSymptomsRespiratory + , AcuteIllnessTravelHistory + , AcuteIllnessPriorTreatment + , AcuteIllnessOngoingTreatment + ] + + +allNutritionIndividualActivities : List NutritionChildActivity +allNutritionIndividualActivities = + [ NutritionHeight + , NutritionNutrition + , NutritionPhoto + , NutritionWeight + , NutritionMUAC + , NutritionContributingFactors + , NutritionFollowUp + , NutritionHealthEducation + , NutritionSendToHC + , NutritionNCDA + ] + + +allNutritionChildGroupActivities : List NutritionChildActivity +allNutritionChildGroupActivities = + allNutritionIndividualActivities ++ [ NutritionChildFbf ] + + +allNutritionMotherGroupActivities : List NutritionMotherActivity +allNutritionMotherGroupActivities = + [ NutritionFamilyPlanning + , NutritionLactation + , NutritionMotherFbf + ] diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index 97ce007a4f..438662dff4 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -4,7 +4,8 @@ import App.Types exposing (Language, Site) import AssocList as Dict exposing (Dict) import Backend.Completion.Model exposing - ( CompletionData + ( AcuteIllnessActivity(..) + , CompletionData , EncounterData , NutritionChildActivity(..) , NutritionGroupEncounterData @@ -24,7 +25,7 @@ import Html.Events exposing (onClick) import List.Extra import Maybe.Extra exposing (isJust, isNothing) import Pages.Completion.Model exposing (..) -import Pages.Completion.Utils exposing (reportTypeToString) +import Pages.Completion.Utils exposing (..) import Pages.Components.View exposing (viewNutritionMetricsResultsTable) import Pages.Model exposing (MetricsResultsTableData) import Pages.Utils exposing (launchDate, viewCustomSelectListInput, viewSelectListInput, wrapSelectListInput) @@ -169,11 +170,14 @@ viewCompletionData language currentDate themePath data model = Maybe.map3 (\reportType startDate limitDate -> case reportType of - ReportNutritionIndividual -> - viewNutritionIndividualReport language startDate limitDate model.takenBy data.nutritionIndividualData + ReportAcuteIllness -> + viewAcuteIllnessReport language startDate limitDate model.takenBy data.acuteIllnessData ReportNutritionGroup -> viewNutritionGroupReport language startDate limitDate model.takenBy data.nutritionGroupData + + ReportNutritionIndividual -> + viewNutritionIndividualReport language startDate limitDate model.takenBy data.nutritionIndividualData ) model.reportType model.startDate @@ -185,7 +189,7 @@ viewCompletionData language currentDate themePath data model = , div [ class "inputs" ] <| [ viewSelectListInput language model.reportType - [ ReportNutritionIndividual, ReportNutritionGroup ] + [ ReportAcuteIllness, ReportNutritionGroup, ReportNutritionIndividual ] reportTypeToString SetReportType Translate.CompletionReportType @@ -222,6 +226,14 @@ viewNutritionGroupReport language startDate limitDate mTakenBy reportData = |> div [ class "report nutrition-individual" ] +viewAcuteIllnessReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData AcuteIllnessActivity) -> Html Msg +viewAcuteIllnessReport language startDate limitDate mTakenBy reportData = + applyFilters startDate limitDate mTakenBy reportData + |> generateAcuteIllnessReportData language + |> viewNutritionMetricsResultsTable + |> div [ class "report acute-illness" ] + + applyFilters : NominalDate -> NominalDate @@ -315,6 +327,37 @@ generateNutritionGroupReportData language records = } +generateAcuteIllnessReportData : + Language + -> List (EncounterData AcuteIllnessActivity) + -> MetricsResultsTableData +generateAcuteIllnessReportData language records = + { heading = translate language Translate.AcuteIllness + , captions = generateCaptionsList language + , rows = + List.map + (\activity -> + let + expected = + countOccurrences (.completion >> .expectedActivities) activity records + + completed = + countOccurrences (.completion >> .completedActivities) activity records + in + [ translate language <| Translate.AcuteIllnessActivity activity + , String.fromInt expected + , String.fromInt completed + , calcualtePercentage completed expected + ] + ) + allAcuteIllnessActivities + } + + + +-- Helper functions. + + generateCaptionsList : Language -> List String generateCaptionsList language = [ translate language Translate.Activity diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 283487b0fb..76af8d4450 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -5,7 +5,13 @@ module Translate exposing ) import App.Types exposing (Language(..)) -import Backend.Completion.Model exposing (NutritionChildActivity(..), NutritionMotherActivity(..), TakenBy(..)) +import Backend.Completion.Model + exposing + ( AcuteIllnessActivity(..) + , NutritionChildActivity(..) + , NutritionMotherActivity(..) + , TakenBy(..) + ) import Backend.Reports.Model exposing (AcuteIllnessDiagnosis(..), NutritionReportTableType(..)) import Backend.Scoreboard.Model import Date @@ -55,6 +61,8 @@ type StringIdHttpError type TranslationId = ACHI | Activity + | AcuteIllness + | AcuteIllnessActivity AcuteIllnessActivity | AcuteIllnessDiagnosis AcuteIllnessDiagnosis | AcuteIllnessTotal | AcuteMalnutrition @@ -190,6 +198,152 @@ translationSet transId = , kirundi = Nothing } + AcuteIllness -> + { english = "Acute Illness" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessActivity activity -> + case activity of + AcuteIllnessAcuteFindings -> + { english = "Acute Findings" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessContactsTracing -> + { english = "Contacts Tracing" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessCoreExam -> + { english = "Core Exam" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessDangerSigns -> + { english = "Danger Signs" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessFollowUp -> + { english = "Follow Up" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessMUAC -> + { english = "MUAC" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessNutrition -> + { english = "Nutrition" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessVitals -> + { english = "Vitals" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessCall114 -> + { english = "Call 114" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessCOVIDTesting -> + { english = "COVID Testing" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessExposure -> + { english = "Exposure" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessContactHC -> + { english = "Contact HC" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessHealthEducation -> + { english = "Health Education" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessIsolation -> + { english = "Isolation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessMalariaTesting -> + { english = "Malaria Testing" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessMedicationDistribution -> + { english = "MedicationDistribution" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessSendToHC -> + { english = "Referal" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessSymptomsGeneral -> + { english = "Symptoms General" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessSymptomsGI -> + { english = "Symptoms GI" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessSymptomsRespiratory -> + { english = "Symptoms Respiratory" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessTravelHistory -> + { english = "Travel History" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessPriorTreatment -> + { english = "Prior Treatment" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + AcuteIllnessOngoingTreatment -> + { english = "Ongoing Treatment" + , kinyarwanda = Nothing + , kirundi = Nothing + } + AcuteIllnessDiagnosis diagnosis -> case diagnosis of DiagnosisCovid19Suspect -> @@ -356,14 +510,17 @@ translationSet transId = CompletionReportType reportType -> case reportType of - Pages.Completion.Model.ReportNutritionIndividual -> - { english = "Nutrition Individual" + Pages.Completion.Model.ReportAcuteIllness -> + translationSet AcuteIllness + + Pages.Completion.Model.ReportNutritionGroup -> + { english = "Nutrition Group" , kinyarwanda = Nothing , kirundi = Nothing } - Pages.Completion.Model.ReportNutritionGroup -> - { english = "Nutrition Group" + Pages.Completion.Model.ReportNutritionIndividual -> + { english = "Nutrition Individual" , kinyarwanda = Nothing , kirundi = Nothing } @@ -1047,10 +1204,7 @@ translationSet transId = ReportType reportType -> case reportType of ReportAcuteIllness -> - { english = "Acute Illness" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet AcuteIllness ReportDemographics -> { english = "Demographics" diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index dda0a4e407..65ea48d0d4 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5825,14 +5825,17 @@ var $elm_community$maybe_extra$Maybe$Extra$or = F2( return ma; } }); +var $author$project$Pages$Completion$Model$ReportAcuteIllness = {$: 'ReportAcuteIllness'}; var $author$project$Pages$Completion$Model$ReportNutritionGroup = {$: 'ReportNutritionGroup'}; var $author$project$Pages$Completion$Model$ReportNutritionIndividual = {$: 'ReportNutritionIndividual'}; var $author$project$Pages$Completion$Utils$reportTypeFromString = function (reportType) { switch (reportType) { - case 'nutrition-individual': - return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionIndividual); + case 'acute-illness': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportAcuteIllness); case 'nutrition-group': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionGroup); + case 'nutrition-individual': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionIndividual); default: return $elm$core$Maybe$Nothing; } @@ -6839,10 +6842,85 @@ var $author$project$Backend$Types$BackendReturn = F4( function (model, cmd, error, appMsgs) { return {appMsgs: appMsgs, cmd: cmd, error: error, model: model}; }); -var $author$project$Backend$Completion$Model$CompletionData = F5( - function (site, entityName, entityType, nutritionIndividualData, nutritionGroupData) { - return {entityName: entityName, entityType: entityType, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site}; - }); +var $author$project$Backend$Completion$Model$CompletionData = F6( + function (site, entityName, entityType, acuteIllnessData, nutritionIndividualData, nutritionGroupData) { + return {acuteIllnessData: acuteIllnessData, entityName: entityName, entityType: entityType, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site}; + }); +var $author$project$Backend$Completion$Model$AcuteIllnessAcuteFindings = {$: 'AcuteIllnessAcuteFindings'}; +var $author$project$Backend$Completion$Model$AcuteIllnessCOVIDTesting = {$: 'AcuteIllnessCOVIDTesting'}; +var $author$project$Backend$Completion$Model$AcuteIllnessCall114 = {$: 'AcuteIllnessCall114'}; +var $author$project$Backend$Completion$Model$AcuteIllnessContactHC = {$: 'AcuteIllnessContactHC'}; +var $author$project$Backend$Completion$Model$AcuteIllnessContactsTracing = {$: 'AcuteIllnessContactsTracing'}; +var $author$project$Backend$Completion$Model$AcuteIllnessCoreExam = {$: 'AcuteIllnessCoreExam'}; +var $author$project$Backend$Completion$Model$AcuteIllnessDangerSigns = {$: 'AcuteIllnessDangerSigns'}; +var $author$project$Backend$Completion$Model$AcuteIllnessExposure = {$: 'AcuteIllnessExposure'}; +var $author$project$Backend$Completion$Model$AcuteIllnessFollowUp = {$: 'AcuteIllnessFollowUp'}; +var $author$project$Backend$Completion$Model$AcuteIllnessHealthEducation = {$: 'AcuteIllnessHealthEducation'}; +var $author$project$Backend$Completion$Model$AcuteIllnessIsolation = {$: 'AcuteIllnessIsolation'}; +var $author$project$Backend$Completion$Model$AcuteIllnessMUAC = {$: 'AcuteIllnessMUAC'}; +var $author$project$Backend$Completion$Model$AcuteIllnessMalariaTesting = {$: 'AcuteIllnessMalariaTesting'}; +var $author$project$Backend$Completion$Model$AcuteIllnessMedicationDistribution = {$: 'AcuteIllnessMedicationDistribution'}; +var $author$project$Backend$Completion$Model$AcuteIllnessNutrition = {$: 'AcuteIllnessNutrition'}; +var $author$project$Backend$Completion$Model$AcuteIllnessOngoingTreatment = {$: 'AcuteIllnessOngoingTreatment'}; +var $author$project$Backend$Completion$Model$AcuteIllnessPriorTreatment = {$: 'AcuteIllnessPriorTreatment'}; +var $author$project$Backend$Completion$Model$AcuteIllnessSendToHC = {$: 'AcuteIllnessSendToHC'}; +var $author$project$Backend$Completion$Model$AcuteIllnessSymptomsGI = {$: 'AcuteIllnessSymptomsGI'}; +var $author$project$Backend$Completion$Model$AcuteIllnessSymptomsGeneral = {$: 'AcuteIllnessSymptomsGeneral'}; +var $author$project$Backend$Completion$Model$AcuteIllnessSymptomsRespiratory = {$: 'AcuteIllnessSymptomsRespiratory'}; +var $author$project$Backend$Completion$Model$AcuteIllnessTravelHistory = {$: 'AcuteIllnessTravelHistory'}; +var $author$project$Backend$Completion$Model$AcuteIllnessVitals = {$: 'AcuteIllnessVitals'}; +var $author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessAcuteFindings); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessContactsTracing); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessCoreExam); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessDangerSigns); + case 'e': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessFollowUp); + case 'f': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessMUAC); + case 'g': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessNutrition); + case 'h': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessVitals); + case 'i': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessCall114); + case 'j': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessCOVIDTesting); + case 'k': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessExposure); + case 'l': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessContactHC); + case 'm': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessHealthEducation); + case 'n': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessIsolation); + case 'o': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessMalariaTesting); + case 'p': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessMedicationDistribution); + case 'q': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessSendToHC); + case 'r': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessSymptomsGeneral); + case 's': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessSymptomsGI); + case 't': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessSymptomsRespiratory); + case 'u': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessTravelHistory); + case 'v': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessPriorTreatment); + case 'w': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$AcuteIllnessOngoingTreatment); + default: + return $elm$core$Maybe$Nothing; + } +}; var $author$project$Backend$Completion$Model$EncounterData = F3( function (startDate, takenBy, completion) { return {completion: completion, startDate: startDate, takenBy: takenBy}; @@ -7921,18 +7999,24 @@ var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( $elm$json$Json$Decode$list( $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_type', - $author$project$Backend$Completion$Decoder$decodeSelectedEntity, + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, + _List_fromArray( + ['results', 'acute_illness']), + $elm$json$Json$Decode$list( + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_name', - $elm$json$Json$Decode$string, + 'entity_type', + $author$project$Backend$Completion$Decoder$decodeSelectedEntity, A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'site', - $author$project$Backend$Decoder$decodeSite, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData)))))); + 'entity_name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData))))))); var $author$project$Backend$Completion$Update$update = F3( function (currentDate, msg, model) { var value = msg.a; @@ -9688,6 +9772,7 @@ var $author$project$Translate$HttpError = function (a) { return {$: 'HttpError', a: a}; }; var $elm$json$Json$Decode$decodeString = _Json_runOnString; +var $author$project$Translate$AcuteIllness = {$: 'AcuteIllness'}; var $author$project$Translate$Cell = {$: 'Cell'}; var $author$project$Translate$District = {$: 'District'}; var $author$project$Translate$Global = {$: 'Global'}; @@ -9876,6 +9961,58 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'ACHI', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Activity': return {english: 'Activity', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllness': + return {english: 'Acute Illness', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessActivity': + var activity = transId.a; + switch (activity.$) { + case 'AcuteIllnessAcuteFindings': + return {english: 'Acute Findings', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessContactsTracing': + return {english: 'Contacts Tracing', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessCoreExam': + return {english: 'Core Exam', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessDangerSigns': + return {english: 'Danger Signs', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessFollowUp': + return {english: 'Follow Up', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessMUAC': + return {english: 'MUAC', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessNutrition': + return {english: 'Nutrition', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessVitals': + return {english: 'Vitals', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessCall114': + return {english: 'Call 114', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessCOVIDTesting': + return {english: 'COVID Testing', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessExposure': + return {english: 'Exposure', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessContactHC': + return {english: 'Contact HC', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessHealthEducation': + return {english: 'Health Education', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessIsolation': + return {english: 'Isolation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessMalariaTesting': + return {english: 'Malaria Testing', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessMedicationDistribution': + return {english: 'MedicationDistribution', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessSendToHC': + return {english: 'Referal', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessSymptomsGeneral': + return {english: 'Symptoms General', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessSymptomsGI': + return {english: 'Symptoms GI', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessSymptomsRespiratory': + return {english: 'Symptoms Respiratory', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessTravelHistory': + return {english: 'Travel History', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'AcuteIllnessPriorTreatment': + return {english: 'Prior Treatment', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + default: + return {english: 'Ongoing Treatment', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + } case 'AcuteIllnessDiagnosis': var diagnosis = transId.a; switch (diagnosis.$) { @@ -9996,10 +10133,15 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Completed', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'CompletionReportType': var reportType = transId.a; - if (reportType.$ === 'ReportNutritionIndividual') { - return {english: 'Nutrition Individual', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; - } else { - return {english: 'Nutrition Group', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + switch (reportType.$) { + case 'ReportAcuteIllness': + var $temp$transId = $author$project$Translate$AcuteIllness; + transId = $temp$transId; + continue translationSet; + case 'ReportNutritionGroup': + return {english: 'Nutrition Group', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + default: + return {english: 'Nutrition Individual', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; } case 'CBNP': return {english: 'CBNP', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; @@ -10392,7 +10534,9 @@ var $author$project$Translate$translationSet = function (transId) { var reportType = transId.a; switch (reportType.$) { case 'ReportAcuteIllness': - return {english: 'Acute Illness', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$AcuteIllness; + transId = $temp$transId; + continue translationSet; case 'ReportDemographics': return {english: 'Demographics', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'ReportNutrition': @@ -11398,10 +11542,13 @@ var $elm$html$Html$Events$onClick = function (msg) { $elm$json$Json$Decode$succeed(msg)); }; var $author$project$Pages$Completion$Utils$reportTypeToString = function (reportType) { - if (reportType.$ === 'ReportNutritionIndividual') { - return 'nutrition-individual'; - } else { - return 'nutrition-group'; + switch (reportType.$) { + case 'ReportAcuteIllness': + return 'acute-illness'; + case 'ReportNutritionGroup': + return 'nutrition-group'; + default: + return 'nutrition-individual'; } }; var $author$project$Backend$Completion$Utils$takenByToString = function (value) { @@ -11414,131 +11561,532 @@ var $author$project$Backend$Completion$Utils$takenByToString = function (value) return 'unknown'; } }; -var $author$project$Translate$Save = {$: 'Save'}; -var $author$project$Translate$MonthLabel = {$: 'MonthLabel'}; -var $author$project$Translate$YearLabel = {$: 'YearLabel'}; -var $justinmimbs$date$Date$clamp = F3( - function (dateA, dateB, dateX) { - var a = dateA.a; - var b = dateB.a; - var x = dateX.a; - return (_Utils_cmp(x, a) < 0) ? dateA : ((_Utils_cmp(b, x) < 0) ? dateB : dateX); +var $author$project$Pages$Completion$View$applyFilters = F3( + function (startDate, limitDate, mTakenBy) { + return $elm$core$List$filter( + function (encounter) { + var takenByCondition = A2( + $elm$core$Maybe$withDefault, + true, + A2( + $elm$core$Maybe$map, + function (takenBy) { + return _Utils_eq( + encounter.takenBy, + $elm$core$Maybe$Just(takenBy)); + }, + mTakenBy)); + return (!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), + $elm$core$Basics$LT)) && ((!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, limitDate), + $elm$core$Basics$GT)) && takenByCondition); + }); }); -var $elm$html$Html$p = _VirtualDom_node('p'); -var $author$project$DateSelector$Selector$Dimmed = {$: 'Dimmed'}; -var $author$project$DateSelector$Selector$Disabled = {$: 'Disabled'}; -var $author$project$DateSelector$Selector$Normal = {$: 'Normal'}; -var $author$project$DateSelector$Selector$Selected = {$: 'Selected'}; -var $author$project$DateSelector$Selector$classNameFromState = function (state) { - switch (state.$) { - case 'Normal': - return ''; - case 'Dimmed': - return 'date-selector--dimmed'; - case 'Disabled': - return 'date-selector--disabled'; - default: - return 'date-selector--selected'; - } -}; -var $justinmimbs$date$Date$fromRataDie = function (rd) { - return $justinmimbs$date$Date$RD(rd); +var $author$project$Translate$AcuteIllnessActivity = function (a) { + return {$: 'AcuteIllnessActivity', a: a}; }; -var $elm$core$List$drop = F2( - function (n, list) { - drop: - while (true) { - if (n <= 0) { - return list; - } else { - if (!list.b) { - return list; - } else { - var x = list.a; - var xs = list.b; - var $temp$n = n - 1, - $temp$list = xs; - n = $temp$n; - list = $temp$list; - continue drop; - } - } - } +var $author$project$Pages$Completion$Utils$allAcuteIllnessActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$AcuteIllnessAcuteFindings, $author$project$Backend$Completion$Model$AcuteIllnessContactsTracing, $author$project$Backend$Completion$Model$AcuteIllnessCoreExam, $author$project$Backend$Completion$Model$AcuteIllnessDangerSigns, $author$project$Backend$Completion$Model$AcuteIllnessFollowUp, $author$project$Backend$Completion$Model$AcuteIllnessMUAC, $author$project$Backend$Completion$Model$AcuteIllnessNutrition, $author$project$Backend$Completion$Model$AcuteIllnessVitals, $author$project$Backend$Completion$Model$AcuteIllnessCall114, $author$project$Backend$Completion$Model$AcuteIllnessCOVIDTesting, $author$project$Backend$Completion$Model$AcuteIllnessExposure, $author$project$Backend$Completion$Model$AcuteIllnessContactHC, $author$project$Backend$Completion$Model$AcuteIllnessHealthEducation, $author$project$Backend$Completion$Model$AcuteIllnessIsolation, $author$project$Backend$Completion$Model$AcuteIllnessMalariaTesting, $author$project$Backend$Completion$Model$AcuteIllnessMedicationDistribution, $author$project$Backend$Completion$Model$AcuteIllnessSendToHC, $author$project$Backend$Completion$Model$AcuteIllnessSymptomsGeneral, $author$project$Backend$Completion$Model$AcuteIllnessSymptomsGI, $author$project$Backend$Completion$Model$AcuteIllnessSymptomsRespiratory, $author$project$Backend$Completion$Model$AcuteIllnessTravelHistory, $author$project$Backend$Completion$Model$AcuteIllnessPriorTreatment, $author$project$Backend$Completion$Model$AcuteIllnessOngoingTreatment]); +var $myrho$elm_round$Round$addSign = F2( + function (signed, str) { + var isNotZero = A2( + $elm$core$List$any, + function (c) { + return (!_Utils_eq( + c, + _Utils_chr('0'))) && (!_Utils_eq( + c, + _Utils_chr('.'))); + }, + $elm$core$String$toList(str)); + return _Utils_ap( + (signed && isNotZero) ? '-' : '', + str); }); -var $elm$core$List$takeReverse = F3( - function (n, list, kept) { - takeReverse: - while (true) { - if (n <= 0) { - return kept; - } else { - if (!list.b) { - return kept; - } else { - var x = list.a; - var xs = list.b; - var $temp$n = n - 1, - $temp$list = xs, - $temp$kept = A2($elm$core$List$cons, x, kept); - n = $temp$n; - list = $temp$list; - kept = $temp$kept; - continue takeReverse; - } - } +var $elm$core$String$fromFloat = _String_fromNumber; +var $elm$core$Char$fromCode = _Char_fromCode; +var $myrho$elm_round$Round$increaseNum = function (_v0) { + var head = _v0.a; + var tail = _v0.b; + if (_Utils_eq( + head, + _Utils_chr('9'))) { + var _v1 = $elm$core$String$uncons(tail); + if (_v1.$ === 'Nothing') { + return '01'; + } else { + var headtail = _v1.a; + return A2( + $elm$core$String$cons, + _Utils_chr('0'), + $myrho$elm_round$Round$increaseNum(headtail)); } + } else { + var c = $elm$core$Char$toCode(head); + return ((c >= 48) && (c < 57)) ? A2( + $elm$core$String$cons, + $elm$core$Char$fromCode(c + 1), + tail) : '0'; + } +}; +var $elm$core$Basics$isInfinite = _Basics_isInfinite; +var $elm$core$Basics$isNaN = _Basics_isNaN; +var $elm$core$String$padRight = F3( + function (n, _char, string) { + return _Utils_ap( + string, + A2( + $elm$core$String$repeat, + n - $elm$core$String$length(string), + $elm$core$String$fromChar(_char))); }); -var $elm$core$List$takeTailRec = F2( - function (n, list) { - return $elm$core$List$reverse( - A3($elm$core$List$takeReverse, n, list, _List_Nil)); - }); -var $elm$core$List$takeFast = F3( - function (ctr, n, list) { - if (n <= 0) { - return _List_Nil; +var $elm$core$String$reverse = _String_reverse; +var $myrho$elm_round$Round$splitComma = function (str) { + var _v0 = A2($elm$core$String$split, '.', str); + if (_v0.b) { + if (_v0.b.b) { + var before = _v0.a; + var _v1 = _v0.b; + var after = _v1.a; + return _Utils_Tuple2(before, after); } else { - var _v0 = _Utils_Tuple2(n, list); - _v0$1: - while (true) { - _v0$5: - while (true) { - if (!_v0.b.b) { - return list; - } else { - if (_v0.b.b.b) { - switch (_v0.a) { - case 1: - break _v0$1; - case 2: - var _v2 = _v0.b; - var x = _v2.a; - var _v3 = _v2.b; - var y = _v3.a; - return _List_fromArray( - [x, y]); - case 3: - if (_v0.b.b.b.b) { - var _v4 = _v0.b; - var x = _v4.a; - var _v5 = _v4.b; - var y = _v5.a; - var _v6 = _v5.b; - var z = _v6.a; - return _List_fromArray( - [x, y, z]); - } else { - break _v0$5; - } - default: - if (_v0.b.b.b.b && _v0.b.b.b.b.b) { - var _v7 = _v0.b; - var x = _v7.a; - var _v8 = _v7.b; - var y = _v8.a; - var _v9 = _v8.b; - var z = _v9.a; - var _v10 = _v9.b; + var before = _v0.a; + return _Utils_Tuple2(before, '0'); + } + } else { + return _Utils_Tuple2('0', '0'); + } +}; +var $elm$core$Tuple$mapFirst = F2( + function (func, _v0) { + var x = _v0.a; + var y = _v0.b; + return _Utils_Tuple2( + func(x), + y); + }); +var $myrho$elm_round$Round$toDecimal = function (fl) { + var _v0 = A2( + $elm$core$String$split, + 'e', + $elm$core$String$fromFloat( + $elm$core$Basics$abs(fl))); + if (_v0.b) { + if (_v0.b.b) { + var num = _v0.a; + var _v1 = _v0.b; + var exp = _v1.a; + var e = A2( + $elm$core$Maybe$withDefault, + 0, + $elm$core$String$toInt( + A2($elm$core$String$startsWith, '+', exp) ? A2($elm$core$String$dropLeft, 1, exp) : exp)); + var _v2 = $myrho$elm_round$Round$splitComma(num); + var before = _v2.a; + var after = _v2.b; + var total = _Utils_ap(before, after); + var zeroed = (e < 0) ? A2( + $elm$core$Maybe$withDefault, + '0', + A2( + $elm$core$Maybe$map, + function (_v3) { + var a = _v3.a; + var b = _v3.b; + return a + ('.' + b); + }, + A2( + $elm$core$Maybe$map, + $elm$core$Tuple$mapFirst($elm$core$String$fromChar), + $elm$core$String$uncons( + _Utils_ap( + A2( + $elm$core$String$repeat, + $elm$core$Basics$abs(e), + '0'), + total))))) : A3( + $elm$core$String$padRight, + e + 1, + _Utils_chr('0'), + total); + return _Utils_ap( + (fl < 0) ? '-' : '', + zeroed); + } else { + var num = _v0.a; + return _Utils_ap( + (fl < 0) ? '-' : '', + num); + } + } else { + return ''; + } +}; +var $myrho$elm_round$Round$roundFun = F3( + function (functor, s, fl) { + if ($elm$core$Basics$isInfinite(fl) || $elm$core$Basics$isNaN(fl)) { + return $elm$core$String$fromFloat(fl); + } else { + var signed = fl < 0; + var _v0 = $myrho$elm_round$Round$splitComma( + $myrho$elm_round$Round$toDecimal( + $elm$core$Basics$abs(fl))); + var before = _v0.a; + var after = _v0.b; + var r = $elm$core$String$length(before) + s; + var normalized = _Utils_ap( + A2($elm$core$String$repeat, (-r) + 1, '0'), + A3( + $elm$core$String$padRight, + r, + _Utils_chr('0'), + _Utils_ap(before, after))); + var totalLen = $elm$core$String$length(normalized); + var roundDigitIndex = A2($elm$core$Basics$max, 1, r); + var increase = A2( + functor, + signed, + A3($elm$core$String$slice, roundDigitIndex, totalLen, normalized)); + var remains = A3($elm$core$String$slice, 0, roundDigitIndex, normalized); + var num = increase ? $elm$core$String$reverse( + A2( + $elm$core$Maybe$withDefault, + '1', + A2( + $elm$core$Maybe$map, + $myrho$elm_round$Round$increaseNum, + $elm$core$String$uncons( + $elm$core$String$reverse(remains))))) : remains; + var numLen = $elm$core$String$length(num); + var numZeroed = (num === '0') ? num : ((s <= 0) ? _Utils_ap( + num, + A2( + $elm$core$String$repeat, + $elm$core$Basics$abs(s), + '0')) : ((_Utils_cmp( + s, + $elm$core$String$length(after)) < 0) ? (A3($elm$core$String$slice, 0, numLen - s, num) + ('.' + A3($elm$core$String$slice, numLen - s, numLen, num))) : _Utils_ap( + before + '.', + A3( + $elm$core$String$padRight, + s, + _Utils_chr('0'), + after)))); + return A2($myrho$elm_round$Round$addSign, signed, numZeroed); + } + }); +var $myrho$elm_round$Round$round = $myrho$elm_round$Round$roundFun( + F2( + function (signed, str) { + var _v0 = $elm$core$String$uncons(str); + if (_v0.$ === 'Nothing') { + return false; + } else { + if ('5' === _v0.a.a.valueOf()) { + if (_v0.a.b === '') { + var _v1 = _v0.a; + return !signed; + } else { + var _v2 = _v0.a; + return true; + } + } else { + var _v3 = _v0.a; + var _int = _v3.a; + return function (i) { + return ((i > 53) && signed) || ((i >= 53) && (!signed)); + }( + $elm$core$Char$toCode(_int)); + } + } + })); +var $author$project$Pages$Completion$View$calcualtePercentage = F2( + function (nominator, total) { + return (!total) ? '0' : (A2($myrho$elm_round$Round$round, 2, (nominator / total) * 100) + '%'); + }); +var $author$project$Pages$Completion$View$countOccurrences = F3( + function (resolveFunc, activity, data) { + return $elm$core$List$length( + A2( + $elm$core$List$filter, + A2( + $elm$core$Basics$composeR, + resolveFunc, + $elm$core$List$member(activity)), + data)); + }); +var $author$project$Translate$Activity = {$: 'Activity'}; +var $author$project$Translate$Completed = {$: 'Completed'}; +var $author$project$Translate$Expected = {$: 'Expected'}; +var $author$project$Pages$Completion$View$generateCaptionsList = function (language) { + return _List_fromArray( + [ + A2($author$project$Translate$translate, language, $author$project$Translate$Activity), + A2($author$project$Translate$translate, language, $author$project$Translate$Expected), + A2($author$project$Translate$translate, language, $author$project$Translate$Completed), + '%' + ]); +}; +var $author$project$Pages$Completion$View$generateAcuteIllnessReportData = F2( + function (language, records) { + return { + captions: $author$project$Pages$Completion$View$generateCaptionsList(language), + heading: A2($author$project$Translate$translate, language, $author$project$Translate$AcuteIllness), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.expectedActivities; + }), + activity, + records); + var completed = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.completedActivities; + }), + activity, + records); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$AcuteIllnessActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) + ]); + }, + $author$project$Pages$Completion$Utils$allAcuteIllnessActivities) + }; + }); +var $elm$html$Html$Attributes$classList = function (classes) { + return $elm$html$Html$Attributes$class( + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $elm$core$Tuple$first, + A2($elm$core$List$filter, $elm$core$Tuple$second, classes)))); +}; +var $author$project$Pages$Components$View$viewCustomCells = F2( + function (labelClass, valueClass) { + return $elm$core$List$indexedMap( + F2( + function (index, cellText) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$classList( + _List_fromArray( + [ + _Utils_Tuple2('item', true), + _Utils_Tuple2(labelClass, !index), + _Utils_Tuple2(valueClass, !(!index)) + ])) + ]), + _List_fromArray( + [ + $elm$html$Html$text(cellText) + ])); + })); + }); +var $author$project$Pages$Components$View$viewNutritionMetricsResultsTable = function (data) { + var viewRow = function (cells) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('row') + ]), + A3($author$project$Pages$Components$View$viewCustomCells, 'row-label', 'value', cells)); + }; + var captionsRow = A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('row') + ]), + A3($author$project$Pages$Components$View$viewCustomCells, 'row-label', 'heading', data.captions)); + return _List_fromArray( + [ + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('section heading') + ]), + _List_fromArray( + [ + $elm$html$Html$text(data.heading) + ])), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('table wide') + ]), + A2( + $elm$core$List$cons, + captionsRow, + A2($elm$core$List$map, viewRow, data.rows))) + ]); +}; +var $author$project$Pages$Completion$View$viewAcuteIllnessReport = F5( + function (language, startDate, limitDate, mTakenBy, reportData) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report acute-illness') + ]), + $author$project$Pages$Components$View$viewNutritionMetricsResultsTable( + A2( + $author$project$Pages$Completion$View$generateAcuteIllnessReportData, + language, + A4($author$project$Pages$Completion$View$applyFilters, startDate, limitDate, mTakenBy, reportData)))); + }); +var $author$project$Translate$Save = {$: 'Save'}; +var $author$project$Translate$MonthLabel = {$: 'MonthLabel'}; +var $author$project$Translate$YearLabel = {$: 'YearLabel'}; +var $justinmimbs$date$Date$clamp = F3( + function (dateA, dateB, dateX) { + var a = dateA.a; + var b = dateB.a; + var x = dateX.a; + return (_Utils_cmp(x, a) < 0) ? dateA : ((_Utils_cmp(b, x) < 0) ? dateB : dateX); + }); +var $elm$html$Html$p = _VirtualDom_node('p'); +var $author$project$DateSelector$Selector$Dimmed = {$: 'Dimmed'}; +var $author$project$DateSelector$Selector$Disabled = {$: 'Disabled'}; +var $author$project$DateSelector$Selector$Normal = {$: 'Normal'}; +var $author$project$DateSelector$Selector$Selected = {$: 'Selected'}; +var $author$project$DateSelector$Selector$classNameFromState = function (state) { + switch (state.$) { + case 'Normal': + return ''; + case 'Dimmed': + return 'date-selector--dimmed'; + case 'Disabled': + return 'date-selector--disabled'; + default: + return 'date-selector--selected'; + } +}; +var $justinmimbs$date$Date$fromRataDie = function (rd) { + return $justinmimbs$date$Date$RD(rd); +}; +var $elm$core$List$drop = F2( + function (n, list) { + drop: + while (true) { + if (n <= 0) { + return list; + } else { + if (!list.b) { + return list; + } else { + var x = list.a; + var xs = list.b; + var $temp$n = n - 1, + $temp$list = xs; + n = $temp$n; + list = $temp$list; + continue drop; + } + } + } + }); +var $elm$core$List$takeReverse = F3( + function (n, list, kept) { + takeReverse: + while (true) { + if (n <= 0) { + return kept; + } else { + if (!list.b) { + return kept; + } else { + var x = list.a; + var xs = list.b; + var $temp$n = n - 1, + $temp$list = xs, + $temp$kept = A2($elm$core$List$cons, x, kept); + n = $temp$n; + list = $temp$list; + kept = $temp$kept; + continue takeReverse; + } + } + } + }); +var $elm$core$List$takeTailRec = F2( + function (n, list) { + return $elm$core$List$reverse( + A3($elm$core$List$takeReverse, n, list, _List_Nil)); + }); +var $elm$core$List$takeFast = F3( + function (ctr, n, list) { + if (n <= 0) { + return _List_Nil; + } else { + var _v0 = _Utils_Tuple2(n, list); + _v0$1: + while (true) { + _v0$5: + while (true) { + if (!_v0.b.b) { + return list; + } else { + if (_v0.b.b.b) { + switch (_v0.a) { + case 1: + break _v0$1; + case 2: + var _v2 = _v0.b; + var x = _v2.a; + var _v3 = _v2.b; + var y = _v3.a; + return _List_fromArray( + [x, y]); + case 3: + if (_v0.b.b.b.b) { + var _v4 = _v0.b; + var x = _v4.a; + var _v5 = _v4.b; + var y = _v5.a; + var _v6 = _v5.b; + var z = _v6.a; + return _List_fromArray( + [x, y, z]); + } else { + break _v0$5; + } + default: + if (_v0.b.b.b.b && _v0.b.b.b.b.b) { + var _v7 = _v0.b; + var x = _v7.a; + var _v8 = _v7.b; + var y = _v8.a; + var _v9 = _v8.b; + var z = _v9.a; + var _v10 = _v9.b; var w = _v10.a; var tl = _v10.b; return (ctr > 1000) ? A2( @@ -12284,464 +12832,202 @@ var $author$project$DateSelector$Selector$viewPopup = F4( var daysSection = A2( $elm$html$Html$div, _List_fromArray( - [ - $elm$html$Html$Attributes$class('days') - ]), - _List_fromArray( - [ - A2( - $elm$core$Maybe$withDefault, - $author$project$DateSelector$Selector$viewDateTableDisabled(minimum), - A2( - $elm$core$Maybe$map, - A2($author$project$DateSelector$Selector$viewDateTable, minimum, maximum), - maybeSelected)) - ])); - return A2( - $elm$html$Html$map, - A2($justinmimbs$date$Date$clamp, minimum, maximum), - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('calendar') - ]), - _List_fromArray( - [yearSection, monthSection, daysSection]))); - }); -var $author$project$DateSelector$SelectorPopup$view = F6( - function (language, toSelect, toClose, minimum, maximum, selected) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('date-selector-popup') - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$map, - toSelect, - A4($author$project$DateSelector$Selector$viewPopup, language, minimum, maximum, selected)), - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('ui button save'), - $elm$html$Html$Events$onClick(toClose) - ]), - _List_fromArray( - [ - $elm$html$Html$text( - A2($author$project$Translate$translate, language, $author$project$Translate$Save)) - ])) - ])); - }); -var $author$project$DateSelector$SelectorPopup$viewCalendarPopup = F3( - function (language, popupState, selected) { - return A2( - $elm$core$Maybe$map, - function (config) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('ui active modal calendar-popup') - ]), - _List_fromArray( - [ - A6($author$project$DateSelector$SelectorPopup$view, language, config.select, config.close, config.dateFrom, config.dateTo, selected) - ])); - }, - popupState); - }); -var $author$project$Pages$Utils$customEmptySelectOption = F2( - function (label, isSelected) { - return A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value(''), - $elm$html$Html$Attributes$selected(isSelected) - ]), - _List_fromArray( - [ - $elm$html$Html$text(label) - ])); - }); -var $elm$html$Html$Events$alwaysStop = function (x) { - return _Utils_Tuple2(x, true); -}; -var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { - return {$: 'MayStopPropagation', a: a}; -}; -var $elm$html$Html$Events$stopPropagationOn = F2( - function (event, decoder) { - return A2( - $elm$virtual_dom$VirtualDom$on, - event, - $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); - }); -var $elm$html$Html$Events$targetValue = A2( - $elm$json$Json$Decode$at, - _List_fromArray( - ['target', 'value']), - $elm$json$Json$Decode$string); -var $elm$html$Html$Events$onInput = function (tagger) { - return A2( - $elm$html$Html$Events$stopPropagationOn, - 'input', - A2( - $elm$json$Json$Decode$map, - $elm$html$Html$Events$alwaysStop, - A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); -}; -var $author$project$Pages$Utils$viewCustomSelectListInput = F6( - function (currentValue, options, toStringFunc, setMsg, inputClass, emptyOptionLabel) { - var emptyOption = A2( - $elm$core$Maybe$withDefault, - $author$project$Gizra$Html$emptyNode, - A2( - $elm$core$Maybe$map, - function (label) { - return A2( - $author$project$Pages$Utils$customEmptySelectOption, - label, - _Utils_eq(currentValue, $elm$core$Maybe$Nothing)); - }, - emptyOptionLabel)); - return A2( - $elm$html$Html$select, - _List_fromArray( - [ - $elm$html$Html$Events$onInput(setMsg), - $elm$html$Html$Attributes$class(inputClass) - ]), - A2( - $elm$core$List$cons, - emptyOption, - A2( - $elm$core$List$map, - function (_v0) { - var label = _v0.a; - var value_ = _v0.b; - return A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value( - toStringFunc(value_)), - $elm$html$Html$Attributes$selected( - _Utils_eq( - currentValue, - $elm$core$Maybe$Just(value_))) - ]), - _List_fromArray( - [ - $elm$html$Html$text(label) - ])); - }, - options))); - }); -var $author$project$Gizra$Html$showMaybe = $elm$core$Maybe$withDefault($author$project$Gizra$Html$emptyNode); -var $author$project$Utils$Html$viewCustomModal = function (extraClasses) { - var classes = A2( - $elm$core$String$join, - ' ', - A2($elm$core$List$cons, 'overlay', extraClasses)); - return A2( - $elm$core$Basics$composeL, - $author$project$Gizra$Html$showMaybe, - $elm$core$Maybe$map( - function (modal) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class(classes) - ]), - _List_fromArray( - [modal])); - })); -}; -var $author$project$Utils$Html$viewModal = $author$project$Utils$Html$viewCustomModal(_List_Nil); -var $author$project$Pages$Completion$View$applyFilters = F3( - function (startDate, limitDate, mTakenBy) { - return $elm$core$List$filter( - function (encounter) { - var takenByCondition = A2( + [ + $elm$html$Html$Attributes$class('days') + ]), + _List_fromArray( + [ + A2( $elm$core$Maybe$withDefault, - true, + $author$project$DateSelector$Selector$viewDateTableDisabled(minimum), A2( $elm$core$Maybe$map, - function (takenBy) { - return _Utils_eq( - encounter.takenBy, - $elm$core$Maybe$Just(takenBy)); - }, - mTakenBy)); - return (!_Utils_eq( - A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), - $elm$core$Basics$LT)) && ((!_Utils_eq( - A2($justinmimbs$date$Date$compare, encounter.startDate, limitDate), - $elm$core$Basics$GT)) && takenByCondition); - }); - }); -var $author$project$Translate$NutritionChildActivity = function (a) { - return {$: 'NutritionChildActivity', a: a}; -}; -var $author$project$Translate$NutritionGroup = {$: 'NutritionGroup'}; -var $author$project$Translate$NutritionMotherActivity = function (a) { - return {$: 'NutritionMotherActivity', a: a}; -}; -var $author$project$Pages$Completion$Model$allNutritionIndividualActivities = _List_fromArray( - [$author$project$Backend$Completion$Model$NutritionHeight, $author$project$Backend$Completion$Model$NutritionNutrition, $author$project$Backend$Completion$Model$NutritionPhoto, $author$project$Backend$Completion$Model$NutritionWeight, $author$project$Backend$Completion$Model$NutritionMUAC, $author$project$Backend$Completion$Model$NutritionContributingFactors, $author$project$Backend$Completion$Model$NutritionFollowUp, $author$project$Backend$Completion$Model$NutritionHealthEducation, $author$project$Backend$Completion$Model$NutritionSendToHC, $author$project$Backend$Completion$Model$NutritionNCDA]); -var $author$project$Pages$Completion$Model$allNutritionChildGroupActivities = _Utils_ap( - $author$project$Pages$Completion$Model$allNutritionIndividualActivities, - _List_fromArray( - [$author$project$Backend$Completion$Model$NutritionChildFbf])); -var $author$project$Pages$Completion$Model$allNutritionMotherGroupActivities = _List_fromArray( - [$author$project$Backend$Completion$Model$NutritionFamilyPlanning, $author$project$Backend$Completion$Model$NutritionLactation, $author$project$Backend$Completion$Model$NutritionMotherFbf]); -var $myrho$elm_round$Round$addSign = F2( - function (signed, str) { - var isNotZero = A2( - $elm$core$List$any, - function (c) { - return (!_Utils_eq( - c, - _Utils_chr('0'))) && (!_Utils_eq( - c, - _Utils_chr('.'))); - }, - $elm$core$String$toList(str)); - return _Utils_ap( - (signed && isNotZero) ? '-' : '', - str); - }); -var $elm$core$String$fromFloat = _String_fromNumber; -var $elm$core$Char$fromCode = _Char_fromCode; -var $myrho$elm_round$Round$increaseNum = function (_v0) { - var head = _v0.a; - var tail = _v0.b; - if (_Utils_eq( - head, - _Utils_chr('9'))) { - var _v1 = $elm$core$String$uncons(tail); - if (_v1.$ === 'Nothing') { - return '01'; - } else { - var headtail = _v1.a; - return A2( - $elm$core$String$cons, - _Utils_chr('0'), - $myrho$elm_round$Round$increaseNum(headtail)); - } - } else { - var c = $elm$core$Char$toCode(head); - return ((c >= 48) && (c < 57)) ? A2( - $elm$core$String$cons, - $elm$core$Char$fromCode(c + 1), - tail) : '0'; - } -}; -var $elm$core$Basics$isInfinite = _Basics_isInfinite; -var $elm$core$Basics$isNaN = _Basics_isNaN; -var $elm$core$String$padRight = F3( - function (n, _char, string) { - return _Utils_ap( - string, + A2($author$project$DateSelector$Selector$viewDateTable, minimum, maximum), + maybeSelected)) + ])); + return A2( + $elm$html$Html$map, + A2($justinmimbs$date$Date$clamp, minimum, maximum), A2( - $elm$core$String$repeat, - n - $elm$core$String$length(string), - $elm$core$String$fromChar(_char))); - }); -var $elm$core$String$reverse = _String_reverse; -var $myrho$elm_round$Round$splitComma = function (str) { - var _v0 = A2($elm$core$String$split, '.', str); - if (_v0.b) { - if (_v0.b.b) { - var before = _v0.a; - var _v1 = _v0.b; - var after = _v1.a; - return _Utils_Tuple2(before, after); - } else { - var before = _v0.a; - return _Utils_Tuple2(before, '0'); - } - } else { - return _Utils_Tuple2('0', '0'); - } -}; -var $elm$core$Tuple$mapFirst = F2( - function (func, _v0) { - var x = _v0.a; - var y = _v0.b; - return _Utils_Tuple2( - func(x), - y); + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('calendar') + ]), + _List_fromArray( + [yearSection, monthSection, daysSection]))); }); -var $myrho$elm_round$Round$toDecimal = function (fl) { - var _v0 = A2( - $elm$core$String$split, - 'e', - $elm$core$String$fromFloat( - $elm$core$Basics$abs(fl))); - if (_v0.b) { - if (_v0.b.b) { - var num = _v0.a; - var _v1 = _v0.b; - var exp = _v1.a; - var e = A2( - $elm$core$Maybe$withDefault, - 0, - $elm$core$String$toInt( - A2($elm$core$String$startsWith, '+', exp) ? A2($elm$core$String$dropLeft, 1, exp) : exp)); - var _v2 = $myrho$elm_round$Round$splitComma(num); - var before = _v2.a; - var after = _v2.b; - var total = _Utils_ap(before, after); - var zeroed = (e < 0) ? A2( - $elm$core$Maybe$withDefault, - '0', - A2( - $elm$core$Maybe$map, - function (_v3) { - var a = _v3.a; - var b = _v3.b; - return a + ('.' + b); - }, +var $author$project$DateSelector$SelectorPopup$view = F6( + function (language, toSelect, toClose, minimum, maximum, selected) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('date-selector-popup') + ]), + _List_fromArray( + [ A2( - $elm$core$Maybe$map, - $elm$core$Tuple$mapFirst($elm$core$String$fromChar), - $elm$core$String$uncons( - _Utils_ap( - A2( - $elm$core$String$repeat, - $elm$core$Basics$abs(e), - '0'), - total))))) : A3( - $elm$core$String$padRight, - e + 1, - _Utils_chr('0'), - total); - return _Utils_ap( - (fl < 0) ? '-' : '', - zeroed); - } else { - var num = _v0.a; - return _Utils_ap( - (fl < 0) ? '-' : '', - num); - } - } else { - return ''; - } -}; -var $myrho$elm_round$Round$roundFun = F3( - function (functor, s, fl) { - if ($elm$core$Basics$isInfinite(fl) || $elm$core$Basics$isNaN(fl)) { - return $elm$core$String$fromFloat(fl); - } else { - var signed = fl < 0; - var _v0 = $myrho$elm_round$Round$splitComma( - $myrho$elm_round$Round$toDecimal( - $elm$core$Basics$abs(fl))); - var before = _v0.a; - var after = _v0.b; - var r = $elm$core$String$length(before) + s; - var normalized = _Utils_ap( - A2($elm$core$String$repeat, (-r) + 1, '0'), - A3( - $elm$core$String$padRight, - r, - _Utils_chr('0'), - _Utils_ap(before, after))); - var totalLen = $elm$core$String$length(normalized); - var roundDigitIndex = A2($elm$core$Basics$max, 1, r); - var increase = A2( - functor, - signed, - A3($elm$core$String$slice, roundDigitIndex, totalLen, normalized)); - var remains = A3($elm$core$String$slice, 0, roundDigitIndex, normalized); - var num = increase ? $elm$core$String$reverse( - A2( - $elm$core$Maybe$withDefault, - '1', + $elm$html$Html$map, + toSelect, + A4($author$project$DateSelector$Selector$viewPopup, language, minimum, maximum, selected)), A2( - $elm$core$Maybe$map, - $myrho$elm_round$Round$increaseNum, - $elm$core$String$uncons( - $elm$core$String$reverse(remains))))) : remains; - var numLen = $elm$core$String$length(num); - var numZeroed = (num === '0') ? num : ((s <= 0) ? _Utils_ap( - num, - A2( - $elm$core$String$repeat, - $elm$core$Basics$abs(s), - '0')) : ((_Utils_cmp( - s, - $elm$core$String$length(after)) < 0) ? (A3($elm$core$String$slice, 0, numLen - s, num) + ('.' + A3($elm$core$String$slice, numLen - s, numLen, num))) : _Utils_ap( - before + '.', - A3( - $elm$core$String$padRight, - s, - _Utils_chr('0'), - after)))); - return A2($myrho$elm_round$Round$addSign, signed, numZeroed); - } + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('ui button save'), + $elm$html$Html$Events$onClick(toClose) + ]), + _List_fromArray( + [ + $elm$html$Html$text( + A2($author$project$Translate$translate, language, $author$project$Translate$Save)) + ])) + ])); + }); +var $author$project$DateSelector$SelectorPopup$viewCalendarPopup = F3( + function (language, popupState, selected) { + return A2( + $elm$core$Maybe$map, + function (config) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('ui active modal calendar-popup') + ]), + _List_fromArray( + [ + A6($author$project$DateSelector$SelectorPopup$view, language, config.select, config.close, config.dateFrom, config.dateTo, selected) + ])); + }, + popupState); }); -var $myrho$elm_round$Round$round = $myrho$elm_round$Round$roundFun( - F2( - function (signed, str) { - var _v0 = $elm$core$String$uncons(str); - if (_v0.$ === 'Nothing') { - return false; - } else { - if ('5' === _v0.a.a.valueOf()) { - if (_v0.a.b === '') { - var _v1 = _v0.a; - return !signed; - } else { - var _v2 = _v0.a; - return true; - } - } else { - var _v3 = _v0.a; - var _int = _v3.a; - return function (i) { - return ((i > 53) && signed) || ((i >= 53) && (!signed)); - }( - $elm$core$Char$toCode(_int)); - } - } - })); -var $author$project$Pages$Completion$View$calcualtePercentage = F2( - function (nominator, total) { - return (!total) ? '0' : (A2($myrho$elm_round$Round$round, 2, (nominator / total) * 100) + '%'); +var $author$project$Pages$Utils$customEmptySelectOption = F2( + function (label, isSelected) { + return A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value(''), + $elm$html$Html$Attributes$selected(isSelected) + ]), + _List_fromArray( + [ + $elm$html$Html$text(label) + ])); }); -var $author$project$Pages$Completion$View$countOccurrences = F3( - function (resolveFunc, activity, data) { - return $elm$core$List$length( +var $elm$html$Html$Events$alwaysStop = function (x) { + return _Utils_Tuple2(x, true); +}; +var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { + return {$: 'MayStopPropagation', a: a}; +}; +var $elm$html$Html$Events$stopPropagationOn = F2( + function (event, decoder) { + return A2( + $elm$virtual_dom$VirtualDom$on, + event, + $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); + }); +var $elm$html$Html$Events$targetValue = A2( + $elm$json$Json$Decode$at, + _List_fromArray( + ['target', 'value']), + $elm$json$Json$Decode$string); +var $elm$html$Html$Events$onInput = function (tagger) { + return A2( + $elm$html$Html$Events$stopPropagationOn, + 'input', + A2( + $elm$json$Json$Decode$map, + $elm$html$Html$Events$alwaysStop, + A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); +}; +var $author$project$Pages$Utils$viewCustomSelectListInput = F6( + function (currentValue, options, toStringFunc, setMsg, inputClass, emptyOptionLabel) { + var emptyOption = A2( + $elm$core$Maybe$withDefault, + $author$project$Gizra$Html$emptyNode, A2( - $elm$core$List$filter, + $elm$core$Maybe$map, + function (label) { + return A2( + $author$project$Pages$Utils$customEmptySelectOption, + label, + _Utils_eq(currentValue, $elm$core$Maybe$Nothing)); + }, + emptyOptionLabel)); + return A2( + $elm$html$Html$select, + _List_fromArray( + [ + $elm$html$Html$Events$onInput(setMsg), + $elm$html$Html$Attributes$class(inputClass) + ]), + A2( + $elm$core$List$cons, + emptyOption, A2( - $elm$core$Basics$composeR, - resolveFunc, - $elm$core$List$member(activity)), - data)); + $elm$core$List$map, + function (_v0) { + var label = _v0.a; + var value_ = _v0.b; + return A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value( + toStringFunc(value_)), + $elm$html$Html$Attributes$selected( + _Utils_eq( + currentValue, + $elm$core$Maybe$Just(value_))) + ]), + _List_fromArray( + [ + $elm$html$Html$text(label) + ])); + }, + options))); }); -var $author$project$Translate$Activity = {$: 'Activity'}; -var $author$project$Translate$Completed = {$: 'Completed'}; -var $author$project$Translate$Expected = {$: 'Expected'}; -var $author$project$Pages$Completion$View$generateCaptionsList = function (language) { - return _List_fromArray( - [ - A2($author$project$Translate$translate, language, $author$project$Translate$Activity), - A2($author$project$Translate$translate, language, $author$project$Translate$Expected), - A2($author$project$Translate$translate, language, $author$project$Translate$Completed), - '%' - ]); +var $author$project$Gizra$Html$showMaybe = $elm$core$Maybe$withDefault($author$project$Gizra$Html$emptyNode); +var $author$project$Utils$Html$viewCustomModal = function (extraClasses) { + var classes = A2( + $elm$core$String$join, + ' ', + A2($elm$core$List$cons, 'overlay', extraClasses)); + return A2( + $elm$core$Basics$composeL, + $author$project$Gizra$Html$showMaybe, + $elm$core$Maybe$map( + function (modal) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class(classes) + ]), + _List_fromArray( + [modal])); + })); +}; +var $author$project$Utils$Html$viewModal = $author$project$Utils$Html$viewCustomModal(_List_Nil); +var $author$project$Translate$NutritionChildActivity = function (a) { + return {$: 'NutritionChildActivity', a: a}; +}; +var $author$project$Translate$NutritionGroup = {$: 'NutritionGroup'}; +var $author$project$Translate$NutritionMotherActivity = function (a) { + return {$: 'NutritionMotherActivity', a: a}; }; +var $author$project$Pages$Completion$Utils$allNutritionIndividualActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$NutritionHeight, $author$project$Backend$Completion$Model$NutritionNutrition, $author$project$Backend$Completion$Model$NutritionPhoto, $author$project$Backend$Completion$Model$NutritionWeight, $author$project$Backend$Completion$Model$NutritionMUAC, $author$project$Backend$Completion$Model$NutritionContributingFactors, $author$project$Backend$Completion$Model$NutritionFollowUp, $author$project$Backend$Completion$Model$NutritionHealthEducation, $author$project$Backend$Completion$Model$NutritionSendToHC, $author$project$Backend$Completion$Model$NutritionNCDA]); +var $author$project$Pages$Completion$Utils$allNutritionChildGroupActivities = _Utils_ap( + $author$project$Pages$Completion$Utils$allNutritionIndividualActivities, + _List_fromArray( + [$author$project$Backend$Completion$Model$NutritionChildFbf])); +var $author$project$Pages$Completion$Utils$allNutritionMotherGroupActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$NutritionFamilyPlanning, $author$project$Backend$Completion$Model$NutritionLactation, $author$project$Backend$Completion$Model$NutritionMotherFbf]); var $author$project$Pages$Completion$View$generateNutritionGroupReportData = F2( function (language, records) { var motherData = A2( @@ -12780,7 +13066,7 @@ var $author$project$Pages$Completion$View$generateNutritionGroupReportData = F2( ]); }); }); - var motherActivityRows = A3(generateActivityRows, $author$project$Translate$NutritionMotherActivity, motherData, $author$project$Pages$Completion$Model$allNutritionMotherGroupActivities); + var motherActivityRows = A3(generateActivityRows, $author$project$Translate$NutritionMotherActivity, motherData, $author$project$Pages$Completion$Utils$allNutritionMotherGroupActivities); var childrenData = $elm$core$List$concat( A2( $elm$core$List$map, @@ -12788,87 +13074,13 @@ var $author$project$Pages$Completion$View$generateNutritionGroupReportData = F2( return $.childrenData; }, records)); - var childrenActivityRows = A3(generateActivityRows, $author$project$Translate$NutritionChildActivity, childrenData, $author$project$Pages$Completion$Model$allNutritionChildGroupActivities); + var childrenActivityRows = A3(generateActivityRows, $author$project$Translate$NutritionChildActivity, childrenData, $author$project$Pages$Completion$Utils$allNutritionChildGroupActivities); return { captions: $author$project$Pages$Completion$View$generateCaptionsList(language), heading: A2($author$project$Translate$translate, language, $author$project$Translate$NutritionGroup), rows: _Utils_ap(motherActivityRows, childrenActivityRows) }; }); -var $elm$html$Html$Attributes$classList = function (classes) { - return $elm$html$Html$Attributes$class( - A2( - $elm$core$String$join, - ' ', - A2( - $elm$core$List$map, - $elm$core$Tuple$first, - A2($elm$core$List$filter, $elm$core$Tuple$second, classes)))); -}; -var $author$project$Pages$Components$View$viewCustomCells = F2( - function (labelClass, valueClass) { - return $elm$core$List$indexedMap( - F2( - function (index, cellText) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$classList( - _List_fromArray( - [ - _Utils_Tuple2('item', true), - _Utils_Tuple2(labelClass, !index), - _Utils_Tuple2(valueClass, !(!index)) - ])) - ]), - _List_fromArray( - [ - $elm$html$Html$text(cellText) - ])); - })); - }); -var $author$project$Pages$Components$View$viewNutritionMetricsResultsTable = function (data) { - var viewRow = function (cells) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('row') - ]), - A3($author$project$Pages$Components$View$viewCustomCells, 'row-label', 'value', cells)); - }; - var captionsRow = A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('row') - ]), - A3($author$project$Pages$Components$View$viewCustomCells, 'row-label', 'heading', data.captions)); - return _List_fromArray( - [ - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('section heading') - ]), - _List_fromArray( - [ - $elm$html$Html$text(data.heading) - ])), - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('table wide') - ]), - A2( - $elm$core$List$cons, - captionsRow, - A2($elm$core$List$map, viewRow, data.rows))) - ]); -}; var $author$project$Pages$Completion$View$viewNutritionGroupReport = F5( function (language, startDate, limitDate, mTakenBy, reportData) { return A2( @@ -12927,7 +13139,7 @@ var $author$project$Pages$Completion$View$generateNutritionIndividualReportData A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) ]); }, - $author$project$Pages$Completion$Model$allNutritionIndividualActivities) + $author$project$Pages$Completion$Utils$allNutritionIndividualActivities) }; }); var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F5( @@ -13176,10 +13388,13 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( $elm$core$Maybe$map3, F3( function (reportType, startDate, limitDate) { - if (reportType.$ === 'ReportNutritionIndividual') { - return A5($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, model.takenBy, data.nutritionIndividualData); - } else { - return A5($author$project$Pages$Completion$View$viewNutritionGroupReport, language, startDate, limitDate, model.takenBy, data.nutritionGroupData); + switch (reportType.$) { + case 'ReportAcuteIllness': + return A5($author$project$Pages$Completion$View$viewAcuteIllnessReport, language, startDate, limitDate, model.takenBy, data.acuteIllnessData); + case 'ReportNutritionGroup': + return A5($author$project$Pages$Completion$View$viewNutritionGroupReport, language, startDate, limitDate, model.takenBy, data.nutritionGroupData); + default: + return A5($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, model.takenBy, data.nutritionIndividualData); } }), model.reportType, @@ -13213,7 +13428,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( language, model.reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportNutritionGroup]), + [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual]), $author$project$Pages$Completion$Utils$reportTypeToString, $author$project$Pages$Completion$Model$SetReportType, $author$project$Translate$CompletionReportType, From 8989c3891df49baace09e3926285e887c680942c Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 19:25:01 +0300 Subject: [PATCH 048/185] Improve code [ci skip] --- server/elm/src/Pages/Completion/View.elm | 10 +++++----- server/elm/src/Pages/Components/View.elm | 4 ++-- server/elm/src/Pages/Reports/View.elm | 4 ++-- .../modules/custom/hedley_general/js/elm-main.js | 12 ++++++------ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index 438662dff4..1e179ee29c 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -26,7 +26,7 @@ import List.Extra import Maybe.Extra exposing (isJust, isNothing) import Pages.Completion.Model exposing (..) import Pages.Completion.Utils exposing (..) -import Pages.Components.View exposing (viewNutritionMetricsResultsTable) +import Pages.Components.View exposing (viewMetricsResultsTable) import Pages.Model exposing (MetricsResultsTableData) import Pages.Utils exposing (launchDate, viewCustomSelectListInput, viewSelectListInput, wrapSelectListInput) import RemoteData exposing (RemoteData(..)) @@ -208,7 +208,7 @@ viewNutritionIndividualReport : Language -> NominalDate -> NominalDate -> Maybe viewNutritionIndividualReport language startDate limitDate mTakenBy reportData = applyFilters startDate limitDate mTakenBy reportData |> generateNutritionIndividualReportData language - |> viewNutritionMetricsResultsTable + |> viewMetricsResultsTable |> div [ class "report nutrition-individual" ] @@ -222,15 +222,15 @@ viewNutritionGroupReport : viewNutritionGroupReport language startDate limitDate mTakenBy reportData = applyFilters startDate limitDate mTakenBy reportData |> generateNutritionGroupReportData language - |> viewNutritionMetricsResultsTable - |> div [ class "report nutrition-individual" ] + |> viewMetricsResultsTable + |> div [ class "report nutrition-group" ] viewAcuteIllnessReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData AcuteIllnessActivity) -> Html Msg viewAcuteIllnessReport language startDate limitDate mTakenBy reportData = applyFilters startDate limitDate mTakenBy reportData |> generateAcuteIllnessReportData language - |> viewNutritionMetricsResultsTable + |> viewMetricsResultsTable |> div [ class "report acute-illness" ] diff --git a/server/elm/src/Pages/Components/View.elm b/server/elm/src/Pages/Components/View.elm index 5a5c61c8ca..9db70b45a0 100644 --- a/server/elm/src/Pages/Components/View.elm +++ b/server/elm/src/Pages/Components/View.elm @@ -224,8 +224,8 @@ viewDemographicsSelectionActionButton language site pathPrefix label selectionMa -- Table -viewNutritionMetricsResultsTable : MetricsResultsTableData -> List (Html any) -viewNutritionMetricsResultsTable data = +viewMetricsResultsTable : MetricsResultsTableData -> List (Html any) +viewMetricsResultsTable data = let captionsRow = div [ class "row" ] <| diff --git a/server/elm/src/Pages/Reports/View.elm b/server/elm/src/Pages/Reports/View.elm index d9de0fd009..67630db811 100644 --- a/server/elm/src/Pages/Reports/View.elm +++ b/server/elm/src/Pages/Reports/View.elm @@ -25,7 +25,7 @@ import Html.Attributes exposing (..) import Html.Events exposing (onClick) import List.Extra import Maybe.Extra exposing (isJust, isNothing) -import Pages.Components.View exposing (viewCustomCells, viewNutritionMetricsResultsTable, viewStandardCells, viewStandardRow) +import Pages.Components.View exposing (viewCustomCells, viewMetricsResultsTable, viewStandardCells, viewStandardRow) import Pages.Model exposing (MetricsResultsTableData) import Pages.Reports.Model exposing (..) import Pages.Reports.Utils exposing (..) @@ -1022,7 +1022,7 @@ viewNutritionReport language currentDate scopeLabel mBackendGeneratedData report reportTablesDataToCSV generatedData in div [ class "report nutrition" ] <| - (List.map viewNutritionMetricsResultsTable generatedData + (List.map viewMetricsResultsTable generatedData |> List.concat ) ++ [ viewDownloadCSVButton language csvFileName csvContent ] diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 65ea48d0d4..700df7211f 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -11907,7 +11907,7 @@ var $author$project$Pages$Components$View$viewCustomCells = F2( ])); })); }); -var $author$project$Pages$Components$View$viewNutritionMetricsResultsTable = function (data) { +var $author$project$Pages$Components$View$viewMetricsResultsTable = function (data) { var viewRow = function (cells) { return A2( $elm$html$Html$div, @@ -11956,7 +11956,7 @@ var $author$project$Pages$Completion$View$viewAcuteIllnessReport = F5( [ $elm$html$Html$Attributes$class('report acute-illness') ]), - $author$project$Pages$Components$View$viewNutritionMetricsResultsTable( + $author$project$Pages$Components$View$viewMetricsResultsTable( A2( $author$project$Pages$Completion$View$generateAcuteIllnessReportData, language, @@ -13087,9 +13087,9 @@ var $author$project$Pages$Completion$View$viewNutritionGroupReport = F5( $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$Attributes$class('report nutrition-individual') + $elm$html$Html$Attributes$class('report nutrition-group') ]), - $author$project$Pages$Components$View$viewNutritionMetricsResultsTable( + $author$project$Pages$Components$View$viewMetricsResultsTable( A2( $author$project$Pages$Completion$View$generateNutritionGroupReportData, language, @@ -13150,7 +13150,7 @@ var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F5( [ $elm$html$Html$Attributes$class('report nutrition-individual') ]), - $author$project$Pages$Components$View$viewNutritionMetricsResultsTable( + $author$project$Pages$Components$View$viewMetricsResultsTable( A2( $author$project$Pages$Completion$View$generateNutritionIndividualReportData, language, @@ -16022,7 +16022,7 @@ var $author$project$Pages$Reports$View$viewNutritionReport = F5( ]), _Utils_ap( $elm$core$List$concat( - A2($elm$core$List$map, $author$project$Pages$Components$View$viewNutritionMetricsResultsTable, generatedData)), + A2($elm$core$List$map, $author$project$Pages$Components$View$viewMetricsResultsTable, generatedData)), _List_fromArray( [ A3($author$project$Pages$Reports$View$viewDownloadCSVButton, language, csvFileName, csvContent) From d1787e19cb267a75cd68ed070e805dbb9417072a Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 19:25:25 +0300 Subject: [PATCH 049/185] Style [ci skip] --- server/hedley/modules/custom/hedley_general/css/elm.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/hedley/modules/custom/hedley_general/css/elm.css b/server/hedley/modules/custom/hedley_general/css/elm.css index d0406d88f7..5539741b71 100644 --- a/server/hedley/modules/custom/hedley_general/css/elm.css +++ b/server/hedley/modules/custom/hedley_general/css/elm.css @@ -394,10 +394,16 @@ body.admin-menu #page-wrapper #header { width: 120%; } +.page-content .inputs .report.acute-illness .table .row .item.row-label, +.page-content .inputs .report.nutrition-group .table .row .item.row-label, .page-content .inputs .report.nutrition-individual .table .row .item.row-label { width: 30%; } +.page-content .inputs .report.acute-illness .table .row .item.heading, +.page-content .inputs .report.acute-illness .table .row .item.value, +.page-content .inputs .report.nutrition-group .table .row .item.heading, +.page-content .inputs .report.nutrition-group .table .row .item.value, .page-content .inputs .report.nutrition-individual .table .row .item.heading, .page-content .inputs .report.nutrition-individual .table .row .item.value { width: 20%; From e6c1255ebbf5e00458971c08b68884ddaf8f2c80 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 21 Aug 2024 19:41:46 +0300 Subject: [PATCH 050/185] Fix for follow up [ci skip] --- .../custom/hedley_reports/hedley_reports.module | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index e48761b4c1..7c2e15e5db 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2845,11 +2845,11 @@ function hedley_reports_acute_illness_add_next_steps_activities_initial_encounte $launch_date_obj = new DateTime($launch_date); if (($encounter_data['start_date_obj'] >= $launch_date_obj) && !in_array($diagnosis, ['covid19-severe', 'fever-of-unknown-origin'])) { if (($diagnosis == 'tuberculosis-suspect') || - !empty($expected['isolation']) || - !empty($expected['call_114']) || - !empty($expected['hc_contact']) || - !empty($expected['medication_distribution']) || - !empty($expected['send_to_hc'])) { + in_array('isolation', $expected) || + in_array('call_114', $expected) || + in_array('hc_contact', $expected) || + in_array('medication_distribution', $expected) || + in_array('send_to_hc', $expected)) { $expected[] = 'acute_illness_follow_up'; } } @@ -2945,9 +2945,9 @@ function hedley_reports_acute_illness_add_next_steps_activities_subsequent_encou $launch_date = '2021-06-07'; $launch_date_obj = new DateTime($launch_date); if (($encounter_data['start_date_obj'] >= $launch_date_obj)) { - if (!empty($expected['hc_contact']) || - !empty($expected['medication_distribution']) || - !empty($expected['send_to_hc'])) { + if (in_array('hc_contact', $expected) || + in_array('medication_distribution', $expected) || + in_array('send_to_hc', $expected)) { $expected[] = 'acute_illness_follow_up'; } } From 5744c3ab660658e63ab00d9d9a676864a4168f52 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 22 Aug 2024 20:44:23 +0300 Subject: [PATCH 051/185] Fixes [ci skip] --- server/elm/src/Translate.elm | 2 +- .../custom/hedley_general/js/elm-main.js | 2 +- .../hedley_reports/hedley_reports.module | 49 ++++++++++++------- ...generate-acute-illness-completion-data.php | 7 +-- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 76af8d4450..449450030d 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -297,7 +297,7 @@ translationSet transId = } AcuteIllnessMedicationDistribution -> - { english = "MedicationDistribution" + { english = "Medication Distribution" , kinyarwanda = Nothing , kirundi = Nothing } diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 700df7211f..e4709f1dc3 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -9997,7 +9997,7 @@ var $author$project$Translate$translationSet = function (transId) { case 'AcuteIllnessMalariaTesting': return {english: 'Malaria Testing', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessMedicationDistribution': - return {english: 'MedicationDistribution', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Medication Distribution', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessSendToHC': return {english: 'Referal', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessSymptomsGeneral': diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 7c2e15e5db..c8c567223d 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2394,7 +2394,7 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ return $return; } -function hedley_reports_generate_completion_data_for_aculte_illness($participant) { +function hedley_reports_generate_completion_data_for_aculte_illness($participant, $exclude_set) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ 'acute_findings' => 'a', @@ -2440,6 +2440,11 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant $encounters = node_load_multiple(array_keys($result['node'])); $encounters_data = []; foreach ($encounters as $encounter) { + // Skip encounter if exclusion flag is raised and it's report data is set. + if ($exclude_set && !empty($encounter->field_reports_data[LANGUAGE_NONE][0]['value'])) { + continue; + } + // Loading all measurements that belong to encounter. $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); $encounter_type = $encounter->field_ai_encounter_type[LANGUAGE_NONE][0]['value']; @@ -2595,34 +2600,40 @@ function hedley_reports_generate_acute_illness_expected_initial_activities($enco } function hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, &$expected) { - $encounter = $encounter_data['encounter']; + // Malaria test is suggested only if fever is recorder. + if ($encounter_data['fever']) { + return; + } $measurements_by_type = $encounter_data['measurements_by_type']; - $fever = $encounter_data['fever']; - - $current_encounter_diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; + $diagnosis = $encounter_data['illness_diagnosis']; $covid_diagnoses = ['covid19-severe', 'covid19-pneumonia', 'covid19-low-risk']; - $covid_diagnosed = FALSE; + $covid_not_diagnosed = TRUE; if (!empty($current_encounter_diagnosis)) { - $covid_diagnosed = !in_array($current_encounter_diagnosis, $covid_diagnoses); + $covid_not_diagnosed = !in_array($diagnosis, $covid_diagnoses); } + // Initial encounter logic. if ($encounter_data['is_initial']) { - // If patient was not diagnosed with Covid, and fever is recorded - // on current encounter, and patient was suggested to take - // COVID test, but did not run it, we expect patient to take Malaria test. - $covid_rapid_test_suggested_but_not_run = FALSE; - if (!empty($measurements_by_type['covid_testing'])) { - $covid_rapid_test_result = $measurements_by_type['covid_testing']->field_rapid_test_result[LANGUAGE_NONE][0]['value']; - if (!empty($covid_rapid_test_result)) { - $not_run_values = ['unable-to-run', 'unable-to-run-and-pregnant']; - $covid_rapid_test_suggested_but_not_run = in_array($covid_rapid_test_result, $not_run_values); + if ($covid_not_diagnosed) { + $expected[] = 'malaria_testing'; + } + else { + // Patient was not diagnosed with Covid, and patient was suggested to take + // COVID test, but did not run it, we expect patient to take Malaria test. + $covid_rapid_test_suggested_but_not_run = FALSE; + if (!empty($measurements_by_type['covid_testing'])) { + $covid_rapid_test_result = $measurements_by_type['covid_testing']->field_rapid_test_result[LANGUAGE_NONE][0]['value']; + if (!empty($covid_rapid_test_result)) { + $not_run_values = ['unable-to-run', 'unable-to-run-and-pregnant']; + $covid_rapid_test_suggested_but_not_run = in_array($covid_rapid_test_result, $not_run_values); + } } - - if (!$covid_diagnosed && $fever && $covid_rapid_test_suggested_but_not_run) { + if ($covid_rapid_test_suggested_but_not_run) { $expected[] = 'malaria_testing'; } } } + // Subsequent encounter logic. else { // If patient was not diagnosed with Covid on current encounter, and fever // is recorded on current encounter, and patient did not test positive @@ -2643,7 +2654,7 @@ function hedley_reports_acute_illness_add_expected_malaria_testing($encounter_da } } - if (!$covid_diagnosed && $fever && !$diagnosed_with_malaria_previously) { + if ($covid_not_diagnosed && !$diagnosed_with_malaria_previously) { $expected[] = 'malaria_testing'; } } diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php index 71a72f541d..1497805ffd 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php @@ -33,10 +33,6 @@ ->fieldCondition('field_encounter_type', 'value', 'acute-illness') ->propertyCondition('status', NODE_PUBLISHED); -if ($exclude_set) { - $base_query->addTag('exclude_set_reports_data'); -} - $count_query = clone $base_query; $count_query->propertyCondition('nid', $nid, '>'); $count = $count_query->count()->execute(); @@ -67,8 +63,7 @@ $ids = array_keys($result['node']); $nodes = node_load_multiple($ids); foreach ($nodes as $node) { - hedley_reports_generate_completion_data_for_aculte_illness($node); - node_save($node); + hedley_reports_generate_completion_data_for_aculte_illness($node, $exclude_set); $total++; $memory = round(memory_get_usage() / 1048576); From ba07f10bf84a29f6fd435125c05eed693ef86fb8 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 22 Aug 2024 21:50:23 +0300 Subject: [PATCH 052/185] More fixes [ci skip] --- .../custom/hedley_reports/hedley_reports.module | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index c8c567223d..f60d197f4f 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2818,12 +2818,12 @@ function hedley_reports_acute_illness_add_next_steps_activities_initial_encounte // Adding Contact HC activity. if ($is_chw && $diagnosis == 'covid19' && !empty($measurements_by_type['call_114']) ) { - $signs = $measurements_by_type['call_114']->field_114_contact[LANGUAGE_NONE]; - foreach ($signs as $sign) { - if ($sign['value'] == 'call-114') { - $expected[] = 'hc_contact'; - break; - } + // If suspected COVID case, but call to 114 was not made, need + // to contact HC. This means that 114 contact filed got single + // value set to 'none'. + $sign = $measurements_by_type['call_114']->field_114_contact[LANGUAGE_NONE][0]['value']; + if ($sign == 'none') { + $expected[] = 'hc_contact'; } } @@ -2876,7 +2876,7 @@ function hedley_reports_acute_illness_add_send_to_hc_initial_encounter($encounte in_array($diagnosis, ['gi-complicated', 'ri-complicated', 'fever-of-unknown-origin', 'undetermined', 'covid19-severe']) || ($medication_prescribed && $diagnosis != 'covid19-pneumonia' && hedley_reports_acute_illness_send_to_hc_due_to_medication_non_administration($encounter_data)) || - ($encounter_data['taken_by'] == 'chw' && $diagnosis != 'tuberculosis-suspect') + ($encounter_data['taken_by'] == 'chw' && $diagnosis == 'tuberculosis-suspect') ) { $expected[] = 'send_to_hc'; } From 01f9be5642bf6baac095e6591a3189e2318fbe3d Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 23 Aug 2024 00:45:44 +0300 Subject: [PATCH 053/185] More fixes [ci skip] --- .../custom/hedley_reports/hedley_reports.module | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index f60d197f4f..17ed55dc5e 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2601,7 +2601,7 @@ function hedley_reports_generate_acute_illness_expected_initial_activities($enco function hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, &$expected) { // Malaria test is suggested only if fever is recorder. - if ($encounter_data['fever']) { + if (!$encounter_data['fever']) { return; } $measurements_by_type = $encounter_data['measurements_by_type']; @@ -2696,17 +2696,16 @@ function hedley_reports_acute_illness_add_expected_covid_testing($encounter_data } $signs_indicate_covid = ($total_exposure_signs + $total_travel_history_signs) > 0; - $malaria_rapid_test_result = FALSE; + $malaria_rdt_run_and_not_positive = FALSE; if (!empty($measurements_by_type['malaria_testing'])) { $malaria_rapid_test_result = $measurements_by_type['malaria_testing']->field_malaria_rapid_test[LANGUAGE_NONE][0]['value']; + $malaria_rdt_run_and_not_positive = !in_array($malaria_rapid_test_result, RDT_POSITIVE_VALUES); } - $malaria_rdt_run_and_not_positive = !empty($malaria_rapid_test_result) && !in_array($malaria_rapid_test_result, RDT_POSITIVE_VALUES); - - if (($symptoms_indicate_covid && $signs_indicate_covid) || + if (($signs_indicate_covid && $symptoms_indicate_covid) || ($signs_indicate_covid && $fever) || - (!$symptoms_indicate_covid && $fever && $malaria_rdt_run_and_not_positive && $total_symptoms_respiratory > 0) || - (!$symptoms_indicate_covid && $fever && $malaria_rdt_run_and_not_positive && $total_symptoms_general > 1)) { + (!$signs_indicate_covid && $fever && $malaria_rdt_run_and_not_positive && $total_symptoms_respiratory > 0) || + (!$signs_indicate_covid && $fever && $malaria_rdt_run_and_not_positive && $total_symptoms_general > 1)) { $expected[] = 'covid_testing'; } } From 1d13dc1932fe09e8f99e64a22c89f855ff4495ea Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 23 Aug 2024 11:09:27 +0300 Subject: [PATCH 054/185] Fix launch dates [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 17ed55dc5e..92b4ebf658 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2666,7 +2666,7 @@ function hedley_reports_acute_illness_add_expected_covid_testing($encounter_data return; } - $launch_date = '2022-02-06'; + $launch_date = '2021-12-22'; $launch_date_obj = new DateTime($launch_date); if ($encounter_data['start_date_obj'] < $launch_date_obj) { // Feature was not yet launched. @@ -2769,7 +2769,7 @@ function hedley_reports_acute_illness_add_physical_exam_activities($encounter_da $expected[] = 'acute_illness_core_exam'; } - $launch_date = '2020-12-10'; + $launch_date = '2020-12-06'; $launch_date_obj = new DateTime($launch_date); if ($encounter_data['start_date_obj'] >= $launch_date_obj) { // MUAC is taken for children that are 6 months to 5 years old. @@ -2838,7 +2838,7 @@ function hedley_reports_acute_illness_add_next_steps_activities_initial_encounte } // Adding Contacts Tracing activity. - $launch_date = '2022-02-06'; + $launch_date = '2021-12-22'; $launch_date_obj = new DateTime($launch_date); if ($encounter_data['start_date_obj'] >= $launch_date_obj) { if (in_array($diagnosis, ['covid19-pneumonia', 'covid19-low-risk'])) { From 5d6808fea99cbe0dffccf0122a775d6a311bbb61 Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 23 Aug 2024 12:10:21 +0300 Subject: [PATCH 055/185] Fixes and some comments [ci skip] --- .../hedley_reports/hedley_reports.module | 69 +++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 92b4ebf658..b419443b61 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2524,8 +2524,8 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant } } $fever_at_vitals = FALSE; - if (!empty($measurements_by_type['vitals'])) { - $body_temperature = $measurements_by_type['vitals']->field_body_temperature[LANGUAGE_NONE][0]['value']; + if (!empty($measurements_by_type['acute_illness_vitals'])) { + $body_temperature = $measurements_by_type['acute_illness_vitals']->field_body_temperature[LANGUAGE_NONE][0]['value']; if (!empty($body_temperature)) { $fever_at_vitals = $body_temperature >= 37.5; } @@ -2550,6 +2550,7 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); $completed = []; + // $expected = array_unique(array_merge($expected, array_keys($measurements_by_type))); foreach ($expected as $measurement_type) { if (!empty($measurements_by_type[$measurement_type])) { $completed[] = $measurement_type; @@ -3113,6 +3114,15 @@ function hedley_reports_get_acute_illness_diagnosis_by_previous_encounters($enco return NULL; } +/** + * Count acute illness general symptoms. + * + * @param object $measurement + * The measurement object containing symptom data. + * + * @return int + * The count of general symptoms. + */ function hedley_reports_count_acute_illness_symptoms_general($measurement) { $fields = [ 'field_chills_period', @@ -3124,8 +3134,18 @@ function hedley_reports_count_acute_illness_symptoms_general($measurement) { return hedley_reports_count_acute_illness_symptoms($measurement, $fields); } +/** + * Count acute illness respiratory symptoms. + * + * @param object $measurement + * The measurement object containing symptom data. + * + * @return int + * The count of respiratory symptoms. + */ function hedley_reports_count_acute_illness_symptoms_respiratory($measurement) { $fields = [ + 'field_cough_period', 'field_shortness_of_breath_period', 'field_nasal_congestion_period', 'field_blood_in_sputum_period', @@ -3137,6 +3157,15 @@ function hedley_reports_count_acute_illness_symptoms_respiratory($measurement) { return hedley_reports_count_acute_illness_symptoms($measurement, $fields); } +/** + * Count acute illness gastrointestinal symptoms. + * + * @param object $measurement + * The measurement object containing symptom data. + * + * @return int + * The count of gastrointestinal symptoms. + */ function hedley_reports_count_acute_illness_symptoms_gi($measurement) { $fields = [ 'field_bloody_diarrhea_period', @@ -3149,7 +3178,18 @@ function hedley_reports_count_acute_illness_symptoms_gi($measurement) { return hedley_reports_count_acute_illness_symptoms($measurement, $fields); } -function hedley_reports_count_acute_illness_symptoms($measurement, $fields) { +/** + * Helper function to count the number of acute illness symptoms present. + * + * @param object $measurement + * The measurement object containing symptom data. + * @param array $fields + * An array of field names to check within the measurement object. + * + * @return int + * The count of symptoms that are present. + */ +function hedley_reports_count_acute_illness_symptoms($measurement, array $fields) { $count = 0; if (empty($measurement)) { return $count; @@ -3165,7 +3205,16 @@ function hedley_reports_count_acute_illness_symptoms($measurement, $fields) { return $count; } -function hedley_reports_count_acute_illness_signs($values) { +/** + * Count the number of acute illness signs present. + * + * @param array $values + * An array of values, where each value represents a sign of illness. + * + * @return int + * The count of signs that are present (i.e., not equal to 'none'). + */ +function hedley_reports_count_acute_illness_signs(array $values) { $count = 0; foreach ($values as $value) { if ($value['value'] != 'none') { @@ -3176,6 +3225,17 @@ function hedley_reports_count_acute_illness_signs($values) { return $count; } +/** + * Resolve the age in months for an individual at the time of a specific encounter. + * + * @param object $encounter + * The encounter object, which includes the participant and person data. + * @param DateTime $start_date_obj + * The date object representing the start date of the encounter. + * + * @return int|null + * The age in months of the individual at the time of the encounter, or NULL if an error occurs. + */ function hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj) { try { // Get participant ID and node. @@ -3194,6 +3254,7 @@ function hedley_reports_resolve_age_in_months_for_individual_encounter($encounte $interval = $start_date_obj->diff($birth_date_obj); return ($interval->y * 12) + $interval->m; } catch (Exception $e) { + watchdog('hedley_reports', "Failed to resolve patient age at encounter ID $encounter->nid."); return NULL; } } From 862f132dec6b79f4e480094d5e47482904c45132 Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 23 Aug 2024 13:08:58 +0300 Subject: [PATCH 056/185] Eliminate code duplications [ci skip] --- .../hedley_reports/hedley_reports.module | 72 ++++++++++--------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index b419443b61..38e25461ec 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2078,7 +2078,6 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun 'nutrition_photo', 'nutrition_weight', ]; - $completed = []; // Was encounter recorded by nurse or CHW. $taken_by = $encounter->field_nutrition_encounter_type[LANGUAGE_NONE][0]['value']; @@ -2090,7 +2089,7 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); if (empty($measurements_ids)) { - $completion = hedley_reports_generate_completion_result($expected, $completed, $mapping); + $completion = hedley_reports_generate_completion_result($expected, [], $mapping); return [ 'start_date' => $start_date, @@ -2148,13 +2147,7 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun $expected[] = 'nutrition_ncda'; } - foreach ($expected as $measurement_type) { - if (!empty($measurements_by_type[$measurement_type])) { - $completed[] = $measurement_type; - } - } - - $completion = hedley_reports_generate_completion_result($expected, $completed, $mapping); + $completion = hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping); return [ 'start_date' => $start_date, @@ -2295,14 +2288,7 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ } } - $completed = []; - foreach ($expected as $measurement_type) { - if (!empty($measurements_by_type[$measurement_type])) { - $completed[] = $measurement_type; - } - } - - $return['mother'] = hedley_reports_generate_completion_result($expected, $completed, $mapping_mother); + $return['mother'] = hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping_mother); } } // Handling child. @@ -2378,14 +2364,7 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ $expected[] = 'group_ncda'; } - $completed = []; - foreach ($expected as $measurement_type) { - if (!empty($measurements_by_type[$measurement_type])) { - $completed[] = $measurement_type; - } - } - - $return['children'][] = hedley_reports_generate_completion_result($expected, $completed, $mapping_child); + $return['children'][] = hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping_child); } } @@ -2549,18 +2528,11 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant // If conditions match, add next steps activities. hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); - $completed = []; - // $expected = array_unique(array_merge($expected, array_keys($measurements_by_type))); - foreach ($expected as $measurement_type) { - if (!empty($measurements_by_type[$measurement_type])) { - $completed[] = $measurement_type; - } - } - + $expected = array_unique(array_merge($expected, array_keys($measurements_by_type))); $completion_data = [ 'start_date' => $start_date, 'taken_by' => $encounter_data['taken_by'], - 'completion' => hedley_reports_generate_completion_result($expected, $completed, $mapping), + 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), ]; $encounter->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); @@ -3268,7 +3240,37 @@ function hedley_reports_load_individual_encounter_measurements_ids($encounter) { return $query->execute()->fetchCol(); } -function hedley_reports_generate_completion_result($expected, $completed, $mapping) { + +/** + * Generate a completion result string per expected and completed measurements. + * + * This function checks which expected measurements have been completed based on + * the provided measurements by type, maps both the expected and completed + * measurement types using the provided mapping array, and then generates a string + * representing the completion result. + * + * @param array $expected + * An array of expected measurement types. + * @param array $measurements_by_type + * An associative array where the keys are measurement types and the values + * indicate whether the measurement has been completed. + * @param array $mapping + * An associative array where keys are measurement types and values are their + * corresponding mapped values. + * + * @return string + * A string that concatenates the mapped expected and completed measurement + * types, separated by a '|' character. The expected and completed values are + * each comma-separated within their respective sections. + */ +function hedley_reports_generate_completion_result(array $expected, array $measurements_by_type, array $mapping) { + $completed = []; + foreach ($expected as $measurement_type) { + if (!empty($measurements_by_type[$measurement_type])) { + $completed[] = $measurement_type; + } + } + foreach ($expected as $index => $measurement_type) { $expected[$index] = $mapping[$measurement_type]; } From 28b972de6e154702334abc8a8e0f792ffe50096d Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 23 Aug 2024 14:37:21 +0300 Subject: [PATCH 057/185] More fixes and comments [ci skip] --- .../hedley_reports/hedley_reports.module | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 38e25461ec..d9e4a522db 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2735,7 +2735,7 @@ function hedley_reports_acute_illness_add_physical_exam_activities($encounter_da $expected[] = 'acute_findings'; } - $launch_date = '2022-12-22'; + $launch_date = '2021-12-22'; $launch_date_obj = new DateTime($launch_date); // Core exam is taken only by nurse. if ($encounter_data['start_date_obj'] >= $launch_date_obj && $encounter_data['taken_by'] == 'nurse') { @@ -2814,7 +2814,7 @@ function hedley_reports_acute_illness_add_next_steps_activities_initial_encounte $launch_date = '2021-12-22'; $launch_date_obj = new DateTime($launch_date); if ($encounter_data['start_date_obj'] >= $launch_date_obj) { - if (in_array($diagnosis, ['covid19-pneumonia', 'covid19-low-risk'])) { + if (in_array($diagnosis, ['covid19-pneumonia', 'covid19-low-risk', 'covid19-severe'])) { $expected[] = 'acute_illness_contacts_tracing'; } } @@ -3074,6 +3074,18 @@ function hedley_reports_acute_illness_conditions_not_improving_on_subsequent_vis return FALSE; } +/** + * Retrieve the acute illness diagnosis for given list of encounters. + * + * This function iterates through an array of encounter data to find and return + * the first non-empty acute illness diagnosis that is not 'none'. + * + * @param array $encounters_data + * An array of encounter data, where each item contains an 'encounter' object. + * + * @return string|null + * The acute illness diagnosis if found, or NULL if no valid diagnosis is found. + */ function hedley_reports_get_acute_illness_diagnosis_by_previous_encounters($encounters_data) { foreach ($encounters_data as $encounter_data) { $encounter = $encounter_data['encounter']; @@ -3231,6 +3243,18 @@ function hedley_reports_resolve_age_in_months_for_individual_encounter($encounte } } +/** + * Load the measurement IDs associated with an individual encounter. + * + * This function retrieves the IDs of measurements related to a specific + * encounter by querying the database for entities linked to the encounter node. + * + * @param object $encounter + * The encounter object, which includes the node ID and bundle type. + * + * @return array + * An array of measurement entity IDs associated with the encounter. + */ function hedley_reports_load_individual_encounter_measurements_ids($encounter) { $bundle = $encounter->type; $encounter_field ="field_$bundle"; @@ -3240,7 +3264,6 @@ function hedley_reports_load_individual_encounter_measurements_ids($encounter) { return $query->execute()->fetchCol(); } - /** * Generate a completion result string per expected and completed measurements. * From 31bf559e2be339d9b5639201fae9150920c0b561 Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 23 Aug 2024 15:44:34 +0300 Subject: [PATCH 058/185] Fixes for medication distribution [ci skip] --- .../hedley_reports/hedley_reports.module | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index d9e4a522db..fe260357d2 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2426,12 +2426,14 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant // Loading all measurements that belong to encounter. $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); - $encounter_type = $encounter->field_ai_encounter_type[LANGUAGE_NONE][0]['value']; // If encounter type field is empty, we default to CHW, since // CHW mode was developed before nurse mode. - if (empty($encounter_type)) { + if (empty($encounter->field_ai_encounter_type)) { $encounter_type = 'chw-encounter'; } + else { + $encounter_type = $encounter->field_ai_encounter_type[LANGUAGE_NONE][0]['value']; + } $measurements = !empty($measurements_ids) ? node_load_multiple($measurements_ids) : []; // Ordering measurements by type. @@ -2448,6 +2450,15 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant ]; } + // If we have more than one encounter for illness, and first + // encounter got no measurements, we drop that encounter. + // This case should not be happening, because no diagnosis at + // first encounter should prevent running additional encounters, + // but actual data at DB shows these cases are present. + if (count($encounters_data) > 1 && empty($encounters_data[0]['measurements_by_type'])) { + array_shift($encounters_data); + } + foreach ($encounters_data as $index => $encounter_data) { $encounter = $encounter_data['encounter']; $encounter_type = $encounter_data['encounter_type']; @@ -2464,12 +2475,12 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant $previous_encounters_data = array_slice($encounters_data, 0, $index); $is_initial = ($encounter_type == 'nurse-encounter') || (($encounter_type == 'chw-encounter') && empty($previous_encounters_data)); + $encounter_data['is_initial'] = $is_initial; $illness_diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; if (!$is_initial && (empty($diagnosis) || $diagnosis == 'none')) { // Reversing passed array, to have the encounters sorted DESC. $illness_diagnosis = hedley_reports_get_acute_illness_diagnosis_by_previous_encounters(array_reverse($previous_encounters_data)); } - $encounter_data['is_initial'] = $is_initial; $encounter_data['illness_diagnosis'] = $illness_diagnosis; // Acute illness module defines following logic: @@ -2774,7 +2785,11 @@ function hedley_reports_acute_illness_add_next_steps_activities_initial_encounte $medication_prescribed = FALSE; if ((($diagnosis == 'malaria-uncomplicated') && $age_in_months >= 6) || (in_array($diagnosis, ['cough-and-cold', 'ri-uncomplicated']) && ($age_in_months >= 2 && $age_in_months < 60)) || - (in_array($diagnosis, ['gi-uncomplicated', 'covid19-pneumonia']))) { + (in_array($diagnosis, ['gi-uncomplicated', 'covid19-pneumonia'])) || + // DB data shows that in some cases, medication was distributed, but + // diagnosis was not set properly. + ($diagnosis == 'none' && !empty($measurements_by_type['medication_distribution'])) + ) { $medication_prescribed = TRUE; } From 5c1eec68831ff9447913ff0af2338354fd6d15d0 Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 23 Aug 2024 16:29:10 +0300 Subject: [PATCH 059/185] More fixes and comments [ci skip] --- .../elm/Pages/NCD/RecurrentActivity/Utils.elm | 2 +- .../hedley_reports/hedley_reports.module | 109 +++++++++++++++--- 2 files changed, 95 insertions(+), 16 deletions(-) diff --git a/client/src/elm/Pages/NCD/RecurrentActivity/Utils.elm b/client/src/elm/Pages/NCD/RecurrentActivity/Utils.elm index 30a55ec81b..557cad33d1 100644 --- a/client/src/elm/Pages/NCD/RecurrentActivity/Utils.elm +++ b/client/src/elm/Pages/NCD/RecurrentActivity/Utils.elm @@ -89,7 +89,7 @@ nextStepsTaskCompleted assembled task = TaskReferral -> -- On recurrent phase of the encounter, only referral - -- facility possible is hospital, since referal to ARV + -- facility possible is hospital, since referral to ARV -- Services always happens on initial phase. referralToFacilityCompleted assembled FacilityHospital diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index fe260357d2..ff6f3aaabc 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2539,7 +2539,6 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant // If conditions match, add next steps activities. hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); - $expected = array_unique(array_merge($expected, array_keys($measurements_by_type))); $completion_data = [ 'start_date' => $start_date, 'taken_by' => $encounter_data['taken_by'], @@ -2863,7 +2862,10 @@ function hedley_reports_acute_illness_add_send_to_hc_initial_encounter($encounte in_array($diagnosis, ['gi-complicated', 'ri-complicated', 'fever-of-unknown-origin', 'undetermined', 'covid19-severe']) || ($medication_prescribed && $diagnosis != 'covid19-pneumonia' && hedley_reports_acute_illness_send_to_hc_due_to_medication_non_administration($encounter_data)) || - ($encounter_data['taken_by'] == 'chw' && $diagnosis == 'tuberculosis-suspect') + ($encounter_data['taken_by'] == 'chw' && $diagnosis == 'tuberculosis-suspect') || + // DB data shows that in some cases, referral activity was completed, but + // diagnosis was not set properly. + ($diagnosis == 'none' && !empty($measurements_by_type['send_to_hc'])) ) { $expected[] = 'send_to_hc'; } @@ -2894,15 +2896,26 @@ function hedley_reports_acute_illness_send_to_hc_due_to_medication_non_administr return FALSE; } -function hedley_reports_ends_with($haystack, $needle) { - $length = strlen($needle); - if(!$length) { - return TRUE; - } - return substr($haystack, -$length) === $needle; -} - -function hedley_reports_acute_illness_add_next_steps_activities_subsequent_encounter($encounter_data, &$expected) { +/** + * Determine and add next steps activities for a subsequent encounter. + * + * This function evaluates the encounter data to determine and add the next + * steps activities to be performed based on diagnosis, measurements, and + * various conditions. Activities include medication distribution, health + * education, contacting healthcare, sending to healthcare, and follow-up. + * + * @param array $encounter_data + * An array containing data for the encounter, including illness diagnosis, + * measurements by type, and other relevant information. + * @param array &$expected + * An array to which the next steps activities will be added based on the + * conditions evaluated. Activities are added if specific criteria are met. + * + * @return void + * This function does not return a value but modifies the $expected array + * with the activities to be performed. + */ +function hedley_reports_acute_illness_add_next_steps_activities_subsequent_encounter(array $encounter_data, array &$expected) { $diagnosis = $encounter_data['illness_diagnosis']; $measurements_by_type = $encounter_data['measurements_by_type']; @@ -2951,7 +2964,20 @@ function hedley_reports_acute_illness_add_next_steps_activities_subsequent_encou } } -function hedley_reports_acute_illness_danger_sign_present_on_subsequent_visit($encounter_data) { +/** + * Check if any of acute illness danger signs are present on a subsequent visit. + * + * This function examines the encounter data to determine if any of the recorded + * danger signs match predefined signs list indicating serious conditions. + * + * @param array $encounter_data + * An array containing measurement data for the encounter, including + * 'measurements_by_type' which holds the measurements for various types. + * + * @return bool + * TRUE if any of the danger signs are present, FALSE otherwise. + */ +function hedley_reports_acute_illness_danger_sign_present_on_subsequent_visit(array $encounter_data) { $measurements_by_type = $encounter_data['measurements_by_type']; if (empty($measurements_by_type['acute_illness_danger_signs'])) { @@ -2979,13 +3005,33 @@ function hedley_reports_acute_illness_danger_sign_present_on_subsequent_visit($e return FALSE; } +/** + * Determine if referral activity is expected, based on various conditions. + * + * @param array $encounter_data + * An array containing data for the encounter, including illness diagnosis, + * measurements by type, and age in months. + * @param bool $malaria_diagnosed_at_current_encounter + * TRUE if malaria was diagnosed at the current encounter, FALSE otherwise. + * @param bool $send_to_hc_by_malaria_testing + * TRUE if the case should be sent to healthcare based on malaria testing, + * FALSE otherwise. + * @param bool $danger_sign_present_on_subsequent_visit + * TRUE if danger signs are present on a subsequent visit, FALSE otherwise. + * @param array &$expected + * An array to which the result ('send_to_hc') will be added if conditions are met. + * + * @return void + * This function does not return a value but modifies the $expected array + * if certain conditions are met. + */ function hedley_reports_acute_illness_add_send_to_hc_subsequent_encounter ( - $encounter_data, + array $encounter_data, $malaria_diagnosed_at_current_encounter, $send_to_hc_by_malaria_testing, $danger_sign_present_on_subsequent_visit, - &$expected + array &$expected ) { $diagnosis = $encounter_data['illness_diagnosis']; $measurements_by_type = $encounter_data['measurements_by_type']; @@ -3071,7 +3117,21 @@ function hedley_reports_acute_illness_add_send_to_hc_subsequent_encounter } } -function hedley_reports_acute_illness_conditions_not_improving_on_subsequent_visit($encounter_data) { +/** + * Check if any patients condition is not improving on a subsequent visit. + * + * This function examines the provided encounter data to determine if any of + * the recorded danger signs indicate that a condition is not improving. + * + * @param array $encounter_data + * An array containing measurement data for the encounter, including + * 'measurements_by_type' which holds the measurements. + * + * @return bool + * TRUE if there are signs indicating that the condition is not improving, + * FALSE otherwise. + */ +function hedley_reports_acute_illness_conditions_not_improving_on_subsequent_visit(array $encounter_data) { $measurements_by_type = $encounter_data['measurements_by_type']; if (empty($measurements_by_type['acute_illness_danger_signs'])) { @@ -3319,3 +3379,22 @@ function hedley_reports_generate_completion_result(array $expected, array $measu return implode(',', $expected) . '|' . implode(',', $completed); } + +/** + * Check if a string ends with a given substring. + * + * @param string $haystack + * The string to search within. + * @param string $needle + * The substring to check for at the end of the `$haystack` string. + * + * @return bool + * TRUE if `$haystack` ends with `$needle`, FALSE otherwise. + */ +function hedley_reports_ends_with($haystack, $needle) { + $length = strlen($needle); + if(!$length) { + return TRUE; + } + return substr($haystack, -$length) === $needle; +} From 68a61263f8a03a36561c43e9a192ad1a48621d2d Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 23 Aug 2024 16:31:12 +0300 Subject: [PATCH 060/185] A fix [ci skip] --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 1 + 1 file changed, 1 insertion(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index ff6f3aaabc..64b715a775 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2855,6 +2855,7 @@ function hedley_reports_acute_illness_add_next_steps_activities_initial_encounte function hedley_reports_acute_illness_add_send_to_hc_initial_encounter($encounter_data, $medication_prescribed, &$expected) { $age_in_months = $encounter_data['age_in_months']; $diagnosis = $encounter_data['illness_diagnosis']; + $measurements_by_type = $encounter_data['measurements_by_type']; if ( hedley_reports_acute_illness_send_to_hc_by_malaria_testing($encounter_data) || From be37ef02a01f6f2d33d1e6de70578e1c4dc600dd Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 25 Aug 2024 20:23:07 +0300 Subject: [PATCH 061/185] Fixes + docs --- .../hedley_reports/hedley_reports.module | 275 +++++++++++++----- 1 file changed, 204 insertions(+), 71 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 64b715a775..4d8bc317ff 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -211,6 +211,16 @@ function hedley_reports_statistical_queries_report_callback_menu() { return hedley_reports_callback_menu_by_page('reports-menu'); } +/** + * Generates data for a callback menu page. + * + * @param string $page + * The page identifier used to build the Elm app. + * + * @return array + * A renderable array containing the Elm app with site name + * and health centers data. + */ function hedley_reports_callback_menu_by_page($page) { $site = variable_get('hedley_general_site_name', ''); @@ -1895,8 +1905,16 @@ function hedley_ncda_query_exclude_set_reports_data_alter(QueryAlterableInterfac $query->isNull('fnd.field_reports_data_value'); } +/** + * Resolves all Nurse IDs. + * + * This function queries the database for all entities + * with the role of 'nurse' and returns their IDs. + * + * @return array + * An array of nurse node IDs. + */ function hedley_ncda_resolve_nurses_ids() { - // Resolve all Nurses. We need to determine if measurement was taken by nurse or CHW. $query = db_select('field_data_field_role', 'fr'); $query->addField('fr', 'entity_id'); $query->condition('fr.field_role_value', 'nurse'); @@ -1933,7 +1951,7 @@ function hedley_reports_completion_report_callback_global() { * The HTML markup for the Elm application. */ function hedley_reports_completion_report_callback_health_center($health_center) { - return hedley_reports_build_completion_results_app($health_center); + return hedley_reports_build_completion_results_app($health_center); } /** @@ -1979,9 +1997,12 @@ function hedley_reports_build_completion_results_app($health_center = NULL) { */ function hedley_reports_generate_completion_results_data($health_center) { $bundles = [ - 'acute_illness_encounter', // Acute Illness data. - 'attendance', // Nutrition Group data. - 'nutrition_encounter', // Nutrition Individual data. + // Acute Illness data. + 'acute_illness_encounter', + // Nutrition Group data. + 'attendance', + // Nutrition Individual data. + 'nutrition_encounter', ]; $base_query = new EntityFieldQuery(); @@ -2056,6 +2077,15 @@ function hedley_reports_generate_completion_results_data($health_center) { return $data; } +/** + * Generates completion data for an individual nutrition encounter. + * + * @param object $encounter + * The encounter node object. + * + * @return array + * An array containing the completion data for given encounter. + */ function hedley_reports_generate_completion_data_for_nutrition_individual_encounter($encounter) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ @@ -2117,7 +2147,7 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun if (!empty($measurements_by_type['nutrition_nutrition'])) { $assessment = $measurements_by_type['nutrition_nutrition']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; } - else if (!empty($measurements_by_type['nutrition_follow_up'])) { + elseif (!empty($measurements_by_type['nutrition_follow_up'])) { $assessment = $measurements_by_type['nutrition_follow_up']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; } @@ -2156,6 +2186,18 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun ]; } +/** + * Generates completion data for a group nutrition encounter. + * + * Nutrition group encounter is done for adult+child pair, where for both + * measurements are recorded. + * + * @param object $attendance + * The attendance node object. + * + * @return array + * An array containing the completion data for group encounter. + */ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($attendance) { // To reduce memory usage, mapping measurement types as single characters. $mapping_child = [ @@ -2310,7 +2352,8 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ $birth_date_obj = new DateTime($birth_date); $interval = $start_date_obj->diff($birth_date_obj); $age_in_months = ($interval->y * 12) + $interval->m; - } catch (Exception $e) { + } + catch (Exception $e) { $age_in_months = NULL; } @@ -2329,7 +2372,7 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ if (!empty($measurements_by_type['nutrition'])) { $assessment = $measurements_by_type['nutrition']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; } - else if (!empty($measurements_by_type['follow_up'])) { + elseif (!empty($measurements_by_type['follow_up'])) { $assessment = $measurements_by_type['follow_up']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; } @@ -2347,7 +2390,8 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ } } - // Child FBF activity is shown for sessions taking place at FBF and ACHI clinics. + // Child FBF activity is shown for sessions taking + // place at FBF and ACHI clinics. if ($start_date_obj >= $fbf_launch_date_obj && in_array($clinic_type, ['fbf', 'achi'])) { $expected[] = 'child_fbf'; } @@ -2373,6 +2417,14 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ return $return; } +/** + * Generates completion data for acute illness encounters taken during illness. + * + * @param object $participant + * The participant node object representing illness. + * @param bool $exclude_set + * Indicate whether to exclude encounters with report data already set. + */ function hedley_reports_generate_completion_data_for_aculte_illness($participant, $exclude_set) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ @@ -2476,12 +2528,12 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant $previous_encounters_data = array_slice($encounters_data, 0, $index); $is_initial = ($encounter_type == 'nurse-encounter') || (($encounter_type == 'chw-encounter') && empty($previous_encounters_data)); $encounter_data['is_initial'] = $is_initial; - $illness_diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; + $diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; if (!$is_initial && (empty($diagnosis) || $diagnosis == 'none')) { // Reversing passed array, to have the encounters sorted DESC. - $illness_diagnosis = hedley_reports_get_acute_illness_diagnosis_by_previous_encounters(array_reverse($previous_encounters_data)); + $diagnosis = hedley_reports_get_acute_illness_diagnosis_by_previous_encounters(array_reverse($previous_encounters_data)); } - $encounter_data['illness_diagnosis'] = $illness_diagnosis; + $encounter_data['illness_diagnosis'] = $diagnosis; // Acute illness module defines following logic: // If first encounter(s) were taken by CHW, but then @@ -2499,7 +2551,8 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant if ($initial_nurse_encounter_index == -1) { $first_initial_with_subsequents = $previous_encounters_data; $second_initial_with_subsequents = []; - } else { + } + else { $first_initial_with_subsequents = array_slice($previous_encounters_data, 0, $initial_nurse_encounter_index + 1); $second_initial_with_subsequents = array_slice($previous_encounters_data, $initial_nurse_encounter_index + 1); } @@ -2525,7 +2578,6 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. - // Load all activities expected only by encounter type and start date. $expected = hedley_reports_generate_acute_illness_expected_initial_activities($encounter_data); // If conditions match, add malaria_testing activity. @@ -2539,7 +2591,7 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant // If conditions match, add next steps activities. hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); - $completion_data = [ + $completion_data = [ 'start_date' => $start_date, 'taken_by' => $encounter_data['taken_by'], 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), @@ -2550,7 +2602,16 @@ function hedley_reports_generate_completion_data_for_aculte_illness($participant } } -function hedley_reports_generate_acute_illness_expected_initial_activities($encounter_data) { +/** + * Generates the list of expected activities for an acute illness encounter. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * + * @return array + * An array of expected activity names. + */ +function hedley_reports_generate_acute_illness_expected_initial_activities(array $encounter_data) { // Activities that are shown at any type of encounter, // unconditionally. Existed with initial launch of the feature. $expected = [ @@ -2582,7 +2643,15 @@ function hedley_reports_generate_acute_illness_expected_initial_activities($enco return $expected; } -function hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, &$expected) { +/** + * Adds Malaria Testing as expected activity, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_acute_illness_add_expected_malaria_testing(array $encounter_data, array &$expected) { // Malaria test is suggested only if fever is recorder. if (!$encounter_data['fever']) { return; @@ -2591,7 +2660,7 @@ function hedley_reports_acute_illness_add_expected_malaria_testing($encounter_da $diagnosis = $encounter_data['illness_diagnosis']; $covid_diagnoses = ['covid19-severe', 'covid19-pneumonia', 'covid19-low-risk']; $covid_not_diagnosed = TRUE; - if (!empty($current_encounter_diagnosis)) { + if (!empty($diagnosis)) { $covid_not_diagnosed = !in_array($diagnosis, $covid_diagnoses); } @@ -2643,7 +2712,15 @@ function hedley_reports_acute_illness_add_expected_malaria_testing($encounter_da } } -function hedley_reports_acute_illness_add_expected_covid_testing($encounter_data, &$expected) { +/** + * Adds expected COVID-19 as expected activity, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_acute_illness_add_expected_covid_testing(array $encounter_data, array &$expected) { if ($encounter_data['taken_by'] != 'nurse') { // COVID lab check is available for nurse only. return; @@ -2659,13 +2736,13 @@ function hedley_reports_acute_illness_add_expected_covid_testing($encounter_data $measurements_by_type = $encounter_data['measurements_by_type']; $fever = $encounter_data['fever']; - $total_symptoms_respiratory = hedley_reports_count_acute_illness_symptoms_respiratory($measurements_by_type['symptoms_respiratory']); - $total_symptoms_gi = hedley_reports_count_acute_illness_symptoms_gi($measurements_by_type['symptoms_gi']); + $total_symptoms_respiratory = hedley_reports_count_acute_illness_symptoms_respiratory($measurements_by_type['symptoms_respiratory']); + $total_symptoms_gi = hedley_reports_count_acute_illness_symptoms_gi($measurements_by_type['symptoms_gi']); if ($total_symptoms_gi > 0) { $symptoms_indicate_covid = $total_symptoms_respiratory > 0; } else { - $total_symptoms_general = hedley_reports_count_acute_illness_symptoms_general($measurements_by_type['symptoms_general']); + $total_symptoms_general = hedley_reports_count_acute_illness_symptoms_general($measurements_by_type['symptoms_general']); $symptoms_indicate_covid = ($total_symptoms_general + $total_symptoms_respiratory + $total_symptoms_gi) > 1; } @@ -2693,7 +2770,15 @@ function hedley_reports_acute_illness_add_expected_covid_testing($encounter_data } } -function hedley_reports_acute_illness_add_expected_treatment_ongoing($encounter_data, &$expected) { +/** + * Adds Ongoing Treatment as expected activity, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_acute_illness_add_expected_treatment_ongoing(array $encounter_data, array &$expected) { if ($encounter_data['is_initial']) { // Ongoing treatment is available only for subsequent encounters. return; @@ -2706,7 +2791,8 @@ function hedley_reports_acute_illness_add_expected_treatment_ongoing($encounter_ return; } - // Activity is expected, if medication was prescribed at any of previous encounters. + // Activity is expected, if medication was prescribed at any + // of previous encounters. $medication_prescribed = FALSE; $initial_with_subsequents = $encounter_data['initial_with_subsequents']; foreach ($initial_with_subsequents as $prev_encounter_data) { @@ -2739,7 +2825,15 @@ function hedley_reports_acute_illness_add_expected_treatment_ongoing($encounter_ } } -function hedley_reports_acute_illness_add_physical_exam_activities($encounter_data, &$expected) { +/** + * Adds Physical Exam activities to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_acute_illness_add_physical_exam_activities(array $encounter_data, array &$expected) { if ($encounter_data['is_initial']) { // Acute findings is available only for initial encounter. $expected[] = 'acute_findings'; @@ -2766,7 +2860,15 @@ function hedley_reports_acute_illness_add_physical_exam_activities($encounter_da } } -function hedley_reports_acute_illness_add_next_steps_activities($encounter_data, &$expected) { +/** + * Adds Next Steps activities to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_acute_illness_add_next_steps_activities(array $encounter_data, array &$expected) { if ($encounter_data['is_initial']) { hedley_reports_acute_illness_add_next_steps_activities_initial_encounter($encounter_data, $expected); } @@ -2775,7 +2877,15 @@ function hedley_reports_acute_illness_add_next_steps_activities($encounter_data, } } -function hedley_reports_acute_illness_add_next_steps_activities_initial_encounter($encounter_data, &$expected) { +/** + * Adds Next Steps activities for the initial encounter, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_acute_illness_add_next_steps_activities_initial_encounter(array $encounter_data, array &$expected) { $age_in_months = $encounter_data['age_in_months']; $diagnosis = $encounter_data['illness_diagnosis']; $measurements_by_type = $encounter_data['measurements_by_type']; @@ -2803,7 +2913,7 @@ function hedley_reports_acute_illness_add_next_steps_activities_initial_encounte } // Adding Contact HC activity. - if ($is_chw && $diagnosis == 'covid19' && !empty($measurements_by_type['call_114']) ) { + if ($is_chw && $diagnosis == 'covid19' && !empty($measurements_by_type['call_114'])) { // If suspected COVID case, but call to 114 was not made, need // to contact HC. This means that 114 contact filed got single // value set to 'none'. @@ -2828,7 +2938,11 @@ function hedley_reports_acute_illness_add_next_steps_activities_initial_encounte $launch_date = '2021-12-22'; $launch_date_obj = new DateTime($launch_date); if ($encounter_data['start_date_obj'] >= $launch_date_obj) { - if (in_array($diagnosis, ['covid19-pneumonia', 'covid19-low-risk', 'covid19-severe'])) { + if (in_array($diagnosis, [ + 'covid19-pneumonia', + 'covid19-low-risk', + 'covid19-severe', + ])) { $expected[] = 'acute_illness_contacts_tracing'; } } @@ -2852,7 +2966,17 @@ function hedley_reports_acute_illness_add_next_steps_activities_initial_encounte } } -function hedley_reports_acute_illness_add_send_to_hc_initial_encounter($encounter_data, $medication_prescribed, &$expected) { +/** + * Adds "Send to HC" activity during initial encounter, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param bool $medication_prescribed + * Whether medication was prescribed during the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_acute_illness_add_send_to_hc_initial_encounter(array $encounter_data, $medication_prescribed, array &$expected) { $age_in_months = $encounter_data['age_in_months']; $diagnosis = $encounter_data['illness_diagnosis']; $measurements_by_type = $encounter_data['measurements_by_type']; @@ -2860,7 +2984,13 @@ function hedley_reports_acute_illness_add_send_to_hc_initial_encounter($encounte if ( hedley_reports_acute_illness_send_to_hc_by_malaria_testing($encounter_data) || (in_array($diagnosis, ['cough-and-cold', 'ri-uncomplicated']) && $age_in_months < 2) || - in_array($diagnosis, ['gi-complicated', 'ri-complicated', 'fever-of-unknown-origin', 'undetermined', 'covid19-severe']) || + in_array($diagnosis, [ + 'gi-complicated', + 'ri-complicated', + 'fever-of-unknown-origin', + 'undetermined', + 'covid19-severe', + ]) || ($medication_prescribed && $diagnosis != 'covid19-pneumonia' && hedley_reports_acute_illness_send_to_hc_due_to_medication_non_administration($encounter_data)) || ($encounter_data['taken_by'] == 'chw' && $diagnosis == 'tuberculosis-suspect') || @@ -2872,16 +3002,33 @@ function hedley_reports_acute_illness_add_send_to_hc_initial_encounter($encounte } } -function hedley_reports_acute_illness_send_to_hc_by_malaria_testing($encounter_data) { +/** + * Determines whether "Send to HC" activity is triggered per malaria testing. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * + * @return bool + * TRUE if the activity should be triggered, FALSE otherwise. + */ +function hedley_reports_acute_illness_send_to_hc_by_malaria_testing(array $encounter_data) { $age_in_months = $encounter_data['age_in_months']; $diagnosis = $encounter_data['illness_diagnosis']; - return - ($diagnosis == 'malaria-uncomplicated' && $age_in_months < 6) || + return ($diagnosis == 'malaria-uncomplicated' && $age_in_months < 6) || in_array($diagnosis, ['malaria-complicated', 'malaria-uncomplicated-pregnant']); } -function hedley_reports_acute_illness_send_to_hc_due_to_medication_non_administration($encounter_data) { +/** + * Determines if "Send to HC" activity is triggered per medication medication. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * + * @return bool + * TRUE if the activity should be triggered, FALSE otherwise. + */ +function hedley_reports_acute_illness_send_to_hc_due_to_medication_non_administration(array $encounter_data) { $measurements_by_type = $encounter_data['measurements_by_type']; if (empty($measurements_by_type['medication_distribution'])) { return FALSE; @@ -2898,23 +3045,12 @@ function hedley_reports_acute_illness_send_to_hc_due_to_medication_non_administr } /** - * Determine and add next steps activities for a subsequent encounter. - * - * This function evaluates the encounter data to determine and add the next - * steps activities to be performed based on diagnosis, measurements, and - * various conditions. Activities include medication distribution, health - * education, contacting healthcare, sending to healthcare, and follow-up. + * Adds expected Next Steps activities for the subsequent encounter. * * @param array $encounter_data - * An array containing data for the encounter, including illness diagnosis, - * measurements by type, and other relevant information. + * An associative array containing data about the encounter. * @param array &$expected - * An array to which the next steps activities will be added based on the - * conditions evaluated. Activities are added if specific criteria are met. - * - * @return void - * This function does not return a value but modifies the $expected array - * with the activities to be performed. + * An array of expected activity names, passed by reference. */ function hedley_reports_acute_illness_add_next_steps_activities_subsequent_encounter(array $encounter_data, array &$expected) { $diagnosis = $encounter_data['illness_diagnosis']; @@ -2937,7 +3073,7 @@ function hedley_reports_acute_illness_add_next_steps_activities_subsequent_encou $expected[] = 'health_education'; } - // Adding Contact HC activity. + // Adding Contact HC activity. $danger_sign_present_on_subsequent_visit = hedley_reports_acute_illness_danger_sign_present_on_subsequent_visit($encounter_data); if (!$malaria_diagnosed_at_current_encounter && ($danger_sign_present_on_subsequent_visit && $diagnosis == 'covid19')) { @@ -3020,14 +3156,9 @@ function hedley_reports_acute_illness_danger_sign_present_on_subsequent_visit(ar * @param bool $danger_sign_present_on_subsequent_visit * TRUE if danger signs are present on a subsequent visit, FALSE otherwise. * @param array &$expected - * An array to which the result ('send_to_hc') will be added if conditions are met. - * - * @return void - * This function does not return a value but modifies the $expected array - * if certain conditions are met. + * An array to which the result will be added if conditions are met. */ -function hedley_reports_acute_illness_add_send_to_hc_subsequent_encounter -( +function hedley_reports_acute_illness_add_send_to_hc_subsequent_encounter( array $encounter_data, $malaria_diagnosed_at_current_encounter, $send_to_hc_by_malaria_testing, @@ -3053,7 +3184,7 @@ function hedley_reports_acute_illness_add_send_to_hc_subsequent_encounter if ($age_in_months < 12) { $respiratory_rate_elevated = $respiratory_rate >= 50; } - else if ($age_in_months < 60) { + elseif ($age_in_months < 60) { $respiratory_rate_elevated = $respiratory_rate >= 40; } else { @@ -3083,7 +3214,7 @@ function hedley_reports_acute_illness_add_send_to_hc_subsequent_encounter if ($sign['value'] == 'brittle-hair') { $brittle_hair = TRUE; } - else if ($sign['value'] == 'dry-skin') { + elseif ($sign['value'] == 'dry-skin') { $dry_skin = TRUE; } @@ -3101,7 +3232,7 @@ function hedley_reports_acute_illness_add_send_to_hc_subsequent_encounter $hc_recommended_to_come = FALSE; if (!empty($measurements_by_type['hc_contact'])) { - $recommendations = $measurements_by_type['hc_contact'] ->field_hc_recommendation[LANGUAGE_NONE]; + $recommendations = $measurements_by_type['hc_contact']->field_hc_recommendation[LANGUAGE_NONE]; foreach ($recommendations as $recommendation) { if ($recommendation['value'] == 'come-to-hc') { $hc_recommended_to_come = TRUE; @@ -3160,9 +3291,9 @@ function hedley_reports_acute_illness_conditions_not_improving_on_subsequent_vis * An array of encounter data, where each item contains an 'encounter' object. * * @return string|null - * The acute illness diagnosis if found, or NULL if no valid diagnosis is found. + * The acute illness diagnosis if found, or NULL if nothing valid resolved. */ -function hedley_reports_get_acute_illness_diagnosis_by_previous_encounters($encounters_data) { +function hedley_reports_get_acute_illness_diagnosis_by_previous_encounters(array $encounters_data) { foreach ($encounters_data as $encounter_data) { $encounter = $encounter_data['encounter']; $diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; @@ -3286,7 +3417,7 @@ function hedley_reports_count_acute_illness_signs(array $values) { } /** - * Resolve the age in months for an individual at the time of a specific encounter. + * Resolve the age in months for patient at the time of a specific encounter. * * @param object $encounter * The encounter object, which includes the participant and person data. @@ -3294,15 +3425,16 @@ function hedley_reports_count_acute_illness_signs(array $values) { * The date object representing the start date of the encounter. * * @return int|null - * The age in months of the individual at the time of the encounter, or NULL if an error occurs. + * The age in months of the individual at the time of the encounter, + * or NULL if an error occurs. */ -function hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj) { +function hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, DateTime $start_date_obj) { try { // Get participant ID and node. $participant_id = $encounter->field_individual_participant[LANGUAGE_NONE][0]['target_id']; $participant = node_load($participant_id); - // Get person ID and node + // Get person ID and node. $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; $person = node_load($person_id); @@ -3313,7 +3445,8 @@ function hedley_reports_resolve_age_in_months_for_individual_encounter($encounte $birth_date_obj = new DateTime($birth_date); $interval = $start_date_obj->diff($birth_date_obj); return ($interval->y * 12) + $interval->m; - } catch (Exception $e) { + } + catch (Exception $e) { watchdog('hedley_reports', "Failed to resolve patient age at encounter ID $encounter->nid."); return NULL; } @@ -3333,7 +3466,7 @@ function hedley_reports_resolve_age_in_months_for_individual_encounter($encounte */ function hedley_reports_load_individual_encounter_measurements_ids($encounter) { $bundle = $encounter->type; - $encounter_field ="field_$bundle"; + $encounter_field = "field_$bundle"; $query = db_select("field_data_$encounter_field", 'ef'); $query->addField('ef', 'entity_id'); $query->condition("ef.{$encounter_field}_target_id", $encounter->nid); @@ -3345,8 +3478,8 @@ function hedley_reports_load_individual_encounter_measurements_ids($encounter) { * * This function checks which expected measurements have been completed based on * the provided measurements by type, maps both the expected and completed - * measurement types using the provided mapping array, and then generates a string - * representing the completion result. + * measurement types using the provided mapping array, and then generates + * a string representing the completion result. * * @param array $expected * An array of expected measurement types. @@ -3394,7 +3527,7 @@ function hedley_reports_generate_completion_result(array $expected, array $measu */ function hedley_reports_ends_with($haystack, $needle) { $length = strlen($needle); - if(!$length) { + if (!$length) { return TRUE; } return substr($haystack, -$length) === $needle; From cfccc0a1e7d3c0a8f7c94b5ef07c96e8e02c516f Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 26 Aug 2024 16:33:40 +0300 Subject: [PATCH 062/185] Fix typo [ci skip] --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- .../scripts/generate-acute-illness-completion-data.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 4d8bc317ff..693ce3ca4b 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2425,7 +2425,7 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ * @param bool $exclude_set * Indicate whether to exclude encounters with report data already set. */ -function hedley_reports_generate_completion_data_for_aculte_illness($participant, $exclude_set) { +function hedley_reports_generate_completion_data_for_acute_illness($participant, $exclude_set) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ 'acute_findings' => 'a', diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php index 1497805ffd..c25fa9b5aa 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php @@ -63,7 +63,7 @@ $ids = array_keys($result['node']); $nodes = node_load_multiple($ids); foreach ($nodes as $node) { - hedley_reports_generate_completion_data_for_aculte_illness($node, $exclude_set); + hedley_reports_generate_completion_data_for_acute_illness($node, $exclude_set); $total++; $memory = round(memory_get_usage() / 1048576); From 448b64622479fe6446024f935cd8af3617c8955d Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 26 Aug 2024 16:43:16 +0300 Subject: [PATCH 063/185] Add script [ci skip] --- .../hedley_reports/hedley_reports.module | 175 ++++++++++++++++++ .../generate-well-child-completion-data.php | 85 +++++++++ 2 files changed, 260 insertions(+) create mode 100644 server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 693ce3ca4b..306c9cbc16 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3428,6 +3428,181 @@ function hedley_reports_count_acute_illness_signs(array $values) { * The age in months of the individual at the time of the encounter, * or NULL if an error occurs. */ + +/** + * Generates completion data for well child encounters for patient. + * + * @param object $participant + * The participant node object representing illness. + * @param bool $exclude_set + * Indicate whether to exclude encounters with report data already set. + */ +function hedley_reports_generate_completion_data_for_well_child($participant, $exclude_set) { + // To reduce memory usage, mapping measurement types as single characters. + $mapping = [ + 'acute_findings' => 'a', + 'acute_illness_contacts_tracing' => 'b', + 'acute_illness_core_exam' => 'c', + 'acute_illness_danger_signs' => 'd', + 'acute_illness_follow_up' => 'e', + 'acute_illness_muac' => 'f', + 'acute_illness_nutrition' => 'g', + 'acute_illness_vitals' => 'h', + 'call_114' => 'i', + 'covid_testing' => 'j', + 'exposure' => 'k', + 'hc_contact' => 'l', + 'health_education' => 'm', + 'isolation' => 'n', + 'malaria_testing' => 'o', + 'medication_distribution' => 'p', + 'send_to_hc' => 'q', + 'symptoms_general' => 'r', + 'symptoms_gi' => 's', + 'symptoms_respiratory' => 't', + 'travel_history' => 'u', + 'treatment_history' => 'v', + 'treatment_ongoing' => 'w', + ]; + + // Load all encounters of current participant. + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'well_child_encounter') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_individual_participant', 'target_id', $participant->nid) + ->propertyOrderBy('nid') + ->execute(); + + if (empty($result['node'])) { + return; + } + + // Encounters are sorted ASC. + $encounters = node_load_multiple(array_keys($result['node'])); + $encounters_data = []; + foreach ($encounters as $encounter) { + // Skip encounter if exclusion flag is raised and it's report data is set. + if ($exclude_set && !empty($encounter->field_reports_data[LANGUAGE_NONE][0]['value'])) { + continue; + } + + // Loading all measurements that belong to encounter. + $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); + // If encounter type field is empty, we default to pediatric care. + if (empty($encounter->field_well_child_encounter_type)) { + $encounter_type = 'pediatric-care'; + } + else { + $encounter_type = $encounter->field_well_child_encounter_type[LANGUAGE_NONE][0]['value']; + } + + $measurements = !empty($measurements_ids) ? node_load_multiple($measurements_ids) : []; + // Ordering measurements by type. + $measurements_by_type = []; + foreach ($measurements as $measurement) { + $measurements_by_type[$measurement->type] = $measurement; + } + + $encounters_data[] = [ + 'encounter' => $encounter, + 'encounter_type' => $encounter_type, + 'measurements_by_type' => $measurements_by_type, + ]; + } + +// foreach ($encounters_data as $index => $encounter_data) { +// $encounter = $encounter_data['encounter']; +// $encounter_type = $encounter_data['encounter_type']; +// $measurements_by_type = $encounter_data['measurements_by_type']; +// +// // Resolve encounter start date. +// $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; +// $start_date_obj = new DateTime($start_date); +// $encounter_data['start_date_obj'] = $start_date_obj; +// +// // Try to resolve age in months at a time encounter was performed. +// $age_in_months = hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj); +// $encounter_data['age_in_months'] = $age_in_months; +// +// $previous_encounters_data = array_slice($encounters_data, 0, $index); +// $is_initial = ($encounter_type == 'nurse-encounter') || (($encounter_type == 'chw-encounter') && empty($previous_encounters_data)); +// $encounter_data['is_initial'] = $is_initial; +// $diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; +// if (!$is_initial && (empty($diagnosis) || $diagnosis == 'none')) { +// // Reversing passed array, to have the encounters sorted DESC. +// $diagnosis = hedley_reports_get_acute_illness_diagnosis_by_previous_encounters(array_reverse($previous_encounters_data)); +// } +// $encounter_data['illness_diagnosis'] = $diagnosis; +// +// // Acute illness module defines following logic: +// // If first encounter(s) were taken by CHW, but then +// // nurse ran and encounter, we consider that encounter of +// // nurse as initial. All data collected by CHWs until that +// // encounter should be ignored. +// $initial_nurse_encounter_index = -1; +// foreach ($previous_encounters_data as $ind => $data) { +// if ($data['encounter_type'] == 'nurse-encounter') { +// $initial_nurse_encounter_index = $ind; +// break; +// } +// } +// +// if ($initial_nurse_encounter_index == -1) { +// $first_initial_with_subsequents = $previous_encounters_data; +// $second_initial_with_subsequents = []; +// } +// else { +// $first_initial_with_subsequents = array_slice($previous_encounters_data, 0, $initial_nurse_encounter_index + 1); +// $second_initial_with_subsequents = array_slice($previous_encounters_data, $initial_nurse_encounter_index + 1); +// } +// $initial_with_subsequents = empty($second_initial_with_subsequents) ? $first_initial_with_subsequents : $second_initial_with_subsequents; +// $encounter_data['initial_with_subsequents'] = $initial_with_subsequents; +// +// $fever_at_symptoms = FALSE; +// if (!empty($measurements_by_type['symptoms_general'])) { +// $fever_period = $measurements_by_type['symptoms_general']->field_fever_period[LANGUAGE_NONE][0]['value']; +// if (!empty($fever_period)) { +// $fever_at_symptoms = $fever_period > 0; +// } +// } +// $fever_at_vitals = FALSE; +// if (!empty($measurements_by_type['acute_illness_vitals'])) { +// $body_temperature = $measurements_by_type['acute_illness_vitals']->field_body_temperature[LANGUAGE_NONE][0]['value']; +// if (!empty($body_temperature)) { +// $fever_at_vitals = $body_temperature >= 37.5; +// } +// } +// $fever = $fever_at_symptoms || $fever_at_vitals; +// $encounter_data['fever'] = $fever; +// +// // So far we were constructing data structures to resolve encounter data. +// // Now we have enough info to determine which activities were expected. +// // Load all activities expected only by encounter type and start date. +// $expected = hedley_reports_generate_acute_illness_expected_initial_activities($encounter_data); +// // If conditions match, add malaria_testing activity. +// hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, $expected); +// // If conditions match, add covid_testing activity. +// hedley_reports_acute_illness_add_expected_covid_testing($encounter_data, $expected); +// // If conditions match, add treatment_ongoing activity. +// hedley_reports_acute_illness_add_expected_treatment_ongoing($encounter_data, $expected); +// // If conditions match, add physical exam activities. +// hedley_reports_acute_illness_add_physical_exam_activities($encounter_data, $expected); +// // If conditions match, add next steps activities. +// hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); +// +// $completion_data = [ +// 'start_date' => $start_date, +// 'taken_by' => $encounter_data['taken_by'], +// 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), +// ]; +// +// $encounter->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); +// node_save($encounter); +// } +} + function hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, DateTime $start_date_obj) { try { // Get participant ID and node. diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php new file mode 100644 index 0000000000..1146152fea --- /dev/null +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php @@ -0,0 +1,85 @@ +entityCondition('entity_type', 'node') + ->entityCondition('bundle', $type) + ->fieldCondition('field_encounter_type', 'value', 'well-child') + ->propertyCondition('status', NODE_PUBLISHED); + +$count_query = clone $base_query; +$count_query->propertyCondition('nid', $nid, '>'); +$count = $count_query->count()->execute(); + +if ($count == 0) { + drush_print("There are no nodes of type $type for well child encounters in DB."); + exit; +} + +$total = 0; +drush_print("$count nodes of type $type for well child encounters located."); + +while (TRUE) { + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + hedley_reports_generate_completion_data_for_well_child($node, $exclude_set); + $total++; + + $memory = round(memory_get_usage() / 1048576); + if ($memory >= $memory_limit) { + drush_print(dt('Stopped before out of memory. Start process from the node ID @nid', ['@nid' => $nid])); + return; + } + } + + $memory = round(memory_get_usage() / 1048576); + drush_print("Calculated so far: $total, Memory: $memory"); + + // Free up memory. + drupal_static_reset(); + + $nid = end($ids); +} + +drush_print("Done! Completion data calculated for $total participants."); From 972c7d486ead061596d9ad0b69032c8dabe5f0df Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 26 Aug 2024 16:45:49 +0300 Subject: [PATCH 064/185] Add field for completion data to Well Child encounter CT [ci skip] --- ...ley_well_child.features.field_instance.inc | 175 +++++++++++++++++- .../hedley_well_child/hedley_well_child.info | 1 + .../hedley_well_child.strongarm.inc | 132 ++++++------- 3 files changed, 240 insertions(+), 68 deletions(-) diff --git a/server/hedley/modules/custom/hedley_well_child/hedley_well_child.features.field_instance.inc b/server/hedley/modules/custom/hedley_well_child/hedley_well_child.features.field_instance.inc index e53a6278e9..4d1e58d011 100644 --- a/server/hedley/modules/custom/hedley_well_child/hedley_well_child.features.field_instance.inc +++ b/server/hedley/modules/custom/hedley_well_child/hedley_well_child.features.field_instance.inc @@ -140,6 +140,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -184,6 +185,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -228,6 +230,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -313,6 +316,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -547,6 +551,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -591,6 +596,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -635,6 +641,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -720,6 +727,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -858,6 +866,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -940,6 +949,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -984,6 +994,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1069,6 +1080,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1209,6 +1221,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1254,6 +1267,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1299,6 +1313,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1384,6 +1399,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1618,6 +1634,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1662,6 +1679,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1706,6 +1724,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1791,6 +1810,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2024,6 +2044,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2069,6 +2090,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2114,6 +2136,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2199,6 +2222,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2336,6 +2360,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2380,6 +2405,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2424,6 +2450,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2508,6 +2535,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2628,6 +2656,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2637,6 +2666,46 @@ function hedley_well_child_field_default_field_instances() { ), ); + // Exported field_instance: 'node-well_child_encounter-field_reports_data'. + $field_instances['node-well_child_encounter-field_reports_data'] = array( + 'bundle' => 'well_child_encounter', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 7, + ), + 'teaser' => array( + 'label' => 'above', + 'settings' => array(), + 'type' => 'hidden', + 'weight' => 0, + ), + ), + 'entity_type' => 'node', + 'field_name' => 'field_reports_data', + 'label' => 'Completion Data', + 'required' => 0, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'rows' => 5, + ), + 'type' => 'text_textarea', + 'weight' => 6, + ), + ); + // Exported field_instance: 'node-well_child_encounter-field_scheduled_date'. $field_instances['node-well_child_encounter-field_scheduled_date'] = array( 'bundle' => 'well_child_encounter', @@ -2728,12 +2797,13 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => 7, + 'weight' => 8, ), ); @@ -2773,7 +2843,7 @@ function hedley_well_child_field_default_field_instances() { 'size' => 60, ), 'type' => 'text_textfield', - 'weight' => 6, + 'weight' => 7, ), ); @@ -2906,6 +2976,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2988,6 +3059,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3078,6 +3150,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3200,6 +3273,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3394,6 +3468,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3513,6 +3588,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3557,6 +3633,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3642,6 +3719,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3819,6 +3897,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3863,6 +3942,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3907,6 +3987,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3992,6 +4073,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4178,6 +4260,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4222,6 +4305,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4266,6 +4350,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4351,6 +4436,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4537,6 +4623,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4581,6 +4668,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4663,6 +4751,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4748,6 +4837,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4894,6 +4984,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4938,6 +5029,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4982,6 +5074,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5067,6 +5160,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5347,6 +5441,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5391,6 +5486,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5435,6 +5531,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5520,6 +5617,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5657,6 +5755,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5739,6 +5838,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5783,6 +5883,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5906,6 +6007,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6140,6 +6242,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6184,6 +6287,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6228,6 +6332,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6313,6 +6418,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6451,6 +6557,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6495,6 +6602,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6539,6 +6647,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6624,6 +6733,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6858,6 +6968,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6902,6 +7013,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6946,6 +7058,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7031,6 +7144,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7177,6 +7291,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7221,6 +7336,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7265,6 +7381,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7349,6 +7466,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7634,6 +7752,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7678,6 +7797,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7759,6 +7879,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7926,6 +8047,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8196,6 +8318,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8297,6 +8420,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8341,6 +8465,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8426,6 +8551,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8526,6 +8652,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8645,6 +8772,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8689,6 +8817,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8774,6 +8903,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9008,6 +9138,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9052,6 +9183,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9096,6 +9228,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9181,6 +9314,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9415,6 +9549,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9459,6 +9594,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9503,6 +9639,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9588,6 +9725,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9688,6 +9826,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9732,6 +9871,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9826,6 +9966,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9911,6 +10052,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10285,6 +10427,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10329,6 +10472,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10411,6 +10555,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10542,6 +10687,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10777,6 +10923,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10822,6 +10969,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10867,6 +11015,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -10952,6 +11101,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11052,6 +11202,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11096,6 +11247,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11215,6 +11367,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11300,6 +11453,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11401,6 +11555,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11445,6 +11600,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11489,6 +11645,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11574,6 +11731,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11758,6 +11916,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11802,6 +11961,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11892,6 +12052,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -11977,6 +12138,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12115,6 +12277,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12159,6 +12322,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12203,6 +12367,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12287,6 +12452,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12433,6 +12599,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12477,6 +12644,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12521,6 +12689,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12652,6 +12821,7 @@ function hedley_well_child_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -12814,6 +12984,7 @@ function hedley_well_child_field_default_field_instances() { t('Birth Weight'); t('Body temperature'); t('Child Caring Option'); + t('Completion Data'); t('Contributing Factors Signs'); t('Date Measured'); t('Date concluded'); diff --git a/server/hedley/modules/custom/hedley_well_child/hedley_well_child.info b/server/hedley/modules/custom/hedley_well_child/hedley_well_child.info index 29cfaf6ee8..fab1f573b6 100644 --- a/server/hedley/modules/custom/hedley_well_child/hedley_well_child.info +++ b/server/hedley/modules/custom/hedley_well_child/hedley_well_child.info @@ -94,6 +94,7 @@ features[field_instance][] = node-well_child_ecd-field_well_child_encounter features[field_instance][] = node-well_child_encounter-field_encounter_notes features[field_instance][] = node-well_child_encounter-field_encounter_warnings features[field_instance][] = node-well_child_encounter-field_individual_participant +features[field_instance][] = node-well_child_encounter-field_reports_data features[field_instance][] = node-well_child_encounter-field_scheduled_date features[field_instance][] = node-well_child_encounter-field_shards features[field_instance][] = node-well_child_encounter-field_uuid diff --git a/server/hedley/modules/custom/hedley_well_child/hedley_well_child.strongarm.inc b/server/hedley/modules/custom/hedley_well_child/hedley_well_child.strongarm.inc index e0e8bbadf4..123c9c768d 100644 --- a/server/hedley/modules/custom/hedley_well_child/hedley_well_child.strongarm.inc +++ b/server/hedley/modules/custom/hedley_well_child/hedley_well_child.strongarm.inc @@ -709,15 +709,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_albendazole'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_albendazole'] = $strongarm; @@ -726,15 +726,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_bcg_immunisation'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_bcg_immunisation'] = $strongarm; @@ -743,15 +743,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_caring'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_caring'] = $strongarm; @@ -760,15 +760,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_contributing_factors'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_contributing_factors'] = $strongarm; @@ -777,15 +777,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_dtp_immunisation'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_dtp_immunisation'] = $strongarm; @@ -794,15 +794,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_dtp_sa_immunisation'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_dtp_sa_immunisation'] = $strongarm; @@ -811,15 +811,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_ecd'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_ecd'] = $strongarm; @@ -828,15 +828,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_encounter'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_encounter'] = $strongarm; @@ -845,15 +845,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_feeding'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_feeding'] = $strongarm; @@ -862,15 +862,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_follow_up'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_follow_up'] = $strongarm; @@ -879,15 +879,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_food_security'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_food_security'] = $strongarm; @@ -896,15 +896,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_head_circumference'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_head_circumference'] = $strongarm; @@ -913,15 +913,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_health_education'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_health_education'] = $strongarm; @@ -930,15 +930,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_height'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_height'] = $strongarm; @@ -947,15 +947,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_hpv_immunisation'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_hpv_immunisation'] = $strongarm; @@ -964,15 +964,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_hygiene'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_hygiene'] = $strongarm; @@ -981,15 +981,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_ipv_immunisation'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_ipv_immunisation'] = $strongarm; @@ -998,15 +998,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_mebendezole'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_mebendezole'] = $strongarm; @@ -1015,15 +1015,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_mr_immunisation'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_mr_immunisation'] = $strongarm; @@ -1032,15 +1032,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_muac'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_muac'] = $strongarm; @@ -1049,15 +1049,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_ncda'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_ncda'] = $strongarm; @@ -1066,15 +1066,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_next_visit'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_next_visit'] = $strongarm; @@ -1083,15 +1083,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_nutrition'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_nutrition'] = $strongarm; @@ -1100,15 +1100,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_opv_immunisation'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_opv_immunisation'] = $strongarm; @@ -1117,15 +1117,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_pcv13_immunisation'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_pcv13_immunisation'] = $strongarm; @@ -1134,15 +1134,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_photo'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_photo'] = $strongarm; @@ -1151,15 +1151,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_pregnancy_summary'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_pregnancy_summary'] = $strongarm; @@ -1168,15 +1168,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_rotarix_immunisation'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_rotarix_immunisation'] = $strongarm; @@ -1185,15 +1185,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_send_to_hc'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_send_to_hc'] = $strongarm; @@ -1202,15 +1202,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_symptoms_review'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_symptoms_review'] = $strongarm; @@ -1219,15 +1219,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_vitals'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_vitals'] = $strongarm; @@ -1236,15 +1236,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_vitamin_a'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_vitamin_a'] = $strongarm; @@ -1253,15 +1253,15 @@ function hedley_well_child_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__well_child_weight'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__well_child_weight'] = $strongarm; From a26f4c68a3a4b4d53e83e6a1190b60683825cacc Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 26 Aug 2024 18:03:35 +0300 Subject: [PATCH 065/185] Update mapping [ci skip] --- .../hedley_reports/hedley_reports.module | 53 +++++++++++-------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 306c9cbc16..fc34afa638 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3440,29 +3440,36 @@ function hedley_reports_count_acute_illness_signs(array $values) { function hedley_reports_generate_completion_data_for_well_child($participant, $exclude_set) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ - 'acute_findings' => 'a', - 'acute_illness_contacts_tracing' => 'b', - 'acute_illness_core_exam' => 'c', - 'acute_illness_danger_signs' => 'd', - 'acute_illness_follow_up' => 'e', - 'acute_illness_muac' => 'f', - 'acute_illness_nutrition' => 'g', - 'acute_illness_vitals' => 'h', - 'call_114' => 'i', - 'covid_testing' => 'j', - 'exposure' => 'k', - 'hc_contact' => 'l', - 'health_education' => 'm', - 'isolation' => 'n', - 'malaria_testing' => 'o', - 'medication_distribution' => 'p', - 'send_to_hc' => 'q', - 'symptoms_general' => 'r', - 'symptoms_gi' => 's', - 'symptoms_respiratory' => 't', - 'travel_history' => 'u', - 'treatment_history' => 'v', - 'treatment_ongoing' => 'w', + 'well_child_albendazole' => 'a', + 'well_child_bcg_immunisation' => 'b', + 'well_child_caring' => 'c', + 'well_child_contributing_factors' => 'd', + 'well_child_dtp_immunisation' => 'e', + 'well_child_ecd' => 'f', + 'well_child_feeding' => 'g', + 'well_child_follow_up' => 'h', + 'well_child_food_security' => 'i', + 'well_child_head_circumference' => 'j', + 'well_child_health_education' => 'k', + 'well_child_height' => 'l', + 'well_child_hygiene' => 'm', + 'well_child_ipv_immunisation' => 'n', + 'well_child_mebendezole' => 'o', + 'well_child_mr_immunisation' => 'p', + 'well_child_muac' => 'q', + 'well_child_ncda' => 'r', + 'well_child_next_visit' => 's', + 'well_child_nutrition' => 't', + 'well_child_opv_immunisation' => 'u', + 'well_child_pcv13_immunisation' => 'v', + 'well_child_photo' => 'w', + 'well_child_pregnancy_summary' => 'x', + 'well_child_rotarix_immunisation' => 'y', + 'well_child_send_to_hc' => 'z', + 'well_child_symptoms_review' => '1', + 'well_child_vitals' => '2', + 'well_child_vitamin_a' => '3', + 'well_child_weight' => '4', ]; // Load all encounters of current participant. From 087e210a8c4b0afe0f2e4cf682a72f4d44b3a4e7 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 27 Aug 2024 13:06:43 +0300 Subject: [PATCH 066/185] Generate initial activities [ci skip] --- .../hedley_reports/hedley_reports.module | 195 ++++++++++-------- 1 file changed, 106 insertions(+), 89 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index fc34afa638..3e17de64b8 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3519,95 +3519,112 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e ]; } -// foreach ($encounters_data as $index => $encounter_data) { -// $encounter = $encounter_data['encounter']; -// $encounter_type = $encounter_data['encounter_type']; -// $measurements_by_type = $encounter_data['measurements_by_type']; -// -// // Resolve encounter start date. -// $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; -// $start_date_obj = new DateTime($start_date); -// $encounter_data['start_date_obj'] = $start_date_obj; -// -// // Try to resolve age in months at a time encounter was performed. -// $age_in_months = hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj); -// $encounter_data['age_in_months'] = $age_in_months; -// -// $previous_encounters_data = array_slice($encounters_data, 0, $index); -// $is_initial = ($encounter_type == 'nurse-encounter') || (($encounter_type == 'chw-encounter') && empty($previous_encounters_data)); -// $encounter_data['is_initial'] = $is_initial; -// $diagnosis = $encounter->field_acute_illness_diagnosis[LANGUAGE_NONE][0]['value']; -// if (!$is_initial && (empty($diagnosis) || $diagnosis == 'none')) { -// // Reversing passed array, to have the encounters sorted DESC. -// $diagnosis = hedley_reports_get_acute_illness_diagnosis_by_previous_encounters(array_reverse($previous_encounters_data)); -// } -// $encounter_data['illness_diagnosis'] = $diagnosis; -// -// // Acute illness module defines following logic: -// // If first encounter(s) were taken by CHW, but then -// // nurse ran and encounter, we consider that encounter of -// // nurse as initial. All data collected by CHWs until that -// // encounter should be ignored. -// $initial_nurse_encounter_index = -1; -// foreach ($previous_encounters_data as $ind => $data) { -// if ($data['encounter_type'] == 'nurse-encounter') { -// $initial_nurse_encounter_index = $ind; -// break; -// } -// } -// -// if ($initial_nurse_encounter_index == -1) { -// $first_initial_with_subsequents = $previous_encounters_data; -// $second_initial_with_subsequents = []; -// } -// else { -// $first_initial_with_subsequents = array_slice($previous_encounters_data, 0, $initial_nurse_encounter_index + 1); -// $second_initial_with_subsequents = array_slice($previous_encounters_data, $initial_nurse_encounter_index + 1); -// } -// $initial_with_subsequents = empty($second_initial_with_subsequents) ? $first_initial_with_subsequents : $second_initial_with_subsequents; -// $encounter_data['initial_with_subsequents'] = $initial_with_subsequents; -// -// $fever_at_symptoms = FALSE; -// if (!empty($measurements_by_type['symptoms_general'])) { -// $fever_period = $measurements_by_type['symptoms_general']->field_fever_period[LANGUAGE_NONE][0]['value']; -// if (!empty($fever_period)) { -// $fever_at_symptoms = $fever_period > 0; -// } -// } -// $fever_at_vitals = FALSE; -// if (!empty($measurements_by_type['acute_illness_vitals'])) { -// $body_temperature = $measurements_by_type['acute_illness_vitals']->field_body_temperature[LANGUAGE_NONE][0]['value']; -// if (!empty($body_temperature)) { -// $fever_at_vitals = $body_temperature >= 37.5; -// } -// } -// $fever = $fever_at_symptoms || $fever_at_vitals; -// $encounter_data['fever'] = $fever; -// -// // So far we were constructing data structures to resolve encounter data. -// // Now we have enough info to determine which activities were expected. -// // Load all activities expected only by encounter type and start date. -// $expected = hedley_reports_generate_acute_illness_expected_initial_activities($encounter_data); -// // If conditions match, add malaria_testing activity. -// hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, $expected); -// // If conditions match, add covid_testing activity. -// hedley_reports_acute_illness_add_expected_covid_testing($encounter_data, $expected); -// // If conditions match, add treatment_ongoing activity. -// hedley_reports_acute_illness_add_expected_treatment_ongoing($encounter_data, $expected); -// // If conditions match, add physical exam activities. -// hedley_reports_acute_illness_add_physical_exam_activities($encounter_data, $expected); -// // If conditions match, add next steps activities. -// hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); -// -// $completion_data = [ -// 'start_date' => $start_date, -// 'taken_by' => $encounter_data['taken_by'], -// 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), -// ]; -// -// $encounter->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); -// node_save($encounter); -// } + foreach ($encounters_data as $index => $encounter_data) { + $encounter = $encounter_data['encounter']; + $measurements_by_type = $encounter_data['measurements_by_type']; + + // Resolve encounter start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $start_date_obj = new DateTime($start_date); + $encounter_data['start_date_obj'] = $start_date_obj; + + // Try to resolve age in months at a time encounter was performed. + $age_in_months = hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj); + $encounter_data['age_in_months'] = $age_in_months; + + $previous_encounters_data = array_slice($encounters_data, 0, $index); + + // So far we were constructing data structures to resolve encounter data. + // Now we have enough info to determine which activities were expected. + // Load all activities expected only by encounter type and start date. + $expected = hedley_reports_generate_well_child_expected_initial_activities($encounter_data); + // If conditions match, add malaria_testing activity. + hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, $expected); + // If conditions match, add covid_testing activity. + hedley_reports_acute_illness_add_expected_covid_testing($encounter_data, $expected); + // If conditions match, add treatment_ongoing activity. + hedley_reports_acute_illness_add_expected_treatment_ongoing($encounter_data, $expected); + // If conditions match, add physical exam activities. + hedley_reports_acute_illness_add_physical_exam_activities($encounter_data, $expected); + // If conditions match, add next steps activities. + hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); + + $completion_data = [ + 'start_date' => $start_date, + 'taken_by' => $encounter_data['taken_by'], + 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), + ]; + + $encounter->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); + node_save($encounter); + } +} + +/** + * Generates the list of expected activities for an well child encounter. + * + * Here we add activities with simple logic from: + * - Pregnancy Summary. + * - Danger Signs. + * - Nutrition Assessment. + * - Child Photo. + * - Home Visit. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * + * @return array + * An array of expected activity names. + */ +function hedley_reports_generate_well_child_expected_initial_activities(array $encounter_data) { + $encounter_type = $encounter_data['encounter_type']; + $age_in_months = $encounter_data['age_in_months']; + + // Activities that are shown at any type of encounter, + // unconditionally. Existed with initial launch of the feature. + $expected = [ + 'well_child_height', + 'well_child_nutrition', + 'well_child_photo', + 'well_child_weight', + ]; + + // MUAC is taken starting age of 6 months. + if (isset($age_in_months) && $age_in_months >= 6) { + $expected[] = 'well_child_muac'; + } + + // Head Circumference is taken for children bellow age of 3 years. + if (isset($age_in_months) && $age_in_months < 36) { + $expected[] = 'well_child_muac'; + } + + if ($encounter_type == 'newborn-exam') { + $expected[] = 'well_child_pregnancy_summary'; + return $expected; + } + + // Any SPV encounters performed by CHW / nurse. + $expected = array_merge($expected, [ + 'well_child_symptoms_review', + 'well_child_vitals', + ]); + + // Home Visit vas added only for SPV encounter by CHW, on Feb 18, 2024. + if ($encounter_type == 'pediatric-care-chw') { + $launch_date = '2024-02-18'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] >= $launch_date_obj) { + $expected = array_merge($expected, [ + 'well_child_caring', + 'well_child_feeding', + 'well_child_food_security', + 'well_child_hygiene', + ]); + } + } + + return $expected; } function hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, DateTime $start_date_obj) { From 3957c7a5da5e6a5883c8213dbec330b0466ee836 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 27 Aug 2024 17:36:44 +0300 Subject: [PATCH 067/185] A fix [ci skip] --- client/src/elm/Pages/WellChild/Activity/Utils.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/elm/Pages/WellChild/Activity/Utils.elm b/client/src/elm/Pages/WellChild/Activity/Utils.elm index 84efeb6fa8..a03f1ab0b3 100644 --- a/client/src/elm/Pages/WellChild/Activity/Utils.elm +++ b/client/src/elm/Pages/WellChild/Activity/Utils.elm @@ -1187,7 +1187,7 @@ expectMedicationByAge currentDate site person task = -- 6 months to 6 years. TaskVitaminA -> - ageMonths >= 6 && ageMonths < (6 * 6) + ageMonths >= 6 && ageMonths < (6 * 12) _ -> case task of From 9710cac7b884844f4bbf18a8b17cb6115dd83fe0 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 27 Aug 2024 19:02:54 +0300 Subject: [PATCH 068/185] Add Medications activities [ci skip] --- .../hedley_reports/hedley_reports.module | 186 +++++++++++++----- 1 file changed, 139 insertions(+), 47 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 3e17de64b8..0a36e75fb8 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2164,16 +2164,8 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun ); } - // NCDA activity is expected if: - // 1. NCDA feature is enabled. - // 2. Encounter was performed after NCDA launch date. - // 3. Encounter was recorded by nurse (and not by CHW). - // 4. Child was under age of 24 months. - $ncda_enabled = variable_get('hedley_admin_feature_ncda_enabled', FALSE); - $ncda_launch_date = '2023-11-20'; - $ncda_launch_date_obj = new DateTime($ncda_launch_date); - - if ($ncda_enabled && $start_date_obj >= $ncda_launch_date_obj && ($taken_by == 'nurse') && isset($age_in_months) && $age_in_months < 24) { + // NCDA activity is taken by nurse only. + if ($taken_by == 'nurse' && hedley_reports_ncda_expected($age_in_months, $start_date_obj)) { $expected[] = 'nutrition_ncda'; } @@ -2396,15 +2388,8 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ $expected[] = 'child_fbf'; } - // NCDA activity is expected if: - // 1. NCDA feature is enabled. - // 2. Encounter was performed after NCDA launch date. - // 3. Encounter was recorded by nurse (and not by CHW). - // 4. Child was under age of 24 months. - $ncda_enabled = variable_get('hedley_admin_feature_ncda_enabled', FALSE); - $ncda_launch_date = '2023-11-20'; - $ncda_launch_date_obj = new DateTime($ncda_launch_date); - if ($ncda_enabled && $start_date_obj >= $ncda_launch_date_obj && ($taken_by == 'nurse') && isset($age_in_months) && $age_in_months < 24) { + // NCDA activity is taken by nurse only. + if ($taken_by == 'nurse' && hedley_reports_ncda_expected($age_in_months, $start_date_obj)) { $expected[] = 'group_ncda'; } @@ -2579,7 +2564,7 @@ function hedley_reports_generate_completion_data_for_acute_illness($participant, // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. // Load all activities expected only by encounter type and start date. - $expected = hedley_reports_generate_acute_illness_expected_initial_activities($encounter_data); + $expected = hedley_reports_acute_illness_generate_expected_initial_activities($encounter_data); // If conditions match, add malaria_testing activity. hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, $expected); // If conditions match, add covid_testing activity. @@ -2611,7 +2596,7 @@ function hedley_reports_generate_completion_data_for_acute_illness($participant, * @return array * An array of expected activity names. */ -function hedley_reports_generate_acute_illness_expected_initial_activities(array $encounter_data) { +function hedley_reports_acute_illness_generate_expected_initial_activities(array $encounter_data) { // Activities that are shown at any type of encounter, // unconditionally. Existed with initial launch of the feature. $expected = [ @@ -3416,19 +3401,6 @@ function hedley_reports_count_acute_illness_signs(array $values) { return $count; } -/** - * Resolve the age in months for patient at the time of a specific encounter. - * - * @param object $encounter - * The encounter object, which includes the participant and person data. - * @param DateTime $start_date_obj - * The date object representing the start date of the encounter. - * - * @return int|null - * The age in months of the individual at the time of the encounter, - * or NULL if an error occurs. - */ - /** * Generates completion data for well child encounters for patient. * @@ -3533,21 +3505,16 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e $encounter_data['age_in_months'] = $age_in_months; $previous_encounters_data = array_slice($encounters_data, 0, $index); + $encounter_data['previous_encounters_data'] = $previous_encounters_data; // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. // Load all activities expected only by encounter type and start date. - $expected = hedley_reports_generate_well_child_expected_initial_activities($encounter_data); - // If conditions match, add malaria_testing activity. - hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, $expected); - // If conditions match, add covid_testing activity. - hedley_reports_acute_illness_add_expected_covid_testing($encounter_data, $expected); - // If conditions match, add treatment_ongoing activity. - hedley_reports_acute_illness_add_expected_treatment_ongoing($encounter_data, $expected); - // If conditions match, add physical exam activities. - hedley_reports_acute_illness_add_physical_exam_activities($encounter_data, $expected); + $expected = hedley_reports_well_child_generate_expected_initial_activities($encounter_data); + // If conditions match, add medication activities. + hedley_reports_well_child_add_medication_activities($encounter_data, $expected); // If conditions match, add next steps activities. - hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); +// hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); $completion_data = [ 'start_date' => $start_date, @@ -3569,6 +3536,7 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e * - Nutrition Assessment. * - Child Photo. * - Home Visit. + * - NCDA. * * @param array $encounter_data * An associative array containing data about the encounter. @@ -3576,9 +3544,10 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e * @return array * An array of expected activity names. */ -function hedley_reports_generate_well_child_expected_initial_activities(array $encounter_data) { +function hedley_reports_well_child_generate_expected_initial_activities(array $encounter_data) { $encounter_type = $encounter_data['encounter_type']; $age_in_months = $encounter_data['age_in_months']; + $start_date_obj = $encounter_data['start_date_obj']; // Activities that are shown at any type of encounter, // unconditionally. Existed with initial launch of the feature. @@ -3610,11 +3579,12 @@ function hedley_reports_generate_well_child_expected_initial_activities(array $e 'well_child_vitals', ]); - // Home Visit vas added only for SPV encounter by CHW, on Feb 18, 2024. + // CHW SPV encounters. if ($encounter_type == 'pediatric-care-chw') { + // Home Visit vas added only for SPV encounter by CHW, on Feb 18, 2024. $launch_date = '2024-02-18'; $launch_date_obj = new DateTime($launch_date); - if ($encounter_data['start_date_obj'] >= $launch_date_obj) { + if ($start_date_obj >= $launch_date_obj) { $expected = array_merge($expected, [ 'well_child_caring', 'well_child_feeding', @@ -3623,10 +3593,108 @@ function hedley_reports_generate_well_child_expected_initial_activities(array $e ]); } } + // Nurse SPV encounters. + else { + if (hedley_reports_ncda_expected($age_in_months, $start_date_obj)) { + $expected[] = 'well_child_ncda'; + } + } + + return $expected; +} + +function hedley_reports_well_child_add_medication_activities(array $encounter_data, array &$expected) { + $age_in_months = $encounter_data['age_in_months']; + $start_date_obj = $encounter_data['start_date_obj']; + // Reversing array, to have the encounters sorted DESC. + $previous_encounters_data = array_reverse($encounter_data['previous_encounters_data']); + + // Resolving all activities representing medications that are required, + // per child age at a time when encounter was run. + $expected_activities_by_age = hedley_reports_well_child_genrate_expected_medication_activities_by_age($age_in_months); + foreach ($expected_activities_by_age as $expected_activity) { + // Searching for date on which last dose of medication was administered. + $last_administration_date_obj = NULL; + foreach ($previous_encounters_data as $previous_encounter_data) { + $measurements_by_type = $previous_encounter_data['measurements_by_type']; + $measurement = $measurements_by_type[$expected_activity]; + if (empty($measurement) || empty($measurement->field_administration_note)) { + continue; + } + + $administration_note = $measurement->field_administration_note[LANGUAGE_NONE][0]['value']; + if ($administration_note == 'administered-today') { + $last_administration_date_obj = $previous_encounter_data['start_date_obj']; + break; + } + } + + if (is_null($last_administration_date_obj)) { + // Medication was not administered previously - add it as expected. + $expected[] = $expected_activity; + } + else { + $next_administration_date_obj = $last_administration_date_obj->add(new DateInterval('P6M')); + if ($start_date_obj >= $next_administration_date_obj) { + // Medication was administered previously more than 6 months + // ago - add it as expected. + $expected[] = $expected_activity; + } + } + } +} + +function hedley_reports_well_child_genrate_expected_medication_activities_by_age($age_in_months) { + if (!isset($age_in_months)) { + return []; + } + + $site = variable_get('hedley_general_site_name', ''); + $expected = []; + + switch ($site) { + case 'burundi': + // 6 months to 12 years. + if ($age_in_months >= 6 && $age_in_months < (12 * 12)) { + $expected[] = 'well_child_albendazole'; + } + // 6 months to 6 years. + if ($age_in_months >= 6 && $age_in_months < (6 * 12)) { + $expected[] = 'well_child_vitamin_a'; + } + break; + + default: + // 6 years to 12 years. + if ($age_in_months >= (6 * 12) && $age_in_months < (12 * 12)) { + $expected[] = 'well_child_albendazole'; + } + // 1 year to 6 years. + if ($age_in_months >= 12 && $age_in_months < (6 * 12)) { + $expected[] = 'well_child_mebendezole'; + } + // 6 months to 12 years. + if ($age_in_months >= 6 && $age_in_months < (6 * 12)) { + $expected[] = 'well_child_vitamin_a'; + } + break; + } return $expected; } +/** + * Resolve the age in months for patient at the time of a specific encounter. + * + * @param object $encounter + * The encounter object, which includes the participant and person data. + * @param DateTime $start_date_obj + * The date object representing the start date of the encounter. + * + * @return int|null + * The age in months of the individual at the time of the encounter, + * or NULL if an error occurs. + */ function hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, DateTime $start_date_obj) { try { // Get participant ID and node. @@ -3651,6 +3719,30 @@ function hedley_reports_resolve_age_in_months_for_individual_encounter($encounte } } +/** + * Whether NCDA activity is expected. + * + * Conditions for NCDA: + * - NCDA feature is enabled. + * - Encounter was performed after NCDA launch date. + * - Child was under age of 24 months. + * + * @param int $age_in_months + * Age of the child at a time when encounter was performed. + * @param DateTime $start_date_obj + * The date object representing the start date of the encounter. + * + * @return bool + * True, if NCDA activity is expected. + */ +function hedley_reports_ncda_expected($age_in_months, $start_date_obj) { + $ncda_enabled = variable_get('hedley_admin_feature_ncda_enabled', FALSE); + $ncda_launch_date = '2023-11-20'; + $ncda_launch_date_obj = new DateTime($ncda_launch_date); + + return $ncda_enabled && $start_date_obj >= $ncda_launch_date_obj && isset($age_in_months) && $age_in_months < 24; +} + /** * Load the measurement IDs associated with an individual encounter. * From ee63b62cb1b941c6a1d5786f874bbf98e9cde7c1 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 28 Aug 2024 22:17:53 +0300 Subject: [PATCH 069/185] Next steps activities - WIP [ci skip] --- .../hedley_reports/hedley_reports.module | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 0a36e75fb8..1f2b411060 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3514,7 +3514,7 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e // If conditions match, add medication activities. hedley_reports_well_child_add_medication_activities($encounter_data, $expected); // If conditions match, add next steps activities. -// hedley_reports_acute_illness_add_next_steps_activities($encounter_data, $expected); + hedley_reports_well_child_add_next_steps_activities($encounter_data, $expected); $completion_data = [ 'start_date' => $start_date, @@ -3683,6 +3683,36 @@ function hedley_reports_well_child_genrate_expected_medication_activities_by_age return $expected; } +/** + * Adds Next Steps activities to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_well_child_add_next_steps_activities(array $encounter_data, array &$expected) { + $measurements_by_type = $encounter_data['measurements_by_type']; + + $assessment = ''; + if (!empty($measurements_by_type['well_child_nutrition'])) { + $assessment = $measurements_by_type['well_child_nutrition']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; + } + elseif (!empty($measurements_by_type['well_child_follow_up'])) { + $assessment = $measurements_by_type['well_child_follow_up']->field_nutrition_assesment[LANGUAGE_NONE][0]['value']; + } + + if (!empty($assessment) && $assessment !== 'none') { + $expected = array_merge( + $expected, + [ + 'well_child_contributing_factors', + 'well_child_follow_up', + ] + ); + } +} + /** * Resolve the age in months for patient at the time of a specific encounter. * From 16a77957bf20c9a9532e1b8cc8fae3aa284931e7 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 28 Aug 2024 23:38:59 +0300 Subject: [PATCH 070/185] WIP [ci skip] --- .../hedley_reports/hedley_reports.module | 81 ++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 1f2b411060..41dfba44d2 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2271,7 +2271,6 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ ->propertyCondition('status', NODE_PUBLISHED) ->fieldCondition('field_person', 'target_id', $session_participants_ids, 'IN') ->fieldCondition('field_session', 'target_id', $session_id) - ->addTag('exclude_deleted') ->execute(); if (empty($result['node'])) { @@ -3511,6 +3510,9 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e // Now we have enough info to determine which activities were expected. // Load all activities expected only by encounter type and start date. $expected = hedley_reports_well_child_generate_expected_initial_activities($encounter_data); + // If conditions match, add immunisation activities. + $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + hedley_reports_well_child_add_immunisation_activities($encounter_data,$expected); // If conditions match, add medication activities. hedley_reports_well_child_add_medication_activities($encounter_data, $expected); // If conditions match, add next steps activities. @@ -3527,6 +3529,80 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e } } +function hedley_reports_well_child_generate_vaccination_progress_data($person_id, array $encounter_data) { + +} + +function hedley_reports_well_child_generate_vaccination_progress_data_by_child_scoreboard($person_id, DateTime $well_child_encounter_start_date_obj) { + if (empty($person_id)) { + return []; + } + + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'individual_participant') + ->fieldCondition('field_encounter_type', 'value', 'child-scoreboard') + ->fieldCondition('field_person', 'target_id', $person_id) + ->propertyCondition('status', NODE_PUBLISHED) + ->addTag('exclude_deleted'); + + $result = $query + ->range(0, 1) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + return []; + } + + $participant_id = key($result['node']); + // Load all encounters of current participant. + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'child_scoreboard_encounter') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_individual_participant', 'target_id', $participant_id) + ->propertyOrderBy('nid') + ->execute(); + + if (empty($result['node'])) { + return []; + } + + $immunisation_types = [ + 'child_scoreboard_bcg_immunisation', + 'child_scoreboard_dtp_immunisation', + 'child_scoreboard_ipv_immunisation', + 'child_scoreboard_mr_immunisation', + 'child_scoreboard_opv_immunisation', + 'child_scoreboard_pcv13_immunisation', + 'child_scoreboard_rotarix_immunisation', + ]; + + $encounters = node_load_multiple(array_keys($result['node'])); + foreach ($encounters as $encounter) { + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $start_date_obj = new DateTime($start_date); + if ($start_date_obj > $well_child_encounter_start_date_obj) { + // This encounter started after well child encounter, so, skip it. + continue; + } + + // Loading all immunisation activities recorded during the encounter. + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', $immunisation_types, 'IN') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_child_scoreboard_encounter', 'target_id', $encounter->nid) + ->execute(); + } + + return []; +} + /** * Generates the list of expected activities for an well child encounter. * @@ -3603,6 +3679,9 @@ function hedley_reports_well_child_generate_expected_initial_activities(array $e return $expected; } +function hedley_reports_well_child_add_immunisation_activities(array $encounter_data, array &$expected) { +} + function hedley_reports_well_child_add_medication_activities(array $encounter_data, array &$expected) { $age_in_months = $encounter_data['age_in_months']; $start_date_obj = $encounter_data['start_date_obj']; From 0b44b6c4b30e0e496e9ccbb8222aa5516aa38dfa Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 29 Aug 2024 12:13:03 +0300 Subject: [PATCH 071/185] Load immunisations data [ci skip] --- .../hedley_reports/hedley_reports.module | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 41dfba44d2..2b89d14c67 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3572,15 +3572,22 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s } $immunisation_types = [ - 'child_scoreboard_bcg_immunisation', - 'child_scoreboard_dtp_immunisation', - 'child_scoreboard_ipv_immunisation', - 'child_scoreboard_mr_immunisation', - 'child_scoreboard_opv_immunisation', - 'child_scoreboard_pcv13_immunisation', - 'child_scoreboard_rotarix_immunisation', + 'child_scoreboard_bcg_iz', + 'child_scoreboard_dtp_iz', + 'child_scoreboard_ipv_iz', + 'child_scoreboard_mr_iz', + 'child_scoreboard_opv_iz', + 'child_scoreboard_pcv13_iz', + 'child_scoreboard_rotarix_iz', ]; + $immunisations_by_type = []; + foreach ($immunisation_types as $immunisation_type) { + $immunisations_by_type[$immunisation_type] = [ + 'doses' => [], + 'dates' => [], + ]; + } $encounters = node_load_multiple(array_keys($result['node'])); foreach ($encounters as $encounter) { $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; @@ -3598,6 +3605,26 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s ->propertyCondition('status', NODE_PUBLISHED) ->fieldCondition('field_child_scoreboard_encounter', 'target_id', $encounter->nid) ->execute(); + + if (empty($result['node'])) { + continue; + } + + $immunisations = node_load_multiple(array_keys($result['node'])); + foreach ($immunisations as $immunisation) { + $administration_note = $immunisation->field_administration_note[LANGUAGE_NONE][0]['value']; + if (!in_array($administration_note, ['administered-today', 'administered-previously'])) { + continue; + } + $doses = $immunisation->field_administered_doses[LANGUAGE_NONE]; + foreach ($doses as $dose) { + $immunisations_by_type[$immunisation->type]['doses'][] = $dose['value']; + } + $dates = $immunisation->field_administered_dates[LANGUAGE_NONE]; + foreach ($dates as $date) { + $immunisations_by_type[$immunisation->type]['dates'][] = explode(' ', $date['value'])[0]; + } + } } return []; From a7a2cfd03913b6fc29ee37cc4ac82de9dec8865d Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 29 Aug 2024 16:57:37 +0300 Subject: [PATCH 072/185] Complete vaccination progress and history generation [ci skip] --- .../hedley_reports/hedley_reports.module | 202 ++++++++++++++++-- 1 file changed, 189 insertions(+), 13 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 2b89d14c67..bd81d299cd 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3441,6 +3441,8 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e 'well_child_vitals' => '2', 'well_child_vitamin_a' => '3', 'well_child_weight' => '4', + 'well_child_hpv_immunisation' => '5', + 'well_child_dtp_sa_immunisation' => '6', ]; // Load all encounters of current participant. @@ -3506,12 +3508,14 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e $previous_encounters_data = array_slice($encounters_data, 0, $index); $encounter_data['previous_encounters_data'] = $previous_encounters_data; + $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + list($vaccination_history, $vaccination_progress) = hedley_reports_well_child_generate_vaccination_progress_data($person_id, $encounter_data); + // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. // Load all activities expected only by encounter type and start date. $expected = hedley_reports_well_child_generate_expected_initial_activities($encounter_data); // If conditions match, add immunisation activities. - $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; hedley_reports_well_child_add_immunisation_activities($encounter_data,$expected); // If conditions match, add medication activities. hedley_reports_well_child_add_medication_activities($encounter_data, $expected); @@ -3530,12 +3534,121 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e } function hedley_reports_well_child_generate_vaccination_progress_data($person_id, array $encounter_data) { + $previous_encounters_data = $encounter_data['previous_encounters_data']; + + $immunisation_types = [ + 'well_child_bcg_immunisation', + 'well_child_dtp_immunisation', + 'well_child_dtp_sa_immunisation', + 'well_child_ipv_immunisation', + 'well_child_mr_immunisation', + 'well_child_opv_immunisation', + 'well_child_pcv13_immunisation', + 'well_child_rotarix_immunisation', + 'well_child_hpv_immunisation', + ]; + + $immunisations_from_previous_encounters = []; + foreach ($immunisation_types as $immunisation_type) { + $immunisations_from_previous_encounters[$immunisation_type] = []; + } + + foreach ($previous_encounters_data as $previous_encounter_data) { + $measurements_by_type = $previous_encounter_data['measurements_by_type']; + foreach ($immunisation_types as $immunisation_type) { + if (empty($measurements_by_type[$immunisation_type])) { + continue; + } + $immunisations_from_previous_encounters[$immunisation_type][] = $measurements_by_type[$immunisation_type]; + } + } + + $immunisations_from_all_encounters = $immunisations_from_previous_encounters; + $measurements_by_type = $encounter_data['measurements_by_type']; + foreach ($immunisation_types as $immunisation_type) { + if (empty($measurements_by_type[$immunisation_type])) { + continue; + } + $immunisations_from_all_encounters[$immunisation_type][] = $measurements_by_type[$immunisation_type]; + } + + $history_data_by_well_child = hedley_reports_well_child_generate_vaccination_progress_data_regular($immunisations_from_previous_encounters); + $progress_data_by_well_child = hedley_reports_well_child_generate_vaccination_progress_data_regular($immunisations_from_all_encounters); + $progress_data_by_child_scoreboard = hedley_reports_well_child_generate_vaccination_progress_data_by_child_scoreboard($person_id, $encounter_data['start_date_obj']); + return [ + hedley_reports_well_child_merge_vaccination_progress_data($immunisation_types, $history_data_by_well_child, $progress_data_by_child_scoreboard), + hedley_reports_well_child_merge_vaccination_progress_data($immunisation_types, $progress_data_by_well_child, $progress_data_by_child_scoreboard), + ]; +} + +function hedley_reports_well_child_generate_vaccination_progress_data_regular($immunisations_from_encounters) { + $return = []; + $immunisations_by_type = []; + foreach ($immunisations_from_encounters as $immunisation_type => $immunisations) { + foreach ($immunisations as $immunisation) { + $doses = $immunisation->field_administered_doses; + $dates = $immunisation->field_administration_dates; + if (empty($doses) || empty($dates)) { + continue; + } + + $encounter_doses = $encounter_dates = []; + foreach ($doses[LANGUAGE_NONE] as $dose) { + $encounter_doses[] = $dose['value']; + } + foreach ($dates[LANGUAGE_NONE] as $date) { + $encounter_dates[] = explode(' ', $date['value'])[0]; + } + + if (empty($immunisations_by_type[$immunisation_type]['doses'])) { + $immunisations_by_type[$immunisation_type]['doses'] = $encounter_doses; + } + else { + $immunisations_by_type[$immunisation_type]['doses'] = array_merge($immunisations_by_type[$immunisation_type]['doses'], $encounter_doses); + } + + if (empty($immunisations_by_type[$immunisation_type]['dates'])) { + $immunisations_by_type[$immunisation_type]['dates'] = $encounter_dates; + } + else { + $immunisations_by_type[$immunisation_type]['dates'] = array_merge($immunisations_by_type[$immunisation_type]['dates'], $encounter_dates); + } + } + } + + foreach ($immunisations_by_type as $type => $item) { + if (empty($item['doses']) || empty($item['dates'])) { + continue; + } + + $immunisations_by_type[$type]['doses'] = array_unique($item['doses']); + sort($immunisations_by_type[$type]['doses']); + $immunisations_by_type[$type]['dates'] = array_unique($item['dates']); + sort($immunisations_by_type[$type]['dates']); + $total_doses = count($immunisations_by_type[$type]['doses']); + $total_dates = count($immunisations_by_type[$type]['dates']); + + // Make sure number of doses matches the number of dates. + if ($total_doses != $total_dates) { + $common_size = min($total_doses, $total_dates); + $immunisations_by_type[$type]['doses'] = array_slice( $immunisations_by_type[$type]['doses'], 0, $common_size); + $immunisations_by_type[$type]['dates'] = array_slice( $immunisations_by_type[$type]['dates'], 0, $common_size); + } + + foreach ($immunisations_by_type[$type]['doses'] as $index => $dose) { + $common_type = hedley_reports_drop_preffix_and_suffix($type, 'well_child_', '_immunisation'); + $return[$common_type][$dose] = $immunisations_by_type[$type]['dates'][$index]; + } + } + + return $return; } function hedley_reports_well_child_generate_vaccination_progress_data_by_child_scoreboard($person_id, DateTime $well_child_encounter_start_date_obj) { + $return = []; if (empty($person_id)) { - return []; + return $return; } $query = new EntityFieldQuery(); @@ -3553,7 +3666,7 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s if (empty($result['node'])) { // No more items left. - return []; + return $return; } $participant_id = key($result['node']); @@ -3568,12 +3681,13 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s ->execute(); if (empty($result['node'])) { - return []; + return $return; } $immunisation_types = [ 'child_scoreboard_bcg_iz', 'child_scoreboard_dtp_iz', + 'child_scoreboard_dtp_sa_iz', 'child_scoreboard_ipv_iz', 'child_scoreboard_mr_iz', 'child_scoreboard_opv_iz', @@ -3612,22 +3726,72 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s $immunisations = node_load_multiple(array_keys($result['node'])); foreach ($immunisations as $immunisation) { - $administration_note = $immunisation->field_administration_note[LANGUAGE_NONE][0]['value']; - if (!in_array($administration_note, ['administered-today', 'administered-previously'])) { + $doses = $immunisation->field_administered_doses; + $dates = $immunisation->field_administration_dates; + if (empty($doses) || empty($dates)) { continue; } - $doses = $immunisation->field_administered_doses[LANGUAGE_NONE]; - foreach ($doses as $dose) { - $immunisations_by_type[$immunisation->type]['doses'][] = $dose['value']; + + $encounter_doses = $encounter_dates = []; + foreach ($doses[LANGUAGE_NONE] as $dose) { + $encounter_doses[] = $dose['value']; } - $dates = $immunisation->field_administered_dates[LANGUAGE_NONE]; - foreach ($dates as $date) { - $immunisations_by_type[$immunisation->type]['dates'][] = explode(' ', $date['value'])[0]; + foreach ($dates[LANGUAGE_NONE] as $date) { + $encounter_dates[] = explode(' ', $date['value'])[0]; } + + $immunisations_by_type[$immunisation->type]['doses'] = array_merge($immunisations_by_type[$immunisation->type]['doses'], $encounter_doses); + $immunisations_by_type[$immunisation->type]['dates'] = array_merge($immunisations_by_type[$immunisation->type]['dates'], $encounter_dates); } } - return []; + foreach ($immunisations_by_type as $type => $item) { + if (empty($item['doses']) || empty($item['dates'])) { + continue; + } + + $immunisations_by_type[$type]['doses'] = array_unique($item['doses']); + sort($immunisations_by_type[$type]['doses']); + $immunisations_by_type[$type]['dates'] = array_unique($item['dates']); + sort($immunisations_by_type[$type]['dates']); + $total_doses = count($immunisations_by_type[$type]['doses']); + $total_dates = count($immunisations_by_type[$type]['dates']); + + // Make sure number of doses matches the number of dates. + if ($total_doses != $total_dates) { + $common_size = min($total_doses, $total_dates); + $immunisations_by_type[$type]['doses'] = array_slice( $immunisations_by_type[$type]['doses'], 0, $common_size); + $immunisations_by_type[$type]['dates'] = array_slice( $immunisations_by_type[$type]['dates'], 0, $common_size); + } + + foreach ($immunisations_by_type[$type]['doses'] as $index => $dose) { + $common_type = hedley_reports_drop_preffix_and_suffix($type, 'child_scoreboard_', '_iz'); + $return[$common_type][$dose] = $immunisations_by_type[$type]['dates'][$index]; + } + } + + return $return; +} + +function hedley_reports_well_child_merge_vaccination_progress_data($immunisation_types, $first, $second) { + $return = []; + foreach ($immunisation_types as $type) { + $common_type = hedley_reports_drop_preffix_and_suffix($type, 'well_child_', '_immunisation'); + if (!empty($first[$common_type]) && !empty($second[$common_type])) { + $return[$common_type] = array_merge($first[$common_type], $second[$common_type]); + } + elseif (!empty($first[$common_type])) { + $return[$common_type] = $first[$common_type]; + } + elseif (!empty($second[$common_type])) { + $return[$common_type] = $second[$common_type]; + } + else { + $return[$common_type] = []; + } + } + + return $return; } /** @@ -3959,3 +4123,15 @@ function hedley_reports_ends_with($haystack, $needle) { } return substr($haystack, -$length) === $needle; } + +function hedley_reports_drop_preffix_and_suffix(string $string, string $pref, string $suff) { + if (strpos($string, $pref) !== 0 || substr($string, -strlen($suff)) !== $suff) { + return $string; + } + + // Extract the part between the prefix and suffix + $start = strlen($pref); + $length = strlen($string) - $start - strlen($suff); + + return substr($string, $start, $length); +} \ No newline at end of file From 90afb193256efd4b20d28be763eec95f74e85a09 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 29 Aug 2024 21:58:24 +0300 Subject: [PATCH 073/185] Complete immunisations logic [ci skip] --- client/src/elm/Measurement/Utils.elm | 9 +- .../hedley_reports/hedley_reports.module | 209 +++++++++++++++++- 2 files changed, 206 insertions(+), 12 deletions(-) diff --git a/client/src/elm/Measurement/Utils.elm b/client/src/elm/Measurement/Utils.elm index 22414939d3..a593a90f32 100644 --- a/client/src/elm/Measurement/Utils.elm +++ b/client/src/elm/Measurement/Utils.elm @@ -8846,7 +8846,14 @@ latestVaccinationDataForVaccine vaccinationsData vaccineType = ) -nextVaccinationDataForVaccine : Site -> Maybe NominalDate -> WellChildVaccineType -> Bool -> NominalDate -> VaccineDose -> Maybe ( VaccineDose, NominalDate ) +nextVaccinationDataForVaccine : + Site + -> Maybe NominalDate + -> WellChildVaccineType + -> Bool + -> NominalDate + -> VaccineDose + -> Maybe ( VaccineDose, NominalDate ) nextVaccinationDataForVaccine site maybeBirthDate vaccineType initialOpvAdministered lastDoseDate lastDoseAdministered = Maybe.andThen (\birthDate -> diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index bd81d299cd..cab3122578 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3459,6 +3459,19 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e return; } + // Get birthdate. + try { + $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + $person = node_load($person_id); + $birth_date = explode(' ', $person->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; + $birth_date_obj = new DateTime($birth_date); + $gender = $person->field_gender[LANGUAGE_NONE][0]['value']; + } + catch (Exception $e) { + $birth_date_obj = NULL; + $gender = 'male'; + } + // Encounters are sorted ASC. $encounters = node_load_multiple(array_keys($result['node'])); $encounters_data = []; @@ -3502,21 +3515,18 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e $encounter_data['start_date_obj'] = $start_date_obj; // Try to resolve age in months at a time encounter was performed. - $age_in_months = hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj); - $encounter_data['age_in_months'] = $age_in_months; - - $previous_encounters_data = array_slice($encounters_data, 0, $index); - $encounter_data['previous_encounters_data'] = $previous_encounters_data; + $encounter_data['age_in_months'] = hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj); + $encounter_data['previous_encounters_data'] = array_slice($encounters_data, 0, $index); $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; - list($vaccination_history, $vaccination_progress) = hedley_reports_well_child_generate_vaccination_progress_data($person_id, $encounter_data); + list($encounter_data['vaccination_history'], $encounter_data['vaccination_progress']) = hedley_reports_well_child_generate_vaccination_progress_data($person_id, $encounter_data); // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. // Load all activities expected only by encounter type and start date. $expected = hedley_reports_well_child_generate_expected_initial_activities($encounter_data); // If conditions match, add immunisation activities. - hedley_reports_well_child_add_immunisation_activities($encounter_data,$expected); + hedley_reports_well_child_add_immunisation_activities($encounter_data, $birth_date_obj, $gender, $expected); // If conditions match, add medication activities. hedley_reports_well_child_add_medication_activities($encounter_data, $expected); // If conditions match, add next steps activities. @@ -3524,7 +3534,7 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e $completion_data = [ 'start_date' => $start_date, - 'taken_by' => $encounter_data['taken_by'], + 'taken_by' => $encounter_data['encounter_type'] == 'pediatric-care' ? 'nurse' : 'chw', 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), ]; @@ -3870,7 +3880,152 @@ function hedley_reports_well_child_generate_expected_initial_activities(array $e return $expected; } -function hedley_reports_well_child_add_immunisation_activities(array $encounter_data, array &$expected) { +function hedley_reports_well_child_add_immunisation_activities(array $encounter_data, DateTime $birth_date_obj, $gender, array &$expected) { + $vaccination_history = $encounter_data['vaccination_history']; + $vaccination_progress = $encounter_data['vaccination_progress']; + $start_date_obj = $encounter_data['start_date_obj']; + + $initial_opv_administered = hedley_reports_well_child_initial_opv_administered($encounter_data, $birth_date_obj); + $interval = $start_date_obj->diff($birth_date_obj); + $age_in_days = $interval->days; + + $possible_immunisations = ['bcg', 'opv']; + if ($age_in_days >= (6 * 7)) { + $possible_immunisations = array_merge($possible_immunisations, ['dtp', 'pcv13', 'rotarix']); + } + if ($age_in_days >= (14 * 7)) { + $possible_immunisations[] = 'ipv'; + } + if ($age_in_days >= (36 * 7)) { + $possible_immunisations[] = 'mr'; + } + + $site = variable_get('hedley_general_site_name', ''); + if ($site == 'burundi') { + // All 3 dosed of DTP were given, it has passed at least 28 days since + // third dose, and, child is at last 18 months old. + if (!empty($vaccination_progress['dtp']['dose-3'])) { + $age_in_months = ($interval->y * 12) + $interval->m; + $third_dose_date_obj = new DateTime($vaccination_progress['dtp']['dose-3']); + $interval = $start_date_obj->diff($third_dose_date_obj); + $days_since_third_dose = $interval->days; + + if ($age_in_months >= 18 && $days_since_third_dose >= 28) { + $possible_immunisations[] = 'dtp_sa'; + } + } + } + else { + $age_in_years = $interval->y; + if ($age_in_years >= 12 && $gender == 'female') { + $possible_immunisations[] = 'hpv'; + } + } + + foreach ($possible_immunisations as $immunisation_type) { + $immunisation_full_name = "well_child_{$immunisation_type}_immunisation"; + if (empty($vaccination_history)) { + $expected[] = $immunisation_full_name; + continue; + } + + $performed = $vaccination_history[$immunisation_type]; + if (empty($performed)) { + $expected[] = $immunisation_full_name; + continue; + } + + $doses = array_keys($performed); + sort($doses); + $last_dose = array_reverse($doses)[0]; + $last_dose_for_immunisation = hedley_reports_well_child_get_last_dose_for_vaccine($immunisation_type, $initial_opv_administered); + // If all doses we administered, skipping to next immunisation type. + if ($last_dose == $last_dose_for_immunisation) { + continue; + } + + // Calculating when next dose is supposed to be administered. + $last_dose_as_number = (int) explode('-', $last_dose)[1]; + $next_dose_as_number = $last_dose_as_number + 1; + $last_dose_date = $performed[$last_dose]; + $interval_between_dosed = hedley_reports_well_child_get_interval_for_vaccine($immunisation_type, $site); + $last_dose_date_obj = new DateTime($last_dose_date); + $next_dose_date_obj = clone $last_dose_date_obj; + $next_dose_date_obj->modify($interval_between_dosed); + if ($immunisation_type == 'opv' && $next_dose_as_number == 2 && $initial_opv_administered) { + $six_weeks_old_date_obj = clone $birth_date_obj; + $six_weeks_old_date_obj->modify('+6 weeks'); + + if ($six_weeks_old_date_obj > $next_dose_date_obj) { + $next_dose_date_obj = $six_weeks_old_date_obj; + } + } + + // If encounter started after the date when immunisation was supposed + // to be administered, adding it as expected. + if ($start_date_obj >= $next_dose_date_obj) { + $expected[] = $immunisation_full_name; + } + } +} + +function hedley_reports_well_child_initial_opv_administered($encounter_data, $birth_date_obj) { + $vaccination_progress = $encounter_data['vaccination_progress']; + + if (empty($vaccination_progress['opv']) || empty($vaccination_progress['opv']['dose-1'])) { + return FALSE; + } + + $first_dose_date_obj = new DateTime($vaccination_progress['opv']['dose-1']); + $interval = $first_dose_date_obj->diff($birth_date_obj); + + return $interval->days < 14; +} + +function hedley_reports_well_child_get_last_dose_for_vaccine($immunisation_type, $initial_opv_administered) { + switch ($immunisation_type) { + case 'bcg': + case 'ipv': + case 'dtp_sa': + return 'dose-1'; + + case 'rotarix': + case 'mr': + case 'hpv': + return 'dose-2'; + + case 'dtp': + case 'pcv13': + return 'dose-3'; + + case 'opv': + return $initial_opv_administered ? 'dose-4' : 'dose-3'; + } + + return FALSE; +} + +function hedley_reports_well_child_get_interval_for_vaccine($immunisation_type, $site) { + switch ($immunisation_type) { + case 'bcg': + case 'ipv': + case 'dtp_sa': + return '+0 days'; + + case 'opv': + case 'dtp': + case 'pcv13': + case 'rotarix': + return '+4 weeks'; + + case 'mr': + return $site == 'burundi' ? '+9 months' : '+6 months'; + + case 'hpv': + return '+6 months'; + } + + return FALSE; } function hedley_reports_well_child_add_medication_activities(array $encounter_data, array &$expected) { @@ -3887,8 +4042,12 @@ function hedley_reports_well_child_add_medication_activities(array $encounter_da $last_administration_date_obj = NULL; foreach ($previous_encounters_data as $previous_encounter_data) { $measurements_by_type = $previous_encounter_data['measurements_by_type']; + if (empty($measurements_by_type[$expected_activity])) { + continue; + } + $measurement = $measurements_by_type[$expected_activity]; - if (empty($measurement) || empty($measurement->field_administration_note)) { + if (empty($measurement->field_administration_note)) { continue; } @@ -3996,6 +4155,24 @@ function hedley_reports_well_child_add_next_steps_activities(array $encounter_da * or NULL if an error occurs. */ function hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, DateTime $start_date_obj) { + return hedley_reports_resolve_age_for_individual_encounter($encounter, $start_date_obj); +} + +/** + * Resolve the age for patient at the time of a specific encounter. + * + * @param object $encounter + * The encounter object, which includes the participant and person data. + * @param DateTime $start_date_obj + * The date object representing the start date of the encounter. + * @param string $unit + * Units for the age. Supports 'day' and 'month'. + * + * @return int|null + * The age (in units) of the individual at the time of the encounter, + * or NULL if an error occurs / incorrect unit set. + */ +function hedley_reports_resolve_age_for_individual_encounter($encounter, DateTime $start_date_obj, $unit = 'month') { try { // Get participant ID and node. $participant_id = $encounter->field_individual_participant[LANGUAGE_NONE][0]['target_id']; @@ -4011,7 +4188,17 @@ function hedley_reports_resolve_age_in_months_for_individual_encounter($encounte // Calculate age in months. $birth_date_obj = new DateTime($birth_date); $interval = $start_date_obj->diff($birth_date_obj); - return ($interval->y * 12) + $interval->m; + + switch($unit) { + case 'day': + return $interval->days; + + case 'month': + return ($interval->y * 12) + $interval->m; + + default: + return NULL; + } } catch (Exception $e) { watchdog('hedley_reports', "Failed to resolve patient age at encounter ID $encounter->nid."); From 8094827543dfa514f4a4ee3c6788e0a204f21369 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 1 Sep 2024 17:01:12 +0300 Subject: [PATCH 074/185] Complete Next Steps activities logic [ci skip] --- .../hedley_reports/hedley_reports.module | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index cab3122578..c0a5fa7739 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3530,7 +3530,7 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e // If conditions match, add medication activities. hedley_reports_well_child_add_medication_activities($encounter_data, $expected); // If conditions match, add next steps activities. - hedley_reports_well_child_add_next_steps_activities($encounter_data, $expected); + hedley_reports_well_child_add_next_steps_activities($encounter_data, $birth_date_obj, $gender, $expected); $completion_data = [ 'start_date' => $start_date, @@ -3881,8 +3881,18 @@ function hedley_reports_well_child_generate_expected_initial_activities(array $e } function hedley_reports_well_child_add_immunisation_activities(array $encounter_data, DateTime $birth_date_obj, $gender, array &$expected) { - $vaccination_history = $encounter_data['vaccination_history']; + $expected_by_history = hedley_reports_well_child_get_expected_immunisation_activites($encounter_data, $birth_date_obj, $gender,'history'); + foreach ($expected_by_history as $activity) { + $expected[] = $activity; + } +} + +function hedley_reports_well_child_get_expected_immunisation_activites(array $encounter_data, DateTime $birth_date_obj, $gender, $mode) { $vaccination_progress = $encounter_data['vaccination_progress']; + // History mode looks at vaccination status excluding vaccinations done at + // current encounter. Progress mode includes vaccinations done at current + // encounter. + $vaccination_history = $mode == 'history' ? $encounter_data['vaccination_history'] : $vaccination_progress; $start_date_obj = $encounter_data['start_date_obj']; $initial_opv_administered = hedley_reports_well_child_initial_opv_administered($encounter_data, $birth_date_obj); @@ -3922,6 +3932,7 @@ function hedley_reports_well_child_add_immunisation_activities(array $encounter_ } } + $expected = []; foreach ($possible_immunisations as $immunisation_type) { $immunisation_full_name = "well_child_{$immunisation_type}_immunisation"; if (empty($vaccination_history)) { @@ -3967,6 +3978,8 @@ function hedley_reports_well_child_add_immunisation_activities(array $encounter_ $expected[] = $immunisation_full_name; } } + + return $expected; } function hedley_reports_well_child_initial_opv_administered($encounter_data, $birth_date_obj) { @@ -4120,7 +4133,7 @@ function hedley_reports_well_child_genrate_expected_medication_activities_by_age * @param array &$expected * An array of expected activity names, passed by reference. */ -function hedley_reports_well_child_add_next_steps_activities(array $encounter_data, array &$expected) { +function hedley_reports_well_child_add_next_steps_activities(array $encounter_data, $birth_date_obj, $gender, array &$expected) { $measurements_by_type = $encounter_data['measurements_by_type']; $assessment = ''; @@ -4137,9 +4150,29 @@ function hedley_reports_well_child_add_next_steps_activities(array $encounter_da [ 'well_child_contributing_factors', 'well_child_follow_up', + 'well_child_health_education', + 'well_child_send_to_hc', ] ); } + else { + $immunisation_activities_completed = TRUE; + foreach ($expected as $activity) { + if (hedley_reports_ends_with($activity, '_immunisation')) { + if (empty($measurements_by_type[$activity])) { + $immunisation_activities_completed = FALSE; + break; + } + } + } + + if ($immunisation_activities_completed) { + $expected_by_progress = hedley_reports_well_child_get_expected_immunisation_activites($encounter_data, $birth_date_obj, $gender,'progress'); + if (empty($expected_by_progress)) { + $expected = array_merge($expected, ['well_child_health_education', 'well_child_send_to_hc']); + } + } + } } /** From dbfb135d89c68a773eeda230aae9ae1a45a0f8cd Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 1 Sep 2024 19:31:54 +0300 Subject: [PATCH 075/185] Generate data of front-end [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index c0a5fa7739..473f273195 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2003,6 +2003,8 @@ function hedley_reports_generate_completion_results_data($health_center) { 'attendance', // Nutrition Individual data. 'nutrition_encounter', + // Well Child data. + 'well_child_encounter', ]; $base_query = new EntityFieldQuery(); @@ -2021,6 +2023,7 @@ function hedley_reports_generate_completion_results_data($health_center) { 'acute_illness' => [], 'nutrition_individual' => [], 'nutrition_group' => [], + 'well_child' => [], ]; $nid = 0; @@ -2063,6 +2066,10 @@ function hedley_reports_generate_completion_results_data($health_center) { case 'nutrition_encounter': $data['nutrition_individual'][] = json_decode($json_data); break; + + case 'well_child_encounter': + $data['well_child'][] = json_decode($json_data); + break; } // Explicitly unset large variables after use for memory optimization. From 0e2afae4f673bd1de56ee5b603115d9500ef48b1 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 1 Sep 2024 19:32:35 +0300 Subject: [PATCH 076/185] Client side logic + view [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 1 + server/elm/src/Backend/Completion/Model.elm | 36 +++ server/elm/src/Backend/Completion/Utils.elm | 103 ++++++ server/elm/src/Pages/Completion/Model.elm | 1 + server/elm/src/Pages/Completion/Utils.elm | 41 +++ server/elm/src/Pages/Completion/View.elm | 45 ++- server/elm/src/Translate.elm | 202 ++++++++++++ .../custom/hedley_general/js/elm-main.js | 292 ++++++++++++++++-- 8 files changed, 698 insertions(+), 23 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index b7c1dcc809..957b7cb8aa 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -23,6 +23,7 @@ decodeCompletionData = |> requiredAt [ "results", "nutrition_individual" ] (list (decodeEncounterData nutritionChildActivityFromMapping)) |> requiredAt [ "results", "nutrition_group" ] (list (decodeNutritionGroupEncounterData nutritionMotherActivityFromMapping nutritionChildActivityFromMapping)) + |> requiredAt [ "results", "well_child" ] (list (decodeEncounterData wellChildActivityFromMapping)) decodeSelectedEntity : Decoder SelectedEntity diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index 779d725bd6..bcd0ba2030 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -14,6 +14,7 @@ type alias CompletionData = , acuteIllnessData : List (EncounterData AcuteIllnessActivity) , nutritionIndividualData : List (EncounterData NutritionChildActivity) , nutritionGroupData : List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) + , wellChildData : List (EncounterData WellChildActivity) } @@ -89,6 +90,41 @@ type NutritionMotherActivity | NutritionMotherFbf +type WellChildActivity + = WellChildAlbendazole + | WellChildBCGImmunisation + | WellChildCaring + | WellChildContributingFactors + | WellChildDTPImmunisation + | WellChildECD + | WellChildFeeding + | WellChildFollowUp + | WellChildFoodSecurity + | WellChildHeadCircumference + | WellChildHealthEducation + | WellChildHeight + | WellChildHygiene + | WellChildIPVImmunisation + | WellChildMebendezole + | WellChildMRImmunisation + | WellChildMUAC + | WellChildNCDA + | WellChildNextVisit + | WellChildNutrition + | WellChildOPVImmunisation + | WellChildPCV13Immunisation + | WellChildPhoto + | WellChildPregnancySummary + | WellChildRotarixImmunisation + | WellChildSendToHC + | WellChildSymptomsReview + | WellChildVitals + | WellChildVitaminA + | WellChildWeight + | WellChildHPVImmunisation + | WellChildDTPSAImmunisation + + type TakenBy = TakenByNurse | TakenByCHW diff --git a/server/elm/src/Backend/Completion/Utils.elm b/server/elm/src/Backend/Completion/Utils.elm index 961c191611..0a6c7ada50 100644 --- a/server/elm/src/Backend/Completion/Utils.elm +++ b/server/elm/src/Backend/Completion/Utils.elm @@ -135,6 +135,109 @@ acuteIllnessActivityFromMapping mapped = Nothing +wellChildActivityFromMapping : String -> Maybe WellChildActivity +wellChildActivityFromMapping mapped = + case mapped of + "a" -> + Just WellChildAlbendazole + + "b" -> + Just WellChildBCGImmunisation + + "c" -> + Just WellChildCaring + + "d" -> + Just WellChildContributingFactors + + "e" -> + Just WellChildDTPImmunisation + + "f" -> + Just WellChildECD + + "g" -> + Just WellChildFeeding + + "h" -> + Just WellChildFollowUp + + "i" -> + Just WellChildFoodSecurity + + "j" -> + Just WellChildHeadCircumference + + "k" -> + Just WellChildHealthEducation + + "l" -> + Just WellChildHeight + + "m" -> + Just WellChildHygiene + + "n" -> + Just WellChildIPVImmunisation + + "o" -> + Just WellChildMebendezole + + "p" -> + Just WellChildMRImmunisation + + "q" -> + Just WellChildMUAC + + "r" -> + Just WellChildNCDA + + "s" -> + Just WellChildNextVisit + + "t" -> + Just WellChildNutrition + + "u" -> + Just WellChildOPVImmunisation + + "v" -> + Just WellChildPCV13Immunisation + + "w" -> + Just WellChildPhoto + + "x" -> + Just WellChildPregnancySummary + + "y" -> + Just WellChildRotarixImmunisation + + "z" -> + Just WellChildSendToHC + + "1" -> + Just WellChildSymptomsReview + + "2" -> + Just WellChildVitals + + "3" -> + Just WellChildVitaminA + + "4" -> + Just WellChildWeight + + "5" -> + Just WellChildHPVImmunisation + + "6" -> + Just WellChildDTPSAImmunisation + + _ -> + Nothing + + takenByToString : TakenBy -> String takenByToString value = case value of diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index d1a486ed05..ff8d5c795e 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -30,6 +30,7 @@ type ReportType = ReportAcuteIllness | ReportNutritionGroup | ReportNutritionIndividual + | ReportWellChild type Msg diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index 9c6cabad54..816a71b032 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -6,6 +6,7 @@ import Backend.Completion.Model , NutritionChildActivity(..) , NutritionMotherActivity(..) , TakenBy(..) + , WellChildActivity(..) ) import Pages.Completion.Model exposing (ReportType(..)) @@ -22,6 +23,9 @@ reportTypeToString reportType = ReportNutritionIndividual -> "nutrition-individual" + ReportWellChild -> + "well-child" + reportTypeFromString : String -> Maybe ReportType reportTypeFromString reportType = @@ -93,3 +97,40 @@ allNutritionMotherGroupActivities = , NutritionLactation , NutritionMotherFbf ] + + +allWellChildActivities : List WellChildActivity +allWellChildActivities = + [ WellChildAlbendazole + , WellChildBCGImmunisation + , WellChildCaring + , WellChildContributingFactors + , WellChildDTPImmunisation + , WellChildECD + , WellChildFeeding + , WellChildFollowUp + , WellChildFoodSecurity + , WellChildHeadCircumference + , WellChildHealthEducation + , WellChildHeight + , WellChildHygiene + , WellChildIPVImmunisation + , WellChildMebendezole + , WellChildMRImmunisation + , WellChildMUAC + , WellChildNCDA + , WellChildNextVisit + , WellChildNutrition + , WellChildOPVImmunisation + , WellChildPCV13Immunisation + , WellChildPhoto + , WellChildPregnancySummary + , WellChildRotarixImmunisation + , WellChildSendToHC + , WellChildSymptomsReview + , WellChildVitals + , WellChildVitaminA + , WellChildWeight + , WellChildHPVImmunisation + , WellChildDTPSAImmunisation + ] diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index 1e179ee29c..27f63a41a5 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -12,6 +12,7 @@ import Backend.Completion.Model , NutritionMotherActivity(..) , SelectedEntity(..) , TakenBy(..) + , WellChildActivity(..) ) import Backend.Completion.Utils exposing (takenByToString) import Backend.Model exposing (ModelBackend) @@ -178,6 +179,9 @@ viewCompletionData language currentDate themePath data model = ReportNutritionIndividual -> viewNutritionIndividualReport language startDate limitDate model.takenBy data.nutritionIndividualData + + ReportWellChild -> + viewWellChildReport language startDate limitDate model.takenBy data.wellChildData ) model.reportType model.startDate @@ -189,7 +193,11 @@ viewCompletionData language currentDate themePath data model = , div [ class "inputs" ] <| [ viewSelectListInput language model.reportType - [ ReportAcuteIllness, ReportNutritionGroup, ReportNutritionIndividual ] + [ ReportAcuteIllness + , ReportNutritionGroup + , ReportNutritionIndividual + , ReportWellChild + ] reportTypeToString SetReportType Translate.CompletionReportType @@ -234,6 +242,14 @@ viewAcuteIllnessReport language startDate limitDate mTakenBy reportData = |> div [ class "report acute-illness" ] +viewWellChildReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData WellChildActivity) -> Html Msg +viewWellChildReport language startDate limitDate mTakenBy reportData = + applyFilters startDate limitDate mTakenBy reportData + |> generateWellChildReportData language + |> viewMetricsResultsTable + |> div [ class "report well-child" ] + + applyFilters : NominalDate -> NominalDate @@ -354,6 +370,33 @@ generateAcuteIllnessReportData language records = } +generateWellChildReportData : + Language + -> List (EncounterData WellChildActivity) + -> MetricsResultsTableData +generateWellChildReportData language records = + { heading = translate language Translate.StandardPediatricVisit + , captions = generateCaptionsList language + , rows = + List.map + (\activity -> + let + expected = + countOccurrences (.completion >> .expectedActivities) activity records + + completed = + countOccurrences (.completion >> .completedActivities) activity records + in + [ translate language <| Translate.WellChildActivity activity + , String.fromInt expected + , String.fromInt completed + , calcualtePercentage completed expected + ] + ) + allWellChildActivities + } + + -- Helper functions. diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 449450030d..a7ce6ed3a1 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -11,6 +11,7 @@ import Backend.Completion.Model , NutritionChildActivity(..) , NutritionMotherActivity(..) , TakenBy(..) + , WellChildActivity(..) ) import Backend.Reports.Model exposing (AcuteIllnessDiagnosis(..), NutritionReportTableType(..)) import Backend.Scoreboard.Model @@ -177,6 +178,7 @@ type TranslationId | UniversalIntervention | WastingModerate | WastingSevere + | WellChildActivity WellChildActivity | WideScopeNote | Year Int | YearLabel @@ -525,6 +527,12 @@ translationSet transId = , kirundi = Nothing } + Pages.Completion.Model.ReportWellChild -> + { english = "Well Child" + , kinyarwanda = Nothing + , kirundi = Nothing + } + CBNP -> { english = "CBNP" , kinyarwanda = Nothing @@ -1446,6 +1454,200 @@ translationSet transId = , kirundi = Nothing } + WellChildActivity activity -> + case activity of + WellChildAlbendazole -> + { english = "Albendazole" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildBCGImmunisation -> + { english = "BCG Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildCaring -> + { english = "Caring" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildContributingFactors -> + { english = "Contributing Factors" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildDTPImmunisation -> + { english = "DTP Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildECD -> + { english = "ECD" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildFeeding -> + { english = "Feeding" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildFollowUp -> + { english = "Follow Up" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildFoodSecurity -> + { english = "Food Security" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildHeadCircumference -> + { english = "Head Circumference" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildHealthEducation -> + { english = "Health Education" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildHeight -> + { english = "Height" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildHygiene -> + { english = "Hygiene" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildIPVImmunisation -> + { english = "IPV Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildMebendezole -> + { english = "Mebendezole" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildMRImmunisation -> + { english = "MR Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildMUAC -> + { english = "MUAC" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildNCDA -> + { english = "NCDA" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildNextVisit -> + { english = "Next Visit" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildNutrition -> + { english = "Nutrition" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildOPVImmunisation -> + { english = "OPV Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildPCV13Immunisation -> + { english = "PCV13 Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildPhoto -> + { english = "Photo" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildPregnancySummary -> + { english = "Pregnancy Summary" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildRotarixImmunisation -> + { english = "Rotarix Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildSendToHC -> + { english = "Referral" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildSymptomsReview -> + { english = "Symptoms Review" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildVitals -> + { english = "Vitals" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildVitaminA -> + { english = "vVitamin A" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildWeight -> + { english = "Weight" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildHPVImmunisation -> + { english = "HPV Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + WellChildDTPSAImmunisation -> + { english = "DTP Standalone Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + WideScopeNote -> { english = "The selected scope may contain a large number of patients and report generation could take several minutes." , kinyarwanda = Nothing diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index e4709f1dc3..6063b47eba 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -6842,9 +6842,9 @@ var $author$project$Backend$Types$BackendReturn = F4( function (model, cmd, error, appMsgs) { return {appMsgs: appMsgs, cmd: cmd, error: error, model: model}; }); -var $author$project$Backend$Completion$Model$CompletionData = F6( - function (site, entityName, entityType, acuteIllnessData, nutritionIndividualData, nutritionGroupData) { - return {acuteIllnessData: acuteIllnessData, entityName: entityName, entityType: entityType, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site}; +var $author$project$Backend$Completion$Model$CompletionData = F7( + function (site, entityName, entityType, acuteIllnessData, nutritionIndividualData, nutritionGroupData, wellChildData) { + return {acuteIllnessData: acuteIllnessData, entityName: entityName, entityType: entityType, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site, wellChildData: wellChildData}; }); var $author$project$Backend$Completion$Model$AcuteIllnessAcuteFindings = {$: 'AcuteIllnessAcuteFindings'}; var $author$project$Backend$Completion$Model$AcuteIllnessCOVIDTesting = {$: 'AcuteIllnessCOVIDTesting'}; @@ -7986,37 +7986,145 @@ var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt = F3( A2($elm$json$Json$Decode$at, path, valDecoder), decoder); }); +var $author$project$Backend$Completion$Model$WellChildAlbendazole = {$: 'WellChildAlbendazole'}; +var $author$project$Backend$Completion$Model$WellChildBCGImmunisation = {$: 'WellChildBCGImmunisation'}; +var $author$project$Backend$Completion$Model$WellChildCaring = {$: 'WellChildCaring'}; +var $author$project$Backend$Completion$Model$WellChildContributingFactors = {$: 'WellChildContributingFactors'}; +var $author$project$Backend$Completion$Model$WellChildDTPImmunisation = {$: 'WellChildDTPImmunisation'}; +var $author$project$Backend$Completion$Model$WellChildDTPSAImmunisation = {$: 'WellChildDTPSAImmunisation'}; +var $author$project$Backend$Completion$Model$WellChildECD = {$: 'WellChildECD'}; +var $author$project$Backend$Completion$Model$WellChildFeeding = {$: 'WellChildFeeding'}; +var $author$project$Backend$Completion$Model$WellChildFollowUp = {$: 'WellChildFollowUp'}; +var $author$project$Backend$Completion$Model$WellChildFoodSecurity = {$: 'WellChildFoodSecurity'}; +var $author$project$Backend$Completion$Model$WellChildHPVImmunisation = {$: 'WellChildHPVImmunisation'}; +var $author$project$Backend$Completion$Model$WellChildHeadCircumference = {$: 'WellChildHeadCircumference'}; +var $author$project$Backend$Completion$Model$WellChildHealthEducation = {$: 'WellChildHealthEducation'}; +var $author$project$Backend$Completion$Model$WellChildHeight = {$: 'WellChildHeight'}; +var $author$project$Backend$Completion$Model$WellChildHygiene = {$: 'WellChildHygiene'}; +var $author$project$Backend$Completion$Model$WellChildIPVImmunisation = {$: 'WellChildIPVImmunisation'}; +var $author$project$Backend$Completion$Model$WellChildMRImmunisation = {$: 'WellChildMRImmunisation'}; +var $author$project$Backend$Completion$Model$WellChildMUAC = {$: 'WellChildMUAC'}; +var $author$project$Backend$Completion$Model$WellChildMebendezole = {$: 'WellChildMebendezole'}; +var $author$project$Backend$Completion$Model$WellChildNCDA = {$: 'WellChildNCDA'}; +var $author$project$Backend$Completion$Model$WellChildNextVisit = {$: 'WellChildNextVisit'}; +var $author$project$Backend$Completion$Model$WellChildNutrition = {$: 'WellChildNutrition'}; +var $author$project$Backend$Completion$Model$WellChildOPVImmunisation = {$: 'WellChildOPVImmunisation'}; +var $author$project$Backend$Completion$Model$WellChildPCV13Immunisation = {$: 'WellChildPCV13Immunisation'}; +var $author$project$Backend$Completion$Model$WellChildPhoto = {$: 'WellChildPhoto'}; +var $author$project$Backend$Completion$Model$WellChildPregnancySummary = {$: 'WellChildPregnancySummary'}; +var $author$project$Backend$Completion$Model$WellChildRotarixImmunisation = {$: 'WellChildRotarixImmunisation'}; +var $author$project$Backend$Completion$Model$WellChildSendToHC = {$: 'WellChildSendToHC'}; +var $author$project$Backend$Completion$Model$WellChildSymptomsReview = {$: 'WellChildSymptomsReview'}; +var $author$project$Backend$Completion$Model$WellChildVitals = {$: 'WellChildVitals'}; +var $author$project$Backend$Completion$Model$WellChildVitaminA = {$: 'WellChildVitaminA'}; +var $author$project$Backend$Completion$Model$WellChildWeight = {$: 'WellChildWeight'}; +var $author$project$Backend$Completion$Utils$wellChildActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildAlbendazole); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildBCGImmunisation); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildCaring); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildContributingFactors); + case 'e': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildDTPImmunisation); + case 'f': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildECD); + case 'g': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildFeeding); + case 'h': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildFollowUp); + case 'i': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildFoodSecurity); + case 'j': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildHeadCircumference); + case 'k': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildHealthEducation); + case 'l': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildHeight); + case 'm': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildHygiene); + case 'n': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildIPVImmunisation); + case 'o': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildMebendezole); + case 'p': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildMRImmunisation); + case 'q': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildMUAC); + case 'r': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildNCDA); + case 's': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildNextVisit); + case 't': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildNutrition); + case 'u': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildOPVImmunisation); + case 'v': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildPCV13Immunisation); + case 'w': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildPhoto); + case 'x': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildPregnancySummary); + case 'y': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildRotarixImmunisation); + case 'z': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildSendToHC); + case '1': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildSymptomsReview); + case '2': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildVitals); + case '3': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildVitaminA); + case '4': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildWeight); + case '5': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildHPVImmunisation); + case '6': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$WellChildDTPSAImmunisation); + default: + return $elm$core$Maybe$Nothing; + } +}; var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'nutrition_group']), + ['results', 'well_child']), $elm$json$Json$Decode$list( - A2($author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData, $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping, $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$wellChildActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'nutrition_individual']), + ['results', 'nutrition_group']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), + A2($author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData, $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping, $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'acute_illness']), + ['results', 'nutrition_individual']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_type', - $author$project$Backend$Completion$Decoder$decodeSelectedEntity, + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, + _List_fromArray( + ['results', 'acute_illness']), + $elm$json$Json$Decode$list( + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_name', - $elm$json$Json$Decode$string, + 'entity_type', + $author$project$Backend$Completion$Decoder$decodeSelectedEntity, A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'site', - $author$project$Backend$Decoder$decodeSite, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData))))))); + 'entity_name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData)))))))); var $author$project$Backend$Completion$Update$update = F3( function (currentDate, msg, model) { var value = msg.a; @@ -10140,8 +10248,10 @@ var $author$project$Translate$translationSet = function (transId) { continue translationSet; case 'ReportNutritionGroup': return {english: 'Nutrition Group', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; - default: + case 'ReportNutritionIndividual': return {english: 'Nutrition Individual', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + default: + return {english: 'Well Child', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; } case 'CBNP': return {english: 'CBNP', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; @@ -10668,6 +10778,74 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Wasting Moderate', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WastingSevere': return {english: 'Wasting Severe', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildActivity': + var activity = transId.a; + switch (activity.$) { + case 'WellChildAlbendazole': + return {english: 'Albendazole', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildBCGImmunisation': + return {english: 'BCG Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildCaring': + return {english: 'Caring', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildContributingFactors': + return {english: 'Contributing Factors', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildDTPImmunisation': + return {english: 'DTP Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildECD': + return {english: 'ECD', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildFeeding': + return {english: 'Feeding', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildFollowUp': + return {english: 'Follow Up', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildFoodSecurity': + return {english: 'Food Security', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildHeadCircumference': + return {english: 'Head Circumference', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildHealthEducation': + return {english: 'Health Education', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildHeight': + return {english: 'Height', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildHygiene': + return {english: 'Hygiene', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildIPVImmunisation': + return {english: 'IPV Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildMebendezole': + return {english: 'Mebendezole', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildMRImmunisation': + return {english: 'MR Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildMUAC': + return {english: 'MUAC', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildNCDA': + return {english: 'NCDA', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildNextVisit': + return {english: 'Next Visit', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildNutrition': + return {english: 'Nutrition', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildOPVImmunisation': + return {english: 'OPV Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildPCV13Immunisation': + return {english: 'PCV13 Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildPhoto': + return {english: 'Photo', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildPregnancySummary': + return {english: 'Pregnancy Summary', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildRotarixImmunisation': + return {english: 'Rotarix Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildSendToHC': + return {english: 'Referral', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildSymptomsReview': + return {english: 'Symptoms Review', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildVitals': + return {english: 'Vitals', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildVitaminA': + return {english: 'vVitamin A', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildWeight': + return {english: 'Weight', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildHPVImmunisation': + return {english: 'HPV Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + default: + return {english: 'DTP Standalone Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + } case 'WideScopeNote': return {english: 'The selected scope may contain a large number of patients and report generation could take several minutes.', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Year': @@ -10832,6 +11010,7 @@ var $author$project$Translate$CompletionReportType = function (a) { }; var $author$project$Translate$NewScope = {$: 'NewScope'}; var $author$project$Translate$ReportTypeLabel = {$: 'ReportTypeLabel'}; +var $author$project$Pages$Completion$Model$ReportWellChild = {$: 'ReportWellChild'}; var $author$project$Translate$Scope = {$: 'Scope'}; var $author$project$Translate$SelectLimitDate = {$: 'SelectLimitDate'}; var $author$project$Translate$SelectStartDate = {$: 'SelectStartDate'}; @@ -11547,8 +11726,10 @@ var $author$project$Pages$Completion$Utils$reportTypeToString = function (report return 'acute-illness'; case 'ReportNutritionGroup': return 'nutrition-group'; - default: + case 'ReportNutritionIndividual': return 'nutrition-individual'; + default: + return 'well-child'; } }; var $author$project$Backend$Completion$Utils$takenByToString = function (value) { @@ -13179,6 +13360,72 @@ var $author$project$Pages$Utils$viewSelectListInput = F7( inputClass, $elm$core$Maybe$Just('')); }); +var $author$project$Translate$StandardPediatricVisit = {$: 'StandardPediatricVisit'}; +var $author$project$Translate$WellChildActivity = function (a) { + return {$: 'WellChildActivity', a: a}; +}; +var $author$project$Pages$Completion$Utils$allWellChildActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$WellChildAlbendazole, $author$project$Backend$Completion$Model$WellChildBCGImmunisation, $author$project$Backend$Completion$Model$WellChildCaring, $author$project$Backend$Completion$Model$WellChildContributingFactors, $author$project$Backend$Completion$Model$WellChildDTPImmunisation, $author$project$Backend$Completion$Model$WellChildECD, $author$project$Backend$Completion$Model$WellChildFeeding, $author$project$Backend$Completion$Model$WellChildFollowUp, $author$project$Backend$Completion$Model$WellChildFoodSecurity, $author$project$Backend$Completion$Model$WellChildHeadCircumference, $author$project$Backend$Completion$Model$WellChildHealthEducation, $author$project$Backend$Completion$Model$WellChildHeight, $author$project$Backend$Completion$Model$WellChildHygiene, $author$project$Backend$Completion$Model$WellChildIPVImmunisation, $author$project$Backend$Completion$Model$WellChildMebendezole, $author$project$Backend$Completion$Model$WellChildMRImmunisation, $author$project$Backend$Completion$Model$WellChildMUAC, $author$project$Backend$Completion$Model$WellChildNCDA, $author$project$Backend$Completion$Model$WellChildNextVisit, $author$project$Backend$Completion$Model$WellChildNutrition, $author$project$Backend$Completion$Model$WellChildOPVImmunisation, $author$project$Backend$Completion$Model$WellChildPCV13Immunisation, $author$project$Backend$Completion$Model$WellChildPhoto, $author$project$Backend$Completion$Model$WellChildPregnancySummary, $author$project$Backend$Completion$Model$WellChildRotarixImmunisation, $author$project$Backend$Completion$Model$WellChildSendToHC, $author$project$Backend$Completion$Model$WellChildSymptomsReview, $author$project$Backend$Completion$Model$WellChildVitals, $author$project$Backend$Completion$Model$WellChildVitaminA, $author$project$Backend$Completion$Model$WellChildWeight, $author$project$Backend$Completion$Model$WellChildHPVImmunisation, $author$project$Backend$Completion$Model$WellChildDTPSAImmunisation]); +var $author$project$Pages$Completion$View$generateWellChildReportData = F2( + function (language, records) { + return { + captions: $author$project$Pages$Completion$View$generateCaptionsList(language), + heading: A2($author$project$Translate$translate, language, $author$project$Translate$StandardPediatricVisit), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.expectedActivities; + }), + activity, + records); + var completed = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.completedActivities; + }), + activity, + records); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$WellChildActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) + ]); + }, + $author$project$Pages$Completion$Utils$allWellChildActivities) + }; + }); +var $author$project$Pages$Completion$View$viewWellChildReport = F5( + function (language, startDate, limitDate, mTakenBy, reportData) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report well-child') + ]), + $author$project$Pages$Components$View$viewMetricsResultsTable( + A2( + $author$project$Pages$Completion$View$generateWellChildReportData, + language, + A4($author$project$Pages$Completion$View$applyFilters, startDate, limitDate, mTakenBy, reportData)))); + }); var $author$project$Pages$Utils$viewCustomLabel = F4( function (language, translationId, suffix, class_) { return A2( @@ -13393,8 +13640,10 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( return A5($author$project$Pages$Completion$View$viewAcuteIllnessReport, language, startDate, limitDate, model.takenBy, data.acuteIllnessData); case 'ReportNutritionGroup': return A5($author$project$Pages$Completion$View$viewNutritionGroupReport, language, startDate, limitDate, model.takenBy, data.nutritionGroupData); - default: + case 'ReportNutritionIndividual': return A5($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, model.takenBy, data.nutritionIndividualData); + default: + return A5($author$project$Pages$Completion$View$viewWellChildReport, language, startDate, limitDate, model.takenBy, data.wellChildData); } }), model.reportType, @@ -13428,7 +13677,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( language, model.reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual]), + [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportWellChild]), $author$project$Pages$Completion$Utils$reportTypeToString, $author$project$Pages$Completion$Model$SetReportType, $author$project$Translate$CompletionReportType, @@ -13969,7 +14218,6 @@ var $author$project$Translate$NCD = {$: 'NCD'}; var $author$project$Translate$NutritionTotal = {$: 'NutritionTotal'}; var $author$project$Translate$PMTCT = {$: 'PMTCT'}; var $author$project$Translate$Sorwathe = {$: 'Sorwathe'}; -var $author$project$Translate$StandardPediatricVisit = {$: 'StandardPediatricVisit'}; var $author$project$Translate$Tuberculosis = {$: 'Tuberculosis'}; var $author$project$Translate$Unique = {$: 'Unique'}; var $author$project$Pages$Reports$View$generateDemographicsReportEncountersData = F2( From 32b57139b04b5a303c897ed93fbb0daa1c68400b Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 2 Sep 2024 00:13:12 +0300 Subject: [PATCH 077/185] A fix [ci skip] --- server/elm/src/Pages/Completion/Utils.elm | 3 +++ server/hedley/modules/custom/hedley_general/js/elm-main.js | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index 816a71b032..09c4a32f2a 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -39,6 +39,9 @@ reportTypeFromString reportType = "nutrition-individual" -> Just ReportNutritionIndividual + "well-child" -> + Just ReportWellChild + _ -> Nothing diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 6063b47eba..c2033f106f 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5828,6 +5828,7 @@ var $elm_community$maybe_extra$Maybe$Extra$or = F2( var $author$project$Pages$Completion$Model$ReportAcuteIllness = {$: 'ReportAcuteIllness'}; var $author$project$Pages$Completion$Model$ReportNutritionGroup = {$: 'ReportNutritionGroup'}; var $author$project$Pages$Completion$Model$ReportNutritionIndividual = {$: 'ReportNutritionIndividual'}; +var $author$project$Pages$Completion$Model$ReportWellChild = {$: 'ReportWellChild'}; var $author$project$Pages$Completion$Utils$reportTypeFromString = function (reportType) { switch (reportType) { case 'acute-illness': @@ -5836,6 +5837,8 @@ var $author$project$Pages$Completion$Utils$reportTypeFromString = function (repo return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionGroup); case 'nutrition-individual': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionIndividual); + case 'well-child': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportWellChild); default: return $elm$core$Maybe$Nothing; } @@ -11010,7 +11013,6 @@ var $author$project$Translate$CompletionReportType = function (a) { }; var $author$project$Translate$NewScope = {$: 'NewScope'}; var $author$project$Translate$ReportTypeLabel = {$: 'ReportTypeLabel'}; -var $author$project$Pages$Completion$Model$ReportWellChild = {$: 'ReportWellChild'}; var $author$project$Translate$Scope = {$: 'Scope'}; var $author$project$Translate$SelectLimitDate = {$: 'SelectLimitDate'}; var $author$project$Translate$SelectStartDate = {$: 'SelectStartDate'}; From 0850e9e3baa1a865ca22f4ab6eb77ba813800070 Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 2 Sep 2024 00:19:06 +0300 Subject: [PATCH 078/185] A fix [ci skip] --- server/elm/src/Translate.elm | 2 +- server/hedley/modules/custom/hedley_general/js/elm-main.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index a7ce6ed3a1..69c427cc62 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -1625,7 +1625,7 @@ translationSet transId = } WellChildVitaminA -> - { english = "vVitamin A" + { english = "Vitamin A" , kinyarwanda = Nothing , kirundi = Nothing } diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index c2033f106f..2af5e51fe9 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -10841,7 +10841,7 @@ var $author$project$Translate$translationSet = function (transId) { case 'WellChildVitals': return {english: 'Vitals', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildVitaminA': - return {english: 'vVitamin A', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Vitamin A', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildWeight': return {english: 'Weight', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildHPVImmunisation': From b7765f7650f6613302e53da0babfe076f975e129 Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 2 Sep 2024 00:22:51 +0300 Subject: [PATCH 079/185] Styling [ci skip] --- server/hedley/modules/custom/hedley_general/css/elm.css | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_general/css/elm.css b/server/hedley/modules/custom/hedley_general/css/elm.css index 5539741b71..26c5d8df5f 100644 --- a/server/hedley/modules/custom/hedley_general/css/elm.css +++ b/server/hedley/modules/custom/hedley_general/css/elm.css @@ -396,7 +396,8 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.acute-illness .table .row .item.row-label, .page-content .inputs .report.nutrition-group .table .row .item.row-label, -.page-content .inputs .report.nutrition-individual .table .row .item.row-label { +.page-content .inputs .report.nutrition-individual .table .row .item.row-label, + .page-content .inputs .report.well-child .table .row .item.row-label { width: 30%; } @@ -405,7 +406,9 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.nutrition-group .table .row .item.heading, .page-content .inputs .report.nutrition-group .table .row .item.value, .page-content .inputs .report.nutrition-individual .table .row .item.heading, -.page-content .inputs .report.nutrition-individual .table .row .item.value { +.page-content .inputs .report.nutrition-individual .table .row .item.value, +.page-content .inputs .report.well-child .table .row .item.heading, +.page-content .inputs .report.well-child .table .row .item.value { width: 20%; } From 5286bfbf41b5a90368ee45a4050a36fecc725db9 Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 2 Sep 2024 18:58:53 +0300 Subject: [PATCH 080/185] Another fix [ci skip] --- server/hedley/modules/custom/hedley_general/css/elm.css | 2 +- .../modules/custom/hedley_reports/hedley_reports.module | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_general/css/elm.css b/server/hedley/modules/custom/hedley_general/css/elm.css index 26c5d8df5f..c8c6e724d8 100644 --- a/server/hedley/modules/custom/hedley_general/css/elm.css +++ b/server/hedley/modules/custom/hedley_general/css/elm.css @@ -397,7 +397,7 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.acute-illness .table .row .item.row-label, .page-content .inputs .report.nutrition-group .table .row .item.row-label, .page-content .inputs .report.nutrition-individual .table .row .item.row-label, - .page-content .inputs .report.well-child .table .row .item.row-label { +.page-content .inputs .report.well-child .table .row .item.row-label { width: 30%; } diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 473f273195..a5c086c75e 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4175,7 +4175,9 @@ function hedley_reports_well_child_add_next_steps_activities(array $encounter_da if ($immunisation_activities_completed) { $expected_by_progress = hedley_reports_well_child_get_expected_immunisation_activites($encounter_data, $birth_date_obj, $gender,'progress'); - if (empty($expected_by_progress)) { + if (!empty($expected_by_progress)) { + // Immunisation activity completed, but child is still behind + // on vaccinations. $expected = array_merge($expected, ['well_child_health_education', 'well_child_send_to_hc']); } } From c4071ae2635ff65f6a54ef3a83e89c9a394e52bb Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 2 Sep 2024 19:07:38 +0300 Subject: [PATCH 081/185] Fix well_child_head_circumference [ci skip] --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index a5c086c75e..2a825ea041 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3849,7 +3849,7 @@ function hedley_reports_well_child_generate_expected_initial_activities(array $e // Head Circumference is taken for children bellow age of 3 years. if (isset($age_in_months) && $age_in_months < 36) { - $expected[] = 'well_child_muac'; + $expected[] = 'well_child_head_circumference'; } if ($encounter_type == 'newborn-exam') { From c587dfde86c28d00da644ea1ffd720397c3c1d4b Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 2 Sep 2024 19:22:33 +0300 Subject: [PATCH 082/185] Send encounter type instead of taken by [ci skip] --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 2a825ea041..28eae60bb0 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3541,7 +3541,7 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e $completion_data = [ 'start_date' => $start_date, - 'taken_by' => $encounter_data['encounter_type'] == 'pediatric-care' ? 'nurse' : 'chw', + 'encounter_type' => $encounter_data['encounter_type'], 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), ]; From a19cf0acf1fd7a092d0a1f42f4ff855745f4c3ea Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 3 Sep 2024 00:51:39 +0300 Subject: [PATCH 083/185] Add Newborn Exam report [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 32 ++- server/elm/src/Backend/Completion/Model.elm | 15 +- server/elm/src/Pages/Completion/Model.elm | 1 + server/elm/src/Pages/Completion/Utils.elm | 6 + server/elm/src/Pages/Completion/View.elm | 53 +++- server/elm/src/Translate.elm | 6 + .../custom/hedley_general/js/elm-main.js | 266 ++++++++++++------ .../hedley_reports/hedley_reports.module | 3 +- 8 files changed, 283 insertions(+), 99 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index 957b7cb8aa..eb1cb6de3b 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -23,7 +23,7 @@ decodeCompletionData = |> requiredAt [ "results", "nutrition_individual" ] (list (decodeEncounterData nutritionChildActivityFromMapping)) |> requiredAt [ "results", "nutrition_group" ] (list (decodeNutritionGroupEncounterData nutritionMotherActivityFromMapping nutritionChildActivityFromMapping)) - |> requiredAt [ "results", "well_child" ] (list (decodeEncounterData wellChildActivityFromMapping)) + |> requiredAt [ "results", "well_child" ] (list decodeWellChildEncounterData) decodeSelectedEntity : Decoder SelectedEntity @@ -63,6 +63,36 @@ decodeNutritionGroupEncounterData motherActivityFromString childActivityFromStri |> required "children" (decodeActivitiesCompletionDataList childActivityFromString) +decodeWellChildEncounterData : Decoder WellChildEncounterData +decodeWellChildEncounterData = + succeed WellChildEncounterData + |> required "start_date" decodeYYYYMMDD + |> required "encounter_type" decodeWellChildEncounterType + |> required "completion" (decodeActivitiesCompletionData wellChildActivityFromMapping) + + +decodeWellChildEncounterType : Decoder WellChildEncounterType +decodeWellChildEncounterType = + string + |> andThen + (\encounterType -> + case encounterType of + "pediatric-care" -> + succeed PediatricCare + + "pediatric-care-chw" -> + succeed PediatricCareChw + + "newborn-exam" -> + succeed NewbornExam + + _ -> + fail <| + encounterType + ++ " is not a recognized WellChildEncounterType" + ) + + decodeActivitiesCompletionData : (String -> Maybe activity) -> Decoder (ActivitiesCompletionData activity) decodeActivitiesCompletionData activityFromString = string diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index bcd0ba2030..43ab9bc9bc 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -14,7 +14,7 @@ type alias CompletionData = , acuteIllnessData : List (EncounterData AcuteIllnessActivity) , nutritionIndividualData : List (EncounterData NutritionChildActivity) , nutritionGroupData : List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) - , wellChildData : List (EncounterData WellChildActivity) + , wellChildData : List WellChildEncounterData } @@ -38,6 +38,19 @@ type alias NutritionGroupEncounterData motherActivity childActivity = } +type alias WellChildEncounterData = + { startDate : NominalDate + , encounterType : WellChildEncounterType + , completion : ActivitiesCompletionData WellChildActivity + } + + +type WellChildEncounterType + = PediatricCare + | PediatricCareChw + | NewbornExam + + type alias ActivitiesCompletionData activity = { expectedActivities : List activity , completedActivities : List activity diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index ff8d5c795e..3163a35397 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -28,6 +28,7 @@ emptyModel = type ReportType = ReportAcuteIllness + | ReportNewbornExam | ReportNutritionGroup | ReportNutritionIndividual | ReportWellChild diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index 09c4a32f2a..87ef79d14e 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -17,6 +17,9 @@ reportTypeToString reportType = ReportAcuteIllness -> "acute-illness" + ReportNewbornExam -> + "newborn-exam" + ReportNutritionGroup -> "nutrition-group" @@ -33,6 +36,9 @@ reportTypeFromString reportType = "acute-illness" -> Just ReportAcuteIllness + "newborn-exam" -> + Just ReportNewbornExam + "nutrition-group" -> Just ReportNutritionGroup diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index 27f63a41a5..c313a96235 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -13,6 +13,8 @@ import Backend.Completion.Model , SelectedEntity(..) , TakenBy(..) , WellChildActivity(..) + , WellChildEncounterData + , WellChildEncounterType(..) ) import Backend.Completion.Utils exposing (takenByToString) import Backend.Model exposing (ModelBackend) @@ -170,10 +172,17 @@ viewCompletionData language currentDate themePath data model = else Maybe.map3 (\reportType startDate limitDate -> + let + ( newbornExamData, spvData ) = + List.partition (.encounterType >> (==) NewbornExam) data.wellChildData + in case reportType of ReportAcuteIllness -> viewAcuteIllnessReport language startDate limitDate model.takenBy data.acuteIllnessData + ReportNewbornExam -> + viewWellChildReport language startDate limitDate model.takenBy newbornExamData + ReportNutritionGroup -> viewNutritionGroupReport language startDate limitDate model.takenBy data.nutritionGroupData @@ -181,7 +190,7 @@ viewCompletionData language currentDate themePath data model = viewNutritionIndividualReport language startDate limitDate model.takenBy data.nutritionIndividualData ReportWellChild -> - viewWellChildReport language startDate limitDate model.takenBy data.wellChildData + viewWellChildReport language startDate limitDate model.takenBy spvData ) model.reportType model.startDate @@ -194,6 +203,7 @@ viewCompletionData language currentDate themePath data model = [ viewSelectListInput language model.reportType [ ReportAcuteIllness + , ReportNewbornExam , ReportNutritionGroup , ReportNutritionIndividual , ReportWellChild @@ -242,9 +252,19 @@ viewAcuteIllnessReport language startDate limitDate mTakenBy reportData = |> div [ class "report acute-illness" ] -viewWellChildReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData WellChildActivity) -> Html Msg +viewWellChildReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List WellChildEncounterData -> Html Msg viewWellChildReport language startDate limitDate mTakenBy reportData = - applyFilters startDate limitDate mTakenBy reportData + customApplyFilters startDate + limitDate + (\encounter -> + if encounter.encounterType == PediatricCare then + TakenByNurse + + else + TakenByCHW + ) + mTakenBy + reportData |> generateWellChildReportData language |> viewMetricsResultsTable |> div [ class "report well-child" ] @@ -274,6 +294,31 @@ applyFilters startDate limitDate mTakenBy = ) +customApplyFilters : + NominalDate + -> NominalDate + -> ({ a | encounterType : WellChildEncounterType, startDate : Date.Date } -> TakenBy) + -> Maybe TakenBy + -> List { a | encounterType : WellChildEncounterType, startDate : Date.Date } + -> List { a | encounterType : WellChildEncounterType, startDate : Date.Date } +customApplyFilters startDate limitDate resolveTakenByFunc mTakenBy = + List.filter + (\encounter -> + let + takenByCondition = + Maybe.map + (\takenBy -> + resolveTakenByFunc encounter == takenBy + ) + mTakenBy + |> Maybe.withDefault True + in + (not <| Date.compare encounter.startDate startDate == LT) + && (not <| Date.compare encounter.startDate limitDate == GT) + && takenByCondition + ) + + generateNutritionIndividualReportData : Language -> List (EncounterData NutritionChildActivity) @@ -372,7 +417,7 @@ generateAcuteIllnessReportData language records = generateWellChildReportData : Language - -> List (EncounterData WellChildActivity) + -> List WellChildEncounterData -> MetricsResultsTableData generateWellChildReportData language records = { heading = translate language Translate.StandardPediatricVisit diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 69c427cc62..4169cf302f 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -515,6 +515,12 @@ translationSet transId = Pages.Completion.Model.ReportAcuteIllness -> translationSet AcuteIllness + Pages.Completion.Model.ReportNewbornExam -> + { english = "Newborn Exam" + , kinyarwanda = Nothing + , kirundi = Nothing + } + Pages.Completion.Model.ReportNutritionGroup -> { english = "Nutrition Group" , kinyarwanda = Nothing diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 2af5e51fe9..758d020cb9 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5826,6 +5826,7 @@ var $elm_community$maybe_extra$Maybe$Extra$or = F2( } }); var $author$project$Pages$Completion$Model$ReportAcuteIllness = {$: 'ReportAcuteIllness'}; +var $author$project$Pages$Completion$Model$ReportNewbornExam = {$: 'ReportNewbornExam'}; var $author$project$Pages$Completion$Model$ReportNutritionGroup = {$: 'ReportNutritionGroup'}; var $author$project$Pages$Completion$Model$ReportNutritionIndividual = {$: 'ReportNutritionIndividual'}; var $author$project$Pages$Completion$Model$ReportWellChild = {$: 'ReportWellChild'}; @@ -5833,6 +5834,8 @@ var $author$project$Pages$Completion$Utils$reportTypeFromString = function (repo switch (reportType) { case 'acute-illness': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportAcuteIllness); + case 'newborn-exam': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNewbornExam); case 'nutrition-group': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionGroup); case 'nutrition-individual': @@ -7923,72 +7926,28 @@ var $author$project$Backend$Decoder$decodeSite = A2( $elm$json$Json$Decode$andThen, A2($elm$core$Basics$composeR, $author$project$Backend$Decoder$siteFromString, $elm$json$Json$Decode$succeed), $elm$json$Json$Decode$string); -var $elm$json$Json$Decode$list = _Json_decodeList; -var $author$project$Backend$Completion$Model$NutritionChildFbf = {$: 'NutritionChildFbf'}; -var $author$project$Backend$Completion$Model$NutritionContributingFactors = {$: 'NutritionContributingFactors'}; -var $author$project$Backend$Completion$Model$NutritionFollowUp = {$: 'NutritionFollowUp'}; -var $author$project$Backend$Completion$Model$NutritionHealthEducation = {$: 'NutritionHealthEducation'}; -var $author$project$Backend$Completion$Model$NutritionHeight = {$: 'NutritionHeight'}; -var $author$project$Backend$Completion$Model$NutritionMUAC = {$: 'NutritionMUAC'}; -var $author$project$Backend$Completion$Model$NutritionNCDA = {$: 'NutritionNCDA'}; -var $author$project$Backend$Completion$Model$NutritionNutrition = {$: 'NutritionNutrition'}; -var $author$project$Backend$Completion$Model$NutritionPhoto = {$: 'NutritionPhoto'}; -var $author$project$Backend$Completion$Model$NutritionSendToHC = {$: 'NutritionSendToHC'}; -var $author$project$Backend$Completion$Model$NutritionWeight = {$: 'NutritionWeight'}; -var $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping = function (mapped) { - switch (mapped) { - case 'a': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHeight); - case 'b': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionNutrition); - case 'c': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionPhoto); - case 'd': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionWeight); - case 'e': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionMUAC); - case 'f': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionContributingFactors); - case 'g': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionFollowUp); - case 'h': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHealthEducation); - case 'i': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionSendToHC); - case 'j': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionNCDA); - case 'k': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionChildFbf); - default: - return $elm$core$Maybe$Nothing; - } -}; -var $author$project$Backend$Completion$Model$NutritionFamilyPlanning = {$: 'NutritionFamilyPlanning'}; -var $author$project$Backend$Completion$Model$NutritionLactation = {$: 'NutritionLactation'}; -var $author$project$Backend$Completion$Model$NutritionMotherFbf = {$: 'NutritionMotherFbf'}; -var $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping = function (mapped) { - switch (mapped) { - case 'a': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionFamilyPlanning); - case 'b': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionMotherFbf); - case 'c': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionLactation); - default: - return $elm$core$Maybe$Nothing; - } -}; -var $elm$json$Json$Decode$at = F2( - function (fields, decoder) { - return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields); - }); -var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt = F3( - function (path, valDecoder, decoder) { - return A2( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom, - A2($elm$json$Json$Decode$at, path, valDecoder), - decoder); - }); +var $author$project$Backend$Completion$Model$WellChildEncounterData = F3( + function (startDate, encounterType, completion) { + return {completion: completion, encounterType: encounterType, startDate: startDate}; + }); +var $author$project$Backend$Completion$Model$NewbornExam = {$: 'NewbornExam'}; +var $author$project$Backend$Completion$Model$PediatricCare = {$: 'PediatricCare'}; +var $author$project$Backend$Completion$Model$PediatricCareChw = {$: 'PediatricCareChw'}; +var $author$project$Backend$Completion$Decoder$decodeWellChildEncounterType = A2( + $elm$json$Json$Decode$andThen, + function (encounterType) { + switch (encounterType) { + case 'pediatric-care': + return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$PediatricCare); + case 'pediatric-care-chw': + return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$PediatricCareChw); + case 'newborn-exam': + return $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$NewbornExam); + default: + return $elm$json$Json$Decode$fail(encounterType + ' is not a recognized WellChildEncounterType'); + } + }, + $elm$json$Json$Decode$string); var $author$project$Backend$Completion$Model$WellChildAlbendazole = {$: 'WellChildAlbendazole'}; var $author$project$Backend$Completion$Model$WellChildBCGImmunisation = {$: 'WellChildBCGImmunisation'}; var $author$project$Backend$Completion$Model$WellChildCaring = {$: 'WellChildCaring'}; @@ -8091,12 +8050,90 @@ var $author$project$Backend$Completion$Utils$wellChildActivityFromMapping = func return $elm$core$Maybe$Nothing; } }; +var $author$project$Backend$Completion$Decoder$decodeWellChildEncounterData = A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'completion', + $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData($author$project$Backend$Completion$Utils$wellChildActivityFromMapping), + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'encounter_type', + $author$project$Backend$Completion$Decoder$decodeWellChildEncounterType, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'start_date', + $author$project$Gizra$NominalDate$decodeYYYYMMDD, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$WellChildEncounterData)))); +var $elm$json$Json$Decode$list = _Json_decodeList; +var $author$project$Backend$Completion$Model$NutritionChildFbf = {$: 'NutritionChildFbf'}; +var $author$project$Backend$Completion$Model$NutritionContributingFactors = {$: 'NutritionContributingFactors'}; +var $author$project$Backend$Completion$Model$NutritionFollowUp = {$: 'NutritionFollowUp'}; +var $author$project$Backend$Completion$Model$NutritionHealthEducation = {$: 'NutritionHealthEducation'}; +var $author$project$Backend$Completion$Model$NutritionHeight = {$: 'NutritionHeight'}; +var $author$project$Backend$Completion$Model$NutritionMUAC = {$: 'NutritionMUAC'}; +var $author$project$Backend$Completion$Model$NutritionNCDA = {$: 'NutritionNCDA'}; +var $author$project$Backend$Completion$Model$NutritionNutrition = {$: 'NutritionNutrition'}; +var $author$project$Backend$Completion$Model$NutritionPhoto = {$: 'NutritionPhoto'}; +var $author$project$Backend$Completion$Model$NutritionSendToHC = {$: 'NutritionSendToHC'}; +var $author$project$Backend$Completion$Model$NutritionWeight = {$: 'NutritionWeight'}; +var $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHeight); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionNutrition); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionPhoto); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionWeight); + case 'e': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionMUAC); + case 'f': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionContributingFactors); + case 'g': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionFollowUp); + case 'h': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionHealthEducation); + case 'i': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionSendToHC); + case 'j': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionNCDA); + case 'k': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionChildFbf); + default: + return $elm$core$Maybe$Nothing; + } +}; +var $author$project$Backend$Completion$Model$NutritionFamilyPlanning = {$: 'NutritionFamilyPlanning'}; +var $author$project$Backend$Completion$Model$NutritionLactation = {$: 'NutritionLactation'}; +var $author$project$Backend$Completion$Model$NutritionMotherFbf = {$: 'NutritionMotherFbf'}; +var $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionFamilyPlanning); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionMotherFbf); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NutritionLactation); + default: + return $elm$core$Maybe$Nothing; + } +}; +var $elm$json$Json$Decode$at = F2( + function (fields, decoder) { + return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields); + }); +var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt = F3( + function (path, valDecoder, decoder) { + return A2( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom, + A2($elm$json$Json$Decode$at, path, valDecoder), + decoder); + }); var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( ['results', 'well_child']), - $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$wellChildActivityFromMapping)), + $elm$json$Json$Decode$list($author$project$Backend$Completion$Decoder$decodeWellChildEncounterData), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( @@ -10249,6 +10286,8 @@ var $author$project$Translate$translationSet = function (transId) { var $temp$transId = $author$project$Translate$AcuteIllness; transId = $temp$transId; continue translationSet; + case 'ReportNewbornExam': + return {english: 'Newborn Exam', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'ReportNutritionGroup': return {english: 'Nutrition Group', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'ReportNutritionIndividual': @@ -11722,10 +11761,30 @@ var $elm$html$Html$Events$onClick = function (msg) { 'click', $elm$json$Json$Decode$succeed(msg)); }; +var $elm$core$List$partition = F2( + function (pred, list) { + var step = F2( + function (x, _v0) { + var trues = _v0.a; + var falses = _v0.b; + return pred(x) ? _Utils_Tuple2( + A2($elm$core$List$cons, x, trues), + falses) : _Utils_Tuple2( + trues, + A2($elm$core$List$cons, x, falses)); + }); + return A3( + $elm$core$List$foldr, + step, + _Utils_Tuple2(_List_Nil, _List_Nil), + list); + }); var $author$project$Pages$Completion$Utils$reportTypeToString = function (reportType) { switch (reportType.$) { case 'ReportAcuteIllness': return 'acute-illness'; + case 'ReportNewbornExam': + return 'newborn-exam'; case 'ReportNutritionGroup': return 'nutrition-group'; case 'ReportNutritionIndividual': @@ -13362,6 +13421,28 @@ var $author$project$Pages$Utils$viewSelectListInput = F7( inputClass, $elm$core$Maybe$Just('')); }); +var $author$project$Pages$Completion$View$customApplyFilters = F4( + function (startDate, limitDate, resolveTakenByFunc, mTakenBy) { + return $elm$core$List$filter( + function (encounter) { + var takenByCondition = A2( + $elm$core$Maybe$withDefault, + true, + A2( + $elm$core$Maybe$map, + function (takenBy) { + return _Utils_eq( + resolveTakenByFunc(encounter), + takenBy); + }, + mTakenBy)); + return (!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), + $elm$core$Basics$LT)) && ((!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, limitDate), + $elm$core$Basics$GT)) && takenByCondition); + }); + }); var $author$project$Translate$StandardPediatricVisit = {$: 'StandardPediatricVisit'}; var $author$project$Translate$WellChildActivity = function (a) { return {$: 'WellChildActivity', a: a}; @@ -13426,7 +13507,15 @@ var $author$project$Pages$Completion$View$viewWellChildReport = F5( A2( $author$project$Pages$Completion$View$generateWellChildReportData, language, - A4($author$project$Pages$Completion$View$applyFilters, startDate, limitDate, mTakenBy, reportData)))); + A5( + $author$project$Pages$Completion$View$customApplyFilters, + startDate, + limitDate, + function (encounter) { + return _Utils_eq(encounter.encounterType, $author$project$Backend$Completion$Model$PediatricCare) ? $author$project$Backend$Completion$Model$TakenByNurse : $author$project$Backend$Completion$Model$TakenByCHW; + }, + mTakenBy, + reportData)))); }); var $author$project$Pages$Utils$viewCustomLabel = F4( function (language, translationId, suffix, class_) { @@ -13471,8 +13560,8 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( function (language, currentDate, themePath, data, model) { var topBar = function () { var scopeLabel = function () { - var _v1 = data.entityType; - if (_v1.$ === 'EntityGlobal') { + var _v2 = data.entityType; + if (_v2.$ === 'EntityGlobal') { return A2($author$project$Translate$translate, language, $author$project$Translate$Global); } else { return data.entityName; @@ -13637,15 +13726,28 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( $elm$core$Maybe$map3, F3( function (reportType, startDate, limitDate) { + var _v0 = A2( + $elm$core$List$partition, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.encounterType; + }, + $elm$core$Basics$eq($author$project$Backend$Completion$Model$NewbornExam)), + data.wellChildData); + var newbornExamData = _v0.a; + var spvData = _v0.b; switch (reportType.$) { case 'ReportAcuteIllness': return A5($author$project$Pages$Completion$View$viewAcuteIllnessReport, language, startDate, limitDate, model.takenBy, data.acuteIllnessData); + case 'ReportNewbornExam': + return A5($author$project$Pages$Completion$View$viewWellChildReport, language, startDate, limitDate, model.takenBy, newbornExamData); case 'ReportNutritionGroup': return A5($author$project$Pages$Completion$View$viewNutritionGroupReport, language, startDate, limitDate, model.takenBy, data.nutritionGroupData); case 'ReportNutritionIndividual': return A5($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, model.takenBy, data.nutritionIndividualData); default: - return A5($author$project$Pages$Completion$View$viewWellChildReport, language, startDate, limitDate, model.takenBy, data.wellChildData); + return A5($author$project$Pages$Completion$View$viewWellChildReport, language, startDate, limitDate, model.takenBy, spvData); } }), model.reportType, @@ -13679,7 +13781,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( language, model.reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportWellChild]), + [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportWellChild]), $author$project$Pages$Completion$Utils$reportTypeToString, $author$project$Pages$Completion$Model$SetReportType, $author$project$Translate$CompletionReportType, @@ -14531,24 +14633,6 @@ var $author$project$Pages$Reports$Utils$countTotalEncounters = function (data) { }), data.prenatalData))) + $author$project$Pages$Reports$Utils$countIndividualDataEncounters(data.homeVisitData)) + $author$project$Pages$Reports$Utils$countIndividualDataEncounters(data.childScorecardData)) + $author$project$Pages$Reports$Utils$countIndividualDataEncounters(data.ncdData)) + $author$project$Pages$Reports$Utils$countIndividualDataEncounters(data.hivData)) + $author$project$Pages$Reports$Utils$countIndividualDataEncounters(data.tuberculosisData); }; -var $elm$core$List$partition = F2( - function (pred, list) { - var step = F2( - function (x, _v0) { - var trues = _v0.a; - var falses = _v0.b; - return pred(x) ? _Utils_Tuple2( - A2($elm$core$List$cons, x, trues), - falses) : _Utils_Tuple2( - trues, - A2($elm$core$List$cons, x, falses)); - }); - return A3( - $elm$core$List$foldr, - step, - _Utils_Tuple2(_List_Nil, _List_Nil), - list); - }); var $author$project$Pages$Reports$View$generateDemographicsReportPatientsData = F3( function (language, limitDate, records) { var labels = _List_fromArray( diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 28eae60bb0..43a7b43d78 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3467,8 +3467,8 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e } // Get birthdate. + $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; try { - $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; $person = node_load($person_id); $birth_date = explode(' ', $person->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; $birth_date_obj = new DateTime($birth_date); @@ -3525,7 +3525,6 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e $encounter_data['age_in_months'] = hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj); $encounter_data['previous_encounters_data'] = array_slice($encounters_data, 0, $index); - $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; list($encounter_data['vaccination_history'], $encounter_data['vaccination_progress']) = hedley_reports_well_child_generate_vaccination_progress_data($person_id, $encounter_data); // So far we were constructing data structures to resolve encounter data. From b2fc5b7e5f4e08461f865606bbe0dd3e51fba077 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 3 Sep 2024 20:34:20 +0300 Subject: [PATCH 084/185] Newborn exam report front-end logic [ci skip] --- server/elm/src/Pages/Completion/Utils.elm | 64 ++++ server/elm/src/Pages/Completion/View.elm | 77 +++-- server/elm/src/Translate.elm | 17 +- .../custom/hedley_general/js/elm-main.js | 307 +++++++++++------- .../hedley_reports/hedley_reports.module | 65 ++-- 5 files changed, 340 insertions(+), 190 deletions(-) diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index 87ef79d14e..dce81abc4d 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -1,5 +1,6 @@ module Pages.Completion.Utils exposing (..) +import App.Types exposing (Site(..)) import Backend.Completion.Model exposing ( AcuteIllnessActivity(..) @@ -143,3 +144,66 @@ allWellChildActivities = , WellChildHPVImmunisation , WellChildDTPSAImmunisation ] + + +resolveSPVActivities : Site -> List WellChildActivity +resolveSPVActivities site = + [ WellChildAlbendazole + , WellChildBCGImmunisation + , WellChildCaring + , WellChildContributingFactors + , WellChildDTPImmunisation + + -- Not implemented at current phase. + -- , WellChildECD + , WellChildFeeding + , WellChildFollowUp + , WellChildFoodSecurity + , WellChildHeadCircumference + , WellChildHealthEducation + , WellChildHeight + , WellChildHygiene + , WellChildIPVImmunisation + , WellChildMebendezole + , WellChildMRImmunisation + , WellChildMUAC + , WellChildNCDA + + -- This is just an indication that next visit notice + -- was presented. Not showign it. + -- , WellChildNextVisit + , WellChildNutrition + , WellChildOPVImmunisation + , WellChildPCV13Immunisation + , WellChildPhoto + , WellChildPregnancySummary + , WellChildRotarixImmunisation + , WellChildSendToHC + , WellChildSymptomsReview + , WellChildVitals + , WellChildVitaminA + , WellChildWeight + ] + ++ (case site of + SiteBurundi -> + [ WellChildDTPSAImmunisation ] + + _ -> + [ WellChildHPVImmunisation ] + ) + + +newbornExamActivities : List WellChildActivity +newbornExamActivities = + [ WellChildBCGImmunisation + , WellChildContributingFactors + , WellChildFollowUp + , WellChildHeadCircumference + , WellChildHealthEducation + , WellChildNutrition + , WellChildOPVImmunisation + , WellChildPhoto + , WellChildPregnancySummary + , WellChildSendToHC + , WellChildWeight + ] diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index c313a96235..d9eb67a322 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -77,26 +77,35 @@ viewCompletionData language currentDate themePath data model = ] takenByInput = - let - options = - List.map - (\option -> - ( translate language <| Translate.TakenBy option, option ) - ) - [ TakenByNurse, TakenByCHW ] - in - if isJust model.reportType then - viewCustomSelectListInput - model.takenBy - options - takenByToString - SetTakenBy - "select-input" - (Just <| translate language Translate.Any) - |> wrapSelectListInput language Translate.TakenByLabel False + Maybe.map + (\reportType -> + if reportType == ReportNewbornExam then + emptyNode - else - emptyNode + else + let + options = + List.map + (\option -> + ( translate language <| Translate.TakenBy option, option ) + ) + [ TakenByNurse, TakenByCHW ] + in + if isJust model.reportType then + viewCustomSelectListInput + model.takenBy + options + takenByToString + SetTakenBy + "select-input" + (Just <| translate language Translate.Any) + |> wrapSelectListInput language Translate.TakenByLabel False + + else + emptyNode + ) + model.reportType + |> Maybe.withDefault emptyNode dateInputs = Maybe.map @@ -181,7 +190,7 @@ viewCompletionData language currentDate themePath data model = viewAcuteIllnessReport language startDate limitDate model.takenBy data.acuteIllnessData ReportNewbornExam -> - viewWellChildReport language startDate limitDate model.takenBy newbornExamData + viewNewbornExamReport language startDate limitDate model.takenBy newbornExamData ReportNutritionGroup -> viewNutritionGroupReport language startDate limitDate model.takenBy data.nutritionGroupData @@ -190,7 +199,7 @@ viewCompletionData language currentDate themePath data model = viewNutritionIndividualReport language startDate limitDate model.takenBy data.nutritionIndividualData ReportWellChild -> - viewWellChildReport language startDate limitDate model.takenBy spvData + viewSPVReport language data.site startDate limitDate model.takenBy spvData ) model.reportType model.startDate @@ -252,8 +261,8 @@ viewAcuteIllnessReport language startDate limitDate mTakenBy reportData = |> div [ class "report acute-illness" ] -viewWellChildReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List WellChildEncounterData -> Html Msg -viewWellChildReport language startDate limitDate mTakenBy reportData = +viewSPVReport : Language -> Site -> NominalDate -> NominalDate -> Maybe TakenBy -> List WellChildEncounterData -> Html Msg +viewSPVReport language site startDate limitDate mTakenBy reportData = customApplyFilters startDate limitDate (\encounter -> @@ -265,7 +274,19 @@ viewWellChildReport language startDate limitDate mTakenBy reportData = ) mTakenBy reportData - |> generateWellChildReportData language + |> generateWellChildReportData language Translate.StandardPediatricVisit (resolveSPVActivities site) + |> viewMetricsResultsTable + |> div [ class "report well-child" ] + + +viewNewbornExamReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List WellChildEncounterData -> Html Msg +viewNewbornExamReport language startDate limitDate mTakenBy reportData = + customApplyFilters startDate + limitDate + (always TakenByCHW) + mTakenBy + reportData + |> generateWellChildReportData language Translate.NewbornExam newbornExamActivities |> viewMetricsResultsTable |> div [ class "report well-child" ] @@ -417,10 +438,12 @@ generateAcuteIllnessReportData language records = generateWellChildReportData : Language + -> TranslationId + -> List WellChildActivity -> List WellChildEncounterData -> MetricsResultsTableData -generateWellChildReportData language records = - { heading = translate language Translate.StandardPediatricVisit +generateWellChildReportData language labelTransId activities records = + { heading = translate language labelTransId , captions = generateCaptionsList language , rows = List.map @@ -438,7 +461,7 @@ generateWellChildReportData language records = , calcualtePercentage completed expected ] ) - allWellChildActivities + activities } diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 4169cf302f..6e8ec60296 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -121,6 +121,7 @@ type TranslationId | NCDANutritionBehaviorItemLabel NCDANutritionBehaviorItem | NCDATargetedInterventionsItemLabel NCDATargetedInterventionsItem | NCDAUniversalInterventionItemLabel NCDAUniversalInterventionItem + | NewbornExam | NewScope | NewSelection | NoDiagnosis @@ -516,10 +517,7 @@ translationSet transId = translationSet AcuteIllness Pages.Completion.Model.ReportNewbornExam -> - { english = "Newborn Exam" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet NewbornExam Pages.Completion.Model.ReportNutritionGroup -> { english = "Nutrition Group" @@ -534,10 +532,7 @@ translationSet transId = } Pages.Completion.Model.ReportWellChild -> - { english = "Well Child" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet StandardPediatricVisit CBNP -> { english = "CBNP" @@ -942,6 +937,12 @@ translationSet transId = , kirundi = Nothing } + NewbornExam -> + { english = "Newborn Exam" + , kinyarwanda = Nothing + , kirundi = Nothing + } + NewScope -> { english = "New Scope" , kinyarwanda = Nothing diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 758d020cb9..2a699d4e89 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -9931,10 +9931,12 @@ var $author$project$Translate$IncidenceByQuarterOneVisitOrMore = {$: 'IncidenceB var $author$project$Translate$IncidenceByQuarterTwoVisitsOrMore = {$: 'IncidenceByQuarterTwoVisitsOrMore'}; var $author$project$Translate$IncidenceByYearOneVisitOrMore = {$: 'IncidenceByYearOneVisitOrMore'}; var $author$project$Translate$IncidenceByYearTwoVisitsOrMore = {$: 'IncidenceByYearTwoVisitsOrMore'}; +var $author$project$Translate$NewbornExam = {$: 'NewbornExam'}; var $author$project$Translate$PrevalenceByMonthOneVisitOrMore = {$: 'PrevalenceByMonthOneVisitOrMore'}; var $author$project$Translate$PrevalenceByMonthTwoVisitsOrMore = {$: 'PrevalenceByMonthTwoVisitsOrMore'}; var $author$project$Translate$Province = {$: 'Province'}; var $author$project$Translate$Sector = {$: 'Sector'}; +var $author$project$Translate$StandardPediatricVisit = {$: 'StandardPediatricVisit'}; var $author$project$Translate$Village = {$: 'Village'}; var $author$project$Translate$translateHttpError = function (transId) { switch (transId.$) { @@ -10287,13 +10289,17 @@ var $author$project$Translate$translationSet = function (transId) { transId = $temp$transId; continue translationSet; case 'ReportNewbornExam': - return {english: 'Newborn Exam', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$NewbornExam; + transId = $temp$transId; + continue translationSet; case 'ReportNutritionGroup': return {english: 'Nutrition Group', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'ReportNutritionIndividual': return {english: 'Nutrition Individual', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; default: - return {english: 'Well Child', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$StandardPediatricVisit; + transId = $temp$transId; + continue translationSet; } case 'CBNP': return {english: 'CBNP', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; @@ -10539,6 +10545,8 @@ var $author$project$Translate$translationSet = function (transId) { kirundi: $elm$core$Maybe$Nothing }; } + case 'NewbornExam': + return {english: 'Newborn Exam', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NewScope': return {english: 'New Scope', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NewSelection': @@ -13255,6 +13263,101 @@ var $author$project$Utils$Html$viewCustomModal = function (extraClasses) { })); }; var $author$project$Utils$Html$viewModal = $author$project$Utils$Html$viewCustomModal(_List_Nil); +var $author$project$Pages$Completion$View$customApplyFilters = F4( + function (startDate, limitDate, resolveTakenByFunc, mTakenBy) { + return $elm$core$List$filter( + function (encounter) { + var takenByCondition = A2( + $elm$core$Maybe$withDefault, + true, + A2( + $elm$core$Maybe$map, + function (takenBy) { + return _Utils_eq( + resolveTakenByFunc(encounter), + takenBy); + }, + mTakenBy)); + return (!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), + $elm$core$Basics$LT)) && ((!_Utils_eq( + A2($justinmimbs$date$Date$compare, encounter.startDate, limitDate), + $elm$core$Basics$GT)) && takenByCondition); + }); + }); +var $author$project$Translate$WellChildActivity = function (a) { + return {$: 'WellChildActivity', a: a}; +}; +var $author$project$Pages$Completion$View$generateWellChildReportData = F4( + function (language, labelTransId, activities, records) { + return { + captions: $author$project$Pages$Completion$View$generateCaptionsList(language), + heading: A2($author$project$Translate$translate, language, labelTransId), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.expectedActivities; + }), + activity, + records); + var completed = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.completedActivities; + }), + activity, + records); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$WellChildActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) + ]); + }, + activities) + }; + }); +var $author$project$Pages$Completion$Utils$newbornExamActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$WellChildBCGImmunisation, $author$project$Backend$Completion$Model$WellChildContributingFactors, $author$project$Backend$Completion$Model$WellChildFollowUp, $author$project$Backend$Completion$Model$WellChildHeadCircumference, $author$project$Backend$Completion$Model$WellChildHealthEducation, $author$project$Backend$Completion$Model$WellChildNutrition, $author$project$Backend$Completion$Model$WellChildOPVImmunisation, $author$project$Backend$Completion$Model$WellChildPhoto, $author$project$Backend$Completion$Model$WellChildPregnancySummary, $author$project$Backend$Completion$Model$WellChildSendToHC, $author$project$Backend$Completion$Model$WellChildWeight]); +var $author$project$Pages$Completion$View$viewNewbornExamReport = F5( + function (language, startDate, limitDate, mTakenBy, reportData) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report well-child') + ]), + $author$project$Pages$Components$View$viewMetricsResultsTable( + A4( + $author$project$Pages$Completion$View$generateWellChildReportData, + language, + $author$project$Translate$NewbornExam, + $author$project$Pages$Completion$Utils$newbornExamActivities, + A5( + $author$project$Pages$Completion$View$customApplyFilters, + startDate, + limitDate, + $elm$core$Basics$always($author$project$Backend$Completion$Model$TakenByCHW), + mTakenBy, + reportData)))); + }); var $author$project$Translate$NutritionChildActivity = function (a) { return {$: 'NutritionChildActivity', a: a}; }; @@ -13398,6 +13501,44 @@ var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F5( language, A4($author$project$Pages$Completion$View$applyFilters, startDate, limitDate, mTakenBy, reportData)))); }); +var $author$project$Pages$Completion$Utils$resolveSPVActivities = function (site) { + return _Utils_ap( + _List_fromArray( + [$author$project$Backend$Completion$Model$WellChildAlbendazole, $author$project$Backend$Completion$Model$WellChildBCGImmunisation, $author$project$Backend$Completion$Model$WellChildCaring, $author$project$Backend$Completion$Model$WellChildContributingFactors, $author$project$Backend$Completion$Model$WellChildDTPImmunisation, $author$project$Backend$Completion$Model$WellChildFeeding, $author$project$Backend$Completion$Model$WellChildFollowUp, $author$project$Backend$Completion$Model$WellChildFoodSecurity, $author$project$Backend$Completion$Model$WellChildHeadCircumference, $author$project$Backend$Completion$Model$WellChildHealthEducation, $author$project$Backend$Completion$Model$WellChildHeight, $author$project$Backend$Completion$Model$WellChildHygiene, $author$project$Backend$Completion$Model$WellChildIPVImmunisation, $author$project$Backend$Completion$Model$WellChildMebendezole, $author$project$Backend$Completion$Model$WellChildMRImmunisation, $author$project$Backend$Completion$Model$WellChildMUAC, $author$project$Backend$Completion$Model$WellChildNCDA, $author$project$Backend$Completion$Model$WellChildNutrition, $author$project$Backend$Completion$Model$WellChildOPVImmunisation, $author$project$Backend$Completion$Model$WellChildPCV13Immunisation, $author$project$Backend$Completion$Model$WellChildPhoto, $author$project$Backend$Completion$Model$WellChildPregnancySummary, $author$project$Backend$Completion$Model$WellChildRotarixImmunisation, $author$project$Backend$Completion$Model$WellChildSendToHC, $author$project$Backend$Completion$Model$WellChildSymptomsReview, $author$project$Backend$Completion$Model$WellChildVitals, $author$project$Backend$Completion$Model$WellChildVitaminA, $author$project$Backend$Completion$Model$WellChildWeight]), + function () { + if (site.$ === 'SiteBurundi') { + return _List_fromArray( + [$author$project$Backend$Completion$Model$WellChildDTPSAImmunisation]); + } else { + return _List_fromArray( + [$author$project$Backend$Completion$Model$WellChildHPVImmunisation]); + } + }()); +}; +var $author$project$Pages$Completion$View$viewSPVReport = F6( + function (language, site, startDate, limitDate, mTakenBy, reportData) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report well-child') + ]), + $author$project$Pages$Components$View$viewMetricsResultsTable( + A4( + $author$project$Pages$Completion$View$generateWellChildReportData, + language, + $author$project$Translate$StandardPediatricVisit, + $author$project$Pages$Completion$Utils$resolveSPVActivities(site), + A5( + $author$project$Pages$Completion$View$customApplyFilters, + startDate, + limitDate, + function (encounter) { + return _Utils_eq(encounter.encounterType, $author$project$Backend$Completion$Model$PediatricCare) ? $author$project$Backend$Completion$Model$TakenByNurse : $author$project$Backend$Completion$Model$TakenByCHW; + }, + mTakenBy, + reportData)))); + }); var $author$project$Pages$Utils$viewSelectListInput = F7( function (language, currentValue, options, toStringFunc, setMsg, transId, inputClass) { var transFunc = A2( @@ -13421,102 +13562,6 @@ var $author$project$Pages$Utils$viewSelectListInput = F7( inputClass, $elm$core$Maybe$Just('')); }); -var $author$project$Pages$Completion$View$customApplyFilters = F4( - function (startDate, limitDate, resolveTakenByFunc, mTakenBy) { - return $elm$core$List$filter( - function (encounter) { - var takenByCondition = A2( - $elm$core$Maybe$withDefault, - true, - A2( - $elm$core$Maybe$map, - function (takenBy) { - return _Utils_eq( - resolveTakenByFunc(encounter), - takenBy); - }, - mTakenBy)); - return (!_Utils_eq( - A2($justinmimbs$date$Date$compare, encounter.startDate, startDate), - $elm$core$Basics$LT)) && ((!_Utils_eq( - A2($justinmimbs$date$Date$compare, encounter.startDate, limitDate), - $elm$core$Basics$GT)) && takenByCondition); - }); - }); -var $author$project$Translate$StandardPediatricVisit = {$: 'StandardPediatricVisit'}; -var $author$project$Translate$WellChildActivity = function (a) { - return {$: 'WellChildActivity', a: a}; -}; -var $author$project$Pages$Completion$Utils$allWellChildActivities = _List_fromArray( - [$author$project$Backend$Completion$Model$WellChildAlbendazole, $author$project$Backend$Completion$Model$WellChildBCGImmunisation, $author$project$Backend$Completion$Model$WellChildCaring, $author$project$Backend$Completion$Model$WellChildContributingFactors, $author$project$Backend$Completion$Model$WellChildDTPImmunisation, $author$project$Backend$Completion$Model$WellChildECD, $author$project$Backend$Completion$Model$WellChildFeeding, $author$project$Backend$Completion$Model$WellChildFollowUp, $author$project$Backend$Completion$Model$WellChildFoodSecurity, $author$project$Backend$Completion$Model$WellChildHeadCircumference, $author$project$Backend$Completion$Model$WellChildHealthEducation, $author$project$Backend$Completion$Model$WellChildHeight, $author$project$Backend$Completion$Model$WellChildHygiene, $author$project$Backend$Completion$Model$WellChildIPVImmunisation, $author$project$Backend$Completion$Model$WellChildMebendezole, $author$project$Backend$Completion$Model$WellChildMRImmunisation, $author$project$Backend$Completion$Model$WellChildMUAC, $author$project$Backend$Completion$Model$WellChildNCDA, $author$project$Backend$Completion$Model$WellChildNextVisit, $author$project$Backend$Completion$Model$WellChildNutrition, $author$project$Backend$Completion$Model$WellChildOPVImmunisation, $author$project$Backend$Completion$Model$WellChildPCV13Immunisation, $author$project$Backend$Completion$Model$WellChildPhoto, $author$project$Backend$Completion$Model$WellChildPregnancySummary, $author$project$Backend$Completion$Model$WellChildRotarixImmunisation, $author$project$Backend$Completion$Model$WellChildSendToHC, $author$project$Backend$Completion$Model$WellChildSymptomsReview, $author$project$Backend$Completion$Model$WellChildVitals, $author$project$Backend$Completion$Model$WellChildVitaminA, $author$project$Backend$Completion$Model$WellChildWeight, $author$project$Backend$Completion$Model$WellChildHPVImmunisation, $author$project$Backend$Completion$Model$WellChildDTPSAImmunisation]); -var $author$project$Pages$Completion$View$generateWellChildReportData = F2( - function (language, records) { - return { - captions: $author$project$Pages$Completion$View$generateCaptionsList(language), - heading: A2($author$project$Translate$translate, language, $author$project$Translate$StandardPediatricVisit), - rows: A2( - $elm$core$List$map, - function (activity) { - var expected = A3( - $author$project$Pages$Completion$View$countOccurrences, - A2( - $elm$core$Basics$composeR, - function ($) { - return $.completion; - }, - function ($) { - return $.expectedActivities; - }), - activity, - records); - var completed = A3( - $author$project$Pages$Completion$View$countOccurrences, - A2( - $elm$core$Basics$composeR, - function ($) { - return $.completion; - }, - function ($) { - return $.completedActivities; - }), - activity, - records); - return _List_fromArray( - [ - A2( - $author$project$Translate$translate, - language, - $author$project$Translate$WellChildActivity(activity)), - $elm$core$String$fromInt(expected), - $elm$core$String$fromInt(completed), - A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) - ]); - }, - $author$project$Pages$Completion$Utils$allWellChildActivities) - }; - }); -var $author$project$Pages$Completion$View$viewWellChildReport = F5( - function (language, startDate, limitDate, mTakenBy, reportData) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('report well-child') - ]), - $author$project$Pages$Components$View$viewMetricsResultsTable( - A2( - $author$project$Pages$Completion$View$generateWellChildReportData, - language, - A5( - $author$project$Pages$Completion$View$customApplyFilters, - startDate, - limitDate, - function (encounter) { - return _Utils_eq(encounter.encounterType, $author$project$Backend$Completion$Model$PediatricCare) ? $author$project$Backend$Completion$Model$TakenByNurse : $author$project$Backend$Completion$Model$TakenByCHW; - }, - mTakenBy, - reportData)))); - }); var $author$project$Pages$Utils$viewCustomLabel = F4( function (language, translationId, suffix, class_) { return A2( @@ -13614,34 +13659,44 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( ])) ])); }(); - var takenByInput = function () { - var options = A2( - $elm$core$List$map, - function (option) { - return _Utils_Tuple2( - A2( - $author$project$Translate$translate, + var takenByInput = A2( + $elm$core$Maybe$withDefault, + $author$project$Gizra$Html$emptyNode, + A2( + $elm$core$Maybe$map, + function (reportType) { + if (_Utils_eq(reportType, $author$project$Pages$Completion$Model$ReportNewbornExam)) { + return $author$project$Gizra$Html$emptyNode; + } else { + var options = A2( + $elm$core$List$map, + function (option) { + return _Utils_Tuple2( + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$TakenBy(option)), + option); + }, + _List_fromArray( + [$author$project$Backend$Completion$Model$TakenByNurse, $author$project$Backend$Completion$Model$TakenByCHW])); + return $elm_community$maybe_extra$Maybe$Extra$isJust(model.reportType) ? A4( + $author$project$Pages$Utils$wrapSelectListInput, language, - $author$project$Translate$TakenBy(option)), - option); + $author$project$Translate$TakenByLabel, + false, + A6( + $author$project$Pages$Utils$viewCustomSelectListInput, + model.takenBy, + options, + $author$project$Backend$Completion$Utils$takenByToString, + $author$project$Pages$Completion$Model$SetTakenBy, + 'select-input', + $elm$core$Maybe$Just( + A2($author$project$Translate$translate, language, $author$project$Translate$Any)))) : $author$project$Gizra$Html$emptyNode; + } }, - _List_fromArray( - [$author$project$Backend$Completion$Model$TakenByNurse, $author$project$Backend$Completion$Model$TakenByCHW])); - return $elm_community$maybe_extra$Maybe$Extra$isJust(model.reportType) ? A4( - $author$project$Pages$Utils$wrapSelectListInput, - language, - $author$project$Translate$TakenByLabel, - false, - A6( - $author$project$Pages$Utils$viewCustomSelectListInput, - model.takenBy, - options, - $author$project$Backend$Completion$Utils$takenByToString, - $author$project$Pages$Completion$Model$SetTakenBy, - 'select-input', - $elm$core$Maybe$Just( - A2($author$project$Translate$translate, language, $author$project$Translate$Any)))) : $author$project$Gizra$Html$emptyNode; - }(); + model.reportType)); var dateInputs = A2( $elm$core$Maybe$withDefault, _List_Nil, @@ -13741,13 +13796,13 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( case 'ReportAcuteIllness': return A5($author$project$Pages$Completion$View$viewAcuteIllnessReport, language, startDate, limitDate, model.takenBy, data.acuteIllnessData); case 'ReportNewbornExam': - return A5($author$project$Pages$Completion$View$viewWellChildReport, language, startDate, limitDate, model.takenBy, newbornExamData); + return A5($author$project$Pages$Completion$View$viewNewbornExamReport, language, startDate, limitDate, model.takenBy, newbornExamData); case 'ReportNutritionGroup': return A5($author$project$Pages$Completion$View$viewNutritionGroupReport, language, startDate, limitDate, model.takenBy, data.nutritionGroupData); case 'ReportNutritionIndividual': return A5($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, model.takenBy, data.nutritionIndividualData); default: - return A5($author$project$Pages$Completion$View$viewWellChildReport, language, startDate, limitDate, model.takenBy, spvData); + return A6($author$project$Pages$Completion$View$viewSPVReport, language, data.site, startDate, limitDate, model.takenBy, spvData); } }), model.reportType, diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 43a7b43d78..6c425f0746 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3835,14 +3835,18 @@ function hedley_reports_well_child_generate_expected_initial_activities(array $e // Activities that are shown at any type of encounter, // unconditionally. Existed with initial launch of the feature. $expected = [ - 'well_child_height', 'well_child_nutrition', 'well_child_photo', 'well_child_weight', ]; + $is_newborn_exam = $encounter_type == 'newborn-exam'; + if (!$is_newborn_exam) { + $expected[] = 'well_child_height'; + } + // MUAC is taken starting age of 6 months. - if (isset($age_in_months) && $age_in_months >= 6) { + if (!$is_newborn_exam && isset($age_in_months) && $age_in_months >= 6) { $expected[] = 'well_child_muac'; } @@ -3851,7 +3855,7 @@ function hedley_reports_well_child_generate_expected_initial_activities(array $e $expected[] = 'well_child_head_circumference'; } - if ($encounter_type == 'newborn-exam') { + if ($is_newborn_exam) { $expected[] = 'well_child_pregnancy_summary'; return $expected; } @@ -3894,6 +3898,7 @@ function hedley_reports_well_child_add_immunisation_activities(array $encounter_ } function hedley_reports_well_child_get_expected_immunisation_activites(array $encounter_data, DateTime $birth_date_obj, $gender, $mode) { + $encounter_type = $encounter_data['encounter_type']; $vaccination_progress = $encounter_data['vaccination_progress']; // History mode looks at vaccination status excluding vaccinations done at // current encounter. Progress mode includes vaccinations done at current @@ -3906,35 +3911,37 @@ function hedley_reports_well_child_get_expected_immunisation_activites(array $en $age_in_days = $interval->days; $possible_immunisations = ['bcg', 'opv']; - if ($age_in_days >= (6 * 7)) { - $possible_immunisations = array_merge($possible_immunisations, ['dtp', 'pcv13', 'rotarix']); - } - if ($age_in_days >= (14 * 7)) { - $possible_immunisations[] = 'ipv'; - } - if ($age_in_days >= (36 * 7)) { - $possible_immunisations[] = 'mr'; - } + if ($encounter_type != 'newborn-exam') { + if ($age_in_days >= (6 * 7)) { + $possible_immunisations = array_merge($possible_immunisations, ['dtp', 'pcv13', 'rotarix']); + } + if ($age_in_days >= (14 * 7)) { + $possible_immunisations[] = 'ipv'; + } + if ($age_in_days >= (36 * 7)) { + $possible_immunisations[] = 'mr'; + } - $site = variable_get('hedley_general_site_name', ''); - if ($site == 'burundi') { - // All 3 dosed of DTP were given, it has passed at least 28 days since - // third dose, and, child is at last 18 months old. - if (!empty($vaccination_progress['dtp']['dose-3'])) { - $age_in_months = ($interval->y * 12) + $interval->m; - $third_dose_date_obj = new DateTime($vaccination_progress['dtp']['dose-3']); - $interval = $start_date_obj->diff($third_dose_date_obj); - $days_since_third_dose = $interval->days; - - if ($age_in_months >= 18 && $days_since_third_dose >= 28) { - $possible_immunisations[] = 'dtp_sa'; + $site = variable_get('hedley_general_site_name', ''); + if ($site == 'burundi') { + // All 3 dosed of DTP were given, it has passed at least 28 days since + // third dose, and, child is at last 18 months old. + if (!empty($vaccination_progress['dtp']['dose-3'])) { + $age_in_months = ($interval->y * 12) + $interval->m; + $third_dose_date_obj = new DateTime($vaccination_progress['dtp']['dose-3']); + $interval = $start_date_obj->diff($third_dose_date_obj); + $days_since_third_dose = $interval->days; + + if ($age_in_months >= 18 && $days_since_third_dose >= 28) { + $possible_immunisations[] = 'dtp_sa'; + } } } - } - else { - $age_in_years = $interval->y; - if ($age_in_years >= 12 && $gender == 'female') { - $possible_immunisations[] = 'hpv'; + else { + $age_in_years = $interval->y; + if ($age_in_years >= 12 && $gender == 'female') { + $possible_immunisations[] = 'hpv'; + } } } From c93f4dd7b79b39ccca75157d9276d1fc83974a6e Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 3 Sep 2024 22:20:58 +0300 Subject: [PATCH 085/185] Fixes [ci skip] --- client/src/elm/Pages/WellChild/Activity/Utils.elm | 2 +- server/elm/src/Pages/Completion/Utils.elm | 1 - server/hedley/modules/custom/hedley_general/js/elm-main.js | 2 +- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/client/src/elm/Pages/WellChild/Activity/Utils.elm b/client/src/elm/Pages/WellChild/Activity/Utils.elm index a03f1ab0b3..8c00440014 100644 --- a/client/src/elm/Pages/WellChild/Activity/Utils.elm +++ b/client/src/elm/Pages/WellChild/Activity/Utils.elm @@ -1416,7 +1416,7 @@ expectNextStepsTask currentDate zscores site features isChw assembled db task = TaskHealthEducation -> expectNextStepsTask currentDate zscores site features isChw assembled db TaskContributingFactors - || -- CHW should send patient to HC, if child is behind on vaccinatons. + || -- CHW should provide health education, if child is behind on vaccinatons. ((assembled.encounter.encounterType /= PediatricCare) && activityCompleted currentDate zscores site features isChw assembled db WellChildImmunisation && isBehindOnVaccinationsByProgress currentDate site assembled.participant.person db diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index dce81abc4d..bc7127016e 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -176,7 +176,6 @@ resolveSPVActivities site = , WellChildOPVImmunisation , WellChildPCV13Immunisation , WellChildPhoto - , WellChildPregnancySummary , WellChildRotarixImmunisation , WellChildSendToHC , WellChildSymptomsReview diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 2a699d4e89..ba7c87617e 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -13504,7 +13504,7 @@ var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F5( var $author$project$Pages$Completion$Utils$resolveSPVActivities = function (site) { return _Utils_ap( _List_fromArray( - [$author$project$Backend$Completion$Model$WellChildAlbendazole, $author$project$Backend$Completion$Model$WellChildBCGImmunisation, $author$project$Backend$Completion$Model$WellChildCaring, $author$project$Backend$Completion$Model$WellChildContributingFactors, $author$project$Backend$Completion$Model$WellChildDTPImmunisation, $author$project$Backend$Completion$Model$WellChildFeeding, $author$project$Backend$Completion$Model$WellChildFollowUp, $author$project$Backend$Completion$Model$WellChildFoodSecurity, $author$project$Backend$Completion$Model$WellChildHeadCircumference, $author$project$Backend$Completion$Model$WellChildHealthEducation, $author$project$Backend$Completion$Model$WellChildHeight, $author$project$Backend$Completion$Model$WellChildHygiene, $author$project$Backend$Completion$Model$WellChildIPVImmunisation, $author$project$Backend$Completion$Model$WellChildMebendezole, $author$project$Backend$Completion$Model$WellChildMRImmunisation, $author$project$Backend$Completion$Model$WellChildMUAC, $author$project$Backend$Completion$Model$WellChildNCDA, $author$project$Backend$Completion$Model$WellChildNutrition, $author$project$Backend$Completion$Model$WellChildOPVImmunisation, $author$project$Backend$Completion$Model$WellChildPCV13Immunisation, $author$project$Backend$Completion$Model$WellChildPhoto, $author$project$Backend$Completion$Model$WellChildPregnancySummary, $author$project$Backend$Completion$Model$WellChildRotarixImmunisation, $author$project$Backend$Completion$Model$WellChildSendToHC, $author$project$Backend$Completion$Model$WellChildSymptomsReview, $author$project$Backend$Completion$Model$WellChildVitals, $author$project$Backend$Completion$Model$WellChildVitaminA, $author$project$Backend$Completion$Model$WellChildWeight]), + [$author$project$Backend$Completion$Model$WellChildAlbendazole, $author$project$Backend$Completion$Model$WellChildBCGImmunisation, $author$project$Backend$Completion$Model$WellChildCaring, $author$project$Backend$Completion$Model$WellChildContributingFactors, $author$project$Backend$Completion$Model$WellChildDTPImmunisation, $author$project$Backend$Completion$Model$WellChildFeeding, $author$project$Backend$Completion$Model$WellChildFollowUp, $author$project$Backend$Completion$Model$WellChildFoodSecurity, $author$project$Backend$Completion$Model$WellChildHeadCircumference, $author$project$Backend$Completion$Model$WellChildHealthEducation, $author$project$Backend$Completion$Model$WellChildHeight, $author$project$Backend$Completion$Model$WellChildHygiene, $author$project$Backend$Completion$Model$WellChildIPVImmunisation, $author$project$Backend$Completion$Model$WellChildMebendezole, $author$project$Backend$Completion$Model$WellChildMRImmunisation, $author$project$Backend$Completion$Model$WellChildMUAC, $author$project$Backend$Completion$Model$WellChildNCDA, $author$project$Backend$Completion$Model$WellChildNutrition, $author$project$Backend$Completion$Model$WellChildOPVImmunisation, $author$project$Backend$Completion$Model$WellChildPCV13Immunisation, $author$project$Backend$Completion$Model$WellChildPhoto, $author$project$Backend$Completion$Model$WellChildRotarixImmunisation, $author$project$Backend$Completion$Model$WellChildSendToHC, $author$project$Backend$Completion$Model$WellChildSymptomsReview, $author$project$Backend$Completion$Model$WellChildVitals, $author$project$Backend$Completion$Model$WellChildVitaminA, $author$project$Backend$Completion$Model$WellChildWeight]), function () { if (site.$ === 'SiteBurundi') { return _List_fromArray( diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 6c425f0746..361a82f206 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4168,7 +4168,7 @@ function hedley_reports_well_child_add_next_steps_activities(array $encounter_da ] ); } - else { + elseif ($encounter_data['encounter_type'] != 'pediatric-care') { $immunisation_activities_completed = TRUE; foreach ($expected as $activity) { if (hedley_reports_ends_with($activity, '_immunisation')) { From ef352f3bcebbc844f38940bdafbda25642e7a0ac Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 12:15:40 +0300 Subject: [PATCH 086/185] Docs --- .../hedley_reports/hedley_reports.module | 245 ++++++++++++++++-- 1 file changed, 222 insertions(+), 23 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 361a82f206..816da44e78 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3549,6 +3549,25 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e } } +/** + * Generates vaccination progress data for a well-child encounter. + * + * This function processes immunization data from previous and current + * encounters, generating vaccination history and progress data for + * well-child encounters. It merges this data with child scoreboard data + * to produce comprehensive vaccination progress information. + * + * @param int $person_id + * The ID of the person (child) whose vaccination data is being + * processed. + * @param array $encounter_data + * An associative array containing details of the current encounter, + * including previous encounter data and measurements. + * + * @return array + * An array containing merged vaccination progress data, with history + * and progress for the child. + */ function hedley_reports_well_child_generate_vaccination_progress_data($person_id, array $encounter_data) { $previous_encounters_data = $encounter_data['previous_encounters_data']; @@ -3598,7 +3617,22 @@ function hedley_reports_well_child_generate_vaccination_progress_data($person_id ]; } -function hedley_reports_well_child_generate_vaccination_progress_data_regular($immunisations_from_encounters) { +/** + * Generates regular vaccination progress data from encounters. + * + * Processes immunization data from a series of encounters to create + * a structured array of vaccination doses and dates, ensuring the data + * is sorted and aligned. + * + * @param array $immunisations_from_encounters + * An associative array containing immunization data from previous + * encounters, indexed by immunization type. + * + * @return array + * A structured array of vaccination doses and dates, organized by + * immunization type. + */ +function hedley_reports_well_child_generate_vaccination_progress_data_regular(array $immunisations_from_encounters) { $return = []; $immunisations_by_type = []; foreach ($immunisations_from_encounters as $immunisation_type => $immunisations) { @@ -3648,8 +3682,8 @@ function hedley_reports_well_child_generate_vaccination_progress_data_regular($i // Make sure number of doses matches the number of dates. if ($total_doses != $total_dates) { $common_size = min($total_doses, $total_dates); - $immunisations_by_type[$type]['doses'] = array_slice( $immunisations_by_type[$type]['doses'], 0, $common_size); - $immunisations_by_type[$type]['dates'] = array_slice( $immunisations_by_type[$type]['dates'], 0, $common_size); + $immunisations_by_type[$type]['doses'] = array_slice($immunisations_by_type[$type]['doses'], 0, $common_size); + $immunisations_by_type[$type]['dates'] = array_slice($immunisations_by_type[$type]['dates'], 0, $common_size); } foreach ($immunisations_by_type[$type]['doses'] as $index => $dose) { @@ -3661,6 +3695,24 @@ function hedley_reports_well_child_generate_vaccination_progress_data_regular($i return $return; } +/** + * Generates vaccination progress data based on child scoreboard data. + * + * Retrieves immunization data for a child from the child scoreboard, + * considering all encounters up to the current well-child encounter, + * and returns structured vaccination progress data. + * + * @param int $person_id + * The ID of the person (child) whose scoreboard data is being + * processed. + * @param DateTime $well_child_encounter_start_date_obj + * The DateTime object representing the start date of the current + * well-child encounter. + * + * @return array + * A structured array of vaccination doses and dates, organized by + * immunization type, based on child scoreboard encounters. + */ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_scoreboard($person_id, DateTime $well_child_encounter_start_date_obj) { $return = []; if (empty($person_id)) { @@ -3776,8 +3828,8 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s // Make sure number of doses matches the number of dates. if ($total_doses != $total_dates) { $common_size = min($total_doses, $total_dates); - $immunisations_by_type[$type]['doses'] = array_slice( $immunisations_by_type[$type]['doses'], 0, $common_size); - $immunisations_by_type[$type]['dates'] = array_slice( $immunisations_by_type[$type]['dates'], 0, $common_size); + $immunisations_by_type[$type]['doses'] = array_slice($immunisations_by_type[$type]['doses'], 0, $common_size); + $immunisations_by_type[$type]['dates'] = array_slice($immunisations_by_type[$type]['dates'], 0, $common_size); } foreach ($immunisations_by_type[$type]['doses'] as $index => $dose) { @@ -3789,7 +3841,25 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s return $return; } -function hedley_reports_well_child_merge_vaccination_progress_data($immunisation_types, $first, $second) { +/** + * Merges vaccination progress data from different sources. + * + * Combines vaccination progress data from two sources (e.g., history + * and child scoreboard data) into a single structured array, organized + * by immunization type. + * + * @param array $immunisation_types + * An array of immunization types to be merged. + * @param array $first + * The first set of vaccination progress data. + * @param array $second + * The second set of vaccination progress data. + * + * @return array + * A merged array of vaccination progress data, organized by + * immunization type. + */ +function hedley_reports_well_child_merge_vaccination_progress_data(array $immunisation_types, array $first, array $second) { $return = []; foreach ($immunisation_types as $type) { $common_type = hedley_reports_drop_preffix_and_suffix($type, 'well_child_', '_immunisation'); @@ -3890,13 +3960,44 @@ function hedley_reports_well_child_generate_expected_initial_activities(array $e return $expected; } +/** + * Adds Immunisation activities as expected, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_well_child_add_immunisation_activities(array $encounter_data, DateTime $birth_date_obj, $gender, array &$expected) { - $expected_by_history = hedley_reports_well_child_get_expected_immunisation_activites($encounter_data, $birth_date_obj, $gender,'history'); + $expected_by_history = hedley_reports_well_child_get_expected_immunisation_activites($encounter_data, $birth_date_obj, $gender, 'history'); foreach ($expected_by_history as $activity) { $expected[] = $activity; } } +/** + * Generates a list of expected well-child immunization activities. + * + * This function determines the expected immunization activities for a + * well-child based on the child's encounter data, age, gender, and mode. + * It considers the vaccination history or progress, the site of the encounter, + * and other factors such as the child's age in days. It then generates a list + * of immunizations that should be expected during the encounter. + * + * @param array $encounter_data + * An associative array containing details of the encounter, including + * encounter type, vaccination progress, vaccination history, and start date. + * @param DateTime $birth_date_obj + * The DateTime object representing the child's birth date. + * @param string $gender + * The gender of the child, used to determine gender-specific immunizations. + * @param string $mode + * The mode of operation, either 'history' or 'progress', which determines + * whether to consider the vaccination history or progress. + * + * @return array + * An array of expected immunization activities based on the encounter data. + */ function hedley_reports_well_child_get_expected_immunisation_activites(array $encounter_data, DateTime $birth_date_obj, $gender, $mode) { $encounter_type = $encounter_data['encounter_type']; $vaccination_progress = $encounter_data['vaccination_progress']; @@ -3913,7 +4014,10 @@ function hedley_reports_well_child_get_expected_immunisation_activites(array $en $possible_immunisations = ['bcg', 'opv']; if ($encounter_type != 'newborn-exam') { if ($age_in_days >= (6 * 7)) { - $possible_immunisations = array_merge($possible_immunisations, ['dtp', 'pcv13', 'rotarix']); + $possible_immunisations = array_merge( + $possible_immunisations, + ['dtp', 'pcv13', 'rotarix'] + ); } if ($age_in_days >= (14 * 7)) { $possible_immunisations[] = 'ipv'; @@ -3995,7 +4099,24 @@ function hedley_reports_well_child_get_expected_immunisation_activites(array $en return $expected; } -function hedley_reports_well_child_initial_opv_administered($encounter_data, $birth_date_obj) { +/** + * Determines if the initial OPV dose was administered within 14 days of birth. + * + * This function checks whether the first dose of OPV (Oral Polio Vaccine) was + * given within 14 days of the child's birth, based on the vaccination progress + * data. + * + * @param array $encounter_data + * An associative array containing details of the encounter, including + * vaccination progress. + * @param DateTime $birth_date_obj + * The DateTime object representing the child's birth date. + * + * @return bool + * TRUE if the initial OPV dose was administered within 14 days of birth, + * FALSE otherwise. + */ +function hedley_reports_well_child_initial_opv_administered(array $encounter_data, DateTime $birth_date_obj) { $vaccination_progress = $encounter_data['vaccination_progress']; if (empty($vaccination_progress['opv']) || empty($vaccination_progress['opv']['dose-1'])) { @@ -4008,6 +4129,23 @@ function hedley_reports_well_child_initial_opv_administered($encounter_data, $bi return $interval->days < 14; } +/** + * Retrieves the last expected dose for a specific vaccine type. + * + * This function returns the last dose that should be administered for a given + * initial vaccine type, based on the child's vaccination history and whether + * the OPV dose was administered. + * + * @param string $immunisation_type + * The type of immunization (e.g., 'bcg', 'opv', 'dtp'). + * @param bool $initial_opv_administered + * Indicates whether the initial OPV dose was administered within 14 days + * of birth. + * + * @return string|bool + * The last expected dose for the vaccine (e.g., 'dose-1', 'dose-3'), + * or FALSE, if the immunization type is not recognized. + */ function hedley_reports_well_child_get_last_dose_for_vaccine($immunisation_type, $initial_opv_administered) { switch ($immunisation_type) { case 'bcg': @@ -4031,6 +4169,22 @@ function hedley_reports_well_child_get_last_dose_for_vaccine($immunisation_type, return FALSE; } +/** + * Retrieves the interval between doses for a specific vaccine type. + * + * This function returns the time interval that should be observed between + * doses for a given vaccine, taking into account the site where the encounter + * occurs. + * + * @param string $immunisation_type + * The type of immunization (e.g., 'bcg', 'opv', 'dtp'). + * @param string $site + * The site name, which may affect the interval for certain vaccines. + * + * @return string|bool + * A string representing the interval between doses (e.g., '+4 weeks', + * '+9 months'), or FALSE if the immunization type is not recognized. + */ function hedley_reports_well_child_get_interval_for_vaccine($immunisation_type, $site) { switch ($immunisation_type) { case 'bcg': @@ -4054,6 +4208,14 @@ function hedley_reports_well_child_get_interval_for_vaccine($immunisation_type, return FALSE; } +/** + * Adds Medication activities as expected, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_well_child_add_medication_activities(array $encounter_data, array &$expected) { $age_in_months = $encounter_data['age_in_months']; $start_date_obj = $encounter_data['start_date_obj']; @@ -4099,6 +4261,24 @@ function hedley_reports_well_child_add_medication_activities(array $encounter_da } } +/** + * Generates a list of expected well-child medication activities based on age. + * + * This function determines the expected medication activities for a well-child + * visit based on the child's age in months. The activities may differ based + * on the site name, which is retrieved from the configuration. + * + * The function checks age ranges and adds specific activities to the + * expected list. If the site is "burundi", different rules are applied compared + * to the default site. + * + * @param int $age_in_months + * The age of the child in months. + * + * @return array + * An array of expected medication activities for the child based on their + * age. Returns an empty array if the age is not provided. + */ function hedley_reports_well_child_genrate_expected_medication_activities_by_age($age_in_months) { if (!isset($age_in_months)) { return []; @@ -4120,19 +4300,19 @@ function hedley_reports_well_child_genrate_expected_medication_activities_by_age break; default: - // 6 years to 12 years. - if ($age_in_months >= (6 * 12) && $age_in_months < (12 * 12)) { - $expected[] = 'well_child_albendazole'; - } + // 6 years to 12 years. + if ($age_in_months >= (6 * 12) && $age_in_months < (12 * 12)) { + $expected[] = 'well_child_albendazole'; + } // 1 year to 6 years. if ($age_in_months >= 12 && $age_in_months < (6 * 12)) { - $expected[] = 'well_child_mebendezole'; - } + $expected[] = 'well_child_mebendezole'; + } // 6 months to 12 years. if ($age_in_months >= 6 && $age_in_months < (6 * 12)) { - $expected[] = 'well_child_vitamin_a'; - } - break; + $expected[] = 'well_child_vitamin_a'; + } + break; } return $expected; @@ -4180,7 +4360,7 @@ function hedley_reports_well_child_add_next_steps_activities(array $encounter_da } if ($immunisation_activities_completed) { - $expected_by_progress = hedley_reports_well_child_get_expected_immunisation_activites($encounter_data, $birth_date_obj, $gender,'progress'); + $expected_by_progress = hedley_reports_well_child_get_expected_immunisation_activites($encounter_data, $birth_date_obj, $gender, 'progress'); if (!empty($expected_by_progress)) { // Immunisation activity completed, but child is still behind // on vaccinations. @@ -4237,7 +4417,7 @@ function hedley_reports_resolve_age_for_individual_encounter($encounter, DateTim $birth_date_obj = new DateTime($birth_date); $interval = $start_date_obj->diff($birth_date_obj); - switch($unit) { + switch ($unit) { case 'day': return $interval->days; @@ -4270,7 +4450,7 @@ function hedley_reports_resolve_age_for_individual_encounter($encounter, DateTim * @return bool * True, if NCDA activity is expected. */ -function hedley_reports_ncda_expected($age_in_months, $start_date_obj) { +function hedley_reports_ncda_expected($age_in_months, DateTime $start_date_obj) { $ncda_enabled = variable_get('hedley_admin_feature_ncda_enabled', FALSE); $ncda_launch_date = '2023-11-20'; $ncda_launch_date_obj = new DateTime($ncda_launch_date); @@ -4359,14 +4539,33 @@ function hedley_reports_ends_with($haystack, $needle) { return substr($haystack, -$length) === $needle; } +/** + * Removes the specified prefix and suffix from a string, if both are present. + * + * This function checks if the given string starts with the specified prefix + * and ends with the specified suffix. If both conditions are met, the function + * returns the substring that remains after removing the prefix and suffix. + * If either the prefix or suffix is not found, the original string is returned. + * + * @param string $string + * The input string from which the prefix and suffix will be removed. + * @param string $pref + * The prefix to be removed from the start of the string. + * @param string $suff + * The suffix to be removed from the end of the string. + * + * @return string + * The string without the specified prefix and suffix, or the original + * string if the prefix or suffix is not found. + */ function hedley_reports_drop_preffix_and_suffix(string $string, string $pref, string $suff) { if (strpos($string, $pref) !== 0 || substr($string, -strlen($suff)) !== $suff) { return $string; } - // Extract the part between the prefix and suffix + // Extract the part between the prefix and suffix. $start = strlen($pref); $length = strlen($string) - $start - strlen($suff); return substr($string, $start, $length); -} \ No newline at end of file +} From 86259f59f2b513a03de3b0b0f0da764218840e1b Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 12:57:09 +0300 Subject: [PATCH 087/185] Add reports data field to Home Visit encounter CT [ci skip] --- ...edley_schedule.features.field_instance.inc | 77 ++++++++++++++++- .../hedley_schedule/hedley_schedule.info | 2 + .../hedley_schedule.strongarm.inc | 86 +++++++++---------- 3 files changed, 118 insertions(+), 47 deletions(-) diff --git a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc index 5888c9116b..79cc04248d 100644 --- a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc +++ b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc @@ -123,6 +123,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -224,6 +225,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -308,6 +310,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -352,6 +355,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -436,6 +440,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -517,6 +522,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -657,6 +663,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -701,6 +708,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -745,6 +753,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -789,6 +798,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -870,6 +880,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1078,12 +1089,53 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => -1, + 'weight' => 2, + ), + ); + + // Exported field_instance: 'node-home_visit_encounter-field_reports_data'. + $field_instances['node-home_visit_encounter-field_reports_data'] = array( + 'bundle' => 'home_visit_encounter', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 4, + ), + 'teaser' => array( + 'label' => 'above', + 'settings' => array(), + 'type' => 'hidden', + 'weight' => 0, + ), + ), + 'entity_type' => 'node', + 'field_name' => 'field_reports_data', + 'label' => 'Completion Data', + 'required' => 0, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'rows' => 5, + ), + 'type' => 'text_textarea', + 'weight' => 3, ), ); @@ -1139,7 +1191,7 @@ function hedley_schedule_field_default_field_instances() { 'year_range' => '-3:+3', ), 'type' => 'date_select', - 'weight' => -3, + 'weight' => 1, ), ); @@ -1178,12 +1230,13 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => 3, + 'weight' => 5, ), ); @@ -1223,7 +1276,7 @@ function hedley_schedule_field_default_field_instances() { 'size' => 60, ), 'type' => 'text_textfield', - 'weight' => 1, + 'weight' => 4, ), ); @@ -1513,6 +1566,7 @@ function hedley_schedule_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1634,6 +1688,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1678,6 +1733,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1762,6 +1818,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1860,6 +1917,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1945,6 +2003,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2083,6 +2142,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2167,6 +2227,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2252,6 +2313,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2395,6 +2457,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2439,6 +2502,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2524,6 +2588,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2662,6 +2727,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2746,6 +2812,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2890,6 +2957,7 @@ Used to track location where pregnancies were completed.', 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2992,6 +3060,7 @@ Used to track location where pregnancies were completed.', t('Between what dates is the child expected to participate in PMTCT encounters?'); t('Child'); t('Closed (DEPRECATED)'); + t('Completion Data'); t('Date Measured'); t('Date concluded'); t('Deleted'); diff --git a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.info b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.info index e51a30fbb6..22a358c514 100644 --- a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.info +++ b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.info @@ -10,6 +10,7 @@ dependencies[] = hedley_activity dependencies[] = hedley_device dependencies[] = hedley_health_center dependencies[] = hedley_ncd +dependencies[] = hedley_reports dependencies[] = list dependencies[] = node dependencies[] = options @@ -66,6 +67,7 @@ features[field_instance][] = node-counseling_topic-field_kinyarwanda_title features[field_instance][] = node-counseling_topic-field_uuid features[field_instance][] = node-counseling_topic-title_field features[field_instance][] = node-home_visit_encounter-field_individual_participant +features[field_instance][] = node-home_visit_encounter-field_reports_data features[field_instance][] = node-home_visit_encounter-field_scheduled_date features[field_instance][] = node-home_visit_encounter-field_shards features[field_instance][] = node-home_visit_encounter-field_uuid diff --git a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc index b8ed14a601..2df4e8cf03 100644 --- a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc +++ b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc @@ -205,15 +205,15 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__acute_illness_encounter'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__acute_illness_encounter'] = $strongarm; @@ -222,15 +222,15 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__clinic'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__clinic'] = $strongarm; @@ -239,15 +239,15 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__counseling_schedule'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__counseling_schedule'] = $strongarm; @@ -256,15 +256,15 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__counseling_session'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__counseling_session'] = $strongarm; @@ -273,15 +273,15 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__counseling_topic'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__counseling_topic'] = $strongarm; @@ -290,15 +290,15 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__home_visit_encounter'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( - 'weight' => '-5', + 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__home_visit_encounter'] = $strongarm; @@ -307,28 +307,28 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__individual_participant'; $strongarm->value = array( - 'view_modes' => array( - 'teaser' => array( - 'custom_settings' => TRUE, + 'extra_fields' => array( + 'display' => array(), + 'form' => array( + 'title' => array( + 'weight' => '0', + ), ), + ), + 'view_modes' => array( 'full' => array( 'custom_settings' => FALSE, ), 'rss' => array( 'custom_settings' => FALSE, ), + 'teaser' => array( + 'custom_settings' => TRUE, + ), 'token' => array( 'custom_settings' => FALSE, ), ), - 'extra_fields' => array( - 'form' => array( - 'title' => array( - 'weight' => '0', - ), - ), - 'display' => array(), - ), ); $export['field_bundle_settings_node__individual_participant'] = $strongarm; @@ -337,15 +337,15 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_encounter'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_encounter'] = $strongarm; @@ -354,15 +354,15 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__nutrition_encounter'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__nutrition_encounter'] = $strongarm; @@ -371,28 +371,28 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__pmtct_participant'; $strongarm->value = array( - 'view_modes' => array( - 'teaser' => array( - 'custom_settings' => TRUE, + 'extra_fields' => array( + 'display' => array(), + 'form' => array( + 'title' => array( + 'weight' => '0', + ), ), + ), + 'view_modes' => array( 'full' => array( 'custom_settings' => FALSE, ), 'rss' => array( 'custom_settings' => FALSE, ), + 'teaser' => array( + 'custom_settings' => TRUE, + ), 'token' => array( 'custom_settings' => FALSE, ), ), - 'extra_fields' => array( - 'form' => array( - 'title' => array( - 'weight' => '0', - ), - ), - 'display' => array(), - ), ); $export['field_bundle_settings_node__pmtct_participant'] = $strongarm; @@ -401,15 +401,15 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__prenatal_encounter'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '1', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__prenatal_encounter'] = $strongarm; @@ -418,15 +418,15 @@ function hedley_schedule_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__session'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__session'] = $strongarm; From 6f93f66d21eef74e3701305c29c0d0d69b26b7b7 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 13:02:43 +0300 Subject: [PATCH 088/185] Add script [ci skip] --- .../completion-generate-home-visit-data.php | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php new file mode 100644 index 0000000000..7026c81ddd --- /dev/null +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php @@ -0,0 +1,90 @@ +entityCondition('entity_type', 'node') + ->entityCondition('bundle', $type) + ->propertyCondition('status', NODE_PUBLISHED); + +if ($exclude_set) { + $base_query->addTag('exclude_set_reports_data'); +} + +$count_query = clone $base_query; +$count_query->propertyCondition('nid', $nid, '>'); +$count = $count_query->count()->execute(); + +if ($count == 0) { + drush_print("There are no nodes of type $type in DB."); + exit; +} + +$total = 0; +drush_print("$count nodes of type $type located."); + +while (TRUE) { + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + $completion_data = hedley_reports_generate_completion_data_for_nutrition_individual_encounter($node); + $node->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); + node_save($node); + $total++; + + $memory = round(memory_get_usage() / 1048576); + if ($memory >= $memory_limit) { + drush_print(dt('Stopped before out of memory. Start process from the node ID @nid', ['@nid' => $nid])); + return; + } + } + + $memory = round(memory_get_usage() / 1048576); + drush_print("Calculated so far: $total, Memory: $memory"); + + // Free up memory. + drupal_static_reset(); + + $nid = end($ids); +} + +drush_print("Done! Completion data calculated for $total encounters."); From 03ab7a399be3f29aa1220f14c9cb609098a51063 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 13:02:57 +0300 Subject: [PATCH 089/185] Backend logic [ci skip] --- .../hedley_reports/hedley_reports.module | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 816da44e78..cbffe7c05a 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4370,6 +4370,57 @@ function hedley_reports_well_child_add_next_steps_activities(array $encounter_da } } +/** + * Generates completion data for Home Visit encounter. + * + * @param object $encounter + * The encounter node object. + * + * @return array + * An array containing the completion data for given encounter. + */ +function hedley_reports_generate_completion_data_for_home_visit_encounter($encounter) { + // To reduce memory usage, mapping measurement types as single characters. + $mapping = [ + 'nutrition_caring' => 'a', + 'nutrition_feeding' => 'b', + 'nutrition_food_security' => 'c', + 'nutrition_hygiene' => 'd', + ]; + + // Activities that are always taken during encounter. + $expected = array_keys($mapping); + + // Resolve encounter start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + + // Loading all measurements that belong to encounter. + $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); + + if (empty($measurements_ids)) { + $completion = hedley_reports_generate_completion_result($expected, [], $mapping); + + return [ + 'start_date' => $start_date, + 'completion' => $completion, + ]; + } + + // Ordering measurements by type. + $measurements_by_type = []; + $measurements = node_load_multiple($measurements_ids); + foreach ($measurements as $measurement) { + $measurements_by_type[$measurement->type] = $measurement; + } + + $completion = hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping); + + return [ + 'start_date' => $start_date, + 'completion' => $completion, + ]; +} + /** * Resolve the age in months for patient at the time of a specific encounter. * From bd7f41e3afda9b1dfcba43c9d0b5e40a0c2d141c Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 13:04:45 +0300 Subject: [PATCH 090/185] A fix [ci skip] --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index cbffe7c05a..2279f3dbc1 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2136,7 +2136,7 @@ function hedley_reports_generate_completion_data_for_nutrition_individual_encoun } // Try to resolve age in months at a time encounter was performed. - $age_in_months = hedley_reports_resolve_age_in_months_for_individual_encounter($$encounter, $start_date_obj); + $age_in_months = hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj); // MUAC is taken starting age of 6 months. if (isset($age_in_months) && $age_in_months >= 6) { From af13fd1a860b86df9ca86403319badc94b5674a4 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 13:15:05 +0300 Subject: [PATCH 091/185] Extend loaded data [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 2279f3dbc1..25c6c9675a 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2021,6 +2021,7 @@ function hedley_reports_generate_completion_results_data($health_center) { $data = [ 'acute_illness' => [], + 'home_visit' => [], 'nutrition_individual' => [], 'nutrition_group' => [], 'well_child' => [], @@ -2063,6 +2064,10 @@ function hedley_reports_generate_completion_results_data($health_center) { $data['nutrition_group'][] = json_decode($json_data); break; + case 'home_visit_encounter': + $data['home_visit'][] = json_decode($json_data); + break; + case 'nutrition_encounter': $data['nutrition_individual'][] = json_decode($json_data); break; From 7e42ddb4c47de37ad0d1e4575dd6912dc194660a Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 13:17:16 +0300 Subject: [PATCH 092/185] Rename script [ci skip] --- ...e-datasets.php => completion-recalculate-large-datasets.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename server/hedley/modules/custom/hedley_reports/scripts/{recalculate-completion-large-datasets.php => completion-recalculate-large-datasets.php} (94%) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/recalculate-completion-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php similarity index 94% rename from server/hedley/modules/custom/hedley_reports/scripts/recalculate-completion-large-datasets.php rename to server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php index 0ae954e7ce..fdc44dd305 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/recalculate-completion-large-datasets.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php @@ -10,7 +10,7 @@ * - Health center. * * Execution: drush scr - * profiles/hedley/modules/custom/hedley_reports/scripts/recalculate-completion-large-datasets.php. + * profiles/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php. */ if (!drupal_is_cli()) { From d338d553804ee36803d68aa50fadaedc1e8c42ed Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 13:23:07 +0300 Subject: [PATCH 093/185] Decode and store data on client [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 1 + server/elm/src/Backend/Completion/Model.elm | 8 +++ server/elm/src/Backend/Completion/Utils.elm | 19 +++++++ .../custom/hedley_general/js/elm-main.js | 50 ++++++++++++++----- 4 files changed, 65 insertions(+), 13 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index eb1cb6de3b..3f5db9f5eb 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -20,6 +20,7 @@ decodeCompletionData = |> required "entity_name" string |> required "entity_type" decodeSelectedEntity |> requiredAt [ "results", "acute_illness" ] (list (decodeEncounterData acuteIllnessActivityFromMapping)) + |> requiredAt [ "results", "home_visit" ] (list (decodeEncounterData homeVisitActivityFromMapping)) |> requiredAt [ "results", "nutrition_individual" ] (list (decodeEncounterData nutritionChildActivityFromMapping)) |> requiredAt [ "results", "nutrition_group" ] (list (decodeNutritionGroupEncounterData nutritionMotherActivityFromMapping nutritionChildActivityFromMapping)) diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index 43ab9bc9bc..a90a24a0ec 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -12,6 +12,7 @@ type alias CompletionData = , entityName : String , entityType : SelectedEntity , acuteIllnessData : List (EncounterData AcuteIllnessActivity) + , homeVisitData : List (EncounterData HomeVisitActivity) , nutritionIndividualData : List (EncounterData NutritionChildActivity) , nutritionGroupData : List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) , wellChildData : List WellChildEncounterData @@ -83,6 +84,13 @@ type AcuteIllnessActivity | AcuteIllnessOngoingTreatment +type HomeVisitActivity + = HomeVisitCaring + | HomeVisitFeeding + | HomeVisitFoodSecurity + | HomeVisitHygiene + + type NutritionChildActivity = NutritionHeight | NutritionNutrition diff --git a/server/elm/src/Backend/Completion/Utils.elm b/server/elm/src/Backend/Completion/Utils.elm index 0a6c7ada50..a2c85d6b18 100644 --- a/server/elm/src/Backend/Completion/Utils.elm +++ b/server/elm/src/Backend/Completion/Utils.elm @@ -238,6 +238,25 @@ wellChildActivityFromMapping mapped = Nothing +homeVisitActivityFromMapping : String -> Maybe HomeVisitActivity +homeVisitActivityFromMapping mapped = + case mapped of + "a" -> + Just HomeVisitCaring + + "b" -> + Just HomeVisitFeeding + + "c" -> + Just HomeVisitFoodSecurity + + "d" -> + Just HomeVisitHygiene + + _ -> + Nothing + + takenByToString : TakenBy -> String takenByToString value = case value of diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index ba7c87617e..09f7403dd8 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -6848,9 +6848,9 @@ var $author$project$Backend$Types$BackendReturn = F4( function (model, cmd, error, appMsgs) { return {appMsgs: appMsgs, cmd: cmd, error: error, model: model}; }); -var $author$project$Backend$Completion$Model$CompletionData = F7( - function (site, entityName, entityType, acuteIllnessData, nutritionIndividualData, nutritionGroupData, wellChildData) { - return {acuteIllnessData: acuteIllnessData, entityName: entityName, entityType: entityType, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site, wellChildData: wellChildData}; +var $author$project$Backend$Completion$Model$CompletionData = F8( + function (site, entityName, entityType, acuteIllnessData, homeVisitData, nutritionIndividualData, nutritionGroupData, wellChildData) { + return {acuteIllnessData: acuteIllnessData, entityName: entityName, entityType: entityType, homeVisitData: homeVisitData, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site, wellChildData: wellChildData}; }); var $author$project$Backend$Completion$Model$AcuteIllnessAcuteFindings = {$: 'AcuteIllnessAcuteFindings'}; var $author$project$Backend$Completion$Model$AcuteIllnessCOVIDTesting = {$: 'AcuteIllnessCOVIDTesting'}; @@ -8063,6 +8063,24 @@ var $author$project$Backend$Completion$Decoder$decodeWellChildEncounterData = A3 'start_date', $author$project$Gizra$NominalDate$decodeYYYYMMDD, $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$WellChildEncounterData)))); +var $author$project$Backend$Completion$Model$HomeVisitCaring = {$: 'HomeVisitCaring'}; +var $author$project$Backend$Completion$Model$HomeVisitFeeding = {$: 'HomeVisitFeeding'}; +var $author$project$Backend$Completion$Model$HomeVisitFoodSecurity = {$: 'HomeVisitFoodSecurity'}; +var $author$project$Backend$Completion$Model$HomeVisitHygiene = {$: 'HomeVisitHygiene'}; +var $author$project$Backend$Completion$Utils$homeVisitActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$HomeVisitCaring); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$HomeVisitFeeding); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$HomeVisitFoodSecurity); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$HomeVisitHygiene); + default: + return $elm$core$Maybe$Nothing; + } +}; var $elm$json$Json$Decode$list = _Json_decodeList; var $author$project$Backend$Completion$Model$NutritionChildFbf = {$: 'NutritionChildFbf'}; var $author$project$Backend$Completion$Model$NutritionContributingFactors = {$: 'NutritionContributingFactors'}; @@ -8149,22 +8167,28 @@ var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'acute_illness']), + ['results', 'home_visit']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$homeVisitActivityFromMapping)), A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_type', - $author$project$Backend$Completion$Decoder$decodeSelectedEntity, + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, + _List_fromArray( + ['results', 'acute_illness']), + $elm$json$Json$Decode$list( + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_name', - $elm$json$Json$Decode$string, + 'entity_type', + $author$project$Backend$Completion$Decoder$decodeSelectedEntity, A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'site', - $author$project$Backend$Decoder$decodeSite, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData)))))))); + 'entity_name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData))))))))); var $author$project$Backend$Completion$Update$update = F3( function (currentDate, msg, model) { var value = msg.a; From e5e82102b0ad074ae9f400a0cfd24627bd1de8bf Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 13:44:56 +0300 Subject: [PATCH 094/185] View report --- server/elm/src/Backend/Completion/Decoder.elm | 2 +- server/elm/src/Pages/Completion/Model.elm | 1 + server/elm/src/Pages/Completion/Utils.elm | 53 ++--- server/elm/src/Pages/Completion/View.elm | 48 +++- server/elm/src/Translate.elm | 59 ++++- .../modules/custom/hedley_general/css/elm.css | 3 + .../custom/hedley_general/js/elm-main.js | 221 ++++++++++++++---- 7 files changed, 286 insertions(+), 101 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index 3f5db9f5eb..c0f316f2ed 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -48,7 +48,7 @@ decodeEncounterData : (String -> Maybe activity) -> Decoder (EncounterData activ decodeEncounterData activityFromString = succeed EncounterData |> required "start_date" decodeYYYYMMDD - |> required "taken_by" (nullable (decodeWithFallback TakenByUnknown decodeTakenBy)) + |> optional "taken_by" (nullable (decodeWithFallback TakenByUnknown decodeTakenBy)) Nothing |> required "completion" (decodeActivitiesCompletionData activityFromString) diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index 3163a35397..10382d2f33 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -28,6 +28,7 @@ emptyModel = type ReportType = ReportAcuteIllness + | ReportHomeVisit | ReportNewbornExam | ReportNutritionGroup | ReportNutritionIndividual diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index bc7127016e..988bd5c14b 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -4,6 +4,7 @@ import App.Types exposing (Site(..)) import Backend.Completion.Model exposing ( AcuteIllnessActivity(..) + , HomeVisitActivity(..) , NutritionChildActivity(..) , NutritionMotherActivity(..) , TakenBy(..) @@ -18,6 +19,9 @@ reportTypeToString reportType = ReportAcuteIllness -> "acute-illness" + ReportHomeVisit -> + "home-visit" + ReportNewbornExam -> "newborn-exam" @@ -37,6 +41,9 @@ reportTypeFromString reportType = "acute-illness" -> Just ReportAcuteIllness + "home-visit" -> + Just ReportHomeVisit + "newborn-exam" -> Just ReportNewbornExam @@ -109,43 +116,6 @@ allNutritionMotherGroupActivities = ] -allWellChildActivities : List WellChildActivity -allWellChildActivities = - [ WellChildAlbendazole - , WellChildBCGImmunisation - , WellChildCaring - , WellChildContributingFactors - , WellChildDTPImmunisation - , WellChildECD - , WellChildFeeding - , WellChildFollowUp - , WellChildFoodSecurity - , WellChildHeadCircumference - , WellChildHealthEducation - , WellChildHeight - , WellChildHygiene - , WellChildIPVImmunisation - , WellChildMebendezole - , WellChildMRImmunisation - , WellChildMUAC - , WellChildNCDA - , WellChildNextVisit - , WellChildNutrition - , WellChildOPVImmunisation - , WellChildPCV13Immunisation - , WellChildPhoto - , WellChildPregnancySummary - , WellChildRotarixImmunisation - , WellChildSendToHC - , WellChildSymptomsReview - , WellChildVitals - , WellChildVitaminA - , WellChildWeight - , WellChildHPVImmunisation - , WellChildDTPSAImmunisation - ] - - resolveSPVActivities : Site -> List WellChildActivity resolveSPVActivities site = [ WellChildAlbendazole @@ -206,3 +176,12 @@ newbornExamActivities = , WellChildSendToHC , WellChildWeight ] + + +allHomeVisitActivities : List HomeVisitActivity +allHomeVisitActivities = + [ HomeVisitCaring + , HomeVisitFeeding + , HomeVisitFoodSecurity + , HomeVisitHygiene + ] diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index d9eb67a322..d1738b8739 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -7,6 +7,7 @@ import Backend.Completion.Model ( AcuteIllnessActivity(..) , CompletionData , EncounterData + , HomeVisitActivity(..) , NutritionChildActivity(..) , NutritionGroupEncounterData , NutritionMotherActivity(..) @@ -79,7 +80,13 @@ viewCompletionData language currentDate themePath data model = takenByInput = Maybe.map (\reportType -> - if reportType == ReportNewbornExam then + if + List.member reportType + [ -- Exclusively CHW encounters. + ReportHomeVisit + , ReportNewbornExam + ] + then emptyNode else @@ -189,6 +196,9 @@ viewCompletionData language currentDate themePath data model = ReportAcuteIllness -> viewAcuteIllnessReport language startDate limitDate model.takenBy data.acuteIllnessData + ReportHomeVisit -> + viewHomeVisitReport language startDate limitDate model.takenBy data.homeVisitData + ReportNewbornExam -> viewNewbornExamReport language startDate limitDate model.takenBy newbornExamData @@ -212,6 +222,7 @@ viewCompletionData language currentDate themePath data model = [ viewSelectListInput language model.reportType [ ReportAcuteIllness + , ReportHomeVisit , ReportNewbornExam , ReportNutritionGroup , ReportNutritionIndividual @@ -291,6 +302,14 @@ viewNewbornExamReport language startDate limitDate mTakenBy reportData = |> div [ class "report well-child" ] +viewHomeVisitReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData HomeVisitActivity) -> Html Msg +viewHomeVisitReport language startDate limitDate mTakenBy reportData = + applyFilters startDate limitDate mTakenBy reportData + |> generateHomeVisitReportData language + |> viewMetricsResultsTable + |> div [ class "report home-visit" ] + + applyFilters : NominalDate -> NominalDate @@ -465,6 +484,33 @@ generateWellChildReportData language labelTransId activities records = } +generateHomeVisitReportData : + Language + -> List (EncounterData HomeVisitActivity) + -> MetricsResultsTableData +generateHomeVisitReportData language records = + { heading = translate language Translate.HomeVisit + , captions = generateCaptionsList language + , rows = + List.map + (\activity -> + let + expected = + countOccurrences (.completion >> .expectedActivities) activity records + + completed = + countOccurrences (.completion >> .completedActivities) activity records + in + [ translate language <| Translate.HomeVisitActivity activity + , String.fromInt expected + , String.fromInt completed + , calcualtePercentage completed expected + ] + ) + allHomeVisitActivities + } + + -- Helper functions. diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 6e8ec60296..2d3f29e8b0 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -8,6 +8,7 @@ import App.Types exposing (Language(..)) import Backend.Completion.Model exposing ( AcuteIllnessActivity(..) + , HomeVisitActivity(..) , NutritionChildActivity(..) , NutritionMotherActivity(..) , TakenBy(..) @@ -72,6 +73,7 @@ type TranslationId | ANCNewborn | ANCTotal | Any + | Caring | CBNP | Cell | ChildScorecard @@ -90,14 +92,18 @@ type TranslationId | EncounterType | Expected | FBF + | Feeding | Female + | FoodSecurity | GenerateReport | Global | HC | HealthCenter | HIV | HomeVisit + | HomeVisitActivity HomeVisitActivity | HttpError StringIdHttpError + | Hygiene | Impacted | IncidenceByMonthOneVisitOrMore | IncidenceByMonthTwoVisitsOrMore @@ -516,6 +522,9 @@ translationSet transId = Pages.Completion.Model.ReportAcuteIllness -> translationSet AcuteIllness + Pages.Completion.Model.ReportHomeVisit -> + translationSet HomeVisit + Pages.Completion.Model.ReportNewbornExam -> translationSet NewbornExam @@ -540,6 +549,12 @@ translationSet transId = , kirundi = Nothing } + Caring -> + { english = "Caring" + , kinyarwanda = Nothing + , kirundi = Nothing + } + Cell -> { english = "Cell" , kinyarwanda = Nothing @@ -606,6 +621,12 @@ translationSet transId = , kirundi = Nothing } + Feeding -> + { english = "Feeding" + , kinyarwanda = Nothing + , kirundi = Nothing + } + Female -> { english = "Female" , kinyarwanda = Nothing @@ -618,6 +639,12 @@ translationSet transId = , kirundi = Nothing } + FoodSecurity -> + { english = "Food Security" + , kinyarwanda = Nothing + , kirundi = Nothing + } + GenerateReport -> { english = "Generate Report" , kinyarwanda = Nothing @@ -648,9 +675,26 @@ translationSet transId = , kirundi = Nothing } + HomeVisitActivity activity -> + case activity of + HomeVisitCaring -> + translationSet Caring + + HomeVisitFeeding -> + translationSet Feeding + + HomeVisitFoodSecurity -> + translationSet FoodSecurity + + HomeVisitHygiene -> + translationSet Hygiene + HttpError val -> translateHttpError val + Hygiene -> + translationSet Hygiene + Impacted -> { english = "Impacted (2+ visits)" , kinyarwanda = Nothing @@ -1476,10 +1520,7 @@ translationSet transId = } WellChildCaring -> - { english = "Caring" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Caring WellChildContributingFactors -> { english = "Contributing Factors" @@ -1500,10 +1541,7 @@ translationSet transId = } WellChildFeeding -> - { english = "Feeding" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Feeding WellChildFollowUp -> { english = "Follow Up" @@ -1512,10 +1550,7 @@ translationSet transId = } WellChildFoodSecurity -> - { english = "Food Security" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet FoodSecurity WellChildHeadCircumference -> { english = "Head Circumference" diff --git a/server/hedley/modules/custom/hedley_general/css/elm.css b/server/hedley/modules/custom/hedley_general/css/elm.css index c8c6e724d8..e7b32d919c 100644 --- a/server/hedley/modules/custom/hedley_general/css/elm.css +++ b/server/hedley/modules/custom/hedley_general/css/elm.css @@ -395,6 +395,7 @@ body.admin-menu #page-wrapper #header { } .page-content .inputs .report.acute-illness .table .row .item.row-label, +.page-content .inputs .report.home-visit .table .row .item.row-label, .page-content .inputs .report.nutrition-group .table .row .item.row-label, .page-content .inputs .report.nutrition-individual .table .row .item.row-label, .page-content .inputs .report.well-child .table .row .item.row-label { @@ -403,6 +404,8 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.acute-illness .table .row .item.heading, .page-content .inputs .report.acute-illness .table .row .item.value, +.page-content .inputs .report.home-visit .table .row .item.heading, +.page-content .inputs .report.home-visit .table .row .item.value, .page-content .inputs .report.nutrition-group .table .row .item.heading, .page-content .inputs .report.nutrition-group .table .row .item.value, .page-content .inputs .report.nutrition-individual .table .row .item.heading, diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 09f7403dd8..f28ed4dc7c 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5826,6 +5826,7 @@ var $elm_community$maybe_extra$Maybe$Extra$or = F2( } }); var $author$project$Pages$Completion$Model$ReportAcuteIllness = {$: 'ReportAcuteIllness'}; +var $author$project$Pages$Completion$Model$ReportHomeVisit = {$: 'ReportHomeVisit'}; var $author$project$Pages$Completion$Model$ReportNewbornExam = {$: 'ReportNewbornExam'}; var $author$project$Pages$Completion$Model$ReportNutritionGroup = {$: 'ReportNutritionGroup'}; var $author$project$Pages$Completion$Model$ReportNutritionIndividual = {$: 'ReportNutritionIndividual'}; @@ -5834,6 +5835,8 @@ var $author$project$Pages$Completion$Utils$reportTypeFromString = function (repo switch (reportType) { case 'acute-illness': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportAcuteIllness); + case 'home-visit': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportHomeVisit); case 'newborn-exam': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNewbornExam); case 'nutrition-group': @@ -7780,50 +7783,6 @@ var $elm$json$Json$Decode$nullable = function (decoder) { ])); }; var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom = $elm$json$Json$Decode$map2($elm$core$Basics$apR); -var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required = F3( - function (key, valDecoder, decoder) { - return A2( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom, - A2($elm$json$Json$Decode$field, key, valDecoder), - decoder); - }); -var $author$project$Backend$Completion$Decoder$decodeEncounterData = function (activityFromString) { - return A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'completion', - $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData(activityFromString), - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'taken_by', - $elm$json$Json$Decode$nullable( - A2($author$project$Backend$Decoder$decodeWithFallback, $author$project$Backend$Completion$Model$TakenByUnknown, $author$project$Backend$Completion$Decoder$decodeTakenBy)), - A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'start_date', - $author$project$Gizra$NominalDate$decodeYYYYMMDD, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EncounterData)))); -}; -var $author$project$Backend$Completion$Model$NutritionGroupEncounterData = F4( - function (startDate, takenBy, motherData, childrenData) { - return {childrenData: childrenData, motherData: motherData, startDate: startDate, takenBy: takenBy}; - }); -var $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionDataList = function (activityFromString) { - return $elm$json$Json$Decode$oneOf( - _List_fromArray( - [ - A2( - $elm$json$Json$Decode$andThen, - function (s) { - return $elm$json$Json$Decode$succeed( - A2( - $elm$core$List$filterMap, - $author$project$Backend$Completion$Decoder$activitiesCompletionDataFromString(activityFromString), - A2($elm$core$String$split, '$', s))); - }, - $elm$json$Json$Decode$string), - $elm$json$Json$Decode$succeed(_List_Nil) - ])); -}; var $elm$json$Json$Decode$decodeValue = _Json_run; var $elm$json$Json$Decode$value = _Json_decodeValue; var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalDecoder = F3( @@ -7869,6 +7828,51 @@ var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optional = F4( fallback), decoder); }); +var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required = F3( + function (key, valDecoder, decoder) { + return A2( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom, + A2($elm$json$Json$Decode$field, key, valDecoder), + decoder); + }); +var $author$project$Backend$Completion$Decoder$decodeEncounterData = function (activityFromString) { + return A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'completion', + $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionData(activityFromString), + A4( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optional, + 'taken_by', + $elm$json$Json$Decode$nullable( + A2($author$project$Backend$Decoder$decodeWithFallback, $author$project$Backend$Completion$Model$TakenByUnknown, $author$project$Backend$Completion$Decoder$decodeTakenBy)), + $elm$core$Maybe$Nothing, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'start_date', + $author$project$Gizra$NominalDate$decodeYYYYMMDD, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$EncounterData)))); +}; +var $author$project$Backend$Completion$Model$NutritionGroupEncounterData = F4( + function (startDate, takenBy, motherData, childrenData) { + return {childrenData: childrenData, motherData: motherData, startDate: startDate, takenBy: takenBy}; + }); +var $author$project$Backend$Completion$Decoder$decodeActivitiesCompletionDataList = function (activityFromString) { + return $elm$json$Json$Decode$oneOf( + _List_fromArray( + [ + A2( + $elm$json$Json$Decode$andThen, + function (s) { + return $elm$json$Json$Decode$succeed( + A2( + $elm$core$List$filterMap, + $author$project$Backend$Completion$Decoder$activitiesCompletionDataFromString(activityFromString), + A2($elm$core$String$split, '$', s))); + }, + $elm$json$Json$Decode$string), + $elm$json$Json$Decode$succeed(_List_Nil) + ])); +}; var $author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData = F2( function (motherActivityFromString, childActivityFromString) { return A3( @@ -9945,10 +9949,15 @@ var $author$project$Translate$HttpError = function (a) { }; var $elm$json$Json$Decode$decodeString = _Json_runOnString; var $author$project$Translate$AcuteIllness = {$: 'AcuteIllness'}; +var $author$project$Translate$Caring = {$: 'Caring'}; var $author$project$Translate$Cell = {$: 'Cell'}; var $author$project$Translate$District = {$: 'District'}; +var $author$project$Translate$Feeding = {$: 'Feeding'}; +var $author$project$Translate$FoodSecurity = {$: 'FoodSecurity'}; var $author$project$Translate$Global = {$: 'Global'}; var $author$project$Translate$HealthCenter = {$: 'HealthCenter'}; +var $author$project$Translate$HomeVisit = {$: 'HomeVisit'}; +var $author$project$Translate$Hygiene = {$: 'Hygiene'}; var $author$project$Translate$IncidenceByMonthOneVisitOrMore = {$: 'IncidenceByMonthOneVisitOrMore'}; var $author$project$Translate$IncidenceByMonthTwoVisitsOrMore = {$: 'IncidenceByMonthTwoVisitsOrMore'}; var $author$project$Translate$IncidenceByQuarterOneVisitOrMore = {$: 'IncidenceByQuarterOneVisitOrMore'}; @@ -10312,6 +10321,10 @@ var $author$project$Translate$translationSet = function (transId) { var $temp$transId = $author$project$Translate$AcuteIllness; transId = $temp$transId; continue translationSet; + case 'ReportHomeVisit': + var $temp$transId = $author$project$Translate$HomeVisit; + transId = $temp$transId; + continue translationSet; case 'ReportNewbornExam': var $temp$transId = $author$project$Translate$NewbornExam; transId = $temp$transId; @@ -10327,6 +10340,8 @@ var $author$project$Translate$translationSet = function (transId) { } case 'CBNP': return {english: 'CBNP', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Caring': + return {english: 'Caring', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Cell': return {english: 'Cell', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'ChildScorecard': @@ -10349,10 +10364,14 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Expected', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'FBF': return {english: 'FBF', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Feeding': + return {english: 'Feeding', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Female': return {english: 'Female', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Global': return {english: 'Global', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'FoodSecurity': + return {english: 'Food Security', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'GenerateReport': return {english: 'Generate Report', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'HC': @@ -10363,9 +10382,33 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'HIV', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'HomeVisit': return {english: 'Home Visit', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'HomeVisitActivity': + var activity = transId.a; + switch (activity.$) { + case 'HomeVisitCaring': + var $temp$transId = $author$project$Translate$Caring; + transId = $temp$transId; + continue translationSet; + case 'HomeVisitFeeding': + var $temp$transId = $author$project$Translate$Feeding; + transId = $temp$transId; + continue translationSet; + case 'HomeVisitFoodSecurity': + var $temp$transId = $author$project$Translate$FoodSecurity; + transId = $temp$transId; + continue translationSet; + default: + var $temp$transId = $author$project$Translate$Hygiene; + transId = $temp$transId; + continue translationSet; + } case 'HttpError': var val = transId.a; return $author$project$Translate$translateHttpError(val); + case 'Hygiene': + var $temp$transId = $author$project$Translate$Hygiene; + transId = $temp$transId; + continue translationSet; case 'Impacted': return {english: 'Impacted (2+ visits)', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'IncidenceByMonthOneVisitOrMore': @@ -10860,7 +10903,9 @@ var $author$project$Translate$translationSet = function (transId) { case 'WellChildBCGImmunisation': return {english: 'BCG Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildCaring': - return {english: 'Caring', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Caring; + transId = $temp$transId; + continue translationSet; case 'WellChildContributingFactors': return {english: 'Contributing Factors', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildDTPImmunisation': @@ -10868,11 +10913,15 @@ var $author$project$Translate$translationSet = function (transId) { case 'WellChildECD': return {english: 'ECD', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildFeeding': - return {english: 'Feeding', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Feeding; + transId = $temp$transId; + continue translationSet; case 'WellChildFollowUp': return {english: 'Follow Up', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildFoodSecurity': - return {english: 'Food Security', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$FoodSecurity; + transId = $temp$transId; + continue translationSet; case 'WellChildHeadCircumference': return {english: 'Head Circumference', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildHealthEducation': @@ -11815,6 +11864,8 @@ var $author$project$Pages$Completion$Utils$reportTypeToString = function (report switch (reportType.$) { case 'ReportAcuteIllness': return 'acute-illness'; + case 'ReportHomeVisit': + return 'home-visit'; case 'ReportNewbornExam': return 'newborn-exam'; case 'ReportNutritionGroup': @@ -13265,6 +13316,71 @@ var $author$project$Pages$Utils$viewCustomSelectListInput = F6( }, options))); }); +var $author$project$Translate$HomeVisitActivity = function (a) { + return {$: 'HomeVisitActivity', a: a}; +}; +var $author$project$Pages$Completion$Utils$allHomeVisitActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$HomeVisitCaring, $author$project$Backend$Completion$Model$HomeVisitFeeding, $author$project$Backend$Completion$Model$HomeVisitFoodSecurity, $author$project$Backend$Completion$Model$HomeVisitHygiene]); +var $author$project$Pages$Completion$View$generateHomeVisitReportData = F2( + function (language, records) { + return { + captions: $author$project$Pages$Completion$View$generateCaptionsList(language), + heading: A2($author$project$Translate$translate, language, $author$project$Translate$HomeVisit), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.expectedActivities; + }), + activity, + records); + var completed = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.completedActivities; + }), + activity, + records); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$HomeVisitActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) + ]); + }, + $author$project$Pages$Completion$Utils$allHomeVisitActivities) + }; + }); +var $author$project$Pages$Completion$View$viewHomeVisitReport = F5( + function (language, startDate, limitDate, mTakenBy, reportData) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report home-visit') + ]), + $author$project$Pages$Components$View$viewMetricsResultsTable( + A2( + $author$project$Pages$Completion$View$generateHomeVisitReportData, + language, + A4($author$project$Pages$Completion$View$applyFilters, startDate, limitDate, mTakenBy, reportData)))); + }); var $author$project$Gizra$Html$showMaybe = $elm$core$Maybe$withDefault($author$project$Gizra$Html$emptyNode); var $author$project$Utils$Html$viewCustomModal = function (extraClasses) { var classes = A2( @@ -13689,7 +13805,11 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( A2( $elm$core$Maybe$map, function (reportType) { - if (_Utils_eq(reportType, $author$project$Pages$Completion$Model$ReportNewbornExam)) { + if (A2( + $elm$core$List$member, + reportType, + _List_fromArray( + [$author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNewbornExam]))) { return $author$project$Gizra$Html$emptyNode; } else { var options = A2( @@ -13819,6 +13939,8 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( switch (reportType.$) { case 'ReportAcuteIllness': return A5($author$project$Pages$Completion$View$viewAcuteIllnessReport, language, startDate, limitDate, model.takenBy, data.acuteIllnessData); + case 'ReportHomeVisit': + return A5($author$project$Pages$Completion$View$viewHomeVisitReport, language, startDate, limitDate, model.takenBy, data.homeVisitData); case 'ReportNewbornExam': return A5($author$project$Pages$Completion$View$viewNewbornExamReport, language, startDate, limitDate, model.takenBy, newbornExamData); case 'ReportNutritionGroup': @@ -13860,7 +13982,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( language, model.reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportWellChild]), + [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportWellChild]), $author$project$Pages$Completion$Utils$reportTypeToString, $author$project$Pages$Completion$Model$SetReportType, $author$project$Translate$CompletionReportType, @@ -14395,7 +14517,6 @@ var $author$project$Translate$EncounterType = {$: 'EncounterType'}; var $author$project$Translate$Encounters = {$: 'Encounters'}; var $author$project$Translate$FBF = {$: 'FBF'}; var $author$project$Translate$HIV = {$: 'HIV'}; -var $author$project$Translate$HomeVisit = {$: 'HomeVisit'}; var $author$project$Translate$Individual = {$: 'Individual'}; var $author$project$Translate$NCD = {$: 'NCD'}; var $author$project$Translate$NutritionTotal = {$: 'NutritionTotal'}; From ac62f7afa1bb0b226170c67275fe9aee5b0b3ae9 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 14:10:00 +0300 Subject: [PATCH 095/185] Rename scripts [ci skip] --- ...tion-data.php => completion-generate-acute-illness-data.php} | 2 +- ...on-data.php => completion-generate-nutrition-group-data.php} | 2 +- ...ta.php => completion-generate-nutrition-individual-data.php} | 2 +- ...pletion-data.php => completion-generate-well-child-data.php} | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename server/hedley/modules/custom/hedley_reports/scripts/{generate-acute-illness-completion-data.php => completion-generate-acute-illness-data.php} (95%) rename server/hedley/modules/custom/hedley_reports/scripts/{generate-nutrition-group-completion-data.php => completion-generate-nutrition-group-data.php} (95%) rename server/hedley/modules/custom/hedley_reports/scripts/{generate-nutrition-individual-completion-data.php => completion-generate-nutrition-individual-data.php} (95%) rename server/hedley/modules/custom/hedley_reports/scripts/{generate-well-child-completion-data.php => completion-generate-well-child-data.php} (95%) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-acute-illness-data.php similarity index 95% rename from server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php rename to server/hedley/modules/custom/hedley_reports/scripts/completion-generate-acute-illness-data.php index c25fa9b5aa..df34d64389 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-acute-illness-data.php @@ -5,7 +5,7 @@ * Generates completion data for different types of encounters. * * Execution: drush scr - * profiles/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php. + * profiles/hedley/modules/custom/hedley_reports/scripts/completion-generate-acute-illness-data.php. */ if (!drupal_is_cli()) { diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-group-data.php similarity index 95% rename from server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php rename to server/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-group-data.php index 23528cad0d..f3adb17566 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-group-data.php @@ -5,7 +5,7 @@ * Generates completion data for Nutrition group encounters. * * Execution: drush scr - * profiles/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-group-completion-data.php. + * profiles/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-group-data.php. */ if (!drupal_is_cli()) { diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-individual-data.php similarity index 95% rename from server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php rename to server/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-individual-data.php index 386ebaecfe..057e8d8a1b 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-individual-data.php @@ -5,7 +5,7 @@ * Generates completion data for different types of encounters. * * Execution: drush scr - * profiles/hedley/modules/custom/hedley_reports/scripts/generate-nutrition-individual-completion-data.php. + * profiles/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-individual-data.php. */ if (!drupal_is_cli()) { diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php similarity index 95% rename from server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php rename to server/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php index 1146152fea..9a9afe93e1 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php @@ -5,7 +5,7 @@ * Generates completion data for different types of encounters. * * Execution: drush scr - * profiles/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php. + * profiles/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php. */ if (!drupal_is_cli()) { From a4a33a86da42293bbcf6112f9cd8a385b7d85af0 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 14:23:08 +0300 Subject: [PATCH 096/185] A fix [ci skip] --- .../scripts/completion-generate-home-visit-data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php index 7026c81ddd..1966df3233 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php @@ -66,7 +66,7 @@ $ids = array_keys($result['node']); $nodes = node_load_multiple($ids); foreach ($nodes as $node) { - $completion_data = hedley_reports_generate_completion_data_for_nutrition_individual_encounter($node); + $completion_data = hedley_reports_generate_completion_data_for_home_visit_encounter($node); $node->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); node_save($node); $total++; From 1293e573378da4ab12272946f19c8b4d2f2ad359 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 14:50:17 +0300 Subject: [PATCH 097/185] Another fix [ci skip] --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 25c6c9675a..f51b8a815f 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2001,6 +2001,8 @@ function hedley_reports_generate_completion_results_data($health_center) { 'acute_illness_encounter', // Nutrition Group data. 'attendance', + // Home Visit data. + 'home_visit_encounter', // Nutrition Individual data. 'nutrition_encounter', // Well Child data. From c2a71ece25d8f1dabc4fd0ceaa070ba2745e6a96 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 4 Sep 2024 16:02:26 +0300 Subject: [PATCH 098/185] Elminate empty encounters --- server/elm/src/Pages/Completion/View.elm | 48 +++++++++++-------- server/elm/src/Translate.elm | 10 ++-- .../custom/hedley_general/js/elm-main.js | 45 +++++++++++++---- 3 files changed, 70 insertions(+), 33 deletions(-) diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index d1738b8739..41254ff220 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -244,7 +244,8 @@ viewCompletionData language currentDate themePath data model = viewNutritionIndividualReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData NutritionChildActivity) -> Html Msg viewNutritionIndividualReport language startDate limitDate mTakenBy reportData = - applyFilters startDate limitDate mTakenBy reportData + eliminateEmptyEncounters reportData + |> applyFilters startDate limitDate mTakenBy |> generateNutritionIndividualReportData language |> viewMetricsResultsTable |> div [ class "report nutrition-individual" ] @@ -266,7 +267,8 @@ viewNutritionGroupReport language startDate limitDate mTakenBy reportData = viewAcuteIllnessReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData AcuteIllnessActivity) -> Html Msg viewAcuteIllnessReport language startDate limitDate mTakenBy reportData = - applyFilters startDate limitDate mTakenBy reportData + eliminateEmptyEncounters reportData + |> applyFilters startDate limitDate mTakenBy |> generateAcuteIllnessReportData language |> viewMetricsResultsTable |> div [ class "report acute-illness" ] @@ -274,17 +276,17 @@ viewAcuteIllnessReport language startDate limitDate mTakenBy reportData = viewSPVReport : Language -> Site -> NominalDate -> NominalDate -> Maybe TakenBy -> List WellChildEncounterData -> Html Msg viewSPVReport language site startDate limitDate mTakenBy reportData = - customApplyFilters startDate - limitDate - (\encounter -> - if encounter.encounterType == PediatricCare then - TakenByNurse - - else - TakenByCHW - ) - mTakenBy - reportData + eliminateEmptyEncounters reportData + |> customApplyFilters startDate + limitDate + (\encounter -> + if encounter.encounterType == PediatricCare then + TakenByNurse + + else + TakenByCHW + ) + mTakenBy |> generateWellChildReportData language Translate.StandardPediatricVisit (resolveSPVActivities site) |> viewMetricsResultsTable |> div [ class "report well-child" ] @@ -292,11 +294,11 @@ viewSPVReport language site startDate limitDate mTakenBy reportData = viewNewbornExamReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List WellChildEncounterData -> Html Msg viewNewbornExamReport language startDate limitDate mTakenBy reportData = - customApplyFilters startDate - limitDate - (always TakenByCHW) - mTakenBy - reportData + eliminateEmptyEncounters reportData + |> customApplyFilters startDate + limitDate + (always TakenByCHW) + mTakenBy |> generateWellChildReportData language Translate.NewbornExam newbornExamActivities |> viewMetricsResultsTable |> div [ class "report well-child" ] @@ -304,12 +306,20 @@ viewNewbornExamReport language startDate limitDate mTakenBy reportData = viewHomeVisitReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData HomeVisitActivity) -> Html Msg viewHomeVisitReport language startDate limitDate mTakenBy reportData = - applyFilters startDate limitDate mTakenBy reportData + eliminateEmptyEncounters reportData + |> applyFilters startDate limitDate mTakenBy |> generateHomeVisitReportData language |> viewMetricsResultsTable |> div [ class "report home-visit" ] +eliminateEmptyEncounters : + List { c | completion : { b | completedActivities : List a } } + -> List { c | completion : { b | completedActivities : List a } } +eliminateEmptyEncounters = + List.filter (.completion >> .completedActivities >> List.isEmpty >> not) + + applyFilters : NominalDate -> NominalDate diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 2d3f29e8b0..e9d356c792 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -693,7 +693,10 @@ translationSet transId = translateHttpError val Hygiene -> - translationSet Hygiene + { english = "Hygiene" + , kinyarwanda = Nothing + , kirundi = Nothing + } Impacted -> { english = "Impacted (2+ visits)" @@ -1571,10 +1574,7 @@ translationSet transId = } WellChildHygiene -> - { english = "Hygiene" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Hygiene WellChildIPVImmunisation -> { english = "IPV Immunisation" diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index f28ed4dc7c..17fd325e63 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -10406,9 +10406,7 @@ var $author$project$Translate$translationSet = function (transId) { var val = transId.a; return $author$project$Translate$translateHttpError(val); case 'Hygiene': - var $temp$transId = $author$project$Translate$Hygiene; - transId = $temp$transId; - continue translationSet; + return {english: 'Hygiene', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Impacted': return {english: 'Impacted (2+ visits)', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'IncidenceByMonthOneVisitOrMore': @@ -10929,7 +10927,9 @@ var $author$project$Translate$translationSet = function (transId) { case 'WellChildHeight': return {english: 'Height', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildHygiene': - return {english: 'Hygiene', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Hygiene; + transId = $temp$transId; + continue translationSet; case 'WellChildIPVImmunisation': return {english: 'IPV Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildMebendezole': @@ -11908,6 +11908,18 @@ var $author$project$Pages$Completion$View$applyFilters = F3( $elm$core$Basics$GT)) && takenByCondition); }); }); +var $author$project$Pages$Completion$View$eliminateEmptyEncounters = $elm$core$List$filter( + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completedActivities; + }, + A2($elm$core$Basics$composeR, $elm$core$List$isEmpty, $elm$core$Basics$not)))); var $author$project$Translate$AcuteIllnessActivity = function (a) { return {$: 'AcuteIllnessActivity', a: a}; }; @@ -12285,7 +12297,12 @@ var $author$project$Pages$Completion$View$viewAcuteIllnessReport = F5( A2( $author$project$Pages$Completion$View$generateAcuteIllnessReportData, language, - A4($author$project$Pages$Completion$View$applyFilters, startDate, limitDate, mTakenBy, reportData)))); + A4( + $author$project$Pages$Completion$View$applyFilters, + startDate, + limitDate, + mTakenBy, + $author$project$Pages$Completion$View$eliminateEmptyEncounters(reportData))))); }); var $author$project$Translate$Save = {$: 'Save'}; var $author$project$Translate$MonthLabel = {$: 'MonthLabel'}; @@ -13379,7 +13396,12 @@ var $author$project$Pages$Completion$View$viewHomeVisitReport = F5( A2( $author$project$Pages$Completion$View$generateHomeVisitReportData, language, - A4($author$project$Pages$Completion$View$applyFilters, startDate, limitDate, mTakenBy, reportData)))); + A4( + $author$project$Pages$Completion$View$applyFilters, + startDate, + limitDate, + mTakenBy, + $author$project$Pages$Completion$View$eliminateEmptyEncounters(reportData))))); }); var $author$project$Gizra$Html$showMaybe = $elm$core$Maybe$withDefault($author$project$Gizra$Html$emptyNode); var $author$project$Utils$Html$viewCustomModal = function (extraClasses) { @@ -13496,7 +13518,7 @@ var $author$project$Pages$Completion$View$viewNewbornExamReport = F5( limitDate, $elm$core$Basics$always($author$project$Backend$Completion$Model$TakenByCHW), mTakenBy, - reportData)))); + $author$project$Pages$Completion$View$eliminateEmptyEncounters(reportData))))); }); var $author$project$Translate$NutritionChildActivity = function (a) { return {$: 'NutritionChildActivity', a: a}; @@ -13639,7 +13661,12 @@ var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F5( A2( $author$project$Pages$Completion$View$generateNutritionIndividualReportData, language, - A4($author$project$Pages$Completion$View$applyFilters, startDate, limitDate, mTakenBy, reportData)))); + A4( + $author$project$Pages$Completion$View$applyFilters, + startDate, + limitDate, + mTakenBy, + $author$project$Pages$Completion$View$eliminateEmptyEncounters(reportData))))); }); var $author$project$Pages$Completion$Utils$resolveSPVActivities = function (site) { return _Utils_ap( @@ -13677,7 +13704,7 @@ var $author$project$Pages$Completion$View$viewSPVReport = F6( return _Utils_eq(encounter.encounterType, $author$project$Backend$Completion$Model$PediatricCare) ? $author$project$Backend$Completion$Model$TakenByNurse : $author$project$Backend$Completion$Model$TakenByCHW; }, mTakenBy, - reportData)))); + $author$project$Pages$Completion$View$eliminateEmptyEncounters(reportData))))); }); var $author$project$Pages$Utils$viewSelectListInput = F7( function (language, currentValue, options, toStringFunc, setMsg, transId, inputClass) { From 176a84b523f7743d251bad3dff4a30ac111f70ad Mon Sep 17 00:00:00 2001 From: Anatoly Vaitsman Date: Thu, 5 Sep 2024 11:39:44 +0300 Subject: [PATCH 099/185] Update server/hedley/modules/custom/hedley_reports/hedley_reports.module Co-authored-by: Aron Novak --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 816da44e78..0b37be6517 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4028,7 +4028,7 @@ function hedley_reports_well_child_get_expected_immunisation_activites(array $en $site = variable_get('hedley_general_site_name', ''); if ($site == 'burundi') { - // All 3 dosed of DTP were given, it has passed at least 28 days since + // All 3 doses of DTP were given, it has passed at least 28 days since // third dose, and, child is at last 18 months old. if (!empty($vaccination_progress['dtp']['dose-3'])) { $age_in_months = ($interval->y * 12) + $interval->m; From d5e1883c5352f387e5f722060763980db7a9d7e2 Mon Sep 17 00:00:00 2001 From: Anatoly Vaitsman Date: Thu, 5 Sep 2024 11:40:00 +0300 Subject: [PATCH 100/185] Update server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php Co-authored-by: Aron Novak --- .../scripts/generate-well-child-completion-data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php index 1146152fea..568f2b4a50 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php @@ -39,7 +39,7 @@ if ($count == 0) { drush_print("There are no nodes of type $type for well child encounters in DB."); - exit; + exit 1; } $total = 0; From 021dc7891152d0e192f4e6a4494c076d9ad1ae30 Mon Sep 17 00:00:00 2001 From: Anatoly Vaitsman Date: Thu, 5 Sep 2024 13:40:32 +0300 Subject: [PATCH 101/185] Update server/elm/src/Pages/Completion/Utils.elm Co-authored-by: Aron Novak --- server/elm/src/Pages/Completion/Utils.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index bc7127016e..2d8d9969ce 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -170,7 +170,7 @@ resolveSPVActivities site = , WellChildNCDA -- This is just an indication that next visit notice - -- was presented. Not showign it. + -- was presented. Not showing it. -- , WellChildNextVisit , WellChildNutrition , WellChildOPVImmunisation From 9ba86e3e08ed8cc51463648419712a8827b1a777 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 5 Sep 2024 13:53:34 +0300 Subject: [PATCH 102/185] Code review fixes --- .../modules/custom/hedley_reports/hedley_reports.module | 8 ++++---- .../scripts/generate-acute-illness-completion-data.php | 3 ++- .../scripts/generate-well-child-completion-data.php | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 816da44e78..27236d9456 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3687,7 +3687,7 @@ function hedley_reports_well_child_generate_vaccination_progress_data_regular(ar } foreach ($immunisations_by_type[$type]['doses'] as $index => $dose) { - $common_type = hedley_reports_drop_preffix_and_suffix($type, 'well_child_', '_immunisation'); + $common_type = hedley_reports_drop_prefix_and_sufix($type, 'well_child_', '_immunisation'); $return[$common_type][$dose] = $immunisations_by_type[$type]['dates'][$index]; } } @@ -3833,7 +3833,7 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s } foreach ($immunisations_by_type[$type]['doses'] as $index => $dose) { - $common_type = hedley_reports_drop_preffix_and_suffix($type, 'child_scoreboard_', '_iz'); + $common_type = hedley_reports_drop_prefix_and_sufix($type, 'child_scoreboard_', '_iz'); $return[$common_type][$dose] = $immunisations_by_type[$type]['dates'][$index]; } } @@ -3862,7 +3862,7 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s function hedley_reports_well_child_merge_vaccination_progress_data(array $immunisation_types, array $first, array $second) { $return = []; foreach ($immunisation_types as $type) { - $common_type = hedley_reports_drop_preffix_and_suffix($type, 'well_child_', '_immunisation'); + $common_type = hedley_reports_drop_prefix_and_sufix($type, 'well_child_', '_immunisation'); if (!empty($first[$common_type]) && !empty($second[$common_type])) { $return[$common_type] = array_merge($first[$common_type], $second[$common_type]); } @@ -4558,7 +4558,7 @@ function hedley_reports_ends_with($haystack, $needle) { * The string without the specified prefix and suffix, or the original * string if the prefix or suffix is not found. */ -function hedley_reports_drop_preffix_and_suffix(string $string, string $pref, string $suff) { +function hedley_reports_drop_prefix_and_sufix(string $string, string $pref, string $suff) { if (strpos($string, $pref) !== 0 || substr($string, -strlen($suff)) !== $suff) { return $string; } diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php index c25fa9b5aa..01f4304b57 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-acute-illness-completion-data.php @@ -31,7 +31,8 @@ ->entityCondition('entity_type', 'node') ->entityCondition('bundle', $type) ->fieldCondition('field_encounter_type', 'value', 'acute-illness') - ->propertyCondition('status', NODE_PUBLISHED); + ->propertyCondition('status', NODE_PUBLISHED) + ->addTag('exclude_deleted'); $count_query = clone $base_query; $count_query->propertyCondition('nid', $nid, '>'); diff --git a/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php b/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php index 1146152fea..10682a5c39 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/generate-well-child-completion-data.php @@ -31,7 +31,8 @@ ->entityCondition('entity_type', 'node') ->entityCondition('bundle', $type) ->fieldCondition('field_encounter_type', 'value', 'well-child') - ->propertyCondition('status', NODE_PUBLISHED); + ->propertyCondition('status', NODE_PUBLISHED) + ->addTag('exclude_deleted'); $count_query = clone $base_query; $count_query->propertyCondition('nid', $nid, '>'); From 0d2fae17ff3d12e9d870420f4ae9af7de21d2d86 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 5 Sep 2024 14:00:26 +0300 Subject: [PATCH 103/185] Fix spelling [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index bc9fd8d62f..1ad1d470fa 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3687,7 +3687,7 @@ function hedley_reports_well_child_generate_vaccination_progress_data_regular(ar } foreach ($immunisations_by_type[$type]['doses'] as $index => $dose) { - $common_type = hedley_reports_drop_prefix_and_sufix($type, 'well_child_', '_immunisation'); + $common_type = hedley_reports_drop_prefix_and_suffix($type, 'well_child_', '_immunisation'); $return[$common_type][$dose] = $immunisations_by_type[$type]['dates'][$index]; } } @@ -3833,7 +3833,7 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s } foreach ($immunisations_by_type[$type]['doses'] as $index => $dose) { - $common_type = hedley_reports_drop_prefix_and_sufix($type, 'child_scoreboard_', '_iz'); + $common_type = hedley_reports_drop_prefix_and_suffix($type, 'child_scoreboard_', '_iz'); $return[$common_type][$dose] = $immunisations_by_type[$type]['dates'][$index]; } } @@ -3862,7 +3862,7 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s function hedley_reports_well_child_merge_vaccination_progress_data(array $immunisation_types, array $first, array $second) { $return = []; foreach ($immunisation_types as $type) { - $common_type = hedley_reports_drop_prefix_and_sufix($type, 'well_child_', '_immunisation'); + $common_type = hedley_reports_drop_prefix_and_suffix($type, 'well_child_', '_immunisation'); if (!empty($first[$common_type]) && !empty($second[$common_type])) { $return[$common_type] = array_merge($first[$common_type], $second[$common_type]); } @@ -4558,7 +4558,7 @@ function hedley_reports_ends_with($haystack, $needle) { * The string without the specified prefix and suffix, or the original * string if the prefix or suffix is not found. */ -function hedley_reports_drop_prefix_and_sufix(string $string, string $pref, string $suff) { +function hedley_reports_drop_prefix_and_suffix(string $string, string $pref, string $suff) { if (strpos($string, $pref) !== 0 || substr($string, -strlen($suff)) !== $suff) { return $string; } From 5e03cc7a8c2715b80de52f79fa06c83472f8324f Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 5 Sep 2024 15:00:41 +0300 Subject: [PATCH 104/185] Fixes --- .../hedley_reports/hedley_reports.module | 105 ---------------- .../completion-generate-well-child-data.php | 2 +- .../completion-recalculate-large-datasets.php | 114 +++++++++++++++++- 3 files changed, 114 insertions(+), 107 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 973a6ab78e..915afd778f 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -1986,111 +1986,6 @@ function hedley_reports_build_completion_results_app($health_center = NULL) { return hedley_general_build_elm_app('completion-results', $data); } -/** - * Generate Completion report data which is stored on person nodes. - * - * @param int|null $health_center - * Health center ID. - * - * @return array - * An array of generated data. - */ -function hedley_reports_generate_completion_results_data($health_center) { - $bundles = [ - // Acute Illness data. - 'acute_illness_encounter', - // Nutrition Group data. - 'attendance', - // Home Visit data. - 'home_visit_encounter', - // Nutrition Individual data. - 'nutrition_encounter', - // Well Child data. - 'well_child_encounter', - ]; - - $base_query = new EntityFieldQuery(); - $base_query - ->entityCondition('entity_type', 'node') - ->entityCondition('bundle', $bundles, 'IN') - ->propertyCondition('status', NODE_PUBLISHED) - ->fieldCondition('field_reports_data', 'value', NULL, 'IS NOT NULL') - ->propertyOrderBy('nid'); - - if (!empty($health_center)) { - $base_query->fieldCondition('field_shards', 'target_id', $health_center); - } - - $data = [ - 'acute_illness' => [], - 'home_visit' => [], - 'nutrition_individual' => [], - 'nutrition_group' => [], - 'well_child' => [], - ]; - - $nid = 0; - $batch = 400; - while (TRUE) { - // Free up memory. - drupal_static_reset(); - - $query = clone $base_query; - if ($nid) { - $query->propertyCondition('nid', $nid, '>'); - } - - $result = $query - ->range(0, $batch) - ->execute(); - - if (empty($result['node'])) { - // No more items left. - break; - } - - $ids = array_keys($result['node']); - $nodes = node_load_multiple($ids); - foreach ($nodes as $node) { - $json_data = $node->field_reports_data[LANGUAGE_NONE][0]['value']; - if (empty($json_data)) { - continue; - } - - switch ($node->type) { - case 'acute_illness_encounter': - $data['acute_illness'][] = json_decode($json_data); - break; - - case 'attendance': - $data['nutrition_group'][] = json_decode($json_data); - break; - - case 'home_visit_encounter': - $data['home_visit'][] = json_decode($json_data); - break; - - case 'nutrition_encounter': - $data['nutrition_individual'][] = json_decode($json_data); - break; - - case 'well_child_encounter': - $data['well_child'][] = json_decode($json_data); - break; - } - - // Explicitly unset large variables after use for memory optimization. - unset($json_data); - } - - $nid = end($ids); - // Explicitly unset large variables after use for memory optimization. - unset($nodes); - } - - return $data; -} - /** * Generates completion data for an individual nutrition encounter. * diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php index 367ca9bf87..1540385f17 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php @@ -40,7 +40,7 @@ if ($count == 0) { drush_print("There are no nodes of type $type for well child encounters in DB."); - exit 1; + exit; } $total = 0; diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php index fdc44dd305..c4a58bd76a 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php @@ -49,7 +49,7 @@ function create_or_update_results_data_node($scope, $health_center = NULL) { $before = time(); drush_print('Loading data...'); - $data = hedley_reports_generate_completion_results_data($health_center); + $data = generate_completion_results_data($health_center); hedley_reports_create_or_update_results_data_node($data, 'completion', $scope, NULL, NULL, $health_center); $after = time(); // Free up memory. @@ -59,3 +59,115 @@ function create_or_update_results_data_node($scope, $health_center = NULL) { sleep(2); return $after - $before; } + +/** + * Generate Completion report data which is stored on person nodes. + * + * @param int|null $health_center + * Health center ID. + * + * @return array + * An array of generated data. + */ +function generate_completion_results_data($health_center) { + $bundles = [ + // Acute Illness data. + 'acute_illness_encounter', + // Nutrition Group data. + 'attendance', + // Home Visit data. + 'home_visit_encounter', + // Nutrition Individual data. + 'nutrition_encounter', + // Well Child data. + 'well_child_encounter', + ]; + + $base_query = new EntityFieldQuery(); + $base_query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', $bundles, 'IN') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_reports_data', 'value', NULL, 'IS NOT NULL') + ->propertyOrderBy('nid'); + + if (!empty($health_center)) { + $base_query->fieldCondition('field_shards', 'target_id', $health_center); + } + + $data = [ + 'acute_illness' => [], + 'home_visit' => [], + 'nutrition_individual' => [], + 'nutrition_group' => [], + 'well_child' => [], + ]; + + $count_query = clone $base_query; + $total = $count_query->count()->execute(); + + $nid = $processed = 0; + $batch = 400; + + while (TRUE) { + // Free up memory. + drupal_static_reset(); + + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + $json_data = $node->field_reports_data[LANGUAGE_NONE][0]['value']; + if (empty($json_data)) { + continue; + } + + switch ($node->type) { + case 'acute_illness_encounter': + $data['acute_illness'][] = json_decode($json_data); + break; + + case 'attendance': + $data['nutrition_group'][] = json_decode($json_data); + break; + + case 'home_visit_encounter': + $data['home_visit'][] = json_decode($json_data); + break; + + case 'nutrition_encounter': + $data['nutrition_individual'][] = json_decode($json_data); + break; + + case 'well_child_encounter': + $data['well_child'][] = json_decode($json_data); + break; + } + + // Explicitly unset large variables after use for memory optimization. + unset($json_data); + } + + $nid = end($ids); + // Explicitly unset large variables after use for memory optimization. + unset($nodes); + + $processed += 400; + drush_print("Processed $processed out of $total."); + } + + return $data; +} From 44832860458a2fa7c472f54a3ca28d5a8db4aac1 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 5 Sep 2024 15:51:21 +0300 Subject: [PATCH 105/185] Add reports data field to encounter [ci skip] --- .../hedley_ncda.features.field_instance.inc | 88 ++++++++++++++++++- .../custom/hedley_ncda/hedley_ncda.info | 1 + .../hedley_ncda/hedley_ncda.strongarm.inc | 42 ++++----- 3 files changed, 106 insertions(+), 25 deletions(-) diff --git a/server/hedley/modules/custom/hedley_ncda/hedley_ncda.features.field_instance.inc b/server/hedley/modules/custom/hedley_ncda/hedley_ncda.features.field_instance.inc index 3c29db3f12..2453b3c8e4 100644 --- a/server/hedley/modules/custom/hedley_ncda/hedley_ncda.features.field_instance.inc +++ b/server/hedley/modules/custom/hedley_ncda/hedley_ncda.features.field_instance.inc @@ -180,6 +180,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -281,6 +282,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -325,6 +327,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -369,6 +372,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -587,6 +591,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -688,6 +693,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -732,6 +738,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -776,6 +783,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -994,6 +1002,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1095,6 +1104,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1139,6 +1149,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1183,6 +1194,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1268,12 +1280,54 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => -1, + 'weight' => 2, + ), + ); + + // Exported field_instance: + // 'node-child_scoreboard_encounter-field_reports_data'. + $field_instances['node-child_scoreboard_encounter-field_reports_data'] = array( + 'bundle' => 'child_scoreboard_encounter', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 4, + ), + 'teaser' => array( + 'label' => 'above', + 'settings' => array(), + 'type' => 'hidden', + 'weight' => 0, + ), + ), + 'entity_type' => 'node', + 'field_name' => 'field_reports_data', + 'label' => 'Completion Data', + 'required' => 0, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'rows' => 5, + ), + 'type' => 'text_textarea', + 'weight' => 3, ), ); @@ -1330,7 +1384,7 @@ function hedley_ncda_field_default_field_instances() { 'year_range' => '-3:+3', ), 'type' => 'date_select', - 'weight' => -3, + 'weight' => 1, ), ); @@ -1368,12 +1422,13 @@ function hedley_ncda_field_default_field_instances() { 'widget' => array( 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => 3, + 'weight' => 5, ), ); @@ -1413,7 +1468,7 @@ function hedley_ncda_field_default_field_instances() { 'size' => 60, ), 'type' => 'text_textfield', - 'weight' => 1, + 'weight' => 4, ), ); @@ -1586,6 +1641,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1687,6 +1743,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1731,6 +1788,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1775,6 +1833,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1993,6 +2052,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2093,6 +2153,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2137,6 +2198,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2181,6 +2243,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2369,6 +2432,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2552,6 +2616,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2596,6 +2661,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2677,6 +2743,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2978,6 +3045,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3079,6 +3147,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3123,6 +3192,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3167,6 +3237,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3385,6 +3456,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3486,6 +3558,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3530,6 +3603,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3574,6 +3648,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3792,6 +3867,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3893,6 +3969,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3937,6 +4014,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3981,6 +4059,7 @@ function hedley_ncda_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4038,6 +4117,7 @@ function hedley_ncda_field_default_field_instances() { t('Administration Note'); t('Birth Weight'); t('Child Scoreboard Encounter'); + t('Completion Data'); t('Date Measured'); t('Individual Participant'); t('MUAC'); diff --git a/server/hedley/modules/custom/hedley_ncda/hedley_ncda.info b/server/hedley/modules/custom/hedley_ncda/hedley_ncda.info index 41b63ac98d..29273acdae 100644 --- a/server/hedley/modules/custom/hedley_ncda/hedley_ncda.info +++ b/server/hedley/modules/custom/hedley_ncda/hedley_ncda.info @@ -47,6 +47,7 @@ features[field_instance][] = node-child_scoreboard_dtp_sa_iz-field_person features[field_instance][] = node-child_scoreboard_dtp_sa_iz-field_shards features[field_instance][] = node-child_scoreboard_dtp_sa_iz-field_uuid features[field_instance][] = node-child_scoreboard_encounter-field_individual_participant +features[field_instance][] = node-child_scoreboard_encounter-field_reports_data features[field_instance][] = node-child_scoreboard_encounter-field_scheduled_date features[field_instance][] = node-child_scoreboard_encounter-field_shards features[field_instance][] = node-child_scoreboard_encounter-field_uuid diff --git a/server/hedley/modules/custom/hedley_ncda/hedley_ncda.strongarm.inc b/server/hedley/modules/custom/hedley_ncda/hedley_ncda.strongarm.inc index 3186c95494..68e416d78c 100644 --- a/server/hedley/modules/custom/hedley_ncda/hedley_ncda.strongarm.inc +++ b/server/hedley/modules/custom/hedley_ncda/hedley_ncda.strongarm.inc @@ -226,15 +226,15 @@ function hedley_ncda_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__child_scoreboard_bcg_iz'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__child_scoreboard_bcg_iz'] = $strongarm; @@ -243,15 +243,15 @@ function hedley_ncda_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__child_scoreboard_dtp_iz'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__child_scoreboard_dtp_iz'] = $strongarm; @@ -260,15 +260,15 @@ function hedley_ncda_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__child_scoreboard_dtp_sa_iz'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__child_scoreboard_dtp_sa_iz'] = $strongarm; @@ -277,15 +277,15 @@ function hedley_ncda_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__child_scoreboard_encounter'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( - 'weight' => '-5', + 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__child_scoreboard_encounter'] = $strongarm; @@ -294,15 +294,15 @@ function hedley_ncda_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__child_scoreboard_ipv_iz'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__child_scoreboard_ipv_iz'] = $strongarm; @@ -311,15 +311,15 @@ function hedley_ncda_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__child_scoreboard_mr_iz'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__child_scoreboard_mr_iz'] = $strongarm; @@ -328,15 +328,15 @@ function hedley_ncda_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__child_scoreboard_ncda'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__child_scoreboard_ncda'] = $strongarm; @@ -345,15 +345,15 @@ function hedley_ncda_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__child_scoreboard_opv_iz'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__child_scoreboard_opv_iz'] = $strongarm; @@ -362,15 +362,15 @@ function hedley_ncda_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__child_scoreboard_pcv13_iz'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__child_scoreboard_pcv13_iz'] = $strongarm; @@ -379,15 +379,15 @@ function hedley_ncda_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__child_scoreboard_rotarix_iz'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__child_scoreboard_rotarix_iz'] = $strongarm; From f19a54f5b9c3b8bb911cdd956fceda424dfd411e Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 5 Sep 2024 23:35:13 +0300 Subject: [PATCH 106/185] Add script [ci skip] --- .../hedley_reports/hedley_reports.module | 55 ++++++++++++ ...pletion-generate-child-scoreboard-data.php | 90 +++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 915afd778f..8656557de0 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4323,6 +4323,61 @@ function hedley_reports_generate_completion_data_for_home_visit_encounter($encou ]; } +/** + * Generates completion data for Child Scoreboard encounter. + * + * @param object $encounter + * The encounter node object. + * + * @return array + * An array containing the completion data for given encounter. + */ +function hedley_reports_generate_completion_data_for_child_scoreboard_encounter($encounter) { + // To reduce memory usage, mapping measurement types as single characters. + $mapping = [ + 'child_scoreboard_ncda' => 'a', + 'child_scoreboard_bcg_iz' => 'b', + 'child_scoreboard_dtp_iz' => 'c', + 'child_scoreboard_ipv_iz' => 'd', + 'child_scoreboard_mr_iz' => 'e', + 'child_scoreboard_opv_iz' => 'f', + 'child_scoreboard_pcv13_iz' => 'g', + 'child_scoreboard_rotarix_iz' => 'h', + ]; + + // Activities that are always taken during encounter. + $expected = ['child_scoreboard_ncda']; + + // Resolve encounter start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + + // Loading all measurements that belong to encounter. + $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); + + if (empty($measurements_ids)) { + $completion = hedley_reports_generate_completion_result($expected, [], $mapping); + + return [ + 'start_date' => $start_date, + 'completion' => $completion, + ]; + } + + // Ordering measurements by type. + $measurements_by_type = []; + $measurements = node_load_multiple($measurements_ids); + foreach ($measurements as $measurement) { + $measurements_by_type[$measurement->type] = $measurement; + } + + $completion = hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping); + + return [ + 'start_date' => $start_date, + 'completion' => $completion, + ]; +} + /** * Resolve the age in months for patient at the time of a specific encounter. * diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php new file mode 100644 index 0000000000..3ba5e8c311 --- /dev/null +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php @@ -0,0 +1,90 @@ +entityCondition('entity_type', 'node') + ->entityCondition('bundle', $type) + ->propertyCondition('status', NODE_PUBLISHED); + +if ($exclude_set) { + $base_query->addTag('exclude_set_reports_data'); +} + +$count_query = clone $base_query; +$count_query->propertyCondition('nid', $nid, '>'); +$count = $count_query->count()->execute(); + +if ($count == 0) { + drush_print("There are no nodes of type $type in DB."); + exit; +} + +$total = 0; +drush_print("$count nodes of type $type located."); + +while (TRUE) { + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + $completion_data = hedley_reports_generate_completion_data_for_child_scoreboard_encounter($node); + $node->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); + node_save($node); + $total++; + + $memory = round(memory_get_usage() / 1048576); + if ($memory >= $memory_limit) { + drush_print(dt('Stopped before out of memory. Start process from the node ID @nid', ['@nid' => $nid])); + return; + } + } + + $memory = round(memory_get_usage() / 1048576); + drush_print("Calculated so far: $total, Memory: $memory"); + + // Free up memory. + drupal_static_reset(); + + $nid = end($ids); +} + +drush_print("Done! Completion data calculated for $total encounters."); From 5dde29a143a841244a85392c2349e9b813fac9d4 Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 6 Sep 2024 15:48:15 +0300 Subject: [PATCH 107/185] Backend logic [ci skip] --- client/src/elm/SyncManager/Utils.elm | 2 +- .../hedley_reports/hedley_reports.module | 558 ++++++++++++++++-- ...pletion-generate-child-scoreboard-data.php | 10 +- 3 files changed, 503 insertions(+), 67 deletions(-) diff --git a/client/src/elm/SyncManager/Utils.elm b/client/src/elm/SyncManager/Utils.elm index 2048ba8450..c223453e78 100644 --- a/client/src/elm/SyncManager/Utils.elm +++ b/client/src/elm/SyncManager/Utils.elm @@ -61,7 +61,7 @@ determineSyncStatus activePage model = UserPage (SessionPage _ (ActivityPage (ChildActivity ChildPicture))) -> True - -- Participant page, where activites are taken for a child. + -- Participant page, where activities are taken for a child. UserPage (SessionPage _ (ChildPage _)) -> True diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 8656557de0..ff0f06aa42 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3368,7 +3368,7 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e return; } - // Get birthdate. + // Get birthdate and gender. $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; try { $person = node_load($person_id); @@ -3454,7 +3454,7 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e /** * Generates vaccination progress data for a well-child encounter. * - * This function processes immunization data from previous and current + * This function processes immunisation data from previous and current * encounters, generating vaccination history and progress data for * well-child encounters. It merges this data with child scoreboard data * to produce comprehensive vaccination progress information. @@ -3509,32 +3509,35 @@ function hedley_reports_well_child_generate_vaccination_progress_data($person_id $immunisations_from_all_encounters[$immunisation_type][] = $measurements_by_type[$immunisation_type]; } - $history_data_by_well_child = hedley_reports_well_child_generate_vaccination_progress_data_regular($immunisations_from_previous_encounters); - $progress_data_by_well_child = hedley_reports_well_child_generate_vaccination_progress_data_regular($immunisations_from_all_encounters); + $history_data_by_well_child = hedley_reports_generate_vaccination_progress_data($immunisations_from_previous_encounters, 'well-child'); + $progress_data_by_well_child = hedley_reports_generate_vaccination_progress_data($immunisations_from_all_encounters, 'well-child'); $progress_data_by_child_scoreboard = hedley_reports_well_child_generate_vaccination_progress_data_by_child_scoreboard($person_id, $encounter_data['start_date_obj']); return [ - hedley_reports_well_child_merge_vaccination_progress_data($immunisation_types, $history_data_by_well_child, $progress_data_by_child_scoreboard), - hedley_reports_well_child_merge_vaccination_progress_data($immunisation_types, $progress_data_by_well_child, $progress_data_by_child_scoreboard), + hedley_reports_merge_vaccination_progress_data($immunisation_types, 'well-child', $history_data_by_well_child, $progress_data_by_child_scoreboard), + hedley_reports_merge_vaccination_progress_data($immunisation_types, 'well-child', $progress_data_by_well_child, $progress_data_by_child_scoreboard), ]; } /** * Generates regular vaccination progress data from encounters. * - * Processes immunization data from a series of encounters to create + * Processes immunisation data from a series of encounters to create * a structured array of vaccination doses and dates, ensuring the data * is sorted and aligned. * * @param array $immunisations_from_encounters - * An associative array containing immunization data from previous - * encounters, indexed by immunization type. + * An associative array containing immunisation data from previous + * encounters, indexed by immunisation type. + * @param string $module + * The type of individual encounter where immunisations were taken. + * Supported values: 'well-child' / 'child-scoreboard'. * * @return array * A structured array of vaccination doses and dates, organized by - * immunization type. + * immunisation type. */ -function hedley_reports_well_child_generate_vaccination_progress_data_regular(array $immunisations_from_encounters) { +function hedley_reports_generate_vaccination_progress_data(array $immunisations_from_encounters, $module) { $return = []; $immunisations_by_type = []; foreach ($immunisations_from_encounters as $immunisation_type => $immunisations) { @@ -3588,8 +3591,20 @@ function hedley_reports_well_child_generate_vaccination_progress_data_regular(ar $immunisations_by_type[$type]['dates'] = array_slice($immunisations_by_type[$type]['dates'], 0, $common_size); } + $prefix = $suffix = ''; + switch ($module) { + case 'child-scoreboard': + $prefix = 'child_scoreboard_'; + $suffix = '_iz'; + break; + + case 'well-child': + $prefix = 'well_child_'; + $suffix = '_immunisation'; + } + foreach ($immunisations_by_type[$type]['doses'] as $index => $dose) { - $common_type = hedley_reports_drop_prefix_and_suffix($type, 'well_child_', '_immunisation'); + $common_type = hedley_reports_drop_prefix_and_suffix($type, $prefix, $suffix); $return[$common_type][$dose] = $immunisations_by_type[$type]['dates'][$index]; } } @@ -3600,7 +3615,7 @@ function hedley_reports_well_child_generate_vaccination_progress_data_regular(ar /** * Generates vaccination progress data based on child scoreboard data. * - * Retrieves immunization data for a child from the child scoreboard, + * Retrieves immunisation data for a child from the child scoreboard, * considering all encounters up to the current well-child encounter, * and returns structured vaccination progress data. * @@ -3613,7 +3628,7 @@ function hedley_reports_well_child_generate_vaccination_progress_data_regular(ar * * @return array * A structured array of vaccination doses and dates, organized by - * immunization type, based on child scoreboard encounters. + * immunisation type, based on child scoreboard encounters. */ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_scoreboard($person_id, DateTime $well_child_encounter_start_date_obj) { $return = []; @@ -3748,10 +3763,13 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s * * Combines vaccination progress data from two sources (e.g., history * and child scoreboard data) into a single structured array, organized - * by immunization type. + * by immunisation type. * * @param array $immunisation_types - * An array of immunization types to be merged. + * An array of immunisation types to be merged. + * @param string $module + * The type of individual encounter where immunisations were taken. + * Supported values: 'well-child' / 'child-scoreboard'. * @param array $first * The first set of vaccination progress data. * @param array $second @@ -3759,12 +3777,24 @@ function hedley_reports_well_child_generate_vaccination_progress_data_by_child_s * * @return array * A merged array of vaccination progress data, organized by - * immunization type. + * immunisation type. */ -function hedley_reports_well_child_merge_vaccination_progress_data(array $immunisation_types, array $first, array $second) { +function hedley_reports_merge_vaccination_progress_data(array $immunisation_types, $module, array $first, array $second) { + $prefix = $suffix = ''; + switch ($module) { + case 'child-scoreboard': + $prefix = 'child_scoreboard_'; + $suffix = '_iz'; + break; + + case 'well-child': + $prefix = 'well_child_'; + $suffix = '_immunisation'; + } + $return = []; foreach ($immunisation_types as $type) { - $common_type = hedley_reports_drop_prefix_and_suffix($type, 'well_child_', '_immunisation'); + $common_type = hedley_reports_drop_prefix_and_suffix($type, $prefix, $suffix); if (!empty($first[$common_type]) && !empty($second[$common_type])) { $return[$common_type] = array_merge($first[$common_type], $second[$common_type]); } @@ -3871,20 +3901,20 @@ function hedley_reports_well_child_generate_expected_initial_activities(array $e * An array of expected activity names, passed by reference. */ function hedley_reports_well_child_add_immunisation_activities(array $encounter_data, DateTime $birth_date_obj, $gender, array &$expected) { - $expected_by_history = hedley_reports_well_child_get_expected_immunisation_activites($encounter_data, $birth_date_obj, $gender, 'history'); + $expected_by_history = hedley_reports_well_child_get_expected_immunisation_activities($encounter_data, $birth_date_obj, $gender, 'history'); foreach ($expected_by_history as $activity) { $expected[] = $activity; } } /** - * Generates a list of expected well-child immunization activities. + * Generates a list of expected well-child immunisation activities. * - * This function determines the expected immunization activities for a + * This function determines the expected immunisation activities for a * well-child based on the child's encounter data, age, gender, and mode. * It considers the vaccination history or progress, the site of the encounter, * and other factors such as the child's age in days. It then generates a list - * of immunizations that should be expected during the encounter. + * of immunisations that should be expected during the encounter. * * @param array $encounter_data * An associative array containing details of the encounter, including @@ -3892,15 +3922,15 @@ function hedley_reports_well_child_add_immunisation_activities(array $encounter_ * @param DateTime $birth_date_obj * The DateTime object representing the child's birth date. * @param string $gender - * The gender of the child, used to determine gender-specific immunizations. + * The gender of the child, used to determine gender-specific immunisations. * @param string $mode * The mode of operation, either 'history' or 'progress', which determines * whether to consider the vaccination history or progress. * * @return array - * An array of expected immunization activities based on the encounter data. + * An array of expected immunisation activities based on the encounter data. */ -function hedley_reports_well_child_get_expected_immunisation_activites(array $encounter_data, DateTime $birth_date_obj, $gender, $mode) { +function hedley_reports_well_child_get_expected_immunisation_activities(array $encounter_data, DateTime $birth_date_obj, $gender, $mode) { $encounter_type = $encounter_data['encounter_type']; $vaccination_progress = $encounter_data['vaccination_progress']; // History mode looks at vaccination status excluding vaccinations done at @@ -3909,7 +3939,7 @@ function hedley_reports_well_child_get_expected_immunisation_activites(array $en $vaccination_history = $mode == 'history' ? $encounter_data['vaccination_history'] : $vaccination_progress; $start_date_obj = $encounter_data['start_date_obj']; - $initial_opv_administered = hedley_reports_well_child_initial_opv_administered($encounter_data, $birth_date_obj); + $initial_opv_administered = hedley_reports_initial_opv_administered($encounter_data, $birth_date_obj); $interval = $start_date_obj->diff($birth_date_obj); $age_in_days = $interval->days; @@ -3968,7 +3998,7 @@ function hedley_reports_well_child_get_expected_immunisation_activites(array $en $doses = array_keys($performed); sort($doses); $last_dose = array_reverse($doses)[0]; - $last_dose_for_immunisation = hedley_reports_well_child_get_last_dose_for_vaccine($immunisation_type, $initial_opv_administered); + $last_dose_for_immunisation = hedley_reports_get_last_dose_for_vaccine($immunisation_type, $initial_opv_administered); // If all doses we administered, skipping to next immunisation type. if ($last_dose == $last_dose_for_immunisation) { continue; @@ -3978,7 +4008,7 @@ function hedley_reports_well_child_get_expected_immunisation_activites(array $en $last_dose_as_number = (int) explode('-', $last_dose)[1]; $next_dose_as_number = $last_dose_as_number + 1; $last_dose_date = $performed[$last_dose]; - $interval_between_dosed = hedley_reports_well_child_get_interval_for_vaccine($immunisation_type, $site); + $interval_between_dosed = hedley_reports_get_interval_for_vaccine($immunisation_type, $site); $last_dose_date_obj = new DateTime($last_dose_date); $next_dose_date_obj = clone $last_dose_date_obj; $next_dose_date_obj->modify($interval_between_dosed); @@ -4018,7 +4048,7 @@ function hedley_reports_well_child_get_expected_immunisation_activites(array $en * TRUE if the initial OPV dose was administered within 14 days of birth, * FALSE otherwise. */ -function hedley_reports_well_child_initial_opv_administered(array $encounter_data, DateTime $birth_date_obj) { +function hedley_reports_initial_opv_administered(array $encounter_data, DateTime $birth_date_obj) { $vaccination_progress = $encounter_data['vaccination_progress']; if (empty($vaccination_progress['opv']) || empty($vaccination_progress['opv']['dose-1'])) { @@ -4039,16 +4069,16 @@ function hedley_reports_well_child_initial_opv_administered(array $encounter_dat * the OPV dose was administered. * * @param string $immunisation_type - * The type of immunization (e.g., 'bcg', 'opv', 'dtp'). + * The type of immunisation (e.g., 'bcg', 'opv', 'dtp'). * @param bool $initial_opv_administered * Indicates whether the initial OPV dose was administered within 14 days * of birth. * * @return string|bool * The last expected dose for the vaccine (e.g., 'dose-1', 'dose-3'), - * or FALSE, if the immunization type is not recognized. + * or FALSE, if the immunisation type is not recognized. */ -function hedley_reports_well_child_get_last_dose_for_vaccine($immunisation_type, $initial_opv_administered) { +function hedley_reports_get_last_dose_for_vaccine($immunisation_type, $initial_opv_administered) { switch ($immunisation_type) { case 'bcg': case 'ipv': @@ -4079,15 +4109,15 @@ function hedley_reports_well_child_get_last_dose_for_vaccine($immunisation_type, * occurs. * * @param string $immunisation_type - * The type of immunization (e.g., 'bcg', 'opv', 'dtp'). + * The type of immunisation (e.g., 'bcg', 'opv', 'dtp'). * @param string $site * The site name, which may affect the interval for certain vaccines. * * @return string|bool * A string representing the interval between doses (e.g., '+4 weeks', - * '+9 months'), or FALSE if the immunization type is not recognized. + * '+9 months'), or FALSE if the immunisation type is not recognized. */ -function hedley_reports_well_child_get_interval_for_vaccine($immunisation_type, $site) { +function hedley_reports_get_interval_for_vaccine($immunisation_type, $site) { switch ($immunisation_type) { case 'bcg': case 'ipv': @@ -4262,7 +4292,7 @@ function hedley_reports_well_child_add_next_steps_activities(array $encounter_da } if ($immunisation_activities_completed) { - $expected_by_progress = hedley_reports_well_child_get_expected_immunisation_activites($encounter_data, $birth_date_obj, $gender, 'progress'); + $expected_by_progress = hedley_reports_well_child_get_expected_immunisation_activities($encounter_data, $birth_date_obj, $gender, 'progress'); if (!empty($expected_by_progress)) { // Immunisation activity completed, but child is still behind // on vaccinations. @@ -4326,13 +4356,12 @@ function hedley_reports_generate_completion_data_for_home_visit_encounter($encou /** * Generates completion data for Child Scoreboard encounter. * - * @param object $encounter - * The encounter node object. - * - * @return array - * An array containing the completion data for given encounter. + * @param object $participant + * The participant node object representing illness. + * @param bool $exclude_set + * Indicate whether to exclude encounters with report data already set. */ -function hedley_reports_generate_completion_data_for_child_scoreboard_encounter($encounter) { +function hedley_reports_generate_completion_data_for_child_scoreboard_encounter($participant, $exclude_set) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ 'child_scoreboard_ncda' => 'a', @@ -4343,41 +4372,448 @@ function hedley_reports_generate_completion_data_for_child_scoreboard_encounter( 'child_scoreboard_opv_iz' => 'f', 'child_scoreboard_pcv13_iz' => 'g', 'child_scoreboard_rotarix_iz' => 'h', + 'child_scoreboard_dtp_sa_iz' => 'i', + ]; - // Activities that are always taken during encounter. - $expected = ['child_scoreboard_ncda']; + // Load all encounters of current participant. + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'well_child_encounter') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_individual_participant', 'target_id', $participant->nid) + ->propertyOrderBy('nid') + ->execute(); - // Resolve encounter start date. - $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + if (empty($result['node'])) { + return; + } - // Loading all measurements that belong to encounter. - $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); + // Get birthdate and gender. + $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + try { + $person = node_load($person_id); + $birth_date = explode(' ', $person->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; + $birth_date_obj = new DateTime($birth_date); + $gender = $person->field_gender[LANGUAGE_NONE][0]['value']; + } + catch (Exception $e) { + $birth_date_obj = NULL; + $gender = 'male'; + } - if (empty($measurements_ids)) { - $completion = hedley_reports_generate_completion_result($expected, [], $mapping); + // Encounters are sorted ASC. + $encounters = node_load_multiple(array_keys($result['node'])); + $encounters_data = []; + foreach ($encounters as $encounter) { + // Skip encounter if exclusion flag is raised and it's report data is set. + if ($exclude_set && !empty($encounter->field_reports_data[LANGUAGE_NONE][0]['value'])) { + continue; + } - return [ + // Loading all measurements that belong to encounter. + $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); + + $measurements = !empty($measurements_ids) ? node_load_multiple($measurements_ids) : []; + // Ordering measurements by type. + $measurements_by_type = []; + foreach ($measurements as $measurement) { + $measurements_by_type[$measurement->type] = $measurement; + } + + $encounters_data[] = [ + 'encounter' => $encounter, + 'measurements_by_type' => $measurements_by_type, + ]; + } + + foreach ($encounters_data as $index => $encounter_data) { + $encounter = $encounter_data['encounter']; + $measurements_by_type = $encounter_data['measurements_by_type']; + + $expected = ['child_scoreboard_ncda']; + + // Resolve encounter start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $start_date_obj = new DateTime($start_date); + + // Checking patient indicated at NCDA questioner that all vaccinations are up to date + if (empty($measurements_by_type['child_scoreboard_ncda']) || empty($measurements_by_type['child_scoreboard_ncda']->field_ncda_signs)) { + $up_to_date_by_ncda_response = FALSE; + } + else { + $behind_by_ncda_response = FALSE; + $signs = $measurements_by_type['child_scoreboard_ncda']->field_ncda_signs[LANGUAGE_NONE]; + foreach ($signs as $sign) { + if ($sign['value'] == 'child-behind-on-vaccination') { + $behind_by_ncda_response = TRUE; + break; + } + } + + $up_to_date_by_ncda_response = !$behind_by_ncda_response; + } + + // If patient indicated at NCDA questioner that all vaccinations are up to date, + // we'll check that they were all recorded. If not, we should have immunisation + // activities to record data currently missing. + if ($up_to_date_by_ncda_response) { + $encounter_data['start_date_obj'] = $start_date_obj; + + // Try to resolve age in months at a time encounter was performed. + $encounter_data['age_in_months'] = hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj); + $encounter_data['previous_encounters_data'] = array_slice($encounters_data, 0, $index); + + list($encounter_data['vaccination_history'], $encounter_data['vaccination_progress']) = hedley_reports_child_scoreboard_generate_vaccination_progress_data($person_id, $encounter_data); + + $expected_immunisation_activities = hedley_reports_child_scoreboard_get_expected_immunisation_activities($encounter_data, $birth_date_obj, $gender, 'history'); + $expected = array_merge($expected, $expected_immunisation_activities); + } + + $completion_data = [ 'start_date' => $start_date, - 'completion' => $completion, + 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), ]; + + $encounter->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); + node_save($encounter); } +} - // Ordering measurements by type. - $measurements_by_type = []; - $measurements = node_load_multiple($measurements_ids); - foreach ($measurements as $measurement) { - $measurements_by_type[$measurement->type] = $measurement; +/** + * Generates vaccination progress data for a child scoreboard encounter. + * + * This function processes immunisation data from previous and current + * encounters, generating vaccination history and progress data for + * child scoreboard encounters. It merges this data with well-child + * data to produce comprehensive vaccination progress information. + * + * @param int $person_id + * The ID of the person (child) whose vaccination data is being + * processed. + * @param array $encounter_data + * An associative array containing details of the current encounter, + * including previous encounter data and measurements. + * + * @return array + * An array containing merged vaccination progress data, with history + * and progress for the child. + */ +function hedley_reports_child_scoreboard_generate_vaccination_progress_data($person_id, array $encounter_data) { + $previous_encounters_data = $encounter_data['previous_encounters_data']; + + $immunisation_types = [ + 'child_scoreboard_bcg_iz', + 'child_scoreboard_dtp_iz', + 'child_scoreboard_ipv_iz', + 'child_scoreboard_mr_iz', + 'child_scoreboard_opv_iz', + 'child_scoreboard_pcv13_iz', + 'child_scoreboard_rotarix_iz', + ]; + + $immunisations_from_previous_encounters = []; + foreach ($immunisation_types as $immunisation_type) { + $immunisations_from_previous_encounters[$immunisation_type] = []; } - $completion = hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping); + foreach ($previous_encounters_data as $previous_encounter_data) { + $measurements_by_type = $previous_encounter_data['measurements_by_type']; + foreach ($immunisation_types as $immunisation_type) { + if (empty($measurements_by_type[$immunisation_type])) { + continue; + } + $immunisations_from_previous_encounters[$immunisation_type][] = $measurements_by_type[$immunisation_type]; + } + } + + $immunisations_from_all_encounters = $immunisations_from_previous_encounters; + $measurements_by_type = $encounter_data['measurements_by_type']; + foreach ($immunisation_types as $immunisation_type) { + if (empty($measurements_by_type[$immunisation_type])) { + continue; + } + $immunisations_from_all_encounters[$immunisation_type][] = $measurements_by_type[$immunisation_type]; + } + + $history_data_by_well_child = hedley_reports_generate_vaccination_progress_data($immunisations_from_previous_encounters, 'child-scoreboard'); + $progress_data_by_well_child = hedley_reports_generate_vaccination_progress_data($immunisations_from_all_encounters, 'child-scoreboard'); + $progress_data_by_child_scoreboard = hedley_reports_child_scoreboard_generate_vaccination_progress_data_by_well_child($person_id, $encounter_data['start_date_obj']); return [ - 'start_date' => $start_date, - 'completion' => $completion, + hedley_reports_merge_vaccination_progress_data($immunisation_types, 'child-scoreboard', $history_data_by_well_child, $progress_data_by_child_scoreboard), + hedley_reports_merge_vaccination_progress_data($immunisation_types, 'child-scoreboard', $progress_data_by_well_child, $progress_data_by_child_scoreboard), ]; } +/** + * Generates a list of expected well-child immunisation activities. + * + * This function determines the expected immunisation activities for a + * well-child based on the child's encounter data, age, gender, and mode. + * It considers the vaccination history or progress, the site of the encounter, + * and other factors such as the child's age in days. It then generates a list + * of immunisations that should be expected during the encounter. + * + * @param array $encounter_data + * An associative array containing details of the encounter, including + * encounter type, vaccination progress, vaccination history, and start date. + * @param DateTime $birth_date_obj + * The DateTime object representing the child's birth date. + * @param string $gender + * The gender of the child, used to determine gender-specific immunisations. + * @param string $mode + * The mode of operation, either 'history' or 'progress', which determines + * whether to consider the vaccination history or progress. + * + * @return array + * An array of expected immunisation activities based on the encounter data. + */ +function hedley_reports_child_scoreboard_get_expected_immunisation_activities(array $encounter_data, DateTime $birth_date_obj, $gender, $mode) { + $vaccination_progress = $encounter_data['vaccination_progress']; + // History mode looks at vaccination status excluding vaccinations done at + // current encounter. Progress mode includes vaccinations done at current + // encounter. + $vaccination_history = $mode == 'history' ? $encounter_data['vaccination_history'] : $vaccination_progress; + $start_date_obj = $encounter_data['start_date_obj']; + + $initial_opv_administered = hedley_reports_initial_opv_administered($encounter_data, $birth_date_obj); + $interval = $start_date_obj->diff($birth_date_obj); + $age_in_days = $interval->days; + + $possible_immunisations = ['bcg', 'opv']; + if ($age_in_days >= (6 * 7)) { + $possible_immunisations = array_merge( + $possible_immunisations, + ['dtp', 'pcv13', 'rotarix'] + ); + } + if ($age_in_days >= (14 * 7)) { + $possible_immunisations[] = 'ipv'; + } + if ($age_in_days >= (36 * 7)) { + $possible_immunisations[] = 'mr'; + } + + $site = variable_get('hedley_general_site_name', ''); + if ($site == 'burundi') { + // All 3 doses of DTP were given, it has passed at least 28 days since + // third dose, and, child is at last 18 months old. + if (!empty($vaccination_progress['dtp']['dose-3'])) { + $age_in_months = ($interval->y * 12) + $interval->m; + $third_dose_date_obj = new DateTime($vaccination_progress['dtp']['dose-3']); + $interval = $start_date_obj->diff($third_dose_date_obj); + $days_since_third_dose = $interval->days; + + if ($age_in_months >= 18 && $days_since_third_dose >= 28) { + $possible_immunisations[] = 'dtp_sa'; + } + } + } + else { + $age_in_years = $interval->y; + if ($age_in_years >= 12 && $gender == 'female') { + $possible_immunisations[] = 'hpv'; + } + } + + $expected = []; + foreach ($possible_immunisations as $immunisation_type) { + $immunisation_full_name = "well_child_{$immunisation_type}_immunisation"; + if (empty($vaccination_history)) { + $expected[] = $immunisation_full_name; + continue; + } + + $performed = $vaccination_history[$immunisation_type]; + if (empty($performed)) { + $expected[] = $immunisation_full_name; + continue; + } + + $doses = array_keys($performed); + sort($doses); + $last_dose = array_reverse($doses)[0]; + $last_dose_for_immunisation = hedley_reports_get_last_dose_for_vaccine($immunisation_type, $initial_opv_administered); + // If all doses we administered, skipping to next immunisation type. + if ($last_dose == $last_dose_for_immunisation) { + continue; + } + + // Calculating when next dose is supposed to be administered. + $last_dose_as_number = (int) explode('-', $last_dose)[1]; + $next_dose_as_number = $last_dose_as_number + 1; + $last_dose_date = $performed[$last_dose]; + $interval_between_dosed = hedley_reports_get_interval_for_vaccine($immunisation_type, $site); + $last_dose_date_obj = new DateTime($last_dose_date); + $next_dose_date_obj = clone $last_dose_date_obj; + $next_dose_date_obj->modify($interval_between_dosed); + if ($immunisation_type == 'opv' && $next_dose_as_number == 2 && $initial_opv_administered) { + $six_weeks_old_date_obj = clone $birth_date_obj; + $six_weeks_old_date_obj->modify('+6 weeks'); + + if ($six_weeks_old_date_obj > $next_dose_date_obj) { + $next_dose_date_obj = $six_weeks_old_date_obj; + } + } + + // If encounter started after the date when immunisation was supposed + // to be administered, adding it as expected. + if ($start_date_obj >= $next_dose_date_obj) { + $expected[] = $immunisation_full_name; + } + } + + return $expected; +} + +/** + * Generates vaccination progress data based on well-child data. + * + * Retrieves immunisation data for a child from the well-child, + * considering all encounters up to the current child scoreboard encounter, + * and returns structured vaccination progress data. + * + * @param int $person_id + * The ID of the person (child) whose scoreboard data is being + * processed. + * @param DateTime $child_scoreboard_encounter_start_date_obj + * The DateTime object representing the start date of the current + * child scoreboard encounter. + * + * @return array + * A structured array of vaccination doses and dates, organized by + * immunisation type, based on child scoreboard encounters. + */ +function hedley_reports_child_scoreboard_generate_vaccination_progress_data_by_well_child($person_id, DateTime $child_scoreboard_encounter_start_date_obj) { + $return = []; + if (empty($person_id)) { + return $return; + } + + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'individual_participant') + ->fieldCondition('field_encounter_type', 'value', 'well-child') + ->fieldCondition('field_person', 'target_id', $person_id) + ->propertyCondition('status', NODE_PUBLISHED) + ->addTag('exclude_deleted'); + + $result = $query + ->range(0, 1) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + return $return; + } + + $participant_id = key($result['node']); + // Load all encounters of current participant. + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'well_child_encounter') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_individual_participant', 'target_id', $participant_id) + ->propertyOrderBy('nid') + ->execute(); + + if (empty($result['node'])) { + return $return; + } + + $immunisation_types = [ + 'well_child_bcg_immunisation', + 'well_child_dtp_immunisation', + 'well_child_dtp_sa_immunisation', + 'well_child_ipv_immunisation', + 'well_child_mr_immunisation', + 'well_child_opv_immunisation', + 'well_child_pcv13_immunisation', + 'well_child_rotarix_immunisation', + ]; + + $immunisations_by_type = []; + foreach ($immunisation_types as $immunisation_type) { + $immunisations_by_type[$immunisation_type] = [ + 'doses' => [], + 'dates' => [], + ]; + } + $encounters = node_load_multiple(array_keys($result['node'])); + foreach ($encounters as $encounter) { + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $start_date_obj = new DateTime($start_date); + if ($start_date_obj > $child_scoreboard_encounter_start_date_obj) { + // This encounter started after well child encounter, so, skip it. + continue; + } + + // Loading all immunisation activities recorded during the encounter. + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', $immunisation_types, 'IN') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_well_child_encounter', 'target_id', $encounter->nid) + ->execute(); + + if (empty($result['node'])) { + continue; + } + + $immunisations = node_load_multiple(array_keys($result['node'])); + foreach ($immunisations as $immunisation) { + $doses = $immunisation->field_administered_doses; + $dates = $immunisation->field_administration_dates; + if (empty($doses) || empty($dates)) { + continue; + } + + $encounter_doses = $encounter_dates = []; + foreach ($doses[LANGUAGE_NONE] as $dose) { + $encounter_doses[] = $dose['value']; + } + foreach ($dates[LANGUAGE_NONE] as $date) { + $encounter_dates[] = explode(' ', $date['value'])[0]; + } + + $immunisations_by_type[$immunisation->type]['doses'] = array_merge($immunisations_by_type[$immunisation->type]['doses'], $encounter_doses); + $immunisations_by_type[$immunisation->type]['dates'] = array_merge($immunisations_by_type[$immunisation->type]['dates'], $encounter_dates); + } + } + + foreach ($immunisations_by_type as $type => $item) { + if (empty($item['doses']) || empty($item['dates'])) { + continue; + } + + $immunisations_by_type[$type]['doses'] = array_unique($item['doses']); + sort($immunisations_by_type[$type]['doses']); + $immunisations_by_type[$type]['dates'] = array_unique($item['dates']); + sort($immunisations_by_type[$type]['dates']); + $total_doses = count($immunisations_by_type[$type]['doses']); + $total_dates = count($immunisations_by_type[$type]['dates']); + + // Make sure number of doses matches the number of dates. + if ($total_doses != $total_dates) { + $common_size = min($total_doses, $total_dates); + $immunisations_by_type[$type]['doses'] = array_slice($immunisations_by_type[$type]['doses'], 0, $common_size); + $immunisations_by_type[$type]['dates'] = array_slice($immunisations_by_type[$type]['dates'], 0, $common_size); + } + + foreach ($immunisations_by_type[$type]['doses'] as $index => $dose) { + $common_type = hedley_reports_drop_prefix_and_suffix($type, 'well_child_', '_immunisation'); + $return[$common_type][$dose] = $immunisations_by_type[$type]['dates'][$index]; + } + } + + return $return; +} + /** * Resolve the age in months for patient at the time of a specific encounter. * diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php index 3ba5e8c311..ebd28a6174 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php @@ -25,12 +25,14 @@ // Get allowed memory limit. $memory_limit = drush_get_option('memory_limit', 500); -$type = 'child_scoreboard_encounter'; +$type = 'individual_participant'; $base_query = new EntityFieldQuery(); $base_query ->entityCondition('entity_type', 'node') ->entityCondition('bundle', $type) - ->propertyCondition('status', NODE_PUBLISHED); + ->fieldCondition('field_encounter_type', 'value', 'child-scoreboard') + ->propertyCondition('status', NODE_PUBLISHED) + ->addTag('exclude_deleted'); if ($exclude_set) { $base_query->addTag('exclude_set_reports_data'); @@ -67,8 +69,6 @@ $nodes = node_load_multiple($ids); foreach ($nodes as $node) { $completion_data = hedley_reports_generate_completion_data_for_child_scoreboard_encounter($node); - $node->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); - node_save($node); $total++; $memory = round(memory_get_usage() / 1048576); @@ -87,4 +87,4 @@ $nid = end($ids); } -drush_print("Done! Completion data calculated for $total encounters."); +drush_print("Done! Completion data calculated for $total participants."); From 32a271d9a84a7745c70fc7cdf768ed2b7209996c Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 6 Sep 2024 15:52:09 +0300 Subject: [PATCH 108/185] Fixes [ci skip] --- .../scripts/completion-generate-child-scoreboard-data.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php index ebd28a6174..ab9f02f11e 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php @@ -5,7 +5,7 @@ * Generates completion data for different types of encounters. * * Execution: drush scr - * profiles/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php. + * profiles/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php. */ if (!drupal_is_cli()) { @@ -68,7 +68,7 @@ $ids = array_keys($result['node']); $nodes = node_load_multiple($ids); foreach ($nodes as $node) { - $completion_data = hedley_reports_generate_completion_data_for_child_scoreboard_encounter($node); + $completion_data = hedley_reports_generate_completion_data_for_child_scoreboard_encounter($node, $exclude_set); $total++; $memory = round(memory_get_usage() / 1048576); From 102651f6d92539b4fbeb1d736703d7aef7fbbf1c Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 6 Sep 2024 15:57:32 +0300 Subject: [PATCH 109/185] Another fix [ci skip] --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index ff0f06aa42..bd582c9920 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4380,7 +4380,7 @@ function hedley_reports_generate_completion_data_for_child_scoreboard_encounter( $query = new EntityFieldQuery(); $result = $query ->entityCondition('entity_type', 'node') - ->entityCondition('bundle', 'well_child_encounter') + ->entityCondition('bundle', 'child_scoreboard_encounter') ->propertyCondition('status', NODE_PUBLISHED) ->fieldCondition('field_individual_participant', 'target_id', $participant->nid) ->propertyOrderBy('nid') From 4ee15861f49fa6adfbc7b2853c4a32e4048a4d02 Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 6 Sep 2024 16:15:04 +0300 Subject: [PATCH 110/185] One more fix [ci skip] --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index bd582c9920..8b82fd004f 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4620,7 +4620,7 @@ function hedley_reports_child_scoreboard_get_expected_immunisation_activities(ar $expected = []; foreach ($possible_immunisations as $immunisation_type) { - $immunisation_full_name = "well_child_{$immunisation_type}_immunisation"; + $immunisation_full_name = "child_scoreboard_{$immunisation_type}_iz"; if (empty($vaccination_history)) { $expected[] = $immunisation_full_name; continue; From 42e9d5ff22d3c55ebcc0fb3d6118396a6556a1b5 Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 6 Sep 2024 17:56:59 +0300 Subject: [PATCH 111/185] Load data on backend [ci skip] --- .../scripts/completion-recalculate-large-datasets.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php index c4a58bd76a..b4119a50bb 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php @@ -75,6 +75,8 @@ function generate_completion_results_data($health_center) { 'acute_illness_encounter', // Nutrition Group data. 'attendance', + // Child Scoreboard data. + 'child_scoreboard_encounter', // Home Visit data. 'home_visit_encounter', // Nutrition Individual data. @@ -97,6 +99,7 @@ function generate_completion_results_data($health_center) { $data = [ 'acute_illness' => [], + 'child_scoreboard' => [], 'home_visit' => [], 'nutrition_individual' => [], 'nutrition_group' => [], @@ -144,6 +147,10 @@ function generate_completion_results_data($health_center) { $data['nutrition_group'][] = json_decode($json_data); break; + case 'child_scoreboard_encounter': + $data['child_scoreboard'][] = json_decode($json_data); + break; + case 'home_visit_encounter': $data['home_visit'][] = json_decode($json_data); break; From 26ed54bb74dca88b5f511a529a28e04a4711c1a4 Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 6 Sep 2024 17:58:52 +0300 Subject: [PATCH 112/185] Define, decode and store data on client [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 1 + server/elm/src/Backend/Completion/Model.elm | 17 +- server/elm/src/Backend/Completion/Utils.elm | 34 ++++ server/elm/src/Translate.elm | 159 ++++++++++----- .../custom/hedley_general/js/elm-main.js | 181 +++++++++++++++--- 5 files changed, 320 insertions(+), 72 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index c0f316f2ed..c14ef19827 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -20,6 +20,7 @@ decodeCompletionData = |> required "entity_name" string |> required "entity_type" decodeSelectedEntity |> requiredAt [ "results", "acute_illness" ] (list (decodeEncounterData acuteIllnessActivityFromMapping)) + |> requiredAt [ "results", "child_scoreboard" ] (list (decodeEncounterData childScoreboardActivityFromMapping)) |> requiredAt [ "results", "home_visit" ] (list (decodeEncounterData homeVisitActivityFromMapping)) |> requiredAt [ "results", "nutrition_individual" ] (list (decodeEncounterData nutritionChildActivityFromMapping)) |> requiredAt [ "results", "nutrition_group" ] diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index a90a24a0ec..7502c7a34b 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -12,6 +12,7 @@ type alias CompletionData = , entityName : String , entityType : SelectedEntity , acuteIllnessData : List (EncounterData AcuteIllnessActivity) + , childScoreboardData : List (EncounterData ChildScoreboardActivity) , homeVisitData : List (EncounterData HomeVisitActivity) , nutritionIndividualData : List (EncounterData NutritionChildActivity) , nutritionGroupData : List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) @@ -84,6 +85,18 @@ type AcuteIllnessActivity | AcuteIllnessOngoingTreatment +type ChildScoreboardActivity + = ChildScoreboardNCDA + | ChildScoreboardBCGImmunisation + | ChildScoreboardDTPImmunisation + | ChildScoreboardDTPSAImmunisation + | ChildScoreboardIPVImmunisation + | ChildScoreboardMRImmunisation + | ChildScoreboardOPVImmunisation + | ChildScoreboardPCV13Immunisation + | ChildScoreboardRotarixImmunisation + + type HomeVisitActivity = HomeVisitCaring | HomeVisitFeeding @@ -117,6 +130,7 @@ type WellChildActivity | WellChildCaring | WellChildContributingFactors | WellChildDTPImmunisation + | WellChildDTPSAImmunisation | WellChildECD | WellChildFeeding | WellChildFollowUp @@ -124,6 +138,7 @@ type WellChildActivity | WellChildHeadCircumference | WellChildHealthEducation | WellChildHeight + | WellChildHPVImmunisation | WellChildHygiene | WellChildIPVImmunisation | WellChildMebendezole @@ -142,8 +157,6 @@ type WellChildActivity | WellChildVitals | WellChildVitaminA | WellChildWeight - | WellChildHPVImmunisation - | WellChildDTPSAImmunisation type TakenBy diff --git a/server/elm/src/Backend/Completion/Utils.elm b/server/elm/src/Backend/Completion/Utils.elm index a2c85d6b18..b581c2bf90 100644 --- a/server/elm/src/Backend/Completion/Utils.elm +++ b/server/elm/src/Backend/Completion/Utils.elm @@ -257,6 +257,40 @@ homeVisitActivityFromMapping mapped = Nothing +childScoreboardActivityFromMapping : String -> Maybe ChildScoreboardActivity +childScoreboardActivityFromMapping mapped = + case mapped of + "a" -> + Just ChildScoreboardNCDA + + "b" -> + Just ChildScoreboardBCGImmunisation + + "c" -> + Just ChildScoreboardDTPImmunisation + + "i" -> + Just ChildScoreboardDTPSAImmunisation + + "d" -> + Just ChildScoreboardIPVImmunisation + + "e" -> + Just ChildScoreboardMRImmunisation + + "f" -> + Just ChildScoreboardOPVImmunisation + + "g" -> + Just ChildScoreboardPCV13Immunisation + + "h" -> + Just ChildScoreboardRotarixImmunisation + + _ -> + Nothing + + takenByToString : TakenBy -> String takenByToString value = case value of diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index e9d356c792..074d6d7535 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -8,6 +8,7 @@ import App.Types exposing (Language(..)) import Backend.Completion.Model exposing ( AcuteIllnessActivity(..) + , ChildScoreboardActivity(..) , HomeVisitActivity(..) , NutritionChildActivity(..) , NutritionMotherActivity(..) @@ -77,6 +78,7 @@ type TranslationId | CBNP | Cell | ChildScorecard + | ChildScoreboardActivity ChildScoreboardActivity | CHW | Colline | CollineSub @@ -104,6 +106,15 @@ type TranslationId | HomeVisitActivity HomeVisitActivity | HttpError StringIdHttpError | Hygiene + | ImmunisationBCG + | ImmunisationDTP + | ImmunisationDTPSA + | ImmunisationHPV + | ImmunisationIPV + | ImmunisationMR + | ImmunisationOPV + | ImmunisationPCV13 + | ImmunisationRotarix | Impacted | IncidenceByMonthOneVisitOrMore | IncidenceByMonthTwoVisitsOrMore @@ -119,6 +130,7 @@ type TranslationId | MonthLabel | MonthYear Int Int Bool | NCD + | NCDA | NCDADemographicsItemLabel NCDADemographicsItem | NCDAAcuteMalnutritionItemLabel NCDAAcuteMalnutritionItem | NCDAStuntingItemLabel NCDAStuntingItem @@ -567,6 +579,35 @@ translationSet transId = , kirundi = Nothing } + ChildScoreboardActivity activity -> + case activity of + ChildScoreboardNCDA -> + translationSet NCDA + + ChildScoreboardBCGImmunisation -> + translationSet ImmunisationBCG + + ChildScoreboardDTPImmunisation -> + translationSet ImmunisationDTP + + ChildScoreboardDTPSAImmunisation -> + translationSet ImmunisationDTPSA + + ChildScoreboardIPVImmunisation -> + translationSet ImmunisationIPV + + ChildScoreboardMRImmunisation -> + translationSet ImmunisationMR + + ChildScoreboardOPVImmunisation -> + translationSet ImmunisationOPV + + ChildScoreboardPCV13Immunisation -> + translationSet ImmunisationPCV13 + + ChildScoreboardRotarixImmunisation -> + translationSet ImmunisationRotarix + CHW -> { english = "CHW" , kinyarwanda = Nothing @@ -698,6 +739,60 @@ translationSet transId = , kirundi = Nothing } + ImmunisationBCG -> + { english = "BCG Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + ImmunisationDTP -> + { english = "DTP Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + ImmunisationDTPSA -> + { english = "DTP Standalone Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + ImmunisationHPV -> + { english = "HPV Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + ImmunisationIPV -> + { english = "IPV Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + ImmunisationMR -> + { english = "MR Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + ImmunisationOPV -> + { english = "OPV Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + ImmunisationPCV13 -> + { english = "PCV13 Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + ImmunisationRotarix -> + { english = "Rotarix Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + Impacted -> { english = "Impacted (2+ visits)" , kinyarwanda = Nothing @@ -782,6 +877,12 @@ translationSet transId = , kirundi = Nothing } + NCDA -> + { english = "NCDA" + , kinyarwanda = Nothing + , kirundi = Nothing + } + NCDADemographicsItemLabel item -> case item of ChildrenUnder2 -> @@ -1517,10 +1618,7 @@ translationSet transId = } WellChildBCGImmunisation -> - { english = "BCG Immunisation" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet ImmunisationBCG WellChildCaring -> translationSet Caring @@ -1532,10 +1630,10 @@ translationSet transId = } WellChildDTPImmunisation -> - { english = "DTP Immunisation" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet ImmunisationDTP + + WellChildDTPSAImmunisation -> + translationSet ImmunisationDTPSA WellChildECD -> { english = "ECD" @@ -1573,14 +1671,14 @@ translationSet transId = , kirundi = Nothing } + WellChildHPVImmunisation -> + translationSet ImmunisationHPV + WellChildHygiene -> translationSet Hygiene WellChildIPVImmunisation -> - { english = "IPV Immunisation" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet ImmunisationIPV WellChildMebendezole -> { english = "Mebendezole" @@ -1589,10 +1687,7 @@ translationSet transId = } WellChildMRImmunisation -> - { english = "MR Immunisation" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet ImmunisationMR WellChildMUAC -> { english = "MUAC" @@ -1601,10 +1696,7 @@ translationSet transId = } WellChildNCDA -> - { english = "NCDA" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet NCDA WellChildNextVisit -> { english = "Next Visit" @@ -1619,16 +1711,10 @@ translationSet transId = } WellChildOPVImmunisation -> - { english = "OPV Immunisation" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet ImmunisationOPV WellChildPCV13Immunisation -> - { english = "PCV13 Immunisation" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet ImmunisationPCV13 WellChildPhoto -> { english = "Photo" @@ -1643,10 +1729,7 @@ translationSet transId = } WellChildRotarixImmunisation -> - { english = "Rotarix Immunisation" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet ImmunisationRotarix WellChildSendToHC -> { english = "Referral" @@ -1678,18 +1761,6 @@ translationSet transId = , kirundi = Nothing } - WellChildHPVImmunisation -> - { english = "HPV Immunisation" - , kinyarwanda = Nothing - , kirundi = Nothing - } - - WellChildDTPSAImmunisation -> - { english = "DTP Standalone Immunisation" - , kinyarwanda = Nothing - , kirundi = Nothing - } - WideScopeNote -> { english = "The selected scope may contain a large number of patients and report generation could take several minutes." , kinyarwanda = Nothing diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 17fd325e63..6ed2be8a59 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -6851,9 +6851,9 @@ var $author$project$Backend$Types$BackendReturn = F4( function (model, cmd, error, appMsgs) { return {appMsgs: appMsgs, cmd: cmd, error: error, model: model}; }); -var $author$project$Backend$Completion$Model$CompletionData = F8( - function (site, entityName, entityType, acuteIllnessData, homeVisitData, nutritionIndividualData, nutritionGroupData, wellChildData) { - return {acuteIllnessData: acuteIllnessData, entityName: entityName, entityType: entityType, homeVisitData: homeVisitData, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site, wellChildData: wellChildData}; +var $author$project$Backend$Completion$Model$CompletionData = F9( + function (site, entityName, entityType, acuteIllnessData, childScoreboardData, homeVisitData, nutritionIndividualData, nutritionGroupData, wellChildData) { + return {acuteIllnessData: acuteIllnessData, childScoreboardData: childScoreboardData, entityName: entityName, entityType: entityType, homeVisitData: homeVisitData, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site, wellChildData: wellChildData}; }); var $author$project$Backend$Completion$Model$AcuteIllnessAcuteFindings = {$: 'AcuteIllnessAcuteFindings'}; var $author$project$Backend$Completion$Model$AcuteIllnessCOVIDTesting = {$: 'AcuteIllnessCOVIDTesting'}; @@ -6930,6 +6930,39 @@ var $author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping = f return $elm$core$Maybe$Nothing; } }; +var $author$project$Backend$Completion$Model$ChildScoreboardBCGImmunisation = {$: 'ChildScoreboardBCGImmunisation'}; +var $author$project$Backend$Completion$Model$ChildScoreboardDTPImmunisation = {$: 'ChildScoreboardDTPImmunisation'}; +var $author$project$Backend$Completion$Model$ChildScoreboardDTPSAImmunisation = {$: 'ChildScoreboardDTPSAImmunisation'}; +var $author$project$Backend$Completion$Model$ChildScoreboardIPVImmunisation = {$: 'ChildScoreboardIPVImmunisation'}; +var $author$project$Backend$Completion$Model$ChildScoreboardMRImmunisation = {$: 'ChildScoreboardMRImmunisation'}; +var $author$project$Backend$Completion$Model$ChildScoreboardNCDA = {$: 'ChildScoreboardNCDA'}; +var $author$project$Backend$Completion$Model$ChildScoreboardOPVImmunisation = {$: 'ChildScoreboardOPVImmunisation'}; +var $author$project$Backend$Completion$Model$ChildScoreboardPCV13Immunisation = {$: 'ChildScoreboardPCV13Immunisation'}; +var $author$project$Backend$Completion$Model$ChildScoreboardRotarixImmunisation = {$: 'ChildScoreboardRotarixImmunisation'}; +var $author$project$Backend$Completion$Utils$childScoreboardActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$ChildScoreboardNCDA); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$ChildScoreboardBCGImmunisation); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$ChildScoreboardDTPImmunisation); + case 'i': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$ChildScoreboardDTPSAImmunisation); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$ChildScoreboardIPVImmunisation); + case 'e': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$ChildScoreboardMRImmunisation); + case 'f': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$ChildScoreboardOPVImmunisation); + case 'g': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$ChildScoreboardPCV13Immunisation); + case 'h': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$ChildScoreboardRotarixImmunisation); + default: + return $elm$core$Maybe$Nothing; + } +}; var $author$project$Backend$Completion$Model$EncounterData = F3( function (startDate, takenBy, completion) { return {completion: completion, startDate: startDate, takenBy: takenBy}; @@ -8177,22 +8210,28 @@ var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'acute_illness']), + ['results', 'child_scoreboard']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$childScoreboardActivityFromMapping)), A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_type', - $author$project$Backend$Completion$Decoder$decodeSelectedEntity, + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, + _List_fromArray( + ['results', 'acute_illness']), + $elm$json$Json$Decode$list( + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_name', - $elm$json$Json$Decode$string, + 'entity_type', + $author$project$Backend$Completion$Decoder$decodeSelectedEntity, A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'site', - $author$project$Backend$Decoder$decodeSite, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData))))))))); + 'entity_name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData)))))))))); var $author$project$Backend$Completion$Update$update = F3( function (currentDate, msg, model) { var value = msg.a; @@ -9958,12 +9997,22 @@ var $author$project$Translate$Global = {$: 'Global'}; var $author$project$Translate$HealthCenter = {$: 'HealthCenter'}; var $author$project$Translate$HomeVisit = {$: 'HomeVisit'}; var $author$project$Translate$Hygiene = {$: 'Hygiene'}; +var $author$project$Translate$ImmunisationBCG = {$: 'ImmunisationBCG'}; +var $author$project$Translate$ImmunisationDTP = {$: 'ImmunisationDTP'}; +var $author$project$Translate$ImmunisationDTPSA = {$: 'ImmunisationDTPSA'}; +var $author$project$Translate$ImmunisationHPV = {$: 'ImmunisationHPV'}; +var $author$project$Translate$ImmunisationIPV = {$: 'ImmunisationIPV'}; +var $author$project$Translate$ImmunisationMR = {$: 'ImmunisationMR'}; +var $author$project$Translate$ImmunisationOPV = {$: 'ImmunisationOPV'}; +var $author$project$Translate$ImmunisationPCV13 = {$: 'ImmunisationPCV13'}; +var $author$project$Translate$ImmunisationRotarix = {$: 'ImmunisationRotarix'}; var $author$project$Translate$IncidenceByMonthOneVisitOrMore = {$: 'IncidenceByMonthOneVisitOrMore'}; var $author$project$Translate$IncidenceByMonthTwoVisitsOrMore = {$: 'IncidenceByMonthTwoVisitsOrMore'}; var $author$project$Translate$IncidenceByQuarterOneVisitOrMore = {$: 'IncidenceByQuarterOneVisitOrMore'}; var $author$project$Translate$IncidenceByQuarterTwoVisitsOrMore = {$: 'IncidenceByQuarterTwoVisitsOrMore'}; var $author$project$Translate$IncidenceByYearOneVisitOrMore = {$: 'IncidenceByYearOneVisitOrMore'}; var $author$project$Translate$IncidenceByYearTwoVisitsOrMore = {$: 'IncidenceByYearTwoVisitsOrMore'}; +var $author$project$Translate$NCDA = {$: 'NCDA'}; var $author$project$Translate$NewbornExam = {$: 'NewbornExam'}; var $author$project$Translate$PrevalenceByMonthOneVisitOrMore = {$: 'PrevalenceByMonthOneVisitOrMore'}; var $author$project$Translate$PrevalenceByMonthTwoVisitsOrMore = {$: 'PrevalenceByMonthTwoVisitsOrMore'}; @@ -10346,6 +10395,46 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Cell', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'ChildScorecard': return {english: 'Child Scorecard', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'ChildScoreboardActivity': + var activity = transId.a; + switch (activity.$) { + case 'ChildScoreboardNCDA': + var $temp$transId = $author$project$Translate$NCDA; + transId = $temp$transId; + continue translationSet; + case 'ChildScoreboardBCGImmunisation': + var $temp$transId = $author$project$Translate$ImmunisationBCG; + transId = $temp$transId; + continue translationSet; + case 'ChildScoreboardDTPImmunisation': + var $temp$transId = $author$project$Translate$ImmunisationDTP; + transId = $temp$transId; + continue translationSet; + case 'ChildScoreboardDTPSAImmunisation': + var $temp$transId = $author$project$Translate$ImmunisationDTPSA; + transId = $temp$transId; + continue translationSet; + case 'ChildScoreboardIPVImmunisation': + var $temp$transId = $author$project$Translate$ImmunisationIPV; + transId = $temp$transId; + continue translationSet; + case 'ChildScoreboardMRImmunisation': + var $temp$transId = $author$project$Translate$ImmunisationMR; + transId = $temp$transId; + continue translationSet; + case 'ChildScoreboardOPVImmunisation': + var $temp$transId = $author$project$Translate$ImmunisationOPV; + transId = $temp$transId; + continue translationSet; + case 'ChildScoreboardPCV13Immunisation': + var $temp$transId = $author$project$Translate$ImmunisationPCV13; + transId = $temp$transId; + continue translationSet; + default: + var $temp$transId = $author$project$Translate$ImmunisationRotarix; + transId = $temp$transId; + continue translationSet; + } case 'CHW': return {english: 'CHW', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'District': @@ -10407,6 +10496,24 @@ var $author$project$Translate$translationSet = function (transId) { return $author$project$Translate$translateHttpError(val); case 'Hygiene': return {english: 'Hygiene', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'ImmunisationBCG': + return {english: 'BCG Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'ImmunisationDTP': + return {english: 'DTP Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'ImmunisationDTPSA': + return {english: 'DTP Standalone Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'ImmunisationHPV': + return {english: 'HPV Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'ImmunisationIPV': + return {english: 'IPV Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'ImmunisationMR': + return {english: 'MR Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'ImmunisationOPV': + return {english: 'OPV Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'ImmunisationPCV13': + return {english: 'PCV13 Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'ImmunisationRotarix': + return {english: 'Rotarix Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Impacted': return {english: 'Impacted (2+ visits)', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'IncidenceByMonthOneVisitOrMore': @@ -10445,6 +10552,8 @@ var $author$project$Translate$translationSet = function (transId) { return A3($author$project$Translate$translateMonthYY, month, year, _short); case 'NCD': return {english: 'NCD', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDA': + return {english: 'NCDA', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NCDADemographicsItemLabel': var item = transId.a; switch (item.$) { @@ -10899,7 +11008,9 @@ var $author$project$Translate$translationSet = function (transId) { case 'WellChildAlbendazole': return {english: 'Albendazole', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildBCGImmunisation': - return {english: 'BCG Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$ImmunisationBCG; + transId = $temp$transId; + continue translationSet; case 'WellChildCaring': var $temp$transId = $author$project$Translate$Caring; transId = $temp$transId; @@ -10907,7 +11018,13 @@ var $author$project$Translate$translationSet = function (transId) { case 'WellChildContributingFactors': return {english: 'Contributing Factors', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildDTPImmunisation': - return {english: 'DTP Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$ImmunisationDTP; + transId = $temp$transId; + continue translationSet; + case 'WellChildDTPSAImmunisation': + var $temp$transId = $author$project$Translate$ImmunisationDTPSA; + transId = $temp$transId; + continue translationSet; case 'WellChildECD': return {english: 'ECD', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildFeeding': @@ -10926,34 +11043,50 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Health Education', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildHeight': return {english: 'Height', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'WellChildHPVImmunisation': + var $temp$transId = $author$project$Translate$ImmunisationHPV; + transId = $temp$transId; + continue translationSet; case 'WellChildHygiene': var $temp$transId = $author$project$Translate$Hygiene; transId = $temp$transId; continue translationSet; case 'WellChildIPVImmunisation': - return {english: 'IPV Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$ImmunisationIPV; + transId = $temp$transId; + continue translationSet; case 'WellChildMebendezole': return {english: 'Mebendezole', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildMRImmunisation': - return {english: 'MR Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$ImmunisationMR; + transId = $temp$transId; + continue translationSet; case 'WellChildMUAC': return {english: 'MUAC', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildNCDA': - return {english: 'NCDA', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$NCDA; + transId = $temp$transId; + continue translationSet; case 'WellChildNextVisit': return {english: 'Next Visit', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildNutrition': return {english: 'Nutrition', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildOPVImmunisation': - return {english: 'OPV Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$ImmunisationOPV; + transId = $temp$transId; + continue translationSet; case 'WellChildPCV13Immunisation': - return {english: 'PCV13 Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$ImmunisationPCV13; + transId = $temp$transId; + continue translationSet; case 'WellChildPhoto': return {english: 'Photo', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildPregnancySummary': return {english: 'Pregnancy Summary', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildRotarixImmunisation': - return {english: 'Rotarix Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$ImmunisationRotarix; + transId = $temp$transId; + continue translationSet; case 'WellChildSendToHC': return {english: 'Referral', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildSymptomsReview': @@ -10962,12 +11095,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Vitals', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildVitaminA': return {english: 'Vitamin A', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; - case 'WellChildWeight': - return {english: 'Weight', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; - case 'WellChildHPVImmunisation': - return {english: 'HPV Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; default: - return {english: 'DTP Standalone Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Weight', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; } case 'WideScopeNote': return {english: 'The selected scope may contain a large number of patients and report generation could take several minutes.', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; From 34a0fdf73b945072e7a55f9297e0400561b085fe Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 6 Sep 2024 18:37:20 +0300 Subject: [PATCH 113/185] Client logic --- server/elm/src/Pages/Completion/Model.elm | 1 + server/elm/src/Pages/Completion/Utils.elm | 27 +++++ server/elm/src/Pages/Completion/View.elm | 45 ++++++++- server/elm/src/Translate.elm | 3 + .../modules/custom/hedley_general/css/elm.css | 3 + .../custom/hedley_general/js/elm-main.js | 99 ++++++++++++++++++- 6 files changed, 174 insertions(+), 4 deletions(-) diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index 10382d2f33..e551830a10 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -28,6 +28,7 @@ emptyModel = type ReportType = ReportAcuteIllness + | ReportChildScoreboard | ReportHomeVisit | ReportNewbornExam | ReportNutritionGroup diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index 74a0a2eca2..25b14fe943 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -4,6 +4,7 @@ import App.Types exposing (Site(..)) import Backend.Completion.Model exposing ( AcuteIllnessActivity(..) + , ChildScoreboardActivity(..) , HomeVisitActivity(..) , NutritionChildActivity(..) , NutritionMotherActivity(..) @@ -19,6 +20,9 @@ reportTypeToString reportType = ReportAcuteIllness -> "acute-illness" + ReportChildScoreboard -> + "child-scoreboard" + ReportHomeVisit -> "home-visit" @@ -41,6 +45,9 @@ reportTypeFromString reportType = "acute-illness" -> Just ReportAcuteIllness + "child-scoreboard" -> + Just ReportChildScoreboard + "home-visit" -> Just ReportHomeVisit @@ -185,3 +192,23 @@ allHomeVisitActivities = , HomeVisitFoodSecurity , HomeVisitHygiene ] + + +resolveChildScoreboardActivities : Site -> List ChildScoreboardActivity +resolveChildScoreboardActivities site = + [ ChildScoreboardNCDA + , ChildScoreboardBCGImmunisation + , ChildScoreboardDTPImmunisation + , ChildScoreboardIPVImmunisation + , ChildScoreboardMRImmunisation + , ChildScoreboardOPVImmunisation + , ChildScoreboardPCV13Immunisation + , ChildScoreboardRotarixImmunisation + ] + ++ (case site of + SiteBurundi -> + [ ChildScoreboardDTPSAImmunisation ] + + _ -> + [] + ) diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index 41254ff220..8926f88eea 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -5,6 +5,7 @@ import AssocList as Dict exposing (Dict) import Backend.Completion.Model exposing ( AcuteIllnessActivity(..) + , ChildScoreboardActivity(..) , CompletionData , EncounterData , HomeVisitActivity(..) @@ -83,7 +84,8 @@ viewCompletionData language currentDate themePath data model = if List.member reportType [ -- Exclusively CHW encounters. - ReportHomeVisit + ReportChildScoreboard + , ReportHomeVisit , ReportNewbornExam ] then @@ -196,6 +198,9 @@ viewCompletionData language currentDate themePath data model = ReportAcuteIllness -> viewAcuteIllnessReport language startDate limitDate model.takenBy data.acuteIllnessData + ReportChildScoreboard -> + viewChildScoreboardReport language data.site startDate limitDate model.takenBy data.childScoreboardData + ReportHomeVisit -> viewHomeVisitReport language startDate limitDate model.takenBy data.homeVisitData @@ -222,6 +227,7 @@ viewCompletionData language currentDate themePath data model = [ viewSelectListInput language model.reportType [ ReportAcuteIllness + , ReportChildScoreboard , ReportHomeVisit , ReportNewbornExam , ReportNutritionGroup @@ -313,6 +319,15 @@ viewHomeVisitReport language startDate limitDate mTakenBy reportData = |> div [ class "report home-visit" ] +viewChildScoreboardReport : Language -> Site -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData ChildScoreboardActivity) -> Html Msg +viewChildScoreboardReport language site startDate limitDate mTakenBy reportData = + eliminateEmptyEncounters reportData + |> applyFilters startDate limitDate mTakenBy + |> generateChildScoreboardReportData language (resolveChildScoreboardActivities site) + |> viewMetricsResultsTable + |> div [ class "report child-scoreboard" ] + + eliminateEmptyEncounters : List { c | completion : { b | completedActivities : List a } } -> List { c | completion : { b | completedActivities : List a } } @@ -521,6 +536,34 @@ generateHomeVisitReportData language records = } +generateChildScoreboardReportData : + Language + -> List ChildScoreboardActivity + -> List (EncounterData ChildScoreboardActivity) + -> MetricsResultsTableData +generateChildScoreboardReportData language activities records = + { heading = translate language Translate.ChildScorecard + , captions = generateCaptionsList language + , rows = + List.map + (\activity -> + let + expected = + countOccurrences (.completion >> .expectedActivities) activity records + + completed = + countOccurrences (.completion >> .completedActivities) activity records + in + [ translate language <| Translate.ChildScoreboardActivity activity + , String.fromInt expected + , String.fromInt completed + , calcualtePercentage completed expected + ] + ) + activities + } + + -- Helper functions. diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 074d6d7535..42cac55e96 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -534,6 +534,9 @@ translationSet transId = Pages.Completion.Model.ReportAcuteIllness -> translationSet AcuteIllness + Pages.Completion.Model.ReportChildScoreboard -> + translationSet ChildScorecard + Pages.Completion.Model.ReportHomeVisit -> translationSet HomeVisit diff --git a/server/hedley/modules/custom/hedley_general/css/elm.css b/server/hedley/modules/custom/hedley_general/css/elm.css index e7b32d919c..7630b8ab44 100644 --- a/server/hedley/modules/custom/hedley_general/css/elm.css +++ b/server/hedley/modules/custom/hedley_general/css/elm.css @@ -395,6 +395,7 @@ body.admin-menu #page-wrapper #header { } .page-content .inputs .report.acute-illness .table .row .item.row-label, +.page-content .inputs .report.child-scoreboard .table .row .item.row-label, .page-content .inputs .report.home-visit .table .row .item.row-label, .page-content .inputs .report.nutrition-group .table .row .item.row-label, .page-content .inputs .report.nutrition-individual .table .row .item.row-label, @@ -404,6 +405,8 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.acute-illness .table .row .item.heading, .page-content .inputs .report.acute-illness .table .row .item.value, +.page-content .inputs .report.child-scoreboard .table .row .item.heading, +.page-content .inputs .report.child-scoreboard .table .row .item.value, .page-content .inputs .report.home-visit .table .row .item.heading, .page-content .inputs .report.home-visit .table .row .item.value, .page-content .inputs .report.nutrition-group .table .row .item.heading, diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 6ed2be8a59..eb1b0cfb3a 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5826,6 +5826,7 @@ var $elm_community$maybe_extra$Maybe$Extra$or = F2( } }); var $author$project$Pages$Completion$Model$ReportAcuteIllness = {$: 'ReportAcuteIllness'}; +var $author$project$Pages$Completion$Model$ReportChildScoreboard = {$: 'ReportChildScoreboard'}; var $author$project$Pages$Completion$Model$ReportHomeVisit = {$: 'ReportHomeVisit'}; var $author$project$Pages$Completion$Model$ReportNewbornExam = {$: 'ReportNewbornExam'}; var $author$project$Pages$Completion$Model$ReportNutritionGroup = {$: 'ReportNutritionGroup'}; @@ -5835,6 +5836,8 @@ var $author$project$Pages$Completion$Utils$reportTypeFromString = function (repo switch (reportType) { case 'acute-illness': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportAcuteIllness); + case 'child-scoreboard': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportChildScoreboard); case 'home-visit': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportHomeVisit); case 'newborn-exam': @@ -9990,6 +9993,7 @@ var $elm$json$Json$Decode$decodeString = _Json_runOnString; var $author$project$Translate$AcuteIllness = {$: 'AcuteIllness'}; var $author$project$Translate$Caring = {$: 'Caring'}; var $author$project$Translate$Cell = {$: 'Cell'}; +var $author$project$Translate$ChildScorecard = {$: 'ChildScorecard'}; var $author$project$Translate$District = {$: 'District'}; var $author$project$Translate$Feeding = {$: 'Feeding'}; var $author$project$Translate$FoodSecurity = {$: 'FoodSecurity'}; @@ -10370,6 +10374,10 @@ var $author$project$Translate$translationSet = function (transId) { var $temp$transId = $author$project$Translate$AcuteIllness; transId = $temp$transId; continue translationSet; + case 'ReportChildScoreboard': + var $temp$transId = $author$project$Translate$ChildScorecard; + transId = $temp$transId; + continue translationSet; case 'ReportHomeVisit': var $temp$transId = $author$project$Translate$HomeVisit; transId = $temp$transId; @@ -11993,6 +12001,8 @@ var $author$project$Pages$Completion$Utils$reportTypeToString = function (report switch (reportType.$) { case 'ReportAcuteIllness': return 'acute-illness'; + case 'ReportChildScoreboard': + return 'child-scoreboard'; case 'ReportHomeVisit': return 'home-visit'; case 'ReportNewbornExam': @@ -13374,6 +13384,88 @@ var $author$project$DateSelector$SelectorPopup$viewCalendarPopup = F3( }, popupState); }); +var $author$project$Translate$ChildScoreboardActivity = function (a) { + return {$: 'ChildScoreboardActivity', a: a}; +}; +var $author$project$Pages$Completion$View$generateChildScoreboardReportData = F3( + function (language, activities, records) { + return { + captions: $author$project$Pages$Completion$View$generateCaptionsList(language), + heading: A2($author$project$Translate$translate, language, $author$project$Translate$ChildScorecard), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.expectedActivities; + }), + activity, + records); + var completed = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.completedActivities; + }), + activity, + records); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$ChildScoreboardActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) + ]); + }, + activities) + }; + }); +var $author$project$Pages$Completion$Utils$resolveChildScoreboardActivities = function (site) { + return _Utils_ap( + _List_fromArray( + [$author$project$Backend$Completion$Model$ChildScoreboardNCDA, $author$project$Backend$Completion$Model$ChildScoreboardBCGImmunisation, $author$project$Backend$Completion$Model$ChildScoreboardDTPImmunisation, $author$project$Backend$Completion$Model$ChildScoreboardIPVImmunisation, $author$project$Backend$Completion$Model$ChildScoreboardMRImmunisation, $author$project$Backend$Completion$Model$ChildScoreboardOPVImmunisation, $author$project$Backend$Completion$Model$ChildScoreboardPCV13Immunisation, $author$project$Backend$Completion$Model$ChildScoreboardRotarixImmunisation]), + function () { + if (site.$ === 'SiteBurundi') { + return _List_fromArray( + [$author$project$Backend$Completion$Model$ChildScoreboardDTPSAImmunisation]); + } else { + return _List_Nil; + } + }()); +}; +var $author$project$Pages$Completion$View$viewChildScoreboardReport = F6( + function (language, site, startDate, limitDate, mTakenBy, reportData) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report child-scoreboard') + ]), + $author$project$Pages$Components$View$viewMetricsResultsTable( + A3( + $author$project$Pages$Completion$View$generateChildScoreboardReportData, + language, + $author$project$Pages$Completion$Utils$resolveChildScoreboardActivities(site), + A4( + $author$project$Pages$Completion$View$applyFilters, + startDate, + limitDate, + mTakenBy, + $author$project$Pages$Completion$View$eliminateEmptyEncounters(reportData))))); + }); var $author$project$Pages$Utils$customEmptySelectOption = F2( function (label, isSelected) { return A2( @@ -13965,7 +14057,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( $elm$core$List$member, reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNewbornExam]))) { + [$author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNewbornExam]))) { return $author$project$Gizra$Html$emptyNode; } else { var options = A2( @@ -14095,6 +14187,8 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( switch (reportType.$) { case 'ReportAcuteIllness': return A5($author$project$Pages$Completion$View$viewAcuteIllnessReport, language, startDate, limitDate, model.takenBy, data.acuteIllnessData); + case 'ReportChildScoreboard': + return A6($author$project$Pages$Completion$View$viewChildScoreboardReport, language, data.site, startDate, limitDate, model.takenBy, data.childScoreboardData); case 'ReportHomeVisit': return A5($author$project$Pages$Completion$View$viewHomeVisitReport, language, startDate, limitDate, model.takenBy, data.homeVisitData); case 'ReportNewbornExam': @@ -14138,7 +14232,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( language, model.reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportWellChild]), + [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportWellChild]), $author$project$Pages$Completion$Utils$reportTypeToString, $author$project$Pages$Completion$Model$SetReportType, $author$project$Translate$CompletionReportType, @@ -14668,7 +14762,6 @@ var $author$project$Translate$AcuteIllnessTotal = {$: 'AcuteIllnessTotal'}; var $author$project$Translate$All = {$: 'All'}; var $author$project$Translate$CBNP = {$: 'CBNP'}; var $author$project$Translate$CHW = {$: 'CHW'}; -var $author$project$Translate$ChildScorecard = {$: 'ChildScorecard'}; var $author$project$Translate$EncounterType = {$: 'EncounterType'}; var $author$project$Translate$Encounters = {$: 'Encounters'}; var $author$project$Translate$FBF = {$: 'FBF'}; From cf2554266be544fabda37c4a941e11fca9fb73bf Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 6 Sep 2024 18:42:14 +0300 Subject: [PATCH 114/185] Satisfy coder --- .../modules/custom/hedley_reports/hedley_reports.module | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 8b82fd004f..9547c5aaa3 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4438,7 +4438,8 @@ function hedley_reports_generate_completion_data_for_child_scoreboard_encounter( $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; $start_date_obj = new DateTime($start_date); - // Checking patient indicated at NCDA questioner that all vaccinations are up to date + // Checking patient indicated at NCDA questioner that all + // vaccinations are up to date. if (empty($measurements_by_type['child_scoreboard_ncda']) || empty($measurements_by_type['child_scoreboard_ncda']->field_ncda_signs)) { $up_to_date_by_ncda_response = FALSE; } @@ -4455,9 +4456,9 @@ function hedley_reports_generate_completion_data_for_child_scoreboard_encounter( $up_to_date_by_ncda_response = !$behind_by_ncda_response; } - // If patient indicated at NCDA questioner that all vaccinations are up to date, - // we'll check that they were all recorded. If not, we should have immunisation - // activities to record data currently missing. + // If patient indicated at NCDA questioner that all vaccinations are + // up to date, we'll check that they were all recorded. If not, we should + // have immunisation activities to record data currently missing. if ($up_to_date_by_ncda_response) { $encounter_data['start_date_obj'] = $start_date_obj; From 0e6e307c70a2cb8f422c8c1e0e7e9aea06ecaeaa Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 8 Sep 2024 15:51:22 +0300 Subject: [PATCH 115/185] Add reports data field to NCD encounter CT [ci skip] --- .../hedley_ncd.features.field_instance.inc | 129 ++++++++++++++++++ .../modules/custom/hedley_ncd/hedley_ncd.info | 1 + .../hedley_ncd/hedley_ncd.strongarm.inc | 88 ++++++------ 3 files changed, 174 insertions(+), 44 deletions(-) diff --git a/server/hedley/modules/custom/hedley_ncd/hedley_ncd.features.field_instance.inc b/server/hedley/modules/custom/hedley_ncd/hedley_ncd.features.field_instance.inc index 747bfe37fd..980fd07656 100644 --- a/server/hedley/modules/custom/hedley_ncd/hedley_ncd.features.field_instance.inc +++ b/server/hedley/modules/custom/hedley_ncd/hedley_ncd.features.field_instance.inc @@ -139,6 +139,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -183,6 +184,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -227,6 +229,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -271,6 +274,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -706,6 +710,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -787,6 +792,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -831,6 +837,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -875,6 +882,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1164,6 +1172,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1208,6 +1217,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1252,6 +1262,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1296,6 +1307,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1511,6 +1523,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1555,6 +1568,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1599,6 +1613,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1643,6 +1658,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1725,6 +1741,46 @@ function hedley_ncd_field_default_field_instances() { 'module' => 'options', 'settings' => array(), 'type' => 'options_buttons', + 'weight' => 3, + ), + ); + + // Exported field_instance: 'node-ncd_encounter-field_reports_data'. + $field_instances['node-ncd_encounter-field_reports_data'] = array( + 'bundle' => 'ncd_encounter', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 5, + ), + 'teaser' => array( + 'label' => 'above', + 'settings' => array(), + 'type' => 'hidden', + 'weight' => 0, + ), + ), + 'entity_type' => 'node', + 'field_name' => 'field_reports_data', + 'label' => 'Completion Data', + 'required' => 0, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'rows' => 5, + ), + 'type' => 'text_textarea', 'weight' => 4, ), ); @@ -1934,6 +1990,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2016,6 +2073,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2060,6 +2118,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2104,6 +2163,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2282,6 +2342,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2326,6 +2387,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2370,6 +2432,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2414,6 +2477,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2656,6 +2720,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2700,6 +2765,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2744,6 +2810,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2788,6 +2855,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2965,6 +3033,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3047,6 +3116,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3091,6 +3161,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3135,6 +3206,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3368,6 +3440,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3412,6 +3485,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3456,6 +3530,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3500,6 +3575,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3844,6 +3920,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3888,6 +3965,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -3969,6 +4047,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4050,6 +4129,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4376,6 +4456,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4420,6 +4501,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4464,6 +4546,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4508,6 +4591,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -4968,6 +5052,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5012,6 +5097,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5056,6 +5142,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5100,6 +5187,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5280,6 +5368,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5362,6 +5451,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5406,6 +5496,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5488,6 +5579,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5666,6 +5758,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5710,6 +5803,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5754,6 +5848,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -5798,6 +5893,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6051,6 +6147,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6095,6 +6192,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6214,6 +6312,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6258,6 +6357,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6454,6 +6554,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6498,6 +6599,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6542,6 +6644,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6586,6 +6689,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6860,6 +6964,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6904,6 +7009,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6948,6 +7054,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -6992,6 +7099,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7254,6 +7362,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7298,6 +7407,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7342,6 +7452,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7461,6 +7572,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7732,6 +7844,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7814,6 +7927,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7858,6 +7972,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -7902,6 +8017,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8042,6 +8158,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8199,6 +8316,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8243,6 +8361,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8287,6 +8406,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8671,6 +8791,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8752,6 +8873,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8796,6 +8918,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -8914,6 +9037,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9342,6 +9466,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9386,6 +9511,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9430,6 +9556,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9520,6 +9647,7 @@ function hedley_ncd_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -9627,6 +9755,7 @@ function hedley_ncd_field_default_field_instances() { t('Cigarettes Per Week'); t('CoMorbidities'); t('Completed Tests'); + t('Completion Data'); t('Creatinine Result'); t('Date Measured'); t('Date concluded'); diff --git a/server/hedley/modules/custom/hedley_ncd/hedley_ncd.info b/server/hedley/modules/custom/hedley_ncd/hedley_ncd.info index b77000e3fe..23316f7962 100644 --- a/server/hedley/modules/custom/hedley_ncd/hedley_ncd.info +++ b/server/hedley/modules/custom/hedley_ncd/hedley_ncd.info @@ -89,6 +89,7 @@ features[field_instance][] = node-ncd_danger_signs-field_person features[field_instance][] = node-ncd_danger_signs-field_shards features[field_instance][] = node-ncd_danger_signs-field_uuid features[field_instance][] = node-ncd_encounter-field_ncd_diagnoses +features[field_instance][] = node-ncd_encounter-field_reports_data features[field_instance][] = node-ncd_family_history-field_date_measured features[field_instance][] = node-ncd_family_history-field_diabetes_predecessors features[field_instance][] = node-ncd_family_history-field_heart_problem_predecessors diff --git a/server/hedley/modules/custom/hedley_ncd/hedley_ncd.strongarm.inc b/server/hedley/modules/custom/hedley_ncd/hedley_ncd.strongarm.inc index 033b2a2638..145150ef88 100644 --- a/server/hedley/modules/custom/hedley_ncd/hedley_ncd.strongarm.inc +++ b/server/hedley/modules/custom/hedley_ncd/hedley_ncd.strongarm.inc @@ -478,15 +478,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_core_exam'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_core_exam'] = $strongarm; @@ -495,15 +495,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_co_morbidities'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_co_morbidities'] = $strongarm; @@ -512,15 +512,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_creatinine_test'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_creatinine_test'] = $strongarm; @@ -529,15 +529,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_danger_signs'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_danger_signs'] = $strongarm; @@ -546,15 +546,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_family_history'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_family_history'] = $strongarm; @@ -563,15 +563,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_family_planning'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_family_planning'] = $strongarm; @@ -580,15 +580,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_hba1c_test'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_hba1c_test'] = $strongarm; @@ -597,15 +597,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_health_education'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_health_education'] = $strongarm; @@ -614,15 +614,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_hiv_test'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_hiv_test'] = $strongarm; @@ -631,15 +631,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_labs_results'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_labs_results'] = $strongarm; @@ -648,15 +648,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_lipid_panel_test'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_lipid_panel_test'] = $strongarm; @@ -665,15 +665,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_liver_function_test'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_liver_function_test'] = $strongarm; @@ -682,15 +682,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_medication_distribution'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_medication_distribution'] = $strongarm; @@ -699,15 +699,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_medication_history'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_medication_history'] = $strongarm; @@ -716,15 +716,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_outside_care'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_outside_care'] = $strongarm; @@ -733,15 +733,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_pregnancy_test'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_pregnancy_test'] = $strongarm; @@ -750,15 +750,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_random_blood_sugar_test'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_random_blood_sugar_test'] = $strongarm; @@ -767,15 +767,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_referral'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_referral'] = $strongarm; @@ -784,15 +784,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_social_history'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_social_history'] = $strongarm; @@ -801,15 +801,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_symptom_review'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_symptom_review'] = $strongarm; @@ -818,15 +818,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_urine_dipstick_test'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_urine_dipstick_test'] = $strongarm; @@ -835,15 +835,15 @@ function hedley_ncd_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__ncd_vitals'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__ncd_vitals'] = $strongarm; From 1c27c9269a09c4f195b3131bb1a16485a3b5db98 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 8 Sep 2024 22:06:20 +0300 Subject: [PATCH 116/185] Add script and implement partial logic [ci skip] --- .../hedley_reports/hedley_reports.module | 150 +++++++++++++++++- ...completion-generate-acute-illness-data.php | 2 +- ...pletion-generate-child-scoreboard-data.php | 2 +- .../completion-generate-home-visit-data.php | 2 +- .../scripts/completion-generate-ncd-data.php | 86 ++++++++++ ...ion-generate-nutrition-individual-data.php | 2 +- .../completion-generate-well-child-data.php | 2 +- 7 files changed, 240 insertions(+), 6 deletions(-) create mode 100644 server/hedley/modules/custom/hedley_reports/scripts/completion-generate-ncd-data.php diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 9547c5aaa3..8436ba20da 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4357,7 +4357,7 @@ function hedley_reports_generate_completion_data_for_home_visit_encounter($encou * Generates completion data for Child Scoreboard encounter. * * @param object $participant - * The participant node object representing illness. + * The participant node object with which encounters are associated. * @param bool $exclude_set * Indicate whether to exclude encounters with report data already set. */ @@ -4815,6 +4815,154 @@ function hedley_reports_child_scoreboard_generate_vaccination_progress_data_by_w return $return; } +/** + * Generates completion data for NCD encounters for patient. + * + * @param object $participant + * The participant node object with which encounters are associated. + * @param bool $exclude_set + * Indicate whether to exclude encounters with report data already set. + */ +function hedley_reports_generate_completion_data_for_ncd($participant, $exclude_set) { + // To reduce memory usage, mapping measurement types as single characters. + $mapping = [ + 'ncd_core_exam' => 'a', + 'ncd_co_morbidities' => 'b', + 'ncd_creatinine_test' => 'c', + 'ncd_danger_signs' => 'd', + 'ncd_family_history' => 'e', + 'ncd_family_planning' => 'f', + 'ncd_hba1c_test' => 'g', + 'ncd_health_education' => 'h', + 'ncd_hiv_test' => 'i', + // Not a real activity. Used for data only. + 'ncd_labs_results' => '', + 'ncd_lipid_panel_test' => 'j', + 'ncd_liver_function_test' => 'k', + 'ncd_medication_distribution' => 'l', + 'ncd_medication_history' => 'm', + 'ncd_outside_care' => 'n', + 'ncd_pregnancy_test' => 'o', + 'ncd_random_blood_sugar_test' => 'p', + 'ncd_referral' => 'q', + 'ncd_social_history' => 'r', + 'ncd_symptom_review' => 's', + 'ncd_urine_dipstick_test' => 't', + 'ncd_vitals' => 'u', + ]; + + // Load all encounters of current participant. + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'ncd_encounter') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_individual_participant', 'target_id', $participant->nid) + ->propertyOrderBy('nid') + ->execute(); + + if (empty($result['node'])) { + return; + } + + // Get birthdate and gender. + $person_id = $participant->field_person[LANGUAGE_NONE][0]['target_id']; + try { + $person = node_load($person_id); + $birth_date = explode(' ', $person->field_birth_date[LANGUAGE_NONE][0]['value'])[0]; + $birth_date_obj = new DateTime($birth_date); + $gender = $person->field_gender[LANGUAGE_NONE][0]['value']; + } + catch (Exception $e) { + $birth_date_obj = NULL; + $gender = 'male'; + } + + // Encounters are sorted ASC. + $encounters = node_load_multiple(array_keys($result['node'])); + $encounters_data = []; + foreach ($encounters as $encounter) { + // Skip encounter if exclusion flag is raised and it's report data is set. + if ($exclude_set && !empty($encounter->field_reports_data[LANGUAGE_NONE][0]['value'])) { + continue; + } + + // Loading all measurements that belong to encounter. + $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); + $measurements = !empty($measurements_ids) ? node_load_multiple($measurements_ids) : []; + // Ordering measurements by type. + $measurements_by_type = []; + foreach ($measurements as $measurement) { + $measurements_by_type[$measurement->type] = $measurement; + } + + $encounters_data[] = [ + 'encounter' => $encounter, + 'measurements_by_type' => $measurements_by_type, + ]; + } + + foreach ($encounters_data as $index => $encounter_data) { + $encounter = $encounter_data['encounter']; + $measurements_by_type = $encounter_data['measurements_by_type']; + + // Resolve encounter start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $start_date_obj = new DateTime($start_date); + $encounter_data['start_date_obj'] = $start_date_obj; + + // Try to resolve age in months at a time encounter was performed. + $encounter_data['age_in_months'] = hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj); + $encounter_data['previous_encounters_data'] = array_slice($encounters_data, 0, $index); + + // So far we were constructing data structures to resolve encounter data. + // Now we have enough info to determine which activities were expected. + // Load all activities expected only by encounter type and start date. + $expected = hedley_reports_ncd_generate_expected_initial_activities($encounter_data, $birth_date_obj, $gender); + + // If conditions match, add medication activities. + // hedley_reports_well_child_add_medication_activities($encounter_data, $expected); + // If conditions match, add next steps activities. + // hedley_reports_well_child_add_next_steps_activities($encounter_data, $birth_date_obj, $gender, $expected); + + $completion_data = [ + 'start_date' => $start_date, + 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), + ]; + + $encounter->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); + node_save($encounter); + } +} + +function hedley_reports_ncd_generate_expected_initial_activities($encounter_data, $birth_date_obj, $gender) { + $start_date_obj = $encounter_data['start_date_obj']; + + $expected = [ + 'ncd_danger_signs', + 'ncd_symptom_review', + 'ncd_core_exam', + 'ncd_vitals', + ]; + + // If fertile woman, add Family Planning. + if ($gender == 'female' && !empty($birth_date_obj)) { + $interval = $start_date_obj->diff($birth_date_obj); + $age_in_years = $interval->y; + + if ($age_in_years >= 13 && $age_in_years <= 44) { + $expected[] = 'ncd_family_planning'; + } + } + + // If first encounter, add Medication History. + if (empty($encounter_data['previous_encounters_data'])) { + $expected[] = 'ncd_medication_history'; + } + + return $expected; +} + /** * Resolve the age in months for patient at the time of a specific encounter. * diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-acute-illness-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-acute-illness-data.php index 5758270b6d..89480e1a6d 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-acute-illness-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-acute-illness-data.php @@ -2,7 +2,7 @@ /** * @file - * Generates completion data for different types of encounters. + * Generates completion data for Acute Illness encounters. * * Execution: drush scr * profiles/hedley/modules/custom/hedley_reports/scripts/completion-generate-acute-illness-data.php. diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php index ab9f02f11e..083b35c327 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php @@ -2,7 +2,7 @@ /** * @file - * Generates completion data for different types of encounters. + * Generates completion data for Child Scoreboard encounters. * * Execution: drush scr * profiles/hedley/modules/custom/hedley_reports/scripts/completion-generate-child-scoreboard-data.php. diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php index 1966df3233..56fcaa7d62 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php @@ -2,7 +2,7 @@ /** * @file - * Generates completion data for different types of encounters. + * Generates completion data for Home Visit encounters. * * Execution: drush scr * profiles/hedley/modules/custom/hedley_reports/scripts/completion-generate-home-visit-data.php. diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-ncd-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-ncd-data.php new file mode 100644 index 0000000000..4a45eb31b8 --- /dev/null +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-ncd-data.php @@ -0,0 +1,86 @@ +entityCondition('entity_type', 'node') + ->entityCondition('bundle', $type) + ->fieldCondition('field_encounter_type', 'value', 'ncd') + ->propertyCondition('status', NODE_PUBLISHED) + ->addTag('exclude_deleted'); + +$count_query = clone $base_query; +$count_query->propertyCondition('nid', $nid, '>'); +$count = $count_query->count()->execute(); + +if ($count == 0) { + drush_print("There are no nodes of type $type for ncd encounters in DB."); + exit; +} + +$total = 0; +drush_print("$count nodes of type $type for ncd encounters located."); + +while (TRUE) { + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + hedley_reports_generate_completion_data_for_ncd($node, $exclude_set); + $total++; + + $memory = round(memory_get_usage() / 1048576); + if ($memory >= $memory_limit) { + drush_print(dt('Stopped before out of memory. Start process from the node ID @nid', ['@nid' => $nid])); + return; + } + } + + $memory = round(memory_get_usage() / 1048576); + drush_print("Calculated so far: $total, Memory: $memory"); + + // Free up memory. + drupal_static_reset(); + + $nid = end($ids); +} + +drush_print("Done! Completion data calculated for $total participants."); diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-individual-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-individual-data.php index 057e8d8a1b..0280aea64e 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-individual-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-individual-data.php @@ -2,7 +2,7 @@ /** * @file - * Generates completion data for different types of encounters. + * Generates completion data for Nutrition encounters. * * Execution: drush scr * profiles/hedley/modules/custom/hedley_reports/scripts/completion-generate-nutrition-individual-data.php. diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php index 1540385f17..31838e3077 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php @@ -2,7 +2,7 @@ /** * @file - * Generates completion data for different types of encounters. + * Generates completion data for Well Child encounters. * * Execution: drush scr * profiles/hedley/modules/custom/hedley_reports/scripts/completion-generate-well-child-data.php. From 4be3c1ce01247360f240f3b06ecec748fc4ce6ec Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 9 Sep 2024 13:07:53 +0300 Subject: [PATCH 117/185] Add labs activities [ci skip] --- client/src/elm/Measurement/Utils.elm | 8 +- client/src/elm/Pages/NCD/Activity/Utils.elm | 3 +- .../hedley_general/hedley_general.module | 5 + .../hedley_reports/hedley_reports.module | 208 +++++++++++++++++- 4 files changed, 216 insertions(+), 8 deletions(-) diff --git a/client/src/elm/Measurement/Utils.elm b/client/src/elm/Measurement/Utils.elm index a593a90f32..9486bbde20 100644 --- a/client/src/elm/Measurement/Utils.elm +++ b/client/src/elm/Measurement/Utils.elm @@ -8229,7 +8229,11 @@ resolveLabTestDate currentDate resultsExistFunc resultsValidFunc measurement = |> Maybe.andThen (\value -> if testPerformedByExecutionNote value.executionNote then - if resultsExistFunc value && (not <| resultsValidFunc value) then + let + resultsExist = + resultsExistFunc value + in + if resultsExist && (not <| resultsValidFunc value) then -- Entered result is not valid, therefore, -- we treat the test as if it was not performed. Nothing @@ -8247,7 +8251,7 @@ resolveLabTestDate currentDate resultsExistFunc resultsValidFunc measurement = Maybe.map (Tuple.second >> .dateMeasured) measurement |> Maybe.withDefault currentDate in - if (not <| resultsExistFunc value) && (Date.diff Days dateMeasured currentDate >= labExpirationPeriod) then + if not resultsExist && (Date.diff Days dateMeasured currentDate >= labExpirationPeriod) then -- No results were entered for more than 35 days since the -- day on which measurement was taken. -- Test is considered expired, and is being ignored diff --git a/client/src/elm/Pages/NCD/Activity/Utils.elm b/client/src/elm/Pages/NCD/Activity/Utils.elm index 2572c0121b..2a5312ef94 100644 --- a/client/src/elm/Pages/NCD/Activity/Utils.elm +++ b/client/src/elm/Pages/NCD/Activity/Utils.elm @@ -857,7 +857,7 @@ expectLaboratoryTask currentDate assembled task = recurrentTestRequired 12 TaskLiverFunctionTest TaskLipidPanelTest -> - recurrentTestRequired 12 TaskLiverFunctionTest + recurrentTestRequired 12 TaskLipidPanelTest TaskHbA1cTest -> recurrentTestRequired 6 TaskHbA1cTest @@ -884,6 +884,7 @@ generatePreviousLaboratoryTestsDatesDict currentDate assembled = , ( TaskPregnancyTest, generateTestDates .pregnancyTest (.testResult >> isJust) isTestResultValid ) , ( TaskCreatinineTest, generateTestDates .creatinineTest (.creatinineResult >> isJust) (always True) ) , ( TaskLiverFunctionTest, generateTestDates .liverFunctionTest (.altResult >> isJust) (always True) ) + , ( TaskLipidPanelTest, generateTestDates .lipidPanelTest (.totalCholesterolResult >> isJust) (always True) ) , ( TaskHbA1cTest, generateTestDates .hba1cTest (.hba1cResult >> isJust) (always True) ) ] |> Dict.fromList diff --git a/server/hedley/modules/custom/hedley_general/hedley_general.module b/server/hedley/modules/custom/hedley_general/hedley_general.module index 225d1a7635..650745814b 100644 --- a/server/hedley/modules/custom/hedley_general/hedley_general.module +++ b/server/hedley/modules/custom/hedley_general/hedley_general.module @@ -5,6 +5,11 @@ * Code for the Hedley General feature. */ +// Maximal number of days that may pass between the date on which test +// execution was recorded, and the date when the results should be set. +define('HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD', 35); + + /** * Creating a new AQ task of a specific queue if not exist. * diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 8436ba20da..f2dffb7a53 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2155,7 +2155,7 @@ function hedley_reports_generate_completion_data_for_nutrition_group_encounter($ } } - // Resolve encounter start date. We gp by the date of attendance + // Resolve encounter start date. We go by the date of attendance // measurement, since session may have lasted several days. $start_date = explode(' ', $attendance->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; $start_date_obj = new DateTime($start_date); @@ -4920,8 +4920,8 @@ function hedley_reports_generate_completion_data_for_ncd($participant, $exclude_ // Load all activities expected only by encounter type and start date. $expected = hedley_reports_ncd_generate_expected_initial_activities($encounter_data, $birth_date_obj, $gender); - // If conditions match, add medication activities. - // hedley_reports_well_child_add_medication_activities($encounter_data, $expected); + // If conditions match, add labs activities. + hedley_reports_ncd_add_labs_activities($encounter_data, $birth_date_obj, $gender, $expected); // If conditions match, add next steps activities. // hedley_reports_well_child_add_next_steps_activities($encounter_data, $birth_date_obj, $gender, $expected); @@ -4955,14 +4955,212 @@ function hedley_reports_ncd_generate_expected_initial_activities($encounter_data } } - // If first encounter, add Medication History. + // If first encounter, add all Medical History activities. if (empty($encounter_data['previous_encounters_data'])) { - $expected[] = 'ncd_medication_history'; + $expected = array_merge( + $expected, + [ + 'ncd_co_morbidities', + 'ncd_medication_history', + 'ncd_social_history', + 'ncd_family_history', + 'ncd_outside_care', + ] + ); + } + // If subsequent encounter, add Outside Care. + else { + $expected[] = 'ncd_outside_care'; } return $expected; } +function hedley_reports_ncd_add_labs_activities($encounter_data, $birth_date_obj, $gender, $expected) { + // Blood sugar test is performed unconditionally. + $expected[] = 'ncd_random_blood_sugar_test'; + + $tests_dates_by_lab_type = [ + 'ncd_creatinine_test' => [], + 'ncd_hba1c_test' => [], + 'ncd_hiv_test' => [], + 'ncd_lipid_panel_test' => [], + 'ncd_liver_function_test' => [], + 'ncd_pregnancy_test' => [], + 'ncd_urine_dipstick_test' => [], + ]; + $hiv_known_as_positive = FALSE; + + // Reversing, to have most recent dates first. + $previous_encounters_data = array_reverse($encounter_data['previous_encounters_data']); + foreach ($previous_encounters_data as $previous_encounter_data) { + $measurements_by_type = $previous_encounter_data['measurements_by_type']; + + $creatinine_test = $measurements_by_type['ncd_creatinine_test']; + if (hedley_reports_lab_test_performed_by_execution_note($creatinine_test)) { + $date_measured = explode(' ', $creatinine_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; + $date_measured_obj = new DateTime($date_measured); + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $results_exists = !empty($creatinine_test->field_creatinine_result) && !empty($creatinine_test->field_creatinine_result[LANGUAGE_NONE][0]['value']); + if ($results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { + $tests_dates_by_lab_type['ncd_creatinine_test'][] = explode(' ', $creatinine_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; + } + } + + $hba1c_test = $measurements_by_type['ncd_hba1c_test']; + if (hedley_reports_lab_test_performed_by_execution_note($hba1c_test)) { + $date_measured = explode(' ', $hba1c_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; + $date_measured_obj = new DateTime($date_measured); + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $results_exists = !empty($hba1c_test->field_hba1c_result) && !empty($hba1c_test->field_hba1c_result[LANGUAGE_NONE][0]['value']); + if ($results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { + $tests_dates_by_lab_type['ncd_hba1c_test'][] = explode(' ', $hba1c_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; + } + } + + $hiv_test = $measurements_by_type['ncd_hiv_test']; + if (!$hiv_known_as_positive) { + if (!empty($test) && !empty($test->field_test_execution_note)) { + $hiv_known_as_positive = $test->field_test_execution_note[LANGUAGE_NONE][0]['value'] == 'known-as-positive'; + if (!$hiv_known_as_positive && hedley_reports_lab_test_performed_by_execution_note($hiv_test)) { + $date_measured = explode(' ', $hiv_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; + $date_measured_obj = new DateTime($date_measured); + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $valid_results_exists = + !empty($hiv_test->field_test_result) && + !empty($hiv_test->field_test_result[LANGUAGE_NONE][0]['value']) && + $hiv_test->field_test_result[LANGUAGE_NONE][0]['value'] != 'indeterminate'; + if ($valid_results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { + $tests_dates_by_lab_type['ncd_hiv_test'][] = explode(' ', $hiv_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; + } + } + } + } + + $lipid_panel_test = $measurements_by_type['ncd_lipid_panel_test']; + if (hedley_reports_lab_test_performed_by_execution_note($lipid_panel_test)) { + $date_measured = explode(' ', $lipid_panel_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; + $date_measured_obj = new DateTime($date_measured); + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $results_exists = !empty($lipid_panel_test->field_total_cholesterol) && !empty($lipid_panel_test->field_total_cholesterol[LANGUAGE_NONE][0]['value']); + if ($results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { + $tests_dates_by_lab_type['ncd_lipid_panel_test'][] = explode(' ', $lipid_panel_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; + } + } + + $liver_function_test = $measurements_by_type['ncd_liver_function_test']; + if (hedley_reports_lab_test_performed_by_execution_note($liver_function_test)) { + $date_measured = explode(' ', $liver_function_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; + $date_measured_obj = new DateTime($date_measured); + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $results_exists = !empty($liver_function_test->field_alt_result) && !empty($liver_function_test->field_alt_result[LANGUAGE_NONE][0]['value']); + if ($results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { + $tests_dates_by_lab_type['ncd_liver_function_test'][] = explode(' ', $liver_function_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; + } + } + + $pregnancy_test = $measurements_by_type['ncd_pregnancy_test']; + if (hedley_reports_lab_test_performed_by_execution_note($pregnancy_test)) { + $date_measured = explode(' ', $pregnancy_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; + $date_measured_obj = new DateTime($date_measured); + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $valid_results_exists = + !empty($hiv_test->field_test_result) && + !empty($hiv_test->field_test_result[LANGUAGE_NONE][0]['value']) && + $hiv_test->field_test_result[LANGUAGE_NONE][0]['value'] != 'indeterminate'; + if ($valid_results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { + $tests_dates_by_lab_type['ncd_pregnancy_test'][] = explode(' ', $pregnancy_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; + } + } + + $urine_dipstick_test = $measurements_by_type['ncd_urine_dipstick_test']; + if (hedley_reports_lab_test_performed_by_execution_note($urine_dipstick_test)) { + $date_measured = explode(' ', $urine_dipstick_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; + $date_measured_obj = new DateTime($date_measured); + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $results_exists = !empty($urine_dipstick_test->field_protein) && !empty($urine_dipstick_test->field_protein[LANGUAGE_NONE][0]['value']); + if ($results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { + $tests_dates_by_lab_type['ncd_urine_dipstick_test'][] = explode(' ', $urine_dipstick_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; + } + } + } + + foreach ($tests_dates_by_lab_type as $test_name => $dates_by_lab_type) { + $last_date = reset($dates_by_lab_type); + switch ($test_name) { + case 'ncd_creatinine_test': + if (hedley_reports_recurrent_test_required($last_date, $encounter_data['start_date_obj'], 12)) { + $expected[] = 'ncd_creatinine_test'; + } + break; + + case 'ncd_hba1c_test': + if (hedley_reports_recurrent_test_required($last_date, $encounter_data['start_date_obj'], 6)) { + $expected[] = 'ncd_hba1c_test'; + } + break; + + case 'ncd_hiv_test': + if (!$hiv_known_as_positive && empty($last_date)) { + $expected[] = 'ncd_hiv_test'; + } + break; + + case 'ncd_lipid_panel_test': + if (hedley_reports_recurrent_test_required($last_date, $encounter_data['start_date_obj'], 12)) { + $expected[] = 'ncd_lipid_panel_test'; + } + break; + + case 'ncd_liver_function_test': + if (hedley_reports_recurrent_test_required($last_date, $encounter_data['start_date_obj'], 12)) { + $expected[] = 'ncd_liver_function_test'; + } + break; + + case 'ncd_pregnancy_test': + if (empty($last_date)) { + if ($gender == 'female' && !empty($birth_date_obj)) { + $interval = $encounter_data['start_date_obj']->diff($birth_date_obj); + $age_in_years = $interval->y; + + if ($age_in_years >= 13 && $age_in_years <= 44) { + $expected[] = 'ncd_pregnancy_test'; + } + } + } + break; + + case 'ncd_urine_dipstick_test': + if (hedley_reports_recurrent_test_required($last_date, $encounter_data['start_date_obj'], 12)) { + $expected[] = 'ncd_urine_dipstick_test'; + } + break; + } + } +} + +function hedley_reports_lab_test_performed_by_execution_note($test) { + if (empty($test) || empty($test->field_test_execution_note)) { + return FALSE; + } + + return in_array( + $test->field_test_execution_note[LANGUAGE_NONE][0]['value'], + ['run-today', 'run-previously', 'run-confirmed-by-lab-tech'] + ); +} + +function hedley_reports_recurrent_test_required($last_date, $encounter_start_date_obj, $period_between_tests) { + if (empty($last_date)) { + return TRUE; + } + + $last_date_obj = new DateTime($last_date); + $diff_months = $encounter_start_date_obj->diff($last_date_obj)->months; + return $diff_months >= $period_between_tests; +} + /** * Resolve the age in months for patient at the time of a specific encounter. * From e5daf23c7ef430e6f8965b938e15d8fccf3136ca Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 10 Sep 2024 11:31:20 +0300 Subject: [PATCH 118/185] Add next steps activities [ci skip] --- .../hedley_reports/hedley_reports.module | 145 +++++++++++++++++- 1 file changed, 144 insertions(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index f2dffb7a53..689a5f5acb 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4923,7 +4923,7 @@ function hedley_reports_generate_completion_data_for_ncd($participant, $exclude_ // If conditions match, add labs activities. hedley_reports_ncd_add_labs_activities($encounter_data, $birth_date_obj, $gender, $expected); // If conditions match, add next steps activities. - // hedley_reports_well_child_add_next_steps_activities($encounter_data, $birth_date_obj, $gender, $expected); + hedley_reports_ncd_add_next_steps_activities($encounter_data, $birth_date_obj, $gender, $expected); $completion_data = [ 'start_date' => $start_date, @@ -5140,6 +5140,149 @@ function hedley_reports_ncd_add_labs_activities($encounter_data, $birth_date_obj } } +/** + * Adds Next Steps activities to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_ncd_add_next_steps_activities(array $encounter_data, $birth_date_obj, $gender, array &$expected) { + // Resolving diagnoses from current encounter. + $current_encounter = $encounter_data['encounter']; + $measurements_by_type = $encounter_data['measurements_by_type']; + $current_encounter_diagnoses = []; + if (!empty($current_encounter->field_ncd_diagnoses)) { + foreach ($current_encounter->field_ncd_diagnoses[LANGUAGE_NONE] as $diagnosis) { + if ($diagnosis['value'] != 'none') { + $current_encounter_diagnoses[] = $diagnosis['value']; + } + } + } + + // Resolving diagnoses from previous encounters. + $previous_encounters_diagnoses = []; + // Reversing, to have most recent dates first. + $previous_encounters_data = array_reverse($encounter_data['previous_encounters_data']); + foreach ($previous_encounters_data as $previous_encounter_data) { + $previous_encounter = $previous_encounter_data['encounter']; + if (!empty($previous_encounter->field_ncd_diagnoses)) { + foreach ($previous_encounter->field_ncd_diagnoses[LANGUAGE_NONE] as $diagnosis) { + if ($diagnosis['value'] != 'none') { + $previous_encounters_diagnoses[] = $diagnosis['value']; + } + } + } + } + + // Checking is patient is pregnant. + $patient_pregnant = FALSE; + $pregnancy_test = $measurements_by_type['ncd_pregnancy_test']; + if (!empty(($pregnancy_test->field_test_execution_note))) { + $patient_pregnant = $pregnancy_test->field_test_execution_note[LANGUAGE_NONE][0]['value'] == 'known-as-positive'; + } + if (!$patient_pregnant &&!empty(($pregnancy_test->field_test_result))) { + $patient_pregnant = $pregnancy_test->field_test_result[LANGUAGE_NONE][0]['value'] == 'positive'; + } + + $hypertension_diagnoses = [ + 'hypertension-stage1', + 'hypertension-stage2', + 'hypertension-stage3' + ]; + $diabetes_diagnoses = ['diabetes-initial', 'diabetes-recurrent']; + $diabetes_diagnoses_with_renal = array_merge($diabetes_diagnoses, ['renal-complications']); + + if ( + !$patient_pregnant && + in_array('hypertension-stage1', $current_encounter_diagnoses) && + empty(array_intersect($previous_encounters_diagnoses, $hypertension_diagnoses)) && + empty( + array_intersect( + $current_encounter_diagnoses, + ['renal-complications', 'diabetes-initial'] + ) + ) && + empty(array_intersect($previous_encounters_diagnoses, $diabetes_diagnoses_with_renal)) + ) { + $expected[] = 'ncd_health_education'; + } + + // List of all diagnoses. Most recent one comes first. + $all_diagnoses = array_merge($current_encounter_diagnoses, $previous_encounters_diagnoses); + + // Checking if Medication Distribution is expected. + $medicated_for_diabetes = !empty(array_intersect($all_diagnoses, $diabetes_diagnoses)); + + $current_hypertension_stage = ''; + foreach ($all_diagnoses as $diagnosis) { + if (in_array($diagnosis, $hypertension_diagnoses)) { + $current_hypertension_stage = $diagnosis; + break; + } + } + + $medicate_for_hypertension_initial_phase = FALSE; + if (!empty($current_hypertension_stage)) { + if ($current_hypertension_stage == 'hypertension-stage1') { + if ( + $patient_pregnant || + in_array('diabetes-initial', $current_encounter_diagnoses) || + !empty(array_intersect($previous_encounters_diagnoses, $hypertension_diagnoses)) || + !empty(array_intersect($previous_encounters_diagnoses, $diabetes_diagnoses_with_renal)) + ) { + $medicate_for_hypertension_initial_phase = TRUE; + } + } + else { + $medicate_for_hypertension_initial_phase = TRUE; + } + } + + $medicate_for_hypertension_recurrent_phase = FALSE; + if (!$medicate_for_hypertension_initial_phase) { + if ( + in_array('hypertension-stage1', $current_encounter_diagnoses) && + !empty( + array_intersect( + $current_encounter_diagnoses, + ['renal-complications', 'diabetes-recurrent'] + ) + ) && + empty(array_intersect($previous_encounters_diagnoses, $hypertension_diagnoses)) && + empty(array_intersect($previous_encounters_diagnoses, $diabetes_diagnoses_with_renal)) + ) { + $medicate_for_hypertension_recurrent_phase = TRUE; + } + } + $medicate_for_hypertension = $medicate_for_hypertension_initial_phase || $medicate_for_hypertension_recurrent_phase; + + if ($medicated_for_diabetes || $medicate_for_hypertension) { + $expected[] = 'ncd_medication_distribution'; + } + + // Checking if Referral is expected. + $refer_for_hypertension = FALSE; + if (!empty($current_hypertension_stage)) { + $refer_for_hypertension = $patient_pregnant || ($current_hypertension_stage == 'hypertension-stage3'); + } + + $refer_for_diabetes = FALSE; + if (!empty($current_hypertension_stage)) { + $refer_for_diabetes = !empty(array_intersect($all_diagnoses, $diabetes_diagnoses)); + } + + $refer_for_renal_omplications = FALSE; + if (!empty($current_hypertension_stage)) { + $refer_for_renal_omplications = in_array('renal-complications', $all_diagnoses); + } + + if ($refer_for_hypertension || $refer_for_diabetes || $refer_for_renal_omplications) { + $expected[] = 'ncd_referral'; + } +} + function hedley_reports_lab_test_performed_by_execution_note($test) { if (empty($test) || empty($test->field_test_execution_note)) { return FALSE; From bf773e30ae85150dccf2096826f7f2a0207f2637 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 10 Sep 2024 12:12:24 +0300 Subject: [PATCH 119/185] Add labs results activities [ci skip] --- .../hedley_reports/hedley_reports.module | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 689a5f5acb..21009a81cc 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4849,6 +4849,12 @@ function hedley_reports_generate_completion_data_for_ncd($participant, $exclude_ 'ncd_symptom_review' => 's', 'ncd_urine_dipstick_test' => 't', 'ncd_vitals' => 'u', + // Logical activities. + 'ncd_creatinine_test_result' => 'v', + 'ncd_lipid_panel_test_result' => 'w', + 'ncd_liver_function_test_result' => 'x', + 'ncd_random_blood_sugar_test_result' => 'y', + 'ncd_urine_dipstick_test_result' => 'z', ]; // Load all encounters of current participant. @@ -4925,6 +4931,66 @@ function hedley_reports_generate_completion_data_for_ncd($participant, $exclude_ // If conditions match, add next steps activities. hedley_reports_ncd_add_next_steps_activities($encounter_data, $birth_date_obj, $gender, $expected); + // Adding labs test results activities. Since those are logically derived, + // and not actual content, we apply proprietary logic per records recorded + // at labs results content. + $labs_results = $measurements_by_type['ncd_labs_results']; + if (!empty($abs_results)) { + if (!empty($labs_results->field_performed_tests)) { + $performed_tests = $labs_results->field_performed_tests[LANGUAGE_NONE]; + foreach ($performed_tests as $performed_test) { + switch ($performed_test['value']) { + case 'creatinine': + $expected[] = 'ncd_creatinine_test_result'; + break; + + case 'lipid-panel': + $expected[] = 'ncd_lipid_panel_test_result'; + break; + + case 'liver-function': + $expected[] = 'ncd_liver_function_test_result'; + break; + + case 'random-blood-sugar': + $expected[] = 'ncd_random_blood_sugar_test_result'; + break; + + case 'urine-dipstick': + $expected[] = 'ncd_urine_dipstick_test_result'; + break; + } + } + } + + if (!empty($labs_results->field_completed_tests)) { + $completed_tests = $labs_results->field_completed_tests[LANGUAGE_NONE]; + foreach ($completed_tests as $completed_test) { + switch ($completed_test['value']) { + case 'creatinine': + $measurements_by_type['ncd_creatinine_test_result'] = 'dummy'; + break; + + case 'lipid-panel': + $measurements_by_type['ncd_lipid_panel_test_result'] = 'dummy'; + break; + + case 'liver-function': + $measurements_by_type['ncd_liver_function_test_result'] = 'dummy'; + break; + + case 'random-blood-sugar': + $measurements_by_type['ncd_random_blood_sugar_test_result'] = 'dummy'; + break; + + case 'urine-dipstick': + $measurements_by_type['ncd_urine_dipstick_test_result'] = 'dummy'; + break; + } + } + } + } + $completion_data = [ 'start_date' => $start_date, 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), From 2da8641da9a60693768a275d08bd6dbaaef3ff10 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 10 Sep 2024 12:29:27 +0300 Subject: [PATCH 120/185] Pull NCD data when loading large data sets [ci skip] --- .../scripts/completion-recalculate-large-datasets.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php index b4119a50bb..0cf3827f01 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php @@ -101,6 +101,7 @@ function generate_completion_results_data($health_center) { 'acute_illness' => [], 'child_scoreboard' => [], 'home_visit' => [], + 'ncd' => [], 'nutrition_individual' => [], 'nutrition_group' => [], 'well_child' => [], @@ -155,10 +156,14 @@ function generate_completion_results_data($health_center) { $data['home_visit'][] = json_decode($json_data); break; - case 'nutrition_encounter': + case 'ncd_encounter': $data['nutrition_individual'][] = json_decode($json_data); break; + case 'nutrition_encounter': + $data['ncd'][] = json_decode($json_data); + break; + case 'well_child_encounter': $data['well_child'][] = json_decode($json_data); break; From aa28561b317808101c08135a3a5cb8c45be5ea74 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 10 Sep 2024 12:46:08 +0300 Subject: [PATCH 121/185] Expand client data, decode and store on front-end [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 1 + server/elm/src/Backend/Completion/Model.elm | 30 ++++ server/elm/src/Backend/Completion/Utils.elm | 85 +++++++++++ .../custom/hedley_general/js/elm-main.js | 143 +++++++++++++++--- 4 files changed, 241 insertions(+), 18 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index c14ef19827..7ac403f07a 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -22,6 +22,7 @@ decodeCompletionData = |> requiredAt [ "results", "acute_illness" ] (list (decodeEncounterData acuteIllnessActivityFromMapping)) |> requiredAt [ "results", "child_scoreboard" ] (list (decodeEncounterData childScoreboardActivityFromMapping)) |> requiredAt [ "results", "home_visit" ] (list (decodeEncounterData homeVisitActivityFromMapping)) + |> requiredAt [ "results", "ncd" ] (list (decodeEncounterData ncdActivityFromMapping)) |> requiredAt [ "results", "nutrition_individual" ] (list (decodeEncounterData nutritionChildActivityFromMapping)) |> requiredAt [ "results", "nutrition_group" ] (list (decodeNutritionGroupEncounterData nutritionMotherActivityFromMapping nutritionChildActivityFromMapping)) diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index 7502c7a34b..e6a082cdad 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -14,6 +14,7 @@ type alias CompletionData = , acuteIllnessData : List (EncounterData AcuteIllnessActivity) , childScoreboardData : List (EncounterData ChildScoreboardActivity) , homeVisitData : List (EncounterData HomeVisitActivity) + , ncdData : List (EncounterData NCDActivity) , nutritionIndividualData : List (EncounterData NutritionChildActivity) , nutritionGroupData : List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) , wellChildData : List WellChildEncounterData @@ -104,6 +105,35 @@ type HomeVisitActivity | HomeVisitHygiene +type NCDActivity + = NCDCoreExam + | NCDCoMorbidities + | NCDCreatinineTest + | NCDDangerSigns + | NCDFamilyHistory + | NCDFamilyPlanning + | NCDHba1cTest + | NCDHealthEducation + | NCDHivTest + | NCDLipidPanelTest + | NCDLiverFunctionTest + | NCDMedicationDistribution + | NCDMedicationHistory + | NCDOutsideCare + | NCDPregnancyTest + | NCDRandomBloodSugarTest + | NCDReferral + | NCDSocialHistory + | NCDSymptomReview + | NCDUrineDipstickTest + | NCDVitals + | NCDCreatinineTestResult + | NCDLipidPanelTestResult + | NCDLiverFunctionTestResult + | NCDRandomBloodSugarTestResult + | NCDUrineDipstickTestResult + + type NutritionChildActivity = NutritionHeight | NutritionNutrition diff --git a/server/elm/src/Backend/Completion/Utils.elm b/server/elm/src/Backend/Completion/Utils.elm index b581c2bf90..dbe8b4abae 100644 --- a/server/elm/src/Backend/Completion/Utils.elm +++ b/server/elm/src/Backend/Completion/Utils.elm @@ -291,6 +291,91 @@ childScoreboardActivityFromMapping mapped = Nothing +ncdActivityFromMapping : String -> Maybe NCDActivity +ncdActivityFromMapping mapped = + case mapped of + "a" -> + Just NCDCoreExam + + "b" -> + Just NCDCoMorbidities + + "c" -> + Just NCDCreatinineTest + + "d" -> + Just NCDDangerSigns + + "e" -> + Just NCDFamilyHistory + + "f" -> + Just NCDFamilyPlanning + + "g" -> + Just NCDHba1cTest + + "h" -> + Just NCDHealthEducation + + "i" -> + Just NCDHivTest + + "j" -> + Just NCDLipidPanelTest + + "k" -> + Just NCDLiverFunctionTest + + "l" -> + Just NCDMedicationDistribution + + "m" -> + Just NCDMedicationHistory + + "n" -> + Just NCDOutsideCare + + "o" -> + Just NCDPregnancyTest + + "p" -> + Just NCDRandomBloodSugarTest + + "q" -> + Just NCDReferral + + "r" -> + Just NCDSocialHistory + + "s" -> + Just NCDSymptomReview + + "t" -> + Just NCDUrineDipstickTest + + "u" -> + Just NCDVitals + + "v" -> + Just NCDCreatinineTestResult + + "w" -> + Just NCDLipidPanelTestResult + + "x" -> + Just NCDLiverFunctionTestResult + + "y" -> + Just NCDRandomBloodSugarTestResult + + "z" -> + Just NCDUrineDipstickTestResult + + _ -> + Nothing + + takenByToString : TakenBy -> String takenByToString value = case value of diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index eb1b0cfb3a..42c00a16bb 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -6854,10 +6854,27 @@ var $author$project$Backend$Types$BackendReturn = F4( function (model, cmd, error, appMsgs) { return {appMsgs: appMsgs, cmd: cmd, error: error, model: model}; }); -var $author$project$Backend$Completion$Model$CompletionData = F9( - function (site, entityName, entityType, acuteIllnessData, childScoreboardData, homeVisitData, nutritionIndividualData, nutritionGroupData, wellChildData) { - return {acuteIllnessData: acuteIllnessData, childScoreboardData: childScoreboardData, entityName: entityName, entityType: entityType, homeVisitData: homeVisitData, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site, wellChildData: wellChildData}; - }); +var $author$project$Backend$Completion$Model$CompletionData = function (site) { + return function (entityName) { + return function (entityType) { + return function (acuteIllnessData) { + return function (childScoreboardData) { + return function (homeVisitData) { + return function (ncdData) { + return function (nutritionIndividualData) { + return function (nutritionGroupData) { + return function (wellChildData) { + return {acuteIllnessData: acuteIllnessData, childScoreboardData: childScoreboardData, entityName: entityName, entityType: entityType, homeVisitData: homeVisitData, ncdData: ncdData, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site, wellChildData: wellChildData}; + }; + }; + }; + }; + }; + }; + }; + }; + }; +}; var $author$project$Backend$Completion$Model$AcuteIllnessAcuteFindings = {$: 'AcuteIllnessAcuteFindings'}; var $author$project$Backend$Completion$Model$AcuteIllnessCOVIDTesting = {$: 'AcuteIllnessCOVIDTesting'}; var $author$project$Backend$Completion$Model$AcuteIllnessCall114 = {$: 'AcuteIllnessCall114'}; @@ -8122,6 +8139,90 @@ var $author$project$Backend$Completion$Utils$homeVisitActivityFromMapping = func } }; var $elm$json$Json$Decode$list = _Json_decodeList; +var $author$project$Backend$Completion$Model$NCDCoMorbidities = {$: 'NCDCoMorbidities'}; +var $author$project$Backend$Completion$Model$NCDCoreExam = {$: 'NCDCoreExam'}; +var $author$project$Backend$Completion$Model$NCDCreatinineTest = {$: 'NCDCreatinineTest'}; +var $author$project$Backend$Completion$Model$NCDCreatinineTestResult = {$: 'NCDCreatinineTestResult'}; +var $author$project$Backend$Completion$Model$NCDDangerSigns = {$: 'NCDDangerSigns'}; +var $author$project$Backend$Completion$Model$NCDFamilyHistory = {$: 'NCDFamilyHistory'}; +var $author$project$Backend$Completion$Model$NCDFamilyPlanning = {$: 'NCDFamilyPlanning'}; +var $author$project$Backend$Completion$Model$NCDHba1cTest = {$: 'NCDHba1cTest'}; +var $author$project$Backend$Completion$Model$NCDHealthEducation = {$: 'NCDHealthEducation'}; +var $author$project$Backend$Completion$Model$NCDHivTest = {$: 'NCDHivTest'}; +var $author$project$Backend$Completion$Model$NCDLipidPanelTest = {$: 'NCDLipidPanelTest'}; +var $author$project$Backend$Completion$Model$NCDLipidPanelTestResult = {$: 'NCDLipidPanelTestResult'}; +var $author$project$Backend$Completion$Model$NCDLiverFunctionTest = {$: 'NCDLiverFunctionTest'}; +var $author$project$Backend$Completion$Model$NCDLiverFunctionTestResult = {$: 'NCDLiverFunctionTestResult'}; +var $author$project$Backend$Completion$Model$NCDMedicationDistribution = {$: 'NCDMedicationDistribution'}; +var $author$project$Backend$Completion$Model$NCDMedicationHistory = {$: 'NCDMedicationHistory'}; +var $author$project$Backend$Completion$Model$NCDOutsideCare = {$: 'NCDOutsideCare'}; +var $author$project$Backend$Completion$Model$NCDPregnancyTest = {$: 'NCDPregnancyTest'}; +var $author$project$Backend$Completion$Model$NCDRandomBloodSugarTest = {$: 'NCDRandomBloodSugarTest'}; +var $author$project$Backend$Completion$Model$NCDRandomBloodSugarTestResult = {$: 'NCDRandomBloodSugarTestResult'}; +var $author$project$Backend$Completion$Model$NCDReferral = {$: 'NCDReferral'}; +var $author$project$Backend$Completion$Model$NCDSocialHistory = {$: 'NCDSocialHistory'}; +var $author$project$Backend$Completion$Model$NCDSymptomReview = {$: 'NCDSymptomReview'}; +var $author$project$Backend$Completion$Model$NCDUrineDipstickTest = {$: 'NCDUrineDipstickTest'}; +var $author$project$Backend$Completion$Model$NCDUrineDipstickTestResult = {$: 'NCDUrineDipstickTestResult'}; +var $author$project$Backend$Completion$Model$NCDVitals = {$: 'NCDVitals'}; +var $author$project$Backend$Completion$Utils$ncdActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDCoreExam); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDCoMorbidities); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDCreatinineTest); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDDangerSigns); + case 'e': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDFamilyHistory); + case 'f': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDFamilyPlanning); + case 'g': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDHba1cTest); + case 'h': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDHealthEducation); + case 'i': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDHivTest); + case 'j': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDLipidPanelTest); + case 'k': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDLiverFunctionTest); + case 'l': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDMedicationDistribution); + case 'm': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDMedicationHistory); + case 'n': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDOutsideCare); + case 'o': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDPregnancyTest); + case 'p': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDRandomBloodSugarTest); + case 'q': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDReferral); + case 'r': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDSocialHistory); + case 's': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDSymptomReview); + case 't': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDUrineDipstickTest); + case 'u': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDVitals); + case 'v': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDCreatinineTestResult); + case 'w': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDLipidPanelTestResult); + case 'x': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDLiverFunctionTestResult); + case 'y': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDRandomBloodSugarTestResult); + case 'z': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDUrineDipstickTestResult); + default: + return $elm$core$Maybe$Nothing; + } +}; var $author$project$Backend$Completion$Model$NutritionChildFbf = {$: 'NutritionChildFbf'}; var $author$project$Backend$Completion$Model$NutritionContributingFactors = {$: 'NutritionContributingFactors'}; var $author$project$Backend$Completion$Model$NutritionFollowUp = {$: 'NutritionFollowUp'}; @@ -8207,34 +8308,40 @@ var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'home_visit']), + ['results', 'ncd']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$homeVisitActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$ncdActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'child_scoreboard']), + ['results', 'home_visit']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$childScoreboardActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$homeVisitActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'acute_illness']), + ['results', 'child_scoreboard']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$childScoreboardActivityFromMapping)), A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_type', - $author$project$Backend$Completion$Decoder$decodeSelectedEntity, + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, + _List_fromArray( + ['results', 'acute_illness']), + $elm$json$Json$Decode$list( + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_name', - $elm$json$Json$Decode$string, + 'entity_type', + $author$project$Backend$Completion$Decoder$decodeSelectedEntity, A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'site', - $author$project$Backend$Decoder$decodeSite, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData)))))))))); + 'entity_name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData))))))))))); var $author$project$Backend$Completion$Update$update = F3( function (currentDate, msg, model) { var value = msg.a; From 7e1e7642487e4d335b9ddb817923dccfb48acf3f Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 10 Sep 2024 14:19:13 +0300 Subject: [PATCH 122/185] View logic on front-end [ci skip] --- server/elm/src/Backend/Completion/Model.elm | 2 +- server/elm/src/Backend/Completion/Utils.elm | 2 +- server/elm/src/Pages/Completion/Model.elm | 1 + server/elm/src/Pages/Completion/Utils.elm | 39 +++ server/elm/src/Pages/Completion/View.elm | 44 +++ server/elm/src/Translate.elm | 265 +++++++++++++++--- .../custom/hedley_general/js/elm-main.js | 252 ++++++++++++++++- 7 files changed, 548 insertions(+), 57 deletions(-) diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index e6a082cdad..dd7baf69be 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -114,7 +114,7 @@ type NCDActivity | NCDFamilyPlanning | NCDHba1cTest | NCDHealthEducation - | NCDHivTest + | NCDHIVTest | NCDLipidPanelTest | NCDLiverFunctionTest | NCDMedicationDistribution diff --git a/server/elm/src/Backend/Completion/Utils.elm b/server/elm/src/Backend/Completion/Utils.elm index dbe8b4abae..e5f792f67b 100644 --- a/server/elm/src/Backend/Completion/Utils.elm +++ b/server/elm/src/Backend/Completion/Utils.elm @@ -319,7 +319,7 @@ ncdActivityFromMapping mapped = Just NCDHealthEducation "i" -> - Just NCDHivTest + Just NCDHIVTest "j" -> Just NCDLipidPanelTest diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index e551830a10..592b81769d 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -30,6 +30,7 @@ type ReportType = ReportAcuteIllness | ReportChildScoreboard | ReportHomeVisit + | ReportNCD | ReportNewbornExam | ReportNutritionGroup | ReportNutritionIndividual diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index 25b14fe943..0b48fc7d14 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -6,10 +6,12 @@ import Backend.Completion.Model ( AcuteIllnessActivity(..) , ChildScoreboardActivity(..) , HomeVisitActivity(..) + , NCDActivity(..) , NutritionChildActivity(..) , NutritionMotherActivity(..) , TakenBy(..) , WellChildActivity(..) + , WellChildEncounterType(..) ) import Pages.Completion.Model exposing (ReportType(..)) @@ -26,6 +28,9 @@ reportTypeToString reportType = ReportHomeVisit -> "home-visit" + ReportNCD -> + "ncd" + ReportNewbornExam -> "newborn-exam" @@ -51,6 +56,9 @@ reportTypeFromString reportType = "home-visit" -> Just ReportHomeVisit + "ncd" -> + Just ReportNCD + "newborn-exam" -> Just ReportNewbornExam @@ -212,3 +220,34 @@ resolveChildScoreboardActivities site = _ -> [] ) + + +allNCDActivities : List NCDActivity +allNCDActivities = + [ NCDCoreExam + , NCDCoMorbidities + , NCDCreatinineTest + , NCDDangerSigns + , NCDFamilyHistory + , NCDFamilyPlanning + , NCDHba1cTest + , NCDHealthEducation + , NCDHIVTest + , NCDLipidPanelTest + , NCDLiverFunctionTest + , NCDMedicationDistribution + , NCDMedicationHistory + , NCDOutsideCare + , NCDPregnancyTest + , NCDRandomBloodSugarTest + , NCDReferral + , NCDSocialHistory + , NCDSymptomReview + , NCDUrineDipstickTest + , NCDVitals + , NCDCreatinineTestResult + , NCDLipidPanelTestResult + , NCDLiverFunctionTestResult + , NCDRandomBloodSugarTestResult + , NCDUrineDipstickTestResult + ] diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index 8926f88eea..ec47b8fb58 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -9,6 +9,7 @@ import Backend.Completion.Model , CompletionData , EncounterData , HomeVisitActivity(..) + , NCDActivity(..) , NutritionChildActivity(..) , NutritionGroupEncounterData , NutritionMotherActivity(..) @@ -87,6 +88,9 @@ viewCompletionData language currentDate themePath data model = ReportChildScoreboard , ReportHomeVisit , ReportNewbornExam + + -- Exclusively Nurse encounters. + , ReportNCD ] then emptyNode @@ -204,6 +208,9 @@ viewCompletionData language currentDate themePath data model = ReportHomeVisit -> viewHomeVisitReport language startDate limitDate model.takenBy data.homeVisitData + ReportNCD -> + viewNCDReport language startDate limitDate model.takenBy data.ncdData + ReportNewbornExam -> viewNewbornExamReport language startDate limitDate model.takenBy newbornExamData @@ -229,6 +236,7 @@ viewCompletionData language currentDate themePath data model = [ ReportAcuteIllness , ReportChildScoreboard , ReportHomeVisit + , ReportNCD , ReportNewbornExam , ReportNutritionGroup , ReportNutritionIndividual @@ -328,6 +336,15 @@ viewChildScoreboardReport language site startDate limitDate mTakenBy reportData |> div [ class "report child-scoreboard" ] +viewNCDReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData NCDActivity) -> Html Msg +viewNCDReport language startDate limitDate mTakenBy reportData = + eliminateEmptyEncounters reportData + |> applyFilters startDate limitDate mTakenBy + |> generateNCDReportData language + |> viewMetricsResultsTable + |> div [ class "report ncd" ] + + eliminateEmptyEncounters : List { c | completion : { b | completedActivities : List a } } -> List { c | completion : { b | completedActivities : List a } } @@ -564,6 +581,33 @@ generateChildScoreboardReportData language activities records = } +generateNCDReportData : + Language + -> List (EncounterData NCDActivity) + -> MetricsResultsTableData +generateNCDReportData language records = + { heading = translate language Translate.NCD + , captions = generateCaptionsList language + , rows = + List.map + (\activity -> + let + expected = + countOccurrences (.completion >> .expectedActivities) activity records + + completed = + countOccurrences (.completion >> .completedActivities) activity records + in + [ translate language <| Translate.NCDActivity activity + , String.fromInt expected + , String.fromInt completed + , calcualtePercentage completed expected + ] + ) + allNCDActivities + } + + -- Helper functions. diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 42cac55e96..cb55b7df1c 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -10,6 +10,7 @@ import Backend.Completion.Model ( AcuteIllnessActivity(..) , ChildScoreboardActivity(..) , HomeVisitActivity(..) + , NCDActivity(..) , NutritionChildActivity(..) , NutritionMotherActivity(..) , TakenBy(..) @@ -85,6 +86,8 @@ type TranslationId | Commune | Completed | CompletionReportType Pages.Completion.Model.ReportType + | CoreExam + | DangerSigns | Diagnosis | District | Demographics @@ -93,6 +96,7 @@ type TranslationId | Encounters | EncounterType | Expected + | FamilyPlanning | FBF | Feeding | Female @@ -101,7 +105,9 @@ type TranslationId | Global | HC | HealthCenter + | HealthEducation | HIV + | HIVTest | HomeVisit | HomeVisitActivity HomeVisitActivity | HttpError StringIdHttpError @@ -126,11 +132,13 @@ type TranslationId | InfrastructureEnvironmentWash | LoadData | Male + | MedicationDistribution | Month Month | MonthLabel | MonthYear Int Int Bool | NCD | NCDA + | NCDActivity NCDActivity | NCDADemographicsItemLabel NCDADemographicsItem | NCDAAcuteMalnutritionItemLabel NCDAAcuteMalnutritionItem | NCDAStuntingItemLabel NCDAStuntingItem @@ -159,10 +167,14 @@ type TranslationId | PregnanciesActive | PregnanciesAll | PregnanciesCompleted + | PregnancyTest | PrevalenceByMonthOneVisitOrMore | PrevalenceByMonthTwoVisitsOrMore | Province | QuarterYear Int Int + | RandomBloodSugarTest + | RandomBloodSugarTestResult + | Referral | Registered | RegisteredPatients | ReportType ReportType @@ -189,12 +201,15 @@ type TranslationId | TargetedInterventions | Total | Tuberculosis + | Vitals | ViewMode | Village | UnderweightModerate | UnderweightSevere | Unique | UniversalIntervention + | UrineDipstickTest + | UrineDipstickTestResult | WastingModerate | WastingSevere | WellChildActivity WellChildActivity @@ -240,16 +255,10 @@ translationSet transId = } AcuteIllnessCoreExam -> - { english = "Core Exam" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet CoreExam AcuteIllnessDangerSigns -> - { english = "Danger Signs" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet DangerSigns AcuteIllnessFollowUp -> { english = "Follow Up" @@ -270,10 +279,7 @@ translationSet transId = } AcuteIllnessVitals -> - { english = "Vitals" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Vitals AcuteIllnessCall114 -> { english = "Call 114" @@ -300,10 +306,7 @@ translationSet transId = } AcuteIllnessHealthEducation -> - { english = "Health Education" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet HealthEducation AcuteIllnessIsolation -> { english = "Isolation" @@ -318,10 +321,7 @@ translationSet transId = } AcuteIllnessMedicationDistribution -> - { english = "Medication Distribution" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet MedicationDistribution AcuteIllnessSendToHC -> { english = "Referal" @@ -540,6 +540,9 @@ translationSet transId = Pages.Completion.Model.ReportHomeVisit -> translationSet HomeVisit + Pages.Completion.Model.ReportNCD -> + translationSet NCD + Pages.Completion.Model.ReportNewbornExam -> translationSet NewbornExam @@ -617,6 +620,18 @@ translationSet transId = , kirundi = Nothing } + CoreExam -> + { english = "Core Exam" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + DangerSigns -> + { english = "Danger Signs" + , kinyarwanda = Nothing + , kirundi = Nothing + } + District -> { english = "District" , kinyarwanda = Nothing @@ -659,6 +674,12 @@ translationSet transId = , kirundi = Nothing } + FamilyPlanning -> + { english = "Family Planning" + , kinyarwanda = Nothing + , kirundi = Nothing + } + FBF -> { english = "FBF" , kinyarwanda = Nothing @@ -707,12 +728,24 @@ translationSet transId = , kirundi = Nothing } + HealthEducation -> + { english = "Health Education" + , kinyarwanda = Nothing + , kirundi = Nothing + } + HIV -> { english = "HIV" , kinyarwanda = Nothing , kirundi = Nothing } + HIVTest -> + { english = "HIV Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + HomeVisit -> { english = "Home Visit" , kinyarwanda = Nothing @@ -862,6 +895,12 @@ translationSet transId = , kirundi = Nothing } + MedicationDistribution -> + { english = "Medication Distribution" + , kinyarwanda = Nothing + , kirundi = Nothing + } + Month month -> translateMonth month False @@ -886,6 +925,125 @@ translationSet transId = , kirundi = Nothing } + NCDActivity activity -> + case activity of + NCDCoreExam -> + translationSet CoreExam + + NCDCoMorbidities -> + { english = "Co-Morbidities" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDCreatinineTest -> + { english = "Creatinine Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDDangerSigns -> + translationSet DangerSigns + + NCDFamilyHistory -> + { english = "Family History" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDFamilyPlanning -> + translationSet FamilyPlanning + + NCDHba1cTest -> + { english = "HBA1C Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDHealthEducation -> + translationSet HealthEducation + + NCDHIVTest -> + translationSet HIVTest + + NCDLipidPanelTest -> + { english = "Lipid Panel Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDLiverFunctionTest -> + { english = "Liver Function Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDMedicationDistribution -> + translationSet MedicationDistribution + + NCDMedicationHistory -> + { english = "Medication History" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDOutsideCare -> + { english = "Outside Care" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDPregnancyTest -> + translationSet PregnancyTest + + NCDRandomBloodSugarTest -> + translationSet RandomBloodSugarTest + + NCDReferral -> + translationSet Referral + + NCDSocialHistory -> + { english = "Social History" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDSymptomReview -> + { english = "Symptoms Review" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDUrineDipstickTest -> + translationSet UrineDipstickTest + + NCDVitals -> + translationSet Vitals + + NCDCreatinineTestResult -> + { english = "Creatinine Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDLipidPanelTestResult -> + { english = "Lipid Panel Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDLiverFunctionTestResult -> + { english = "Liver Function Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + NCDRandomBloodSugarTestResult -> + translationSet RandomBloodSugarTestResult + + NCDUrineDipstickTestResult -> + translationSet UrineDipstickTestResult + NCDADemographicsItemLabel item -> case item of ChildrenUnder2 -> @@ -1188,10 +1346,7 @@ translationSet transId = } NutritionHealthEducation -> - { english = "Health Education" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet HealthEducation NutritionSendToHC -> { english = "Referal" @@ -1214,10 +1369,7 @@ translationSet transId = NutritionMotherActivity activity -> case activity of NutritionFamilyPlanning -> - { english = "Family Planning" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet FamilyPlanning NutritionLactation -> { english = "Lactation" @@ -1331,6 +1483,12 @@ translationSet transId = , kirundi = Nothing } + PregnancyTest -> + { english = "Pregnancy Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + PrevalenceByMonthOneVisitOrMore -> { english = "Prevalence by month - one visit or more" , kinyarwanda = Nothing @@ -1355,6 +1513,24 @@ translationSet transId = , kirundi = Nothing } + RandomBloodSugarTest -> + { english = "Random BloodSugar Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + RandomBloodSugarTestResult -> + { english = "Random BloodSugar Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + Referral -> + { english = "Referral" + , kinyarwanda = Nothing + , kirundi = Nothing + } + Registered -> { english = "Registered" , kinyarwanda = Nothing @@ -1570,6 +1746,12 @@ translationSet transId = , kirundi = Nothing } + Vitals -> + { english = "Vitals" + , kinyarwanda = Nothing + , kirundi = Nothing + } + Village -> { english = "Village" , kinyarwanda = Nothing @@ -1600,6 +1782,18 @@ translationSet transId = , kirundi = Nothing } + UrineDipstickTest -> + { english = "Urine Dipstick Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + UrineDipstickTestResult -> + { english = "Urine Dipstick Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + WastingModerate -> { english = "Wasting Moderate" , kinyarwanda = Nothing @@ -1663,10 +1857,7 @@ translationSet transId = } WellChildHealthEducation -> - { english = "Health Education" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet HealthEducation WellChildHeight -> { english = "Height" @@ -1735,10 +1926,7 @@ translationSet transId = translationSet ImmunisationRotarix WellChildSendToHC -> - { english = "Referral" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Referral WellChildSymptomsReview -> { english = "Symptoms Review" @@ -1747,10 +1935,7 @@ translationSet transId = } WellChildVitals -> - { english = "Vitals" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Vitals WellChildVitaminA -> { english = "Vitamin A" diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 42c00a16bb..2d72396f0a 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5828,6 +5828,7 @@ var $elm_community$maybe_extra$Maybe$Extra$or = F2( var $author$project$Pages$Completion$Model$ReportAcuteIllness = {$: 'ReportAcuteIllness'}; var $author$project$Pages$Completion$Model$ReportChildScoreboard = {$: 'ReportChildScoreboard'}; var $author$project$Pages$Completion$Model$ReportHomeVisit = {$: 'ReportHomeVisit'}; +var $author$project$Pages$Completion$Model$ReportNCD = {$: 'ReportNCD'}; var $author$project$Pages$Completion$Model$ReportNewbornExam = {$: 'ReportNewbornExam'}; var $author$project$Pages$Completion$Model$ReportNutritionGroup = {$: 'ReportNutritionGroup'}; var $author$project$Pages$Completion$Model$ReportNutritionIndividual = {$: 'ReportNutritionIndividual'}; @@ -5840,6 +5841,8 @@ var $author$project$Pages$Completion$Utils$reportTypeFromString = function (repo return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportChildScoreboard); case 'home-visit': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportHomeVisit); + case 'ncd': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNCD); case 'newborn-exam': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNewbornExam); case 'nutrition-group': @@ -8146,9 +8149,9 @@ var $author$project$Backend$Completion$Model$NCDCreatinineTestResult = {$: 'NCDC var $author$project$Backend$Completion$Model$NCDDangerSigns = {$: 'NCDDangerSigns'}; var $author$project$Backend$Completion$Model$NCDFamilyHistory = {$: 'NCDFamilyHistory'}; var $author$project$Backend$Completion$Model$NCDFamilyPlanning = {$: 'NCDFamilyPlanning'}; +var $author$project$Backend$Completion$Model$NCDHIVTest = {$: 'NCDHIVTest'}; var $author$project$Backend$Completion$Model$NCDHba1cTest = {$: 'NCDHba1cTest'}; var $author$project$Backend$Completion$Model$NCDHealthEducation = {$: 'NCDHealthEducation'}; -var $author$project$Backend$Completion$Model$NCDHivTest = {$: 'NCDHivTest'}; var $author$project$Backend$Completion$Model$NCDLipidPanelTest = {$: 'NCDLipidPanelTest'}; var $author$project$Backend$Completion$Model$NCDLipidPanelTestResult = {$: 'NCDLipidPanelTestResult'}; var $author$project$Backend$Completion$Model$NCDLiverFunctionTest = {$: 'NCDLiverFunctionTest'}; @@ -8184,7 +8187,7 @@ var $author$project$Backend$Completion$Utils$ncdActivityFromMapping = function ( case 'h': return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDHealthEducation); case 'i': - return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDHivTest); + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDHIVTest); case 'j': return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$NCDLipidPanelTest); case 'k': @@ -10101,11 +10104,16 @@ var $author$project$Translate$AcuteIllness = {$: 'AcuteIllness'}; var $author$project$Translate$Caring = {$: 'Caring'}; var $author$project$Translate$Cell = {$: 'Cell'}; var $author$project$Translate$ChildScorecard = {$: 'ChildScorecard'}; +var $author$project$Translate$CoreExam = {$: 'CoreExam'}; +var $author$project$Translate$DangerSigns = {$: 'DangerSigns'}; var $author$project$Translate$District = {$: 'District'}; +var $author$project$Translate$FamilyPlanning = {$: 'FamilyPlanning'}; var $author$project$Translate$Feeding = {$: 'Feeding'}; var $author$project$Translate$FoodSecurity = {$: 'FoodSecurity'}; var $author$project$Translate$Global = {$: 'Global'}; +var $author$project$Translate$HIVTest = {$: 'HIVTest'}; var $author$project$Translate$HealthCenter = {$: 'HealthCenter'}; +var $author$project$Translate$HealthEducation = {$: 'HealthEducation'}; var $author$project$Translate$HomeVisit = {$: 'HomeVisit'}; var $author$project$Translate$Hygiene = {$: 'Hygiene'}; var $author$project$Translate$ImmunisationBCG = {$: 'ImmunisationBCG'}; @@ -10123,14 +10131,23 @@ var $author$project$Translate$IncidenceByQuarterOneVisitOrMore = {$: 'IncidenceB var $author$project$Translate$IncidenceByQuarterTwoVisitsOrMore = {$: 'IncidenceByQuarterTwoVisitsOrMore'}; var $author$project$Translate$IncidenceByYearOneVisitOrMore = {$: 'IncidenceByYearOneVisitOrMore'}; var $author$project$Translate$IncidenceByYearTwoVisitsOrMore = {$: 'IncidenceByYearTwoVisitsOrMore'}; +var $author$project$Translate$MedicationDistribution = {$: 'MedicationDistribution'}; +var $author$project$Translate$NCD = {$: 'NCD'}; var $author$project$Translate$NCDA = {$: 'NCDA'}; var $author$project$Translate$NewbornExam = {$: 'NewbornExam'}; +var $author$project$Translate$PregnancyTest = {$: 'PregnancyTest'}; var $author$project$Translate$PrevalenceByMonthOneVisitOrMore = {$: 'PrevalenceByMonthOneVisitOrMore'}; var $author$project$Translate$PrevalenceByMonthTwoVisitsOrMore = {$: 'PrevalenceByMonthTwoVisitsOrMore'}; var $author$project$Translate$Province = {$: 'Province'}; +var $author$project$Translate$RandomBloodSugarTest = {$: 'RandomBloodSugarTest'}; +var $author$project$Translate$RandomBloodSugarTestResult = {$: 'RandomBloodSugarTestResult'}; +var $author$project$Translate$Referral = {$: 'Referral'}; var $author$project$Translate$Sector = {$: 'Sector'}; var $author$project$Translate$StandardPediatricVisit = {$: 'StandardPediatricVisit'}; +var $author$project$Translate$UrineDipstickTest = {$: 'UrineDipstickTest'}; +var $author$project$Translate$UrineDipstickTestResult = {$: 'UrineDipstickTestResult'}; var $author$project$Translate$Village = {$: 'Village'}; +var $author$project$Translate$Vitals = {$: 'Vitals'}; var $author$project$Translate$translateHttpError = function (transId) { switch (transId.$) { case 'ErrorBadUrl': @@ -10314,9 +10331,13 @@ var $author$project$Translate$translationSet = function (transId) { case 'AcuteIllnessContactsTracing': return {english: 'Contacts Tracing', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessCoreExam': - return {english: 'Core Exam', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$CoreExam; + transId = $temp$transId; + continue translationSet; case 'AcuteIllnessDangerSigns': - return {english: 'Danger Signs', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$DangerSigns; + transId = $temp$transId; + continue translationSet; case 'AcuteIllnessFollowUp': return {english: 'Follow Up', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessMUAC': @@ -10324,7 +10345,9 @@ var $author$project$Translate$translationSet = function (transId) { case 'AcuteIllnessNutrition': return {english: 'Nutrition', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessVitals': - return {english: 'Vitals', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Vitals; + transId = $temp$transId; + continue translationSet; case 'AcuteIllnessCall114': return {english: 'Call 114', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessCOVIDTesting': @@ -10334,13 +10357,17 @@ var $author$project$Translate$translationSet = function (transId) { case 'AcuteIllnessContactHC': return {english: 'Contact HC', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessHealthEducation': - return {english: 'Health Education', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$HealthEducation; + transId = $temp$transId; + continue translationSet; case 'AcuteIllnessIsolation': return {english: 'Isolation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessMalariaTesting': return {english: 'Malaria Testing', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessMedicationDistribution': - return {english: 'Medication Distribution', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$MedicationDistribution; + transId = $temp$transId; + continue translationSet; case 'AcuteIllnessSendToHC': return {english: 'Referal', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessSymptomsGeneral': @@ -10489,6 +10516,10 @@ var $author$project$Translate$translationSet = function (transId) { var $temp$transId = $author$project$Translate$HomeVisit; transId = $temp$transId; continue translationSet; + case 'ReportNCD': + var $temp$transId = $author$project$Translate$NCD; + transId = $temp$transId; + continue translationSet; case 'ReportNewbornExam': var $temp$transId = $author$project$Translate$NewbornExam; transId = $temp$transId; @@ -10552,6 +10583,10 @@ var $author$project$Translate$translationSet = function (transId) { } case 'CHW': return {english: 'CHW', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'CoreExam': + return {english: 'Core Exam', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'DangerSigns': + return {english: 'Danger Signs', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'District': return {english: 'District', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Demographics': @@ -10566,6 +10601,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Encounter Type', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Expected': return {english: 'Expected', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'FamilyPlanning': + return {english: 'Family Planning', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'FBF': return {english: 'FBF', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Feeding': @@ -10582,8 +10619,12 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'HC', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'HealthCenter': return {english: 'Health Center', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'HealthEducation': + return {english: 'Health Education', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'HIV': return {english: 'HIV', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'HIVTest': + return {english: 'HIV Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'HomeVisit': return {english: 'Home Visit', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'HomeVisitActivity': @@ -10651,6 +10692,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Load Data', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Male': return {english: 'Male', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'MedicationDistribution': + return {english: 'Medication Distribution', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Month': var month = transId.a; return A2($author$project$Translate$translateMonth, month, false); @@ -10669,6 +10712,88 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'NCD', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NCDA': return {english: 'NCDA', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDActivity': + var activity = transId.a; + switch (activity.$) { + case 'NCDCoreExam': + var $temp$transId = $author$project$Translate$CoreExam; + transId = $temp$transId; + continue translationSet; + case 'NCDCoMorbidities': + return {english: 'Co-Morbidities', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDCreatinineTest': + return {english: 'Creatinine Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDDangerSigns': + var $temp$transId = $author$project$Translate$DangerSigns; + transId = $temp$transId; + continue translationSet; + case 'NCDFamilyHistory': + return {english: 'Family History', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDFamilyPlanning': + var $temp$transId = $author$project$Translate$FamilyPlanning; + transId = $temp$transId; + continue translationSet; + case 'NCDHba1cTest': + return {english: 'HBA1C Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDHealthEducation': + var $temp$transId = $author$project$Translate$HealthEducation; + transId = $temp$transId; + continue translationSet; + case 'NCDHIVTest': + var $temp$transId = $author$project$Translate$HIVTest; + transId = $temp$transId; + continue translationSet; + case 'NCDLipidPanelTest': + return {english: 'Lipid Panel Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDLiverFunctionTest': + return {english: 'Liver Function Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDMedicationDistribution': + var $temp$transId = $author$project$Translate$MedicationDistribution; + transId = $temp$transId; + continue translationSet; + case 'NCDMedicationHistory': + return {english: 'Medication History', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDOutsideCare': + return {english: 'Outside Care', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDPregnancyTest': + var $temp$transId = $author$project$Translate$PregnancyTest; + transId = $temp$transId; + continue translationSet; + case 'NCDRandomBloodSugarTest': + var $temp$transId = $author$project$Translate$RandomBloodSugarTest; + transId = $temp$transId; + continue translationSet; + case 'NCDReferral': + var $temp$transId = $author$project$Translate$Referral; + transId = $temp$transId; + continue translationSet; + case 'NCDSocialHistory': + return {english: 'Social History', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDSymptomReview': + return {english: 'Symptoms Review', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDUrineDipstickTest': + var $temp$transId = $author$project$Translate$UrineDipstickTest; + transId = $temp$transId; + continue translationSet; + case 'NCDVitals': + var $temp$transId = $author$project$Translate$Vitals; + transId = $temp$transId; + continue translationSet; + case 'NCDCreatinineTestResult': + return {english: 'Creatinine Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDLipidPanelTestResult': + return {english: 'Lipid Panel Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDLiverFunctionTestResult': + return {english: 'Liver Function Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'NCDRandomBloodSugarTestResult': + var $temp$transId = $author$project$Translate$RandomBloodSugarTestResult; + transId = $temp$transId; + continue translationSet; + default: + var $temp$transId = $author$project$Translate$UrineDipstickTestResult; + transId = $temp$transId; + continue translationSet; + } case 'NCDADemographicsItemLabel': var item = transId.a; switch (item.$) { @@ -10879,7 +11004,9 @@ var $author$project$Translate$translationSet = function (transId) { case 'NutritionFollowUp': return {english: 'Follow Up', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NutritionHealthEducation': - return {english: 'Health Education', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$HealthEducation; + transId = $temp$transId; + continue translationSet; case 'NutritionSendToHC': return {english: 'Referal', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NutritionNCDA': @@ -10891,7 +11018,9 @@ var $author$project$Translate$translationSet = function (transId) { var activity = transId.a; switch (activity.$) { case 'NutritionFamilyPlanning': - return {english: 'Family Planning', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$FamilyPlanning; + transId = $temp$transId; + continue translationSet; case 'NutritionLactation': return {english: 'Lactation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; default: @@ -10961,6 +11090,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'All Pregnancies', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'PregnanciesCompleted': return {english: 'Completed Pregnancies', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PregnancyTest': + return {english: 'Pregnancy Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'PrevalenceByMonthOneVisitOrMore': return {english: 'Prevalence by month - one visit or more', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'PrevalenceByMonthTwoVisitsOrMore': @@ -10975,6 +11106,12 @@ var $author$project$Translate$translationSet = function (transId) { kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing }; + case 'RandomBloodSugarTest': + return {english: 'Random BloodSugar Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'RandomBloodSugarTestResult': + return {english: 'Random BloodSugar Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Referral': + return {english: 'Referral', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Registered': return {english: 'Registered', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'RegisteredPatients': @@ -11103,6 +11240,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Tuberculosis', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'ViewMode': return {english: 'View Mode', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Vitals': + return {english: 'Vitals', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Village': return {english: 'Village', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'UnderweightModerate': @@ -11113,6 +11252,10 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Unique', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'UniversalIntervention': return {english: 'Universal Intervention', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'UrineDipstickTest': + return {english: 'Urine Dipstick Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'UrineDipstickTestResult': + return {english: 'Urine Dipstick Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WastingModerate': return {english: 'Wasting Moderate', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WastingSevere': @@ -11155,7 +11298,9 @@ var $author$project$Translate$translationSet = function (transId) { case 'WellChildHeadCircumference': return {english: 'Head Circumference', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildHealthEducation': - return {english: 'Health Education', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$HealthEducation; + transId = $temp$transId; + continue translationSet; case 'WellChildHeight': return {english: 'Height', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildHPVImmunisation': @@ -11203,11 +11348,15 @@ var $author$project$Translate$translationSet = function (transId) { transId = $temp$transId; continue translationSet; case 'WellChildSendToHC': - return {english: 'Referral', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Referral; + transId = $temp$transId; + continue translationSet; case 'WellChildSymptomsReview': return {english: 'Symptoms Review', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildVitals': - return {english: 'Vitals', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Vitals; + transId = $temp$transId; + continue translationSet; case 'WellChildVitaminA': return {english: 'Vitamin A', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; default: @@ -12112,6 +12261,8 @@ var $author$project$Pages$Completion$Utils$reportTypeToString = function (report return 'child-scoreboard'; case 'ReportHomeVisit': return 'home-visit'; + case 'ReportNCD': + return 'ncd'; case 'ReportNewbornExam': return 'newborn-exam'; case 'ReportNutritionGroup': @@ -13753,6 +13904,76 @@ var $author$project$Utils$Html$viewCustomModal = function (extraClasses) { })); }; var $author$project$Utils$Html$viewModal = $author$project$Utils$Html$viewCustomModal(_List_Nil); +var $author$project$Translate$NCDActivity = function (a) { + return {$: 'NCDActivity', a: a}; +}; +var $author$project$Pages$Completion$Utils$allNCDActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$NCDCoreExam, $author$project$Backend$Completion$Model$NCDCoMorbidities, $author$project$Backend$Completion$Model$NCDCreatinineTest, $author$project$Backend$Completion$Model$NCDDangerSigns, $author$project$Backend$Completion$Model$NCDFamilyHistory, $author$project$Backend$Completion$Model$NCDFamilyPlanning, $author$project$Backend$Completion$Model$NCDHba1cTest, $author$project$Backend$Completion$Model$NCDHealthEducation, $author$project$Backend$Completion$Model$NCDHIVTest, $author$project$Backend$Completion$Model$NCDLipidPanelTest, $author$project$Backend$Completion$Model$NCDLiverFunctionTest, $author$project$Backend$Completion$Model$NCDMedicationDistribution, $author$project$Backend$Completion$Model$NCDMedicationHistory, $author$project$Backend$Completion$Model$NCDOutsideCare, $author$project$Backend$Completion$Model$NCDPregnancyTest, $author$project$Backend$Completion$Model$NCDRandomBloodSugarTest, $author$project$Backend$Completion$Model$NCDReferral, $author$project$Backend$Completion$Model$NCDSocialHistory, $author$project$Backend$Completion$Model$NCDSymptomReview, $author$project$Backend$Completion$Model$NCDUrineDipstickTest, $author$project$Backend$Completion$Model$NCDVitals, $author$project$Backend$Completion$Model$NCDCreatinineTestResult, $author$project$Backend$Completion$Model$NCDLipidPanelTestResult, $author$project$Backend$Completion$Model$NCDLiverFunctionTestResult, $author$project$Backend$Completion$Model$NCDRandomBloodSugarTestResult, $author$project$Backend$Completion$Model$NCDUrineDipstickTestResult]); +var $author$project$Pages$Completion$View$generateNCDReportData = F2( + function (language, records) { + return { + captions: $author$project$Pages$Completion$View$generateCaptionsList(language), + heading: A2($author$project$Translate$translate, language, $author$project$Translate$NCD), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.expectedActivities; + }), + activity, + records); + var completed = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.completedActivities; + }), + activity, + records); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$NCDActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) + ]); + }, + $author$project$Pages$Completion$Utils$allNCDActivities) + }; + }); +var $author$project$Pages$Completion$View$viewNCDReport = F5( + function (language, startDate, limitDate, mTakenBy, reportData) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report ncd') + ]), + $author$project$Pages$Components$View$viewMetricsResultsTable( + A2( + $author$project$Pages$Completion$View$generateNCDReportData, + language, + A4( + $author$project$Pages$Completion$View$applyFilters, + startDate, + limitDate, + mTakenBy, + $author$project$Pages$Completion$View$eliminateEmptyEncounters(reportData))))); + }); var $author$project$Pages$Completion$View$customApplyFilters = F4( function (startDate, limitDate, resolveTakenByFunc, mTakenBy) { return $elm$core$List$filter( @@ -14164,7 +14385,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( $elm$core$List$member, reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNewbornExam]))) { + [$author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNCD]))) { return $author$project$Gizra$Html$emptyNode; } else { var options = A2( @@ -14298,6 +14519,8 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( return A6($author$project$Pages$Completion$View$viewChildScoreboardReport, language, data.site, startDate, limitDate, model.takenBy, data.childScoreboardData); case 'ReportHomeVisit': return A5($author$project$Pages$Completion$View$viewHomeVisitReport, language, startDate, limitDate, model.takenBy, data.homeVisitData); + case 'ReportNCD': + return A5($author$project$Pages$Completion$View$viewNCDReport, language, startDate, limitDate, model.takenBy, data.ncdData); case 'ReportNewbornExam': return A5($author$project$Pages$Completion$View$viewNewbornExamReport, language, startDate, limitDate, model.takenBy, newbornExamData); case 'ReportNutritionGroup': @@ -14339,7 +14562,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( language, model.reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportWellChild]), + [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNCD, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportWellChild]), $author$project$Pages$Completion$Utils$reportTypeToString, $author$project$Pages$Completion$Model$SetReportType, $author$project$Translate$CompletionReportType, @@ -14874,7 +15097,6 @@ var $author$project$Translate$Encounters = {$: 'Encounters'}; var $author$project$Translate$FBF = {$: 'FBF'}; var $author$project$Translate$HIV = {$: 'HIV'}; var $author$project$Translate$Individual = {$: 'Individual'}; -var $author$project$Translate$NCD = {$: 'NCD'}; var $author$project$Translate$NutritionTotal = {$: 'NutritionTotal'}; var $author$project$Translate$PMTCT = {$: 'PMTCT'}; var $author$project$Translate$Sorwathe = {$: 'Sorwathe'}; From 62abe64ff651d8388a361ad9388a68391707bb7b Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 10 Sep 2024 14:31:27 +0300 Subject: [PATCH 123/185] A fix [ci skip] --- .../scripts/completion-recalculate-large-datasets.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php index 0cf3827f01..096dbec1de 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php @@ -79,6 +79,8 @@ function generate_completion_results_data($health_center) { 'child_scoreboard_encounter', // Home Visit data. 'home_visit_encounter', + // NCD Data. + 'ncd_encounter', // Nutrition Individual data. 'nutrition_encounter', // Well Child data. From 36bb2a46ff1b15830ea6fe9750439f473a7d66b9 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 10 Sep 2024 14:32:03 +0300 Subject: [PATCH 124/185] Another fix [ci skip] --- .../scripts/completion-recalculate-large-datasets.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php index 096dbec1de..758bfe4bdc 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php @@ -159,11 +159,11 @@ function generate_completion_results_data($health_center) { break; case 'ncd_encounter': - $data['nutrition_individual'][] = json_decode($json_data); + $data['ncd'][] = json_decode($json_data); break; case 'nutrition_encounter': - $data['ncd'][] = json_decode($json_data); + $data['nutrition_individual'][] = json_decode($json_data); break; case 'well_child_encounter': From e619f397f0dd829cbc529f09942da29818dc0be3 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 10 Sep 2024 14:57:29 +0300 Subject: [PATCH 125/185] Fixes [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 21009a81cc..80ac1b3ee6 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4929,7 +4929,7 @@ function hedley_reports_generate_completion_data_for_ncd($participant, $exclude_ // If conditions match, add labs activities. hedley_reports_ncd_add_labs_activities($encounter_data, $birth_date_obj, $gender, $expected); // If conditions match, add next steps activities. - hedley_reports_ncd_add_next_steps_activities($encounter_data, $birth_date_obj, $gender, $expected); + hedley_reports_ncd_add_next_steps_activities($encounter_data, $expected); // Adding labs test results activities. Since those are logically derived, // and not actual content, we apply proprietary logic per records recorded @@ -5042,7 +5042,7 @@ function hedley_reports_ncd_generate_expected_initial_activities($encounter_data return $expected; } -function hedley_reports_ncd_add_labs_activities($encounter_data, $birth_date_obj, $gender, $expected) { +function hedley_reports_ncd_add_labs_activities(array $encounter_data, $birth_date_obj, $gender, array &$expected) { // Blood sugar test is performed unconditionally. $expected[] = 'ncd_random_blood_sugar_test'; @@ -5214,7 +5214,7 @@ function hedley_reports_ncd_add_labs_activities($encounter_data, $birth_date_obj * @param array &$expected * An array of expected activity names, passed by reference. */ -function hedley_reports_ncd_add_next_steps_activities(array $encounter_data, $birth_date_obj, $gender, array &$expected) { +function hedley_reports_ncd_add_next_steps_activities(array $encounter_data, array &$expected) { // Resolving diagnoses from current encounter. $current_encounter = $encounter_data['encounter']; $measurements_by_type = $encounter_data['measurements_by_type']; From d9f3abd954ab06ebafa3c183aae09eaee23dbe25 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 10 Sep 2024 23:19:42 +0300 Subject: [PATCH 126/185] Fixes [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 2 +- .../scripts/completion-recalculate-large-datasets.php | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 80ac1b3ee6..204914ec23 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4935,7 +4935,7 @@ function hedley_reports_generate_completion_data_for_ncd($participant, $exclude_ // and not actual content, we apply proprietary logic per records recorded // at labs results content. $labs_results = $measurements_by_type['ncd_labs_results']; - if (!empty($abs_results)) { + if (!empty($labs_results)) { if (!empty($labs_results->field_performed_tests)) { $performed_tests = $labs_results->field_performed_tests[LANGUAGE_NONE]; foreach ($performed_tests as $performed_test) { diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php index 758bfe4bdc..f42fc2110b 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php @@ -176,11 +176,14 @@ function generate_completion_results_data($health_center) { } $nid = end($ids); + $processed += count($nodes); + // Explicitly unset large variables after use for memory optimization. unset($nodes); - $processed += 400; - drush_print("Processed $processed out of $total."); + if ($processed % 5000 == 0) { + drush_print("Processed $processed out of $total."); + } } return $data; From 9c550e2abc902eab94745ded4a82b0b8329f8ec8 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 10 Sep 2024 23:22:41 +0300 Subject: [PATCH 127/185] Style [ci skip] --- server/hedley/modules/custom/hedley_general/css/elm.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/hedley/modules/custom/hedley_general/css/elm.css b/server/hedley/modules/custom/hedley_general/css/elm.css index 7630b8ab44..822d30d0b5 100644 --- a/server/hedley/modules/custom/hedley_general/css/elm.css +++ b/server/hedley/modules/custom/hedley_general/css/elm.css @@ -397,6 +397,7 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.acute-illness .table .row .item.row-label, .page-content .inputs .report.child-scoreboard .table .row .item.row-label, .page-content .inputs .report.home-visit .table .row .item.row-label, +.page-content .inputs .report.ncd .table .row .item.row-label, .page-content .inputs .report.nutrition-group .table .row .item.row-label, .page-content .inputs .report.nutrition-individual .table .row .item.row-label, .page-content .inputs .report.well-child .table .row .item.row-label { @@ -409,6 +410,8 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.child-scoreboard .table .row .item.value, .page-content .inputs .report.home-visit .table .row .item.heading, .page-content .inputs .report.home-visit .table .row .item.value, +.page-content .inputs .report.ncd .table .row .item.heading, +.page-content .inputs .report.ncd .table .row .item.value, .page-content .inputs .report.nutrition-group .table .row .item.heading, .page-content .inputs .report.nutrition-group .table .row .item.value, .page-content .inputs .report.nutrition-individual .table .row .item.heading, From c4d2576ad365a34417b099494e5020c19847c542 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 11 Sep 2024 09:53:45 +0300 Subject: [PATCH 128/185] Fixes and docs --- server/elm/src/Pages/Completion/Utils.elm | 10 +- server/elm/src/Translate.elm | 12 +- .../hedley_general/hedley_general.module | 1 - .../custom/hedley_general/js/elm-main.js | 14 +-- .../hedley_reports/hedley_reports.module | 103 +++++++++++++++--- 5 files changed, 103 insertions(+), 37 deletions(-) diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index 0b48fc7d14..7b5d3ca6c4 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -227,6 +227,7 @@ allNCDActivities = [ NCDCoreExam , NCDCoMorbidities , NCDCreatinineTest + , NCDCreatinineTestResult , NCDDangerSigns , NCDFamilyHistory , NCDFamilyPlanning @@ -234,20 +235,19 @@ allNCDActivities = , NCDHealthEducation , NCDHIVTest , NCDLipidPanelTest + , NCDLipidPanelTestResult , NCDLiverFunctionTest + , NCDLiverFunctionTestResult , NCDMedicationDistribution , NCDMedicationHistory , NCDOutsideCare , NCDPregnancyTest , NCDRandomBloodSugarTest + , NCDRandomBloodSugarTestResult , NCDReferral , NCDSocialHistory , NCDSymptomReview , NCDUrineDipstickTest - , NCDVitals - , NCDCreatinineTestResult - , NCDLipidPanelTestResult - , NCDLiverFunctionTestResult - , NCDRandomBloodSugarTestResult , NCDUrineDipstickTestResult + , NCDVitals ] diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index cb55b7df1c..87771f576b 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -1021,19 +1021,19 @@ translationSet transId = translationSet Vitals NCDCreatinineTestResult -> - { english = "Creatinine Test Result" + { english = "Creatinine Result" , kinyarwanda = Nothing , kirundi = Nothing } NCDLipidPanelTestResult -> - { english = "Lipid Panel Test Result" + { english = "Lipid Panel Result" , kinyarwanda = Nothing , kirundi = Nothing } NCDLiverFunctionTestResult -> - { english = "Liver Function Test Result" + { english = "Liver Function Result" , kinyarwanda = Nothing , kirundi = Nothing } @@ -1514,13 +1514,13 @@ translationSet transId = } RandomBloodSugarTest -> - { english = "Random BloodSugar Test" + { english = "Random Blood Sugar Test" , kinyarwanda = Nothing , kirundi = Nothing } RandomBloodSugarTestResult -> - { english = "Random BloodSugar Test Result" + { english = "Random Blood Sugar Result" , kinyarwanda = Nothing , kirundi = Nothing } @@ -1789,7 +1789,7 @@ translationSet transId = } UrineDipstickTestResult -> - { english = "Urine Dipstick Test Result" + { english = "Urine Dipstick Result" , kinyarwanda = Nothing , kirundi = Nothing } diff --git a/server/hedley/modules/custom/hedley_general/hedley_general.module b/server/hedley/modules/custom/hedley_general/hedley_general.module index 650745814b..fae43ca400 100644 --- a/server/hedley/modules/custom/hedley_general/hedley_general.module +++ b/server/hedley/modules/custom/hedley_general/hedley_general.module @@ -9,7 +9,6 @@ // execution was recorded, and the date when the results should be set. define('HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD', 35); - /** * Creating a new AQ task of a specific queue if not exist. * diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 2d72396f0a..812a63ee98 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -10780,11 +10780,11 @@ var $author$project$Translate$translationSet = function (transId) { transId = $temp$transId; continue translationSet; case 'NCDCreatinineTestResult': - return {english: 'Creatinine Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Creatinine Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NCDLipidPanelTestResult': - return {english: 'Lipid Panel Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Lipid Panel Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NCDLiverFunctionTestResult': - return {english: 'Liver Function Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Liver Function Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NCDRandomBloodSugarTestResult': var $temp$transId = $author$project$Translate$RandomBloodSugarTestResult; transId = $temp$transId; @@ -11107,9 +11107,9 @@ var $author$project$Translate$translationSet = function (transId) { kirundi: $elm$core$Maybe$Nothing }; case 'RandomBloodSugarTest': - return {english: 'Random BloodSugar Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Random Blood Sugar Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'RandomBloodSugarTestResult': - return {english: 'Random BloodSugar Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Random Blood Sugar Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Referral': return {english: 'Referral', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Registered': @@ -11255,7 +11255,7 @@ var $author$project$Translate$translationSet = function (transId) { case 'UrineDipstickTest': return {english: 'Urine Dipstick Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'UrineDipstickTestResult': - return {english: 'Urine Dipstick Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Urine Dipstick Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WastingModerate': return {english: 'Wasting Moderate', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WastingSevere': @@ -13908,7 +13908,7 @@ var $author$project$Translate$NCDActivity = function (a) { return {$: 'NCDActivity', a: a}; }; var $author$project$Pages$Completion$Utils$allNCDActivities = _List_fromArray( - [$author$project$Backend$Completion$Model$NCDCoreExam, $author$project$Backend$Completion$Model$NCDCoMorbidities, $author$project$Backend$Completion$Model$NCDCreatinineTest, $author$project$Backend$Completion$Model$NCDDangerSigns, $author$project$Backend$Completion$Model$NCDFamilyHistory, $author$project$Backend$Completion$Model$NCDFamilyPlanning, $author$project$Backend$Completion$Model$NCDHba1cTest, $author$project$Backend$Completion$Model$NCDHealthEducation, $author$project$Backend$Completion$Model$NCDHIVTest, $author$project$Backend$Completion$Model$NCDLipidPanelTest, $author$project$Backend$Completion$Model$NCDLiverFunctionTest, $author$project$Backend$Completion$Model$NCDMedicationDistribution, $author$project$Backend$Completion$Model$NCDMedicationHistory, $author$project$Backend$Completion$Model$NCDOutsideCare, $author$project$Backend$Completion$Model$NCDPregnancyTest, $author$project$Backend$Completion$Model$NCDRandomBloodSugarTest, $author$project$Backend$Completion$Model$NCDReferral, $author$project$Backend$Completion$Model$NCDSocialHistory, $author$project$Backend$Completion$Model$NCDSymptomReview, $author$project$Backend$Completion$Model$NCDUrineDipstickTest, $author$project$Backend$Completion$Model$NCDVitals, $author$project$Backend$Completion$Model$NCDCreatinineTestResult, $author$project$Backend$Completion$Model$NCDLipidPanelTestResult, $author$project$Backend$Completion$Model$NCDLiverFunctionTestResult, $author$project$Backend$Completion$Model$NCDRandomBloodSugarTestResult, $author$project$Backend$Completion$Model$NCDUrineDipstickTestResult]); + [$author$project$Backend$Completion$Model$NCDCoreExam, $author$project$Backend$Completion$Model$NCDCoMorbidities, $author$project$Backend$Completion$Model$NCDCreatinineTest, $author$project$Backend$Completion$Model$NCDCreatinineTestResult, $author$project$Backend$Completion$Model$NCDDangerSigns, $author$project$Backend$Completion$Model$NCDFamilyHistory, $author$project$Backend$Completion$Model$NCDFamilyPlanning, $author$project$Backend$Completion$Model$NCDHba1cTest, $author$project$Backend$Completion$Model$NCDHealthEducation, $author$project$Backend$Completion$Model$NCDHIVTest, $author$project$Backend$Completion$Model$NCDLipidPanelTest, $author$project$Backend$Completion$Model$NCDLipidPanelTestResult, $author$project$Backend$Completion$Model$NCDLiverFunctionTest, $author$project$Backend$Completion$Model$NCDLiverFunctionTestResult, $author$project$Backend$Completion$Model$NCDMedicationDistribution, $author$project$Backend$Completion$Model$NCDMedicationHistory, $author$project$Backend$Completion$Model$NCDOutsideCare, $author$project$Backend$Completion$Model$NCDPregnancyTest, $author$project$Backend$Completion$Model$NCDRandomBloodSugarTest, $author$project$Backend$Completion$Model$NCDRandomBloodSugarTestResult, $author$project$Backend$Completion$Model$NCDReferral, $author$project$Backend$Completion$Model$NCDSocialHistory, $author$project$Backend$Completion$Model$NCDSymptomReview, $author$project$Backend$Completion$Model$NCDUrineDipstickTest, $author$project$Backend$Completion$Model$NCDUrineDipstickTestResult, $author$project$Backend$Completion$Model$NCDVitals]); var $author$project$Pages$Completion$View$generateNCDReportData = F2( function (language, records) { return { diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 204914ec23..7f7e85c4ba 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3897,6 +3897,10 @@ function hedley_reports_well_child_generate_expected_initial_activities(array $e * * @param array $encounter_data * An associative array containing data about the encounter. + * @param DateTime $birth_date_obj + * The DateTime object representing the child's birth date. + * @param string $gender + * The gender of the child, used to determine gender-specific immunisations. * @param array &$expected * An array of expected activity names, passed by reference. */ @@ -3940,7 +3944,7 @@ function hedley_reports_well_child_get_expected_immunisation_activities(array $e $start_date_obj = $encounter_data['start_date_obj']; $initial_opv_administered = hedley_reports_initial_opv_administered($encounter_data, $birth_date_obj); - $interval = $start_date_obj->diff($birth_date_obj); + $interval = $start_date_obj->diff($birth_date_obj, TRUE); $age_in_days = $interval->days; $possible_immunisations = ['bcg', 'opv']; @@ -3965,7 +3969,7 @@ function hedley_reports_well_child_get_expected_immunisation_activities(array $e if (!empty($vaccination_progress['dtp']['dose-3'])) { $age_in_months = ($interval->y * 12) + $interval->m; $third_dose_date_obj = new DateTime($vaccination_progress['dtp']['dose-3']); - $interval = $start_date_obj->diff($third_dose_date_obj); + $interval = $start_date_obj->diff($third_dose_date_obj, TRUE); $days_since_third_dose = $interval->days; if ($age_in_months >= 18 && $days_since_third_dose >= 28) { @@ -4604,7 +4608,7 @@ function hedley_reports_child_scoreboard_get_expected_immunisation_activities(ar if (!empty($vaccination_progress['dtp']['dose-3'])) { $age_in_months = ($interval->y * 12) + $interval->m; $third_dose_date_obj = new DateTime($vaccination_progress['dtp']['dose-3']); - $interval = $start_date_obj->diff($third_dose_date_obj); + $interval = $start_date_obj->diff($third_dose_date_obj, TRUE); $days_since_third_dose = $interval->days; if ($age_in_months >= 18 && $days_since_third_dose >= 28) { @@ -5001,7 +5005,18 @@ function hedley_reports_generate_completion_data_for_ncd($participant, $exclude_ } } -function hedley_reports_ncd_generate_expected_initial_activities($encounter_data, $birth_date_obj, $gender) { +/** + * Generates the list of expected activities for an acute illness encounter. + * + * Here we add activities with simple logic. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * + * @return array + * An array of expected activity names. + */ +function hedley_reports_ncd_generate_expected_initial_activities(array $encounter_data, $birth_date_obj, $gender) { $start_date_obj = $encounter_data['start_date_obj']; $expected = [ @@ -5042,7 +5057,19 @@ function hedley_reports_ncd_generate_expected_initial_activities($encounter_data return $expected; } -function hedley_reports_ncd_add_labs_activities(array $encounter_data, $birth_date_obj, $gender, array &$expected) { +/** + * Adds Labs activities to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param DateTime $birth_date_obj + * The DateTime object representing the child's birth date. + * @param string $gender + * The gender of the child, used to determine gender-specific immunisations. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_ncd_add_labs_activities(array $encounter_data, DateTime $birth_date_obj, $gender, array &$expected) { // Blood sugar test is performed unconditionally. $expected[] = 'ncd_random_blood_sugar_test'; @@ -5066,7 +5093,7 @@ function hedley_reports_ncd_add_labs_activities(array $encounter_data, $birth_da if (hedley_reports_lab_test_performed_by_execution_note($creatinine_test)) { $date_measured = explode(' ', $creatinine_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; $date_measured_obj = new DateTime($date_measured); - $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj, TRUE)->days; $results_exists = !empty($creatinine_test->field_creatinine_result) && !empty($creatinine_test->field_creatinine_result[LANGUAGE_NONE][0]['value']); if ($results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { $tests_dates_by_lab_type['ncd_creatinine_test'][] = explode(' ', $creatinine_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; @@ -5077,7 +5104,7 @@ function hedley_reports_ncd_add_labs_activities(array $encounter_data, $birth_da if (hedley_reports_lab_test_performed_by_execution_note($hba1c_test)) { $date_measured = explode(' ', $hba1c_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; $date_measured_obj = new DateTime($date_measured); - $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj, TRUE)->days; $results_exists = !empty($hba1c_test->field_hba1c_result) && !empty($hba1c_test->field_hba1c_result[LANGUAGE_NONE][0]['value']); if ($results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { $tests_dates_by_lab_type['ncd_hba1c_test'][] = explode(' ', $hba1c_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; @@ -5086,12 +5113,12 @@ function hedley_reports_ncd_add_labs_activities(array $encounter_data, $birth_da $hiv_test = $measurements_by_type['ncd_hiv_test']; if (!$hiv_known_as_positive) { - if (!empty($test) && !empty($test->field_test_execution_note)) { - $hiv_known_as_positive = $test->field_test_execution_note[LANGUAGE_NONE][0]['value'] == 'known-as-positive'; + if (!empty($hiv_test) && !empty($hiv_test->field_test_execution_note)) { + $hiv_known_as_positive = $hiv_test->field_test_execution_note[LANGUAGE_NONE][0]['value'] == 'known-as-positive'; if (!$hiv_known_as_positive && hedley_reports_lab_test_performed_by_execution_note($hiv_test)) { $date_measured = explode(' ', $hiv_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; $date_measured_obj = new DateTime($date_measured); - $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj, TRUE)->days; $valid_results_exists = !empty($hiv_test->field_test_result) && !empty($hiv_test->field_test_result[LANGUAGE_NONE][0]['value']) && @@ -5107,7 +5134,7 @@ function hedley_reports_ncd_add_labs_activities(array $encounter_data, $birth_da if (hedley_reports_lab_test_performed_by_execution_note($lipid_panel_test)) { $date_measured = explode(' ', $lipid_panel_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; $date_measured_obj = new DateTime($date_measured); - $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj, TRUE)->days; $results_exists = !empty($lipid_panel_test->field_total_cholesterol) && !empty($lipid_panel_test->field_total_cholesterol[LANGUAGE_NONE][0]['value']); if ($results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { $tests_dates_by_lab_type['ncd_lipid_panel_test'][] = explode(' ', $lipid_panel_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; @@ -5118,7 +5145,7 @@ function hedley_reports_ncd_add_labs_activities(array $encounter_data, $birth_da if (hedley_reports_lab_test_performed_by_execution_note($liver_function_test)) { $date_measured = explode(' ', $liver_function_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; $date_measured_obj = new DateTime($date_measured); - $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj, TRUE)->days; $results_exists = !empty($liver_function_test->field_alt_result) && !empty($liver_function_test->field_alt_result[LANGUAGE_NONE][0]['value']); if ($results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { $tests_dates_by_lab_type['ncd_liver_function_test'][] = explode(' ', $liver_function_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; @@ -5129,7 +5156,7 @@ function hedley_reports_ncd_add_labs_activities(array $encounter_data, $birth_da if (hedley_reports_lab_test_performed_by_execution_note($pregnancy_test)) { $date_measured = explode(' ', $pregnancy_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; $date_measured_obj = new DateTime($date_measured); - $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj, TRUE)->days; $valid_results_exists = !empty($hiv_test->field_test_result) && !empty($hiv_test->field_test_result[LANGUAGE_NONE][0]['value']) && @@ -5143,7 +5170,7 @@ function hedley_reports_ncd_add_labs_activities(array $encounter_data, $birth_da if (hedley_reports_lab_test_performed_by_execution_note($urine_dipstick_test)) { $date_measured = explode(' ', $urine_dipstick_test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; $date_measured_obj = new DateTime($date_measured); - $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj)->days; + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj, TRUE)->days; $results_exists = !empty($urine_dipstick_test->field_protein) && !empty($urine_dipstick_test->field_protein[LANGUAGE_NONE][0]['value']); if ($results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { $tests_dates_by_lab_type['ncd_urine_dipstick_test'][] = explode(' ', $urine_dipstick_test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; @@ -5255,7 +5282,7 @@ function hedley_reports_ncd_add_next_steps_activities(array $encounter_data, arr $hypertension_diagnoses = [ 'hypertension-stage1', 'hypertension-stage2', - 'hypertension-stage3' + 'hypertension-stage3', ]; $diabetes_diagnoses = ['diabetes-initial', 'diabetes-recurrent']; $diabetes_diagnoses_with_renal = array_merge($diabetes_diagnoses, ['renal-complications']); @@ -5322,7 +5349,7 @@ function hedley_reports_ncd_add_next_steps_activities(array $encounter_data, arr $medicate_for_hypertension_recurrent_phase = TRUE; } } - $medicate_for_hypertension = $medicate_for_hypertension_initial_phase || $medicate_for_hypertension_recurrent_phase; + $medicate_for_hypertension = $medicate_for_hypertension_initial_phase || $medicate_for_hypertension_recurrent_phase; if ($medicated_for_diabetes || $medicate_for_hypertension) { $expected[] = 'ncd_medication_distribution'; @@ -5349,6 +5376,20 @@ function hedley_reports_ncd_add_next_steps_activities(array $encounter_data, arr } } +/** + * Checks if a lab test was performed based on the test execution note. + * + * Determines if the test execution note indicates that the test was performed + * by checking if it matches one of the predefined statuses. + * + * @param object $test + * An object representing the lab test, which contains the test execution + * note field. + * + * @return bool + * TRUE if the test was performed based on the execution note, FALSE + * otherwise. + */ function hedley_reports_lab_test_performed_by_execution_note($test) { if (empty($test) || empty($test->field_test_execution_note)) { return FALSE; @@ -5360,13 +5401,39 @@ function hedley_reports_lab_test_performed_by_execution_note($test) { ); } -function hedley_reports_recurrent_test_required($last_date, $encounter_start_date_obj, $period_between_tests) { +/** + * Determines if a recurrent test is required. + * + * Decision is made based on the last test date, + * encounter start date, and the period between tests. + * + * If the last test date is empty, a test is required. Otherwise, it calculates + * the time difference in months between the last test date and the encounter + * start date and checks if it meets or exceeds the required period. + * + * @param string|null $last_date + * The date of the last test in 'Y-m-d' format, or NULL if no test was done. + * @param DateTime $encounter_start_date_obj + * The start date of the encounter as a DateTime object. + * @param int $period_between_tests + * The required period between tests in months. + * + * @return bool + * TRUE if the recurrent test is required, FALSE otherwise. + */ +function hedley_reports_recurrent_test_required($last_date, DateTime $encounter_start_date_obj, $period_between_tests) { if (empty($last_date)) { return TRUE; } $last_date_obj = new DateTime($last_date); - $diff_months = $encounter_start_date_obj->diff($last_date_obj)->months; + // Calculate the difference between the encounter start date + // and the last test date. + $interval = $encounter_start_date_obj->diff($last_date_obj); + + // Total number of months, accounting for years as well. + $diff_months = ($interval->y * 12) + $interval->m; + return $diff_months >= $period_between_tests; } From 80b6b20f9adabece05cd1fe0e2e3f4a3cfb27221 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 11 Sep 2024 11:31:50 +0300 Subject: [PATCH 129/185] Data fields to encounters CT + scripts infra [ci skip] --- .../hedley_hiv.features.field_instance.inc | 79 ++++++++++++++++- .../modules/custom/hedley_hiv/hedley_hiv.info | 1 + .../hedley_hiv/hedley_hiv.strongarm.inc | 34 ++++---- .../hedley_reports/hedley_reports.module | 31 +++++++ .../scripts/completion-generate-hiv-data.php | 86 +++++++++++++++++++ .../completion-generate-tuberculosis-data.php | 86 +++++++++++++++++++ ...edley_schedule.features.field_instance.inc | 8 +- .../hedley_schedule.strongarm.inc | 2 +- ...y_tuberculosis.features.field_instance.inc | 83 +++++++++++++++++- .../hedley_tuberculosis.info | 1 + .../hedley_tuberculosis.strongarm.inc | 38 ++++---- 11 files changed, 400 insertions(+), 49 deletions(-) create mode 100644 server/hedley/modules/custom/hedley_reports/scripts/completion-generate-hiv-data.php create mode 100644 server/hedley/modules/custom/hedley_reports/scripts/completion-generate-tuberculosis-data.php diff --git a/server/hedley/modules/custom/hedley_hiv/hedley_hiv.features.field_instance.inc b/server/hedley/modules/custom/hedley_hiv/hedley_hiv.features.field_instance.inc index 7b4158337a..203c54c355 100644 --- a/server/hedley/modules/custom/hedley_hiv/hedley_hiv.features.field_instance.inc +++ b/server/hedley/modules/custom/hedley_hiv/hedley_hiv.features.field_instance.inc @@ -139,6 +139,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -183,6 +184,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -227,6 +229,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -327,6 +330,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -448,12 +452,53 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => -1, + 'weight' => 2, + ), + ); + + // Exported field_instance: 'node-hiv_encounter-field_reports_data'. + $field_instances['node-hiv_encounter-field_reports_data'] = array( + 'bundle' => 'hiv_encounter', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 4, + ), + 'teaser' => array( + 'label' => 'above', + 'settings' => array(), + 'type' => 'hidden', + 'weight' => 0, + ), + ), + 'entity_type' => 'node', + 'field_name' => 'field_reports_data', + 'label' => 'Completion Data', + 'required' => 0, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'rows' => 5, + ), + 'type' => 'text_textarea', + 'weight' => 3, ), ); @@ -509,7 +554,7 @@ function hedley_hiv_field_default_field_instances() { 'year_range' => '-3:+3', ), 'type' => 'date_select', - 'weight' => -3, + 'weight' => 1, ), ); @@ -548,12 +593,13 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => 3, + 'weight' => 5, ), ); @@ -593,7 +639,7 @@ function hedley_hiv_field_default_field_instances() { 'size' => 60, ), 'type' => 'text_textfield', - 'weight' => 1, + 'weight' => 4, ), ); @@ -781,6 +827,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -825,6 +872,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -869,6 +917,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -913,6 +962,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1053,6 +1103,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1135,6 +1186,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1179,6 +1231,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1223,6 +1276,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1363,6 +1417,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1407,6 +1462,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1451,6 +1507,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1533,6 +1590,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1673,6 +1731,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1717,6 +1776,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1761,6 +1821,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1879,6 +1940,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2019,6 +2081,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2100,6 +2163,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2144,6 +2208,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2188,6 +2253,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2365,6 +2431,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2455,6 +2522,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2499,6 +2567,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2581,6 +2650,7 @@ function hedley_hiv_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2671,6 +2741,7 @@ function hedley_hiv_field_default_field_instances() { // Translatables // Included for use with string extractors like potx. t('Adverse Events'); + t('Completion Data'); t('Date Measured'); t('Follow up options'); t('HIV Diagnosis Signs'); diff --git a/server/hedley/modules/custom/hedley_hiv/hedley_hiv.info b/server/hedley/modules/custom/hedley_hiv/hedley_hiv.info index 45d2ea2e74..5efbb75e15 100644 --- a/server/hedley/modules/custom/hedley_hiv/hedley_hiv.info +++ b/server/hedley/modules/custom/hedley_hiv/hedley_hiv.info @@ -30,6 +30,7 @@ features[field_instance][] = node-hiv_diagnostics-field_shards features[field_instance][] = node-hiv_diagnostics-field_test_result features[field_instance][] = node-hiv_diagnostics-field_uuid features[field_instance][] = node-hiv_encounter-field_individual_participant +features[field_instance][] = node-hiv_encounter-field_reports_data features[field_instance][] = node-hiv_encounter-field_scheduled_date features[field_instance][] = node-hiv_encounter-field_shards features[field_instance][] = node-hiv_encounter-field_uuid diff --git a/server/hedley/modules/custom/hedley_hiv/hedley_hiv.strongarm.inc b/server/hedley/modules/custom/hedley_hiv/hedley_hiv.strongarm.inc index ed03946fb8..fe2515e715 100644 --- a/server/hedley/modules/custom/hedley_hiv/hedley_hiv.strongarm.inc +++ b/server/hedley/modules/custom/hedley_hiv/hedley_hiv.strongarm.inc @@ -184,15 +184,15 @@ function hedley_hiv_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__hiv_diagnostics'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__hiv_diagnostics'] = $strongarm; @@ -201,15 +201,15 @@ function hedley_hiv_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__hiv_encounter'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( - 'weight' => '-5', + 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__hiv_encounter'] = $strongarm; @@ -218,15 +218,15 @@ function hedley_hiv_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__hiv_follow_up'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__hiv_follow_up'] = $strongarm; @@ -235,15 +235,15 @@ function hedley_hiv_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__hiv_health_education'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__hiv_health_education'] = $strongarm; @@ -252,15 +252,15 @@ function hedley_hiv_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__hiv_medication'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__hiv_medication'] = $strongarm; @@ -269,15 +269,15 @@ function hedley_hiv_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__hiv_referral'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__hiv_referral'] = $strongarm; @@ -286,15 +286,15 @@ function hedley_hiv_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__hiv_symptom_review'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__hiv_symptom_review'] = $strongarm; @@ -303,15 +303,15 @@ function hedley_hiv_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__hiv_treatment_review'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__hiv_treatment_review'] = $strongarm; diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 7f7e85c4ba..84fa1a169c 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5376,6 +5376,37 @@ function hedley_reports_ncd_add_next_steps_activities(array $encounter_data, arr } } +/** + * Generates completion data for HIV encounters for patient. + * + * @param object $participant + * The participant node object with which encounters are associated. + * @param bool $exclude_set + * Indicate whether to exclude encounters with report data already set. + */ +function hedley_reports_generate_completion_data_for_hiv($participant, $exclude_set) +{ + // To reduce memory usage, mapping measurement types as single characters. + $mapping = [ + ]; +} + +/** + * Generates completion data for Tuberculosis encounters for patient. + * + * @param object $participant + * The participant node object with which encounters are associated. + * @param bool $exclude_set + * Indicate whether to exclude encounters with report data already set. + */ +function hedley_reports_generate_completion_data_for_tuberculosis($participant, $exclude_set) +{ + // To reduce memory usage, mapping measurement types as single characters. + $mapping = [ + ]; +} + + /** * Checks if a lab test was performed based on the test execution note. * diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-hiv-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-hiv-data.php new file mode 100644 index 0000000000..a7506af605 --- /dev/null +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-hiv-data.php @@ -0,0 +1,86 @@ +entityCondition('entity_type', 'node') + ->entityCondition('bundle', $type) + ->fieldCondition('field_encounter_type', 'value', 'hiv') + ->propertyCondition('status', NODE_PUBLISHED) + ->addTag('exclude_deleted'); + +$count_query = clone $base_query; +$count_query->propertyCondition('nid', $nid, '>'); +$count = $count_query->count()->execute(); + +if ($count == 0) { + drush_print("There are no nodes of type $type for hiv encounters in DB."); + exit; +} + +$total = 0; +drush_print("$count nodes of type $type for hiv encounters located."); + +while (TRUE) { + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + hedley_reports_generate_completion_data_for_hiv($node, $exclude_set); + $total++; + + $memory = round(memory_get_usage() / 1048576); + if ($memory >= $memory_limit) { + drush_print(dt('Stopped before out of memory. Start process from the node ID @nid', ['@nid' => $nid])); + return; + } + } + + $memory = round(memory_get_usage() / 1048576); + drush_print("Calculated so far: $total, Memory: $memory"); + + // Free up memory. + drupal_static_reset(); + + $nid = end($ids); +} + +drush_print("Done! Completion data calculated for $total participants."); diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-tuberculosis-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-tuberculosis-data.php new file mode 100644 index 0000000000..840a745eca --- /dev/null +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-tuberculosis-data.php @@ -0,0 +1,86 @@ +entityCondition('entity_type', 'node') + ->entityCondition('bundle', $type) + ->fieldCondition('field_encounter_type', 'value', 'tuberculosis') + ->propertyCondition('status', NODE_PUBLISHED) + ->addTag('exclude_deleted'); + +$count_query = clone $base_query; +$count_query->propertyCondition('nid', $nid, '>'); +$count = $count_query->count()->execute(); + +if ($count == 0) { + drush_print("There are no nodes of type $type for tuberculosis encounters in DB."); + exit; +} + +$total = 0; +drush_print("$count nodes of type $type for tuberculosis encounters located."); + +while (TRUE) { + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + hedley_reports_generate_completion_data_for_tuberculosis($node, $exclude_set); + $total++; + + $memory = round(memory_get_usage() / 1048576); + if ($memory >= $memory_limit) { + drush_print(dt('Stopped before out of memory. Start process from the node ID @nid', ['@nid' => $nid])); + return; + } + } + + $memory = round(memory_get_usage() / 1048576); + drush_print("Calculated so far: $total, Memory: $memory"); + + // Free up memory. + drupal_static_reset(); + + $nid = end($ids); +} + +drush_print("Done! Completion data calculated for $total participants."); diff --git a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc index 79cc04248d..cfda1990e9 100644 --- a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc +++ b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc @@ -1824,7 +1824,7 @@ Used to track location where pregnancies were completed.', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => -1, + 'weight' => 2, ), ); @@ -1878,7 +1878,7 @@ Used to track location where pregnancies were completed.', 'year_range' => '-3:+3', ), 'type' => 'date_select', - 'weight' => -3, + 'weight' => 1, ), ); @@ -1923,7 +1923,7 @@ Used to track location where pregnancies were completed.', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => 3, + 'weight' => 6, ), ); @@ -1963,7 +1963,7 @@ Used to track location where pregnancies were completed.', 'size' => 60, ), 'type' => 'text_textfield', - 'weight' => 1, + 'weight' => 5, ), ); diff --git a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc index 2df4e8cf03..5584e33fc7 100644 --- a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc +++ b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc @@ -341,7 +341,7 @@ function hedley_schedule_strongarm() { 'display' => array(), 'form' => array( 'title' => array( - 'weight' => '-5', + 'weight' => '0', ), ), ), diff --git a/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.features.field_instance.inc b/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.features.field_instance.inc index 25f078b35d..5e07dfa508 100644 --- a/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.features.field_instance.inc +++ b/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.features.field_instance.inc @@ -103,6 +103,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -147,6 +148,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -191,6 +193,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -274,6 +277,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -489,6 +493,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -533,6 +538,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -577,6 +583,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -622,6 +629,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -707,12 +715,53 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => -1, + 'weight' => 2, + ), + ); + + // Exported field_instance: 'node-tuberculosis_encounter-field_reports_data'. + $field_instances['node-tuberculosis_encounter-field_reports_data'] = array( + 'bundle' => 'tuberculosis_encounter', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 4, + ), + 'teaser' => array( + 'label' => 'above', + 'settings' => array(), + 'type' => 'hidden', + 'weight' => 0, + ), + ), + 'entity_type' => 'node', + 'field_name' => 'field_reports_data', + 'label' => 'Completion Data', + 'required' => 0, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'rows' => 5, + ), + 'type' => 'text_textarea', + 'weight' => 3, ), ); @@ -769,7 +818,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'year_range' => '-3:+3', ), 'type' => 'date_select', - 'weight' => -3, + 'weight' => 1, ), ); @@ -808,12 +857,13 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => 3, + 'weight' => 5, ), ); @@ -853,7 +903,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'size' => 60, ), 'type' => 'text_textfield', - 'weight' => 1, + 'weight' => 4, ), ); @@ -1043,6 +1093,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1087,6 +1138,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1131,6 +1183,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1176,6 +1229,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1317,6 +1371,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1361,6 +1416,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1405,6 +1461,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1488,6 +1545,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1629,6 +1687,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1673,6 +1732,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1755,6 +1815,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1800,6 +1861,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1940,6 +2002,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -1984,6 +2047,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2103,6 +2167,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2148,6 +2213,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2289,6 +2355,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2333,6 +2400,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2377,6 +2445,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2422,6 +2491,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2686,6 +2756,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2730,6 +2801,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2812,6 +2884,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2895,6 +2968,7 @@ function hedley_tuberculosis_field_default_field_instances() { 'active' => 1, 'module' => 'entityreference', 'settings' => array( + 'hide_ids' => FALSE, 'match_operator' => 'CONTAINS', 'path' => '', 'size' => 60, @@ -2947,6 +3021,7 @@ function hedley_tuberculosis_field_default_field_instances() { // Translatables // Included for use with string extractors like potx. t('Adverse Events'); + t('Completion Data'); t('DOT Meds Distribution Signs'); t('DOT Signs'); t('Date Measured'); diff --git a/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.info b/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.info index 9600a0887c..fa1d68b91b 100644 --- a/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.info +++ b/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.info @@ -39,6 +39,7 @@ features[field_instance][] = node-tuberculosis_dot-field_shards features[field_instance][] = node-tuberculosis_dot-field_tuberculosis_encounter features[field_instance][] = node-tuberculosis_dot-field_uuid features[field_instance][] = node-tuberculosis_encounter-field_individual_participant +features[field_instance][] = node-tuberculosis_encounter-field_reports_data features[field_instance][] = node-tuberculosis_encounter-field_scheduled_date features[field_instance][] = node-tuberculosis_encounter-field_shards features[field_instance][] = node-tuberculosis_encounter-field_uuid diff --git a/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.strongarm.inc b/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.strongarm.inc index 013f9f7e33..a268cbede1 100644 --- a/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.strongarm.inc +++ b/server/hedley/modules/custom/hedley_tuberculosis/hedley_tuberculosis.strongarm.inc @@ -205,15 +205,15 @@ function hedley_tuberculosis_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__tuberculosis_diagnostics'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__tuberculosis_diagnostics'] = $strongarm; @@ -222,15 +222,15 @@ function hedley_tuberculosis_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__tuberculosis_dot'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__tuberculosis_dot'] = $strongarm; @@ -239,15 +239,15 @@ function hedley_tuberculosis_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__tuberculosis_encounter'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( - 'weight' => '-5', + 'weight' => '0', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__tuberculosis_encounter'] = $strongarm; @@ -256,15 +256,15 @@ function hedley_tuberculosis_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__tuberculosis_follow_up'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__tuberculosis_follow_up'] = $strongarm; @@ -273,15 +273,15 @@ function hedley_tuberculosis_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__tuberculosis_health_education'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__tuberculosis_health_education'] = $strongarm; @@ -290,15 +290,15 @@ function hedley_tuberculosis_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__tuberculosis_medication'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__tuberculosis_medication'] = $strongarm; @@ -307,15 +307,15 @@ function hedley_tuberculosis_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__tuberculosis_referral'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__tuberculosis_referral'] = $strongarm; @@ -324,15 +324,15 @@ function hedley_tuberculosis_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__tuberculosis_symptom_review'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__tuberculosis_symptom_review'] = $strongarm; @@ -341,15 +341,15 @@ function hedley_tuberculosis_strongarm() { $strongarm->api_version = 1; $strongarm->name = 'field_bundle_settings_node__tuberculosis_treatment_review'; $strongarm->value = array( - 'view_modes' => array(), 'extra_fields' => array( + 'display' => array(), 'form' => array( 'title' => array( 'weight' => '-5', ), ), - 'display' => array(), ), + 'view_modes' => array(), ); $export['field_bundle_settings_node__tuberculosis_treatment_review'] = $strongarm; From 179fe2f3df60680c59ae1d767324290f5aec94fb Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 11 Sep 2024 12:55:42 +0300 Subject: [PATCH 130/185] Add back-end logic [ci skip] --- .../hedley_reports/hedley_reports.module | 281 +++++++++++++++++- 1 file changed, 274 insertions(+), 7 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 84fa1a169c..8743c09875 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -2471,7 +2471,6 @@ function hedley_reports_generate_completion_data_for_acute_illness($participant, // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. - // Load all activities expected only by encounter type and start date. $expected = hedley_reports_acute_illness_generate_expected_initial_activities($encounter_data); // If conditions match, add malaria_testing activity. hedley_reports_acute_illness_add_expected_malaria_testing($encounter_data, $expected); @@ -3431,7 +3430,6 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. - // Load all activities expected only by encounter type and start date. $expected = hedley_reports_well_child_generate_expected_initial_activities($encounter_data); // If conditions match, add immunisation activities. hedley_reports_well_child_add_immunisation_activities($encounter_data, $birth_date_obj, $gender, $expected); @@ -4927,7 +4925,6 @@ function hedley_reports_generate_completion_data_for_ncd($participant, $exclude_ // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. - // Load all activities expected only by encounter type and start date. $expected = hedley_reports_ncd_generate_expected_initial_activities($encounter_data, $birth_date_obj, $gender); // If conditions match, add labs activities. @@ -5384,11 +5381,146 @@ function hedley_reports_ncd_add_next_steps_activities(array $encounter_data, arr * @param bool $exclude_set * Indicate whether to exclude encounters with report data already set. */ -function hedley_reports_generate_completion_data_for_hiv($participant, $exclude_set) -{ +function hedley_reports_generate_completion_data_for_hiv($participant, $exclude_set) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ + 'hiv_diagnostics' => 'a', + 'hiv_follow_up' => 'b', + 'hiv_health_education' => 'c', + 'hiv_medication' => 'd', + 'hiv_referral' => 'e', + 'hiv_symptom_review' => 'f', + 'hiv_treatment_review' => 'g', ]; + + // Load all encounters of current participant. + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'hiv_encounter') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_individual_participant', 'target_id', $participant->nid) + ->propertyOrderBy('nid') + ->execute(); + + if (empty($result['node'])) { + return; + } + + // Encounters are sorted ASC. + $encounters = node_load_multiple(array_keys($result['node'])); + $encounters_data = []; + foreach ($encounters as $encounter) { + // Skip encounter if exclusion flag is raised and it's report data is set. + if ($exclude_set && !empty($encounter->field_reports_data[LANGUAGE_NONE][0]['value'])) { + continue; + } + + // Loading all measurements that belong to encounter. + $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); + $measurements = !empty($measurements_ids) ? node_load_multiple($measurements_ids) : []; + // Ordering measurements by type. + $measurements_by_type = []; + foreach ($measurements as $measurement) { + $measurements_by_type[$measurement->type] = $measurement; + } + + $encounters_data[] = [ + 'encounter' => $encounter, + 'measurements_by_type' => $measurements_by_type, + ]; + } + + foreach ($encounters_data as $index => $encounter_data) { + $encounter = $encounter_data['encounter']; + $measurements_by_type = $encounter_data['measurements_by_type']; + + // Resolve encounter start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $previous_encounters_data = array_slice($encounters_data, 0, $index); + + // So far we were constructing data structures to resolve encounter data. + // Now we have enough info to determine which activities were expected. + $completed = array_keys($measurements_by_type); + + $expected = ['hiv_medication']; + if (empty($previous_encounters_data)) { + $expected[] = 'hiv_diagnostics'; + + if (in_array('hiv_medication', $completed)) { + $expected[] = 'hiv_treatment_review'; + } + } + else { + $expected = array_merge( + $expected, + ['hiv_symptom_review', 'hiv_treatment_review'] + ); + } + + // Checking which Next Steps activities to expect. + $mandatory_activities = [ + 'hiv_diagnostics', + 'hiv_medication', + 'hiv_symptom_review', + ]; + // Here we consider activity as completed, if it was expected, + // and we actually see it as completed at encounter measurements. + // If not expected, we consider it completed. + $mandatory_activities_completed = TRUE; + foreach ($mandatory_activities as $activity) { + if (in_array($activity, $expected) && !in_array($activity, $completed)) { + $mandatory_activities_completed = FALSE; + break; + } + } + + if ($mandatory_activities_completed) { + $expected = array_merge( + $expected, + ['hiv_follow_up', 'hiv_health_education'] + ); + + // Referral is expected, if there was reported symptom or adverse event. + // Checking if symptom was reported. + $symptom_reported = FALSE; + $symptom_review = $measurements_by_type['hiv_symptom_review']; + if (!empty($symptom_review) && !empty($symptom_review->field_hiv_symptoms)) { + $symptoms = $symptom_review->field_hiv_symptoms[LANGUAGE_NONE]; + foreach ($symptoms as $symptom) { + if ($symptom['value'] != 'none') { + // Symptom was reported. Add Referral to expected list. + $expected[] = 'hiv_referral'; + // Raise flag, as there's no need to check for adverse events. + $symptom_reported = TRUE; + break; + } + } + } + + // If symptom was not reported, checking for adverse event. + if (!$symptom_reported) { + $treatment_review = $measurements_by_type['hiv_treatment_review']; + if (!empty($treatment_review) && !empty($treatment_review->field_adverse_events)) { + $adverse_events = $treatment_review->field_adverse_events[LANGUAGE_NONE]; + foreach ($adverse_events as $adverse_event) { + if ($adverse_event['value'] != 'none') { + $expected[] = 'hiv_referral'; + break; + } + } + } + } + } + + $completion_data = [ + 'start_date' => $start_date, + 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), + ]; + + $encounter->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); + node_save($encounter); + } } /** @@ -5399,11 +5531,146 @@ function hedley_reports_generate_completion_data_for_hiv($participant, $exclude_ * @param bool $exclude_set * Indicate whether to exclude encounters with report data already set. */ -function hedley_reports_generate_completion_data_for_tuberculosis($participant, $exclude_set) -{ +function hedley_reports_generate_completion_data_for_tuberculosis($participant, $exclude_set) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ + 'tuberculosis_diagnostics' => 'a', + 'tuberculosis_dot' => 'b', + 'tuberculosis_follow_up' => 'c', + 'tuberculosis_health_education' => 'd', + 'tuberculosis_medication' => 'e', + 'tuberculosis_referral' => 'f', + 'tuberculosis_symptom_review' => 'g', + 'tuberculosis_treatment_review' => 'h', ]; + + // Load all encounters of current participant. + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'tuberculosis_encounter') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_individual_participant', 'target_id', $participant->nid) + ->propertyOrderBy('nid') + ->execute(); + + if (empty($result['node'])) { + return; + } + + // Encounters are sorted ASC. + $encounters = node_load_multiple(array_keys($result['node'])); + $encounters_data = []; + foreach ($encounters as $encounter) { + // Skip encounter if exclusion flag is raised and it's report data is set. + if ($exclude_set && !empty($encounter->field_reports_data[LANGUAGE_NONE][0]['value'])) { + continue; + } + + // Loading all measurements that belong to encounter. + $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); + $measurements = !empty($measurements_ids) ? node_load_multiple($measurements_ids) : []; + // Ordering measurements by type. + $measurements_by_type = []; + foreach ($measurements as $measurement) { + $measurements_by_type[$measurement->type] = $measurement; + } + + $encounters_data[] = [ + 'encounter' => $encounter, + 'measurements_by_type' => $measurements_by_type, + ]; + } + + foreach ($encounters_data as $index => $encounter_data) { + $encounter = $encounter_data['encounter']; + $measurements_by_type = $encounter_data['measurements_by_type']; + + // Resolve encounter start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $previous_encounters_data = array_slice($encounters_data, 0, $index); + + // So far we were constructing data structures to resolve encounter data. + // Now we have enough info to determine which activities were expected. + $completed = array_keys($measurements_by_type); + + $expected = ['tuberculosis_medication']; + if (in_array('tuberculosis_medication', $completed)) { + $expected = array_merge( + $expected, + ['tuberculosis_dot', 'tuberculosis_treatment_review'] + ); + } + if (empty($previous_encounters_data)) { + $expected[] = 'tuberculosis_diagnostics'; + } + else { + $expected[] = 'tuberculosis_symptom_review'; + } + + // Checking which Next Steps activities to expect. + $mandatory_activities = [ + 'tuberculosis_diagnostics', + 'tuberculosis_medication', + 'tuberculosis_symptom_review', + ]; + // Here we consider activity as completed, if it was expected, + // and we actually see it as completed at encounter measurements. + // If not expected, we consider it completed. + $mandatory_activities_completed = TRUE; + foreach ($mandatory_activities as $activity) { + if (in_array($activity, $expected) && !in_array($activity, $completed)) { + $mandatory_activities_completed = FALSE; + break; + } + } + + if ($mandatory_activities_completed) { + $expected = array_merge( + $expected, + ['tuberculosis_follow_up', 'tuberculosis_health_education'] + ); + + // Referral is expected, if there was reported symptom or adverse event. + // Checking if symptom was reported. + $symptom_reported = FALSE; + $symptom_review = $measurements_by_type['tuberculosis_symptom_review']; + if (!empty($symptom_review) && !empty($symptom_review->field_tuberculosis_symptoms)) { + $symptoms = $symptom_review->field_tuberculosis_symptoms[LANGUAGE_NONE]; + foreach ($symptoms as $symptom) { + if ($symptom['value'] != 'none') { + // Symptom was reported. Add Referral to expected list. + $expected[] = 'tuberculosis_referral'; + // Raise flag, as there's no need to check for adverse events. + $symptom_reported = TRUE; + break; + } + } + } + + // If symptom was not reported, checking for adverse event. + if (!$symptom_reported) { + $treatment_review = $measurements_by_type['tuberculosis_treatment_review']; + if (!empty($treatment_review) && !empty($treatment_review->field_adverse_events)) { + $adverse_events = $treatment_review->field_adverse_events[LANGUAGE_NONE]; + foreach ($adverse_events as $adverse_event) { + if ($adverse_event['value'] != 'none') { + $expected[] = 'tuberculosis_referral'; + break; + } + } + } + } + } + + $completion_data = [ + 'start_date' => $start_date, + 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), + ]; + + $encounter->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); + node_save($encounter); + } } From cf78c3d2b787451025b970bb69e0ba655f2ea414 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 11 Sep 2024 12:55:56 +0300 Subject: [PATCH 131/185] Pull data for large data sets [ci skip] --- .../completion-recalculate-large-datasets.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php index f42fc2110b..a0790c7e62 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php @@ -77,12 +77,16 @@ function generate_completion_results_data($health_center) { 'attendance', // Child Scoreboard data. 'child_scoreboard_encounter', + // HIV Data. + 'hiv_encounter', // Home Visit data. 'home_visit_encounter', // NCD Data. 'ncd_encounter', // Nutrition Individual data. 'nutrition_encounter', + // Tuberculosis Data. + 'tuberculosis_encounter', // Well Child data. 'well_child_encounter', ]; @@ -102,10 +106,12 @@ function generate_completion_results_data($health_center) { $data = [ 'acute_illness' => [], 'child_scoreboard' => [], + 'hiv' => [], 'home_visit' => [], 'ncd' => [], 'nutrition_individual' => [], 'nutrition_group' => [], + 'tuberculosis' => [], 'well_child' => [], ]; @@ -154,6 +160,10 @@ function generate_completion_results_data($health_center) { $data['child_scoreboard'][] = json_decode($json_data); break; + case 'hiv_encounter': + $data['hiv'][] = json_decode($json_data); + break; + case 'home_visit_encounter': $data['home_visit'][] = json_decode($json_data); break; @@ -166,6 +176,10 @@ function generate_completion_results_data($health_center) { $data['nutrition_individual'][] = json_decode($json_data); break; + case 'tuberculosis_encounter': + $data['tuberculosis'][] = json_decode($json_data); + break; + case 'well_child_encounter': $data['well_child'][] = json_decode($json_data); break; From 1da1c808c47420042184654a9e5a08c99607793d Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 11 Sep 2024 20:40:47 +0300 Subject: [PATCH 132/185] Expand Model, decode and store data on client [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 9 +- server/elm/src/Backend/Completion/Model.elm | 23 ++++ server/elm/src/Backend/Completion/Utils.elm | 59 ++++++++ .../custom/hedley_general/js/elm-main.js | 127 ++++++++++++++---- 4 files changed, 190 insertions(+), 28 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index 7ac403f07a..fe0b264e3f 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -21,11 +21,18 @@ decodeCompletionData = |> required "entity_type" decodeSelectedEntity |> requiredAt [ "results", "acute_illness" ] (list (decodeEncounterData acuteIllnessActivityFromMapping)) |> requiredAt [ "results", "child_scoreboard" ] (list (decodeEncounterData childScoreboardActivityFromMapping)) + |> requiredAt [ "results", "hiv" ] (list (decodeEncounterData hivActivityFromMapping)) |> requiredAt [ "results", "home_visit" ] (list (decodeEncounterData homeVisitActivityFromMapping)) |> requiredAt [ "results", "ncd" ] (list (decodeEncounterData ncdActivityFromMapping)) |> requiredAt [ "results", "nutrition_individual" ] (list (decodeEncounterData nutritionChildActivityFromMapping)) |> requiredAt [ "results", "nutrition_group" ] - (list (decodeNutritionGroupEncounterData nutritionMotherActivityFromMapping nutritionChildActivityFromMapping)) + (list + (decodeNutritionGroupEncounterData + nutritionMotherActivityFromMapping + nutritionChildActivityFromMapping + ) + ) + |> requiredAt [ "results", "tuberculosis" ] (list (decodeEncounterData tuberculosisActivityFromMapping)) |> requiredAt [ "results", "well_child" ] (list decodeWellChildEncounterData) diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index dd7baf69be..718c1caa8c 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -13,10 +13,12 @@ type alias CompletionData = , entityType : SelectedEntity , acuteIllnessData : List (EncounterData AcuteIllnessActivity) , childScoreboardData : List (EncounterData ChildScoreboardActivity) + , hivData : List (EncounterData HIVActivity) , homeVisitData : List (EncounterData HomeVisitActivity) , ncdData : List (EncounterData NCDActivity) , nutritionIndividualData : List (EncounterData NutritionChildActivity) , nutritionGroupData : List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) + , tuberculosisData : List (EncounterData TuberculosisActivity) , wellChildData : List WellChildEncounterData } @@ -189,6 +191,27 @@ type WellChildActivity | WellChildWeight +type HIVActivity + = HIVDiagnostics + | HIVFollowUp + | HIVHealthEducation + | HIVMedication + | HIVReferral + | HIVSymptomReview + | HIVTreatmentReview + + +type TuberculosisActivity + = TuberculosisDiagnostics + | TuberculosisDOT + | TuberculosisFollowUp + | TuberculosisHealthEducation + | TuberculosisMedication + | TuberculosisReferral + | TuberculosisSymptomReview + | TuberculosisTreatmentReview + + type TakenBy = TakenByNurse | TakenByCHW diff --git a/server/elm/src/Backend/Completion/Utils.elm b/server/elm/src/Backend/Completion/Utils.elm index e5f792f67b..e177445d36 100644 --- a/server/elm/src/Backend/Completion/Utils.elm +++ b/server/elm/src/Backend/Completion/Utils.elm @@ -376,6 +376,65 @@ ncdActivityFromMapping mapped = Nothing +hivActivityFromMapping : String -> Maybe HIVActivity +hivActivityFromMapping mapped = + case mapped of + "a" -> + Just HIVDiagnostics + + "b" -> + Just HIVFollowUp + + "c" -> + Just HIVHealthEducation + + "d" -> + Just HIVMedication + + "e" -> + Just HIVReferral + + "f" -> + Just HIVSymptomReview + + "g" -> + Just HIVTreatmentReview + + _ -> + Nothing + + +tuberculosisActivityFromMapping : String -> Maybe TuberculosisActivity +tuberculosisActivityFromMapping mapped = + case mapped of + "a" -> + Just TuberculosisDiagnostics + + "b" -> + Just TuberculosisDOT + + "c" -> + Just TuberculosisFollowUp + + "d" -> + Just TuberculosisHealthEducation + + "e" -> + Just TuberculosisMedication + + "f" -> + Just TuberculosisReferral + + "g" -> + Just TuberculosisSymptomReview + + "h" -> + Just TuberculosisTreatmentReview + + _ -> + Nothing + + takenByToString : TakenBy -> String takenByToString value = case value of diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 812a63ee98..a41667ea48 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -6862,12 +6862,16 @@ var $author$project$Backend$Completion$Model$CompletionData = function (site) { return function (entityType) { return function (acuteIllnessData) { return function (childScoreboardData) { - return function (homeVisitData) { - return function (ncdData) { - return function (nutritionIndividualData) { - return function (nutritionGroupData) { - return function (wellChildData) { - return {acuteIllnessData: acuteIllnessData, childScoreboardData: childScoreboardData, entityName: entityName, entityType: entityType, homeVisitData: homeVisitData, ncdData: ncdData, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site, wellChildData: wellChildData}; + return function (hivData) { + return function (homeVisitData) { + return function (ncdData) { + return function (nutritionIndividualData) { + return function (nutritionGroupData) { + return function (tuberculosisData) { + return function (wellChildData) { + return {acuteIllnessData: acuteIllnessData, childScoreboardData: childScoreboardData, entityName: entityName, entityType: entityType, hivData: hivData, homeVisitData: homeVisitData, ncdData: ncdData, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site, tuberculosisData: tuberculosisData, wellChildData: wellChildData}; + }; + }; }; }; }; @@ -8123,6 +8127,33 @@ var $author$project$Backend$Completion$Decoder$decodeWellChildEncounterData = A3 'start_date', $author$project$Gizra$NominalDate$decodeYYYYMMDD, $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$WellChildEncounterData)))); +var $author$project$Backend$Completion$Model$HIVDiagnostics = {$: 'HIVDiagnostics'}; +var $author$project$Backend$Completion$Model$HIVFollowUp = {$: 'HIVFollowUp'}; +var $author$project$Backend$Completion$Model$HIVHealthEducation = {$: 'HIVHealthEducation'}; +var $author$project$Backend$Completion$Model$HIVMedication = {$: 'HIVMedication'}; +var $author$project$Backend$Completion$Model$HIVReferral = {$: 'HIVReferral'}; +var $author$project$Backend$Completion$Model$HIVSymptomReview = {$: 'HIVSymptomReview'}; +var $author$project$Backend$Completion$Model$HIVTreatmentReview = {$: 'HIVTreatmentReview'}; +var $author$project$Backend$Completion$Utils$hivActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$HIVDiagnostics); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$HIVFollowUp); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$HIVHealthEducation); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$HIVMedication); + case 'e': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$HIVReferral); + case 'f': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$HIVSymptomReview); + case 'g': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$HIVTreatmentReview); + default: + return $elm$core$Maybe$Nothing; + } +}; var $author$project$Backend$Completion$Model$HomeVisitCaring = {$: 'HomeVisitCaring'}; var $author$project$Backend$Completion$Model$HomeVisitFeeding = {$: 'HomeVisitFeeding'}; var $author$project$Backend$Completion$Model$HomeVisitFoodSecurity = {$: 'HomeVisitFoodSecurity'}; @@ -8291,6 +8322,36 @@ var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt = F3( A2($elm$json$Json$Decode$at, path, valDecoder), decoder); }); +var $author$project$Backend$Completion$Model$TuberculosisDOT = {$: 'TuberculosisDOT'}; +var $author$project$Backend$Completion$Model$TuberculosisDiagnostics = {$: 'TuberculosisDiagnostics'}; +var $author$project$Backend$Completion$Model$TuberculosisFollowUp = {$: 'TuberculosisFollowUp'}; +var $author$project$Backend$Completion$Model$TuberculosisHealthEducation = {$: 'TuberculosisHealthEducation'}; +var $author$project$Backend$Completion$Model$TuberculosisMedication = {$: 'TuberculosisMedication'}; +var $author$project$Backend$Completion$Model$TuberculosisReferral = {$: 'TuberculosisReferral'}; +var $author$project$Backend$Completion$Model$TuberculosisSymptomReview = {$: 'TuberculosisSymptomReview'}; +var $author$project$Backend$Completion$Model$TuberculosisTreatmentReview = {$: 'TuberculosisTreatmentReview'}; +var $author$project$Backend$Completion$Utils$tuberculosisActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$TuberculosisDiagnostics); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$TuberculosisDOT); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$TuberculosisFollowUp); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$TuberculosisHealthEducation); + case 'e': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$TuberculosisMedication); + case 'f': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$TuberculosisReferral); + case 'g': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$TuberculosisSymptomReview); + case 'h': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$TuberculosisTreatmentReview); + default: + return $elm$core$Maybe$Nothing; + } +}; var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( @@ -8299,52 +8360,64 @@ var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'nutrition_group']), + ['results', 'tuberculosis']), $elm$json$Json$Decode$list( - A2($author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData, $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping, $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$tuberculosisActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'nutrition_individual']), + ['results', 'nutrition_group']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), + A2($author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData, $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping, $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'ncd']), + ['results', 'nutrition_individual']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$ncdActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'home_visit']), + ['results', 'ncd']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$homeVisitActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$ncdActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'child_scoreboard']), + ['results', 'home_visit']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$childScoreboardActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$homeVisitActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'acute_illness']), + ['results', 'hiv']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$hivActivityFromMapping)), A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_type', - $author$project$Backend$Completion$Decoder$decodeSelectedEntity, + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, + _List_fromArray( + ['results', 'child_scoreboard']), + $elm$json$Json$Decode$list( + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$childScoreboardActivityFromMapping)), A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_name', - $elm$json$Json$Decode$string, + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, + _List_fromArray( + ['results', 'acute_illness']), + $elm$json$Json$Decode$list( + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'site', - $author$project$Backend$Decoder$decodeSite, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData))))))))))); + 'entity_type', + $author$project$Backend$Completion$Decoder$decodeSelectedEntity, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'entity_name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData))))))))))))); var $author$project$Backend$Completion$Update$update = F3( function (currentDate, msg, model) { var value = msg.a; From fb47062d6ed8c68a5899da08f4f16c1276de9959 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 11 Sep 2024 21:17:33 +0300 Subject: [PATCH 133/185] View logic [ci skip] --- server/elm/src/Pages/Completion/Model.elm | 2 + server/elm/src/Pages/Completion/Utils.elm | 39 +++ server/elm/src/Pages/Completion/View.elm | 84 +++++ server/elm/src/Translate.elm | 137 +++++++-- .../custom/hedley_general/js/elm-main.js | 287 +++++++++++++++++- 5 files changed, 503 insertions(+), 46 deletions(-) diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index 592b81769d..c3520561d8 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -29,11 +29,13 @@ emptyModel = type ReportType = ReportAcuteIllness | ReportChildScoreboard + | ReportHIV | ReportHomeVisit | ReportNCD | ReportNewbornExam | ReportNutritionGroup | ReportNutritionIndividual + | ReportTuberculosis | ReportWellChild diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index 7b5d3ca6c4..43fd2624b6 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -5,11 +5,13 @@ import Backend.Completion.Model exposing ( AcuteIllnessActivity(..) , ChildScoreboardActivity(..) + , HIVActivity(..) , HomeVisitActivity(..) , NCDActivity(..) , NutritionChildActivity(..) , NutritionMotherActivity(..) , TakenBy(..) + , TuberculosisActivity(..) , WellChildActivity(..) , WellChildEncounterType(..) ) @@ -25,6 +27,9 @@ reportTypeToString reportType = ReportChildScoreboard -> "child-scoreboard" + ReportHIV -> + "hiv" + ReportHomeVisit -> "home-visit" @@ -40,6 +45,9 @@ reportTypeToString reportType = ReportNutritionIndividual -> "nutrition-individual" + ReportTuberculosis -> + "tuberculosis" + ReportWellChild -> "well-child" @@ -53,6 +61,9 @@ reportTypeFromString reportType = "child-scoreboard" -> Just ReportChildScoreboard + "hiv" -> + Just ReportHIV + "home-visit" -> Just ReportHomeVisit @@ -68,6 +79,9 @@ reportTypeFromString reportType = "nutrition-individual" -> Just ReportNutritionIndividual + "tuberculosis" -> + Just ReportTuberculosis + "well-child" -> Just ReportWellChild @@ -251,3 +265,28 @@ allNCDActivities = , NCDUrineDipstickTestResult , NCDVitals ] + + +allHIVActivities : List HIVActivity +allHIVActivities = + [ HIVDiagnostics + , HIVFollowUp + , HIVHealthEducation + , HIVMedication + , HIVReferral + , HIVSymptomReview + , HIVTreatmentReview + ] + + +allTuberculosisActivities : List TuberculosisActivity +allTuberculosisActivities = + [ TuberculosisDiagnostics + , TuberculosisDOT + , TuberculosisFollowUp + , TuberculosisHealthEducation + , TuberculosisMedication + , TuberculosisReferral + , TuberculosisSymptomReview + , TuberculosisTreatmentReview + ] diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index ec47b8fb58..97541c10bf 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -8,6 +8,7 @@ import Backend.Completion.Model , ChildScoreboardActivity(..) , CompletionData , EncounterData + , HIVActivity(..) , HomeVisitActivity(..) , NCDActivity(..) , NutritionChildActivity(..) @@ -15,6 +16,7 @@ import Backend.Completion.Model , NutritionMotherActivity(..) , SelectedEntity(..) , TakenBy(..) + , TuberculosisActivity(..) , WellChildActivity(..) , WellChildEncounterData , WellChildEncounterType(..) @@ -86,8 +88,10 @@ viewCompletionData language currentDate themePath data model = List.member reportType [ -- Exclusively CHW encounters. ReportChildScoreboard + , ReportHIV , ReportHomeVisit , ReportNewbornExam + , ReportTuberculosis -- Exclusively Nurse encounters. , ReportNCD @@ -205,6 +209,9 @@ viewCompletionData language currentDate themePath data model = ReportChildScoreboard -> viewChildScoreboardReport language data.site startDate limitDate model.takenBy data.childScoreboardData + ReportHIV -> + viewHIVReport language startDate limitDate model.takenBy data.hivData + ReportHomeVisit -> viewHomeVisitReport language startDate limitDate model.takenBy data.homeVisitData @@ -220,6 +227,9 @@ viewCompletionData language currentDate themePath data model = ReportNutritionIndividual -> viewNutritionIndividualReport language startDate limitDate model.takenBy data.nutritionIndividualData + ReportTuberculosis -> + viewTuberculosisReport language startDate limitDate model.takenBy data.tuberculosisData + ReportWellChild -> viewSPVReport language data.site startDate limitDate model.takenBy spvData ) @@ -235,11 +245,13 @@ viewCompletionData language currentDate themePath data model = model.reportType [ ReportAcuteIllness , ReportChildScoreboard + , ReportHIV , ReportHomeVisit , ReportNCD , ReportNewbornExam , ReportNutritionGroup , ReportNutritionIndividual + , ReportTuberculosis , ReportWellChild ] reportTypeToString @@ -345,6 +357,24 @@ viewNCDReport language startDate limitDate mTakenBy reportData = |> div [ class "report ncd" ] +viewHIVReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData HIVActivity) -> Html Msg +viewHIVReport language startDate limitDate mTakenBy reportData = + eliminateEmptyEncounters reportData + |> applyFilters startDate limitDate mTakenBy + |> generateHIVReportData language + |> viewMetricsResultsTable + |> div [ class "report hiv" ] + + +viewTuberculosisReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData TuberculosisActivity) -> Html Msg +viewTuberculosisReport language startDate limitDate mTakenBy reportData = + eliminateEmptyEncounters reportData + |> applyFilters startDate limitDate mTakenBy + |> generateTuberculosisReportData language + |> viewMetricsResultsTable + |> div [ class "report tuberculosis" ] + + eliminateEmptyEncounters : List { c | completion : { b | completedActivities : List a } } -> List { c | completion : { b | completedActivities : List a } } @@ -608,6 +638,60 @@ generateNCDReportData language records = } +generateHIVReportData : + Language + -> List (EncounterData HIVActivity) + -> MetricsResultsTableData +generateHIVReportData language records = + { heading = translate language Translate.HIV + , captions = generateCaptionsList language + , rows = + List.map + (\activity -> + let + expected = + countOccurrences (.completion >> .expectedActivities) activity records + + completed = + countOccurrences (.completion >> .completedActivities) activity records + in + [ translate language <| Translate.HIVActivity activity + , String.fromInt expected + , String.fromInt completed + , calcualtePercentage completed expected + ] + ) + allHIVActivities + } + + +generateTuberculosisReportData : + Language + -> List (EncounterData TuberculosisActivity) + -> MetricsResultsTableData +generateTuberculosisReportData language records = + { heading = translate language Translate.Tuberculosis + , captions = generateCaptionsList language + , rows = + List.map + (\activity -> + let + expected = + countOccurrences (.completion >> .expectedActivities) activity records + + completed = + countOccurrences (.completion >> .completedActivities) activity records + in + [ translate language <| Translate.TuberculosisActivity activity + , String.fromInt expected + , String.fromInt completed + , calcualtePercentage completed expected + ] + ) + allTuberculosisActivities + } + + -- Helper functions. diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 87771f576b..1d05b1aa13 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -9,11 +9,13 @@ import Backend.Completion.Model exposing ( AcuteIllnessActivity(..) , ChildScoreboardActivity(..) + , HIVActivity(..) , HomeVisitActivity(..) , NCDActivity(..) , NutritionChildActivity(..) , NutritionMotherActivity(..) , TakenBy(..) + , TuberculosisActivity(..) , WellChildActivity(..) ) import Backend.Reports.Model exposing (AcuteIllnessDiagnosis(..), NutritionReportTableType(..)) @@ -89,6 +91,7 @@ type TranslationId | CoreExam | DangerSigns | Diagnosis + | Diagnostics | District | Demographics | DownloadCSV @@ -100,6 +103,7 @@ type TranslationId | FBF | Feeding | Female + | FollowUp | FoodSecurity | GenerateReport | Global @@ -107,6 +111,7 @@ type TranslationId | HealthCenter | HealthEducation | HIV + | HIVActivity HIVActivity | HIVTest | HomeVisit | HomeVisitActivity HomeVisitActivity @@ -132,6 +137,7 @@ type TranslationId | InfrastructureEnvironmentWash | LoadData | Male + | Medication | MedicationDistribution | Month Month | MonthLabel @@ -196,11 +202,14 @@ type TranslationId | StuntingModerate | StuntingSevere | Status + | SymptomsReview | TakenBy TakenBy | TakenByLabel | TargetedInterventions | Total + | TreatmentReview | Tuberculosis + | TuberculosisActivity TuberculosisActivity | Vitals | ViewMode | Village @@ -261,10 +270,7 @@ translationSet transId = translationSet DangerSigns AcuteIllnessFollowUp -> - { english = "Follow Up" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet FollowUp AcuteIllnessMUAC -> { english = "MUAC" @@ -537,6 +543,9 @@ translationSet transId = Pages.Completion.Model.ReportChildScoreboard -> translationSet ChildScorecard + Pages.Completion.Model.ReportHIV -> + translationSet HIV + Pages.Completion.Model.ReportHomeVisit -> translationSet HomeVisit @@ -547,16 +556,13 @@ translationSet transId = translationSet NewbornExam Pages.Completion.Model.ReportNutritionGroup -> - { english = "Nutrition Group" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet NutritionGroup Pages.Completion.Model.ReportNutritionIndividual -> - { english = "Nutrition Individual" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet NutritionIndividual + + Pages.Completion.Model.ReportTuberculosis -> + translationSet Tuberculosis Pages.Completion.Model.ReportWellChild -> translationSet StandardPediatricVisit @@ -632,6 +638,12 @@ translationSet transId = , kirundi = Nothing } + Diagnostics -> + { english = "Diagnostics" + , kinyarwanda = Nothing + , kirundi = Nothing + } + District -> { english = "District" , kinyarwanda = Nothing @@ -704,6 +716,12 @@ translationSet transId = , kirundi = Nothing } + FollowUp -> + { english = "Follow Up" + , kinyarwanda = Nothing + , kirundi = Nothing + } + FoodSecurity -> { english = "Food Security" , kinyarwanda = Nothing @@ -740,6 +758,29 @@ translationSet transId = , kirundi = Nothing } + HIVActivity activity -> + case activity of + HIVDiagnostics -> + translationSet Diagnostics + + HIVFollowUp -> + translationSet FollowUp + + HIVHealthEducation -> + translationSet HealthEducation + + HIVMedication -> + translationSet Medication + + HIVReferral -> + translationSet Referral + + HIVSymptomReview -> + translationSet SymptomsReview + + HIVTreatmentReview -> + translationSet TreatmentReview + HIVTest -> { english = "HIV Test" , kinyarwanda = Nothing @@ -895,6 +936,12 @@ translationSet transId = , kirundi = Nothing } + Medication -> + { english = "Medication" + , kinyarwanda = Nothing + , kirundi = Nothing + } + MedicationDistribution -> { english = "Medication Distribution" , kinyarwanda = Nothing @@ -1009,10 +1056,7 @@ translationSet transId = } NCDSymptomReview -> - { english = "Symptoms Review" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet SymptomsReview NCDUrineDipstickTest -> translationSet UrineDipstickTest @@ -1340,19 +1384,13 @@ translationSet transId = } NutritionFollowUp -> - { english = "Follow Up" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet FollowUp NutritionHealthEducation -> translationSet HealthEducation NutritionSendToHC -> - { english = "Referal" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Referral NutritionNCDA -> { english = "NCDA" @@ -1696,6 +1734,12 @@ translationSet transId = , kirundi = Nothing } + SymptomsReview -> + { english = "Symptoms Review" + , kinyarwanda = Nothing + , kirundi = Nothing + } + TakenBy value -> case value of TakenByNurse -> @@ -1734,12 +1778,47 @@ translationSet transId = , kirundi = Nothing } + TreatmentReview -> + { english = "Treatment Review" + , kinyarwanda = Nothing + , kirundi = Nothing + } + Tuberculosis -> { english = "Tuberculosis" , kinyarwanda = Nothing , kirundi = Nothing } + TuberculosisActivity activity -> + case activity of + TuberculosisDiagnostics -> + translationSet Diagnostics + + TuberculosisDOT -> + { english = "DOT" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + TuberculosisFollowUp -> + translationSet FollowUp + + TuberculosisHealthEducation -> + translationSet HealthEducation + + TuberculosisMedication -> + translationSet Medication + + TuberculosisReferral -> + translationSet Referral + + TuberculosisSymptomReview -> + translationSet SymptomsReview + + TuberculosisTreatmentReview -> + translationSet TreatmentReview + ViewMode -> { english = "View Mode" , kinyarwanda = Nothing @@ -1842,10 +1921,7 @@ translationSet transId = translationSet Feeding WellChildFollowUp -> - { english = "Follow Up" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet FollowUp WellChildFoodSecurity -> translationSet FoodSecurity @@ -1929,10 +2005,7 @@ translationSet transId = translationSet Referral WellChildSymptomsReview -> - { english = "Symptoms Review" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet SymptomsReview WellChildVitals -> translationSet Vitals diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index a41667ea48..9f75ecef1b 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5827,11 +5827,13 @@ var $elm_community$maybe_extra$Maybe$Extra$or = F2( }); var $author$project$Pages$Completion$Model$ReportAcuteIllness = {$: 'ReportAcuteIllness'}; var $author$project$Pages$Completion$Model$ReportChildScoreboard = {$: 'ReportChildScoreboard'}; +var $author$project$Pages$Completion$Model$ReportHIV = {$: 'ReportHIV'}; var $author$project$Pages$Completion$Model$ReportHomeVisit = {$: 'ReportHomeVisit'}; var $author$project$Pages$Completion$Model$ReportNCD = {$: 'ReportNCD'}; var $author$project$Pages$Completion$Model$ReportNewbornExam = {$: 'ReportNewbornExam'}; var $author$project$Pages$Completion$Model$ReportNutritionGroup = {$: 'ReportNutritionGroup'}; var $author$project$Pages$Completion$Model$ReportNutritionIndividual = {$: 'ReportNutritionIndividual'}; +var $author$project$Pages$Completion$Model$ReportTuberculosis = {$: 'ReportTuberculosis'}; var $author$project$Pages$Completion$Model$ReportWellChild = {$: 'ReportWellChild'}; var $author$project$Pages$Completion$Utils$reportTypeFromString = function (reportType) { switch (reportType) { @@ -5839,6 +5841,8 @@ var $author$project$Pages$Completion$Utils$reportTypeFromString = function (repo return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportAcuteIllness); case 'child-scoreboard': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportChildScoreboard); + case 'hiv': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportHIV); case 'home-visit': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportHomeVisit); case 'ncd': @@ -5849,6 +5853,8 @@ var $author$project$Pages$Completion$Utils$reportTypeFromString = function (repo return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionGroup); case 'nutrition-individual': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionIndividual); + case 'tuberculosis': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportTuberculosis); case 'well-child': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportWellChild); default: @@ -10179,11 +10185,14 @@ var $author$project$Translate$Cell = {$: 'Cell'}; var $author$project$Translate$ChildScorecard = {$: 'ChildScorecard'}; var $author$project$Translate$CoreExam = {$: 'CoreExam'}; var $author$project$Translate$DangerSigns = {$: 'DangerSigns'}; +var $author$project$Translate$Diagnostics = {$: 'Diagnostics'}; var $author$project$Translate$District = {$: 'District'}; var $author$project$Translate$FamilyPlanning = {$: 'FamilyPlanning'}; var $author$project$Translate$Feeding = {$: 'Feeding'}; +var $author$project$Translate$FollowUp = {$: 'FollowUp'}; var $author$project$Translate$FoodSecurity = {$: 'FoodSecurity'}; var $author$project$Translate$Global = {$: 'Global'}; +var $author$project$Translate$HIV = {$: 'HIV'}; var $author$project$Translate$HIVTest = {$: 'HIVTest'}; var $author$project$Translate$HealthCenter = {$: 'HealthCenter'}; var $author$project$Translate$HealthEducation = {$: 'HealthEducation'}; @@ -10204,10 +10213,13 @@ var $author$project$Translate$IncidenceByQuarterOneVisitOrMore = {$: 'IncidenceB var $author$project$Translate$IncidenceByQuarterTwoVisitsOrMore = {$: 'IncidenceByQuarterTwoVisitsOrMore'}; var $author$project$Translate$IncidenceByYearOneVisitOrMore = {$: 'IncidenceByYearOneVisitOrMore'}; var $author$project$Translate$IncidenceByYearTwoVisitsOrMore = {$: 'IncidenceByYearTwoVisitsOrMore'}; +var $author$project$Translate$Medication = {$: 'Medication'}; var $author$project$Translate$MedicationDistribution = {$: 'MedicationDistribution'}; var $author$project$Translate$NCD = {$: 'NCD'}; var $author$project$Translate$NCDA = {$: 'NCDA'}; var $author$project$Translate$NewbornExam = {$: 'NewbornExam'}; +var $author$project$Translate$NutritionGroup = {$: 'NutritionGroup'}; +var $author$project$Translate$NutritionIndividual = {$: 'NutritionIndividual'}; var $author$project$Translate$PregnancyTest = {$: 'PregnancyTest'}; var $author$project$Translate$PrevalenceByMonthOneVisitOrMore = {$: 'PrevalenceByMonthOneVisitOrMore'}; var $author$project$Translate$PrevalenceByMonthTwoVisitsOrMore = {$: 'PrevalenceByMonthTwoVisitsOrMore'}; @@ -10217,6 +10229,9 @@ var $author$project$Translate$RandomBloodSugarTestResult = {$: 'RandomBloodSugar var $author$project$Translate$Referral = {$: 'Referral'}; var $author$project$Translate$Sector = {$: 'Sector'}; var $author$project$Translate$StandardPediatricVisit = {$: 'StandardPediatricVisit'}; +var $author$project$Translate$SymptomsReview = {$: 'SymptomsReview'}; +var $author$project$Translate$TreatmentReview = {$: 'TreatmentReview'}; +var $author$project$Translate$Tuberculosis = {$: 'Tuberculosis'}; var $author$project$Translate$UrineDipstickTest = {$: 'UrineDipstickTest'}; var $author$project$Translate$UrineDipstickTestResult = {$: 'UrineDipstickTestResult'}; var $author$project$Translate$Village = {$: 'Village'}; @@ -10412,7 +10427,9 @@ var $author$project$Translate$translationSet = function (transId) { transId = $temp$transId; continue translationSet; case 'AcuteIllnessFollowUp': - return {english: 'Follow Up', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$FollowUp; + transId = $temp$transId; + continue translationSet; case 'AcuteIllnessMUAC': return {english: 'MUAC', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessNutrition': @@ -10585,6 +10602,10 @@ var $author$project$Translate$translationSet = function (transId) { var $temp$transId = $author$project$Translate$ChildScorecard; transId = $temp$transId; continue translationSet; + case 'ReportHIV': + var $temp$transId = $author$project$Translate$HIV; + transId = $temp$transId; + continue translationSet; case 'ReportHomeVisit': var $temp$transId = $author$project$Translate$HomeVisit; transId = $temp$transId; @@ -10598,9 +10619,17 @@ var $author$project$Translate$translationSet = function (transId) { transId = $temp$transId; continue translationSet; case 'ReportNutritionGroup': - return {english: 'Nutrition Group', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$NutritionGroup; + transId = $temp$transId; + continue translationSet; case 'ReportNutritionIndividual': - return {english: 'Nutrition Individual', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$NutritionIndividual; + transId = $temp$transId; + continue translationSet; + case 'ReportTuberculosis': + var $temp$transId = $author$project$Translate$Tuberculosis; + transId = $temp$transId; + continue translationSet; default: var $temp$transId = $author$project$Translate$StandardPediatricVisit; transId = $temp$transId; @@ -10660,6 +10689,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Core Exam', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'DangerSigns': return {english: 'Danger Signs', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Diagnostics': + return {english: 'Diagnostics', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'District': return {english: 'District', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Demographics': @@ -10684,6 +10715,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Female', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Global': return {english: 'Global', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'FollowUp': + return {english: 'Follow Up', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'FoodSecurity': return {english: 'Food Security', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'GenerateReport': @@ -10696,6 +10729,38 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Health Education', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'HIV': return {english: 'HIV', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'HIVActivity': + var activity = transId.a; + switch (activity.$) { + case 'HIVDiagnostics': + var $temp$transId = $author$project$Translate$Diagnostics; + transId = $temp$transId; + continue translationSet; + case 'HIVFollowUp': + var $temp$transId = $author$project$Translate$FollowUp; + transId = $temp$transId; + continue translationSet; + case 'HIVHealthEducation': + var $temp$transId = $author$project$Translate$HealthEducation; + transId = $temp$transId; + continue translationSet; + case 'HIVMedication': + var $temp$transId = $author$project$Translate$Medication; + transId = $temp$transId; + continue translationSet; + case 'HIVReferral': + var $temp$transId = $author$project$Translate$Referral; + transId = $temp$transId; + continue translationSet; + case 'HIVSymptomReview': + var $temp$transId = $author$project$Translate$SymptomsReview; + transId = $temp$transId; + continue translationSet; + default: + var $temp$transId = $author$project$Translate$TreatmentReview; + transId = $temp$transId; + continue translationSet; + } case 'HIVTest': return {english: 'HIV Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'HomeVisit': @@ -10765,6 +10830,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Load Data', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Male': return {english: 'Male', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Medication': + return {english: 'Medication', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'MedicationDistribution': return {english: 'Medication Distribution', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Month': @@ -10843,7 +10910,9 @@ var $author$project$Translate$translationSet = function (transId) { case 'NCDSocialHistory': return {english: 'Social History', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NCDSymptomReview': - return {english: 'Symptoms Review', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$SymptomsReview; + transId = $temp$transId; + continue translationSet; case 'NCDUrineDipstickTest': var $temp$transId = $author$project$Translate$UrineDipstickTest; transId = $temp$transId; @@ -11075,13 +11144,17 @@ var $author$project$Translate$translationSet = function (transId) { case 'NutritionContributingFactors': return {english: 'Contributing Factors', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NutritionFollowUp': - return {english: 'Follow Up', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$FollowUp; + transId = $temp$transId; + continue translationSet; case 'NutritionHealthEducation': var $temp$transId = $author$project$Translate$HealthEducation; transId = $temp$transId; continue translationSet; case 'NutritionSendToHC': - return {english: 'Referal', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Referral; + transId = $temp$transId; + continue translationSet; case 'NutritionNCDA': return {english: 'NCDA', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; default: @@ -11293,6 +11366,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Stunting Severe', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Status': return {english: 'Status', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'SymptomsReview': + return {english: 'Symptoms Review', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'TakenBy': var value = transId.a; switch (value.$) { @@ -11309,8 +11384,44 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Targeted Interventions', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Total': return {english: 'Total', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'TreatmentReview': + return {english: 'Treatment Review', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Tuberculosis': return {english: 'Tuberculosis', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'TuberculosisActivity': + var activity = transId.a; + switch (activity.$) { + case 'TuberculosisDiagnostics': + var $temp$transId = $author$project$Translate$Diagnostics; + transId = $temp$transId; + continue translationSet; + case 'TuberculosisDOT': + return {english: 'DOT', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'TuberculosisFollowUp': + var $temp$transId = $author$project$Translate$FollowUp; + transId = $temp$transId; + continue translationSet; + case 'TuberculosisHealthEducation': + var $temp$transId = $author$project$Translate$HealthEducation; + transId = $temp$transId; + continue translationSet; + case 'TuberculosisMedication': + var $temp$transId = $author$project$Translate$Medication; + transId = $temp$transId; + continue translationSet; + case 'TuberculosisReferral': + var $temp$transId = $author$project$Translate$Referral; + transId = $temp$transId; + continue translationSet; + case 'TuberculosisSymptomReview': + var $temp$transId = $author$project$Translate$SymptomsReview; + transId = $temp$transId; + continue translationSet; + default: + var $temp$transId = $author$project$Translate$TreatmentReview; + transId = $temp$transId; + continue translationSet; + } case 'ViewMode': return {english: 'View Mode', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Vitals': @@ -11363,7 +11474,9 @@ var $author$project$Translate$translationSet = function (transId) { transId = $temp$transId; continue translationSet; case 'WellChildFollowUp': - return {english: 'Follow Up', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$FollowUp; + transId = $temp$transId; + continue translationSet; case 'WellChildFoodSecurity': var $temp$transId = $author$project$Translate$FoodSecurity; transId = $temp$transId; @@ -11425,7 +11538,9 @@ var $author$project$Translate$translationSet = function (transId) { transId = $temp$transId; continue translationSet; case 'WellChildSymptomsReview': - return {english: 'Symptoms Review', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$SymptomsReview; + transId = $temp$transId; + continue translationSet; case 'WellChildVitals': var $temp$transId = $author$project$Translate$Vitals; transId = $temp$transId; @@ -12332,6 +12447,8 @@ var $author$project$Pages$Completion$Utils$reportTypeToString = function (report return 'acute-illness'; case 'ReportChildScoreboard': return 'child-scoreboard'; + case 'ReportHIV': + return 'hiv'; case 'ReportHomeVisit': return 'home-visit'; case 'ReportNCD': @@ -12342,6 +12459,8 @@ var $author$project$Pages$Completion$Utils$reportTypeToString = function (report return 'nutrition-group'; case 'ReportNutritionIndividual': return 'nutrition-individual'; + case 'ReportTuberculosis': + return 'tuberculosis'; default: return 'well-child'; } @@ -13885,6 +14004,76 @@ var $author$project$Pages$Utils$viewCustomSelectListInput = F6( }, options))); }); +var $author$project$Translate$HIVActivity = function (a) { + return {$: 'HIVActivity', a: a}; +}; +var $author$project$Pages$Completion$Utils$allHIVActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$HIVDiagnostics, $author$project$Backend$Completion$Model$HIVFollowUp, $author$project$Backend$Completion$Model$HIVHealthEducation, $author$project$Backend$Completion$Model$HIVMedication, $author$project$Backend$Completion$Model$HIVReferral, $author$project$Backend$Completion$Model$HIVSymptomReview, $author$project$Backend$Completion$Model$HIVTreatmentReview]); +var $author$project$Pages$Completion$View$generateHIVReportData = F2( + function (language, records) { + return { + captions: $author$project$Pages$Completion$View$generateCaptionsList(language), + heading: A2($author$project$Translate$translate, language, $author$project$Translate$HIV), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.expectedActivities; + }), + activity, + records); + var completed = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.completedActivities; + }), + activity, + records); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$HIVActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) + ]); + }, + $author$project$Pages$Completion$Utils$allHIVActivities) + }; + }); +var $author$project$Pages$Completion$View$viewHIVReport = F5( + function (language, startDate, limitDate, mTakenBy, reportData) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report hiv') + ]), + $author$project$Pages$Components$View$viewMetricsResultsTable( + A2( + $author$project$Pages$Completion$View$generateHIVReportData, + language, + A4( + $author$project$Pages$Completion$View$applyFilters, + startDate, + limitDate, + mTakenBy, + $author$project$Pages$Completion$View$eliminateEmptyEncounters(reportData))))); + }); var $author$project$Translate$HomeVisitActivity = function (a) { return {$: 'HomeVisitActivity', a: a}; }; @@ -14145,7 +14334,6 @@ var $author$project$Pages$Completion$View$viewNewbornExamReport = F5( var $author$project$Translate$NutritionChildActivity = function (a) { return {$: 'NutritionChildActivity', a: a}; }; -var $author$project$Translate$NutritionGroup = {$: 'NutritionGroup'}; var $author$project$Translate$NutritionMotherActivity = function (a) { return {$: 'NutritionMotherActivity', a: a}; }; @@ -14224,7 +14412,6 @@ var $author$project$Pages$Completion$View$viewNutritionGroupReport = F5( language, A4($author$project$Pages$Completion$View$applyFilters, startDate, limitDate, mTakenBy, reportData)))); }); -var $author$project$Translate$NutritionIndividual = {$: 'NutritionIndividual'}; var $author$project$Pages$Completion$View$generateNutritionIndividualReportData = F2( function (language, records) { return { @@ -14351,6 +14538,76 @@ var $author$project$Pages$Utils$viewSelectListInput = F7( inputClass, $elm$core$Maybe$Just('')); }); +var $author$project$Translate$TuberculosisActivity = function (a) { + return {$: 'TuberculosisActivity', a: a}; +}; +var $author$project$Pages$Completion$Utils$allTuberculosisActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$TuberculosisDiagnostics, $author$project$Backend$Completion$Model$TuberculosisDOT, $author$project$Backend$Completion$Model$TuberculosisFollowUp, $author$project$Backend$Completion$Model$TuberculosisHealthEducation, $author$project$Backend$Completion$Model$TuberculosisMedication, $author$project$Backend$Completion$Model$TuberculosisReferral, $author$project$Backend$Completion$Model$TuberculosisSymptomReview, $author$project$Backend$Completion$Model$TuberculosisTreatmentReview]); +var $author$project$Pages$Completion$View$generateTuberculosisReportData = F2( + function (language, records) { + return { + captions: $author$project$Pages$Completion$View$generateCaptionsList(language), + heading: A2($author$project$Translate$translate, language, $author$project$Translate$Tuberculosis), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.expectedActivities; + }), + activity, + records); + var completed = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.completedActivities; + }), + activity, + records); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$TuberculosisActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) + ]); + }, + $author$project$Pages$Completion$Utils$allTuberculosisActivities) + }; + }); +var $author$project$Pages$Completion$View$viewTuberculosisReport = F5( + function (language, startDate, limitDate, mTakenBy, reportData) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report tuberculosis') + ]), + $author$project$Pages$Components$View$viewMetricsResultsTable( + A2( + $author$project$Pages$Completion$View$generateTuberculosisReportData, + language, + A4( + $author$project$Pages$Completion$View$applyFilters, + startDate, + limitDate, + mTakenBy, + $author$project$Pages$Completion$View$eliminateEmptyEncounters(reportData))))); + }); var $author$project$Pages$Utils$viewCustomLabel = F4( function (language, translationId, suffix, class_) { return A2( @@ -14458,7 +14715,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( $elm$core$List$member, reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNCD]))) { + [$author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHIV, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportTuberculosis, $author$project$Pages$Completion$Model$ReportNCD]))) { return $author$project$Gizra$Html$emptyNode; } else { var options = A2( @@ -14590,6 +14847,8 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( return A5($author$project$Pages$Completion$View$viewAcuteIllnessReport, language, startDate, limitDate, model.takenBy, data.acuteIllnessData); case 'ReportChildScoreboard': return A6($author$project$Pages$Completion$View$viewChildScoreboardReport, language, data.site, startDate, limitDate, model.takenBy, data.childScoreboardData); + case 'ReportHIV': + return A5($author$project$Pages$Completion$View$viewHIVReport, language, startDate, limitDate, model.takenBy, data.hivData); case 'ReportHomeVisit': return A5($author$project$Pages$Completion$View$viewHomeVisitReport, language, startDate, limitDate, model.takenBy, data.homeVisitData); case 'ReportNCD': @@ -14600,6 +14859,8 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( return A5($author$project$Pages$Completion$View$viewNutritionGroupReport, language, startDate, limitDate, model.takenBy, data.nutritionGroupData); case 'ReportNutritionIndividual': return A5($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, model.takenBy, data.nutritionIndividualData); + case 'ReportTuberculosis': + return A5($author$project$Pages$Completion$View$viewTuberculosisReport, language, startDate, limitDate, model.takenBy, data.tuberculosisData); default: return A6($author$project$Pages$Completion$View$viewSPVReport, language, data.site, startDate, limitDate, model.takenBy, spvData); } @@ -14635,7 +14896,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( language, model.reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNCD, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportWellChild]), + [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHIV, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNCD, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportTuberculosis, $author$project$Pages$Completion$Model$ReportWellChild]), $author$project$Pages$Completion$Utils$reportTypeToString, $author$project$Pages$Completion$Model$SetReportType, $author$project$Translate$CompletionReportType, @@ -15168,12 +15429,10 @@ var $author$project$Translate$CHW = {$: 'CHW'}; var $author$project$Translate$EncounterType = {$: 'EncounterType'}; var $author$project$Translate$Encounters = {$: 'Encounters'}; var $author$project$Translate$FBF = {$: 'FBF'}; -var $author$project$Translate$HIV = {$: 'HIV'}; var $author$project$Translate$Individual = {$: 'Individual'}; var $author$project$Translate$NutritionTotal = {$: 'NutritionTotal'}; var $author$project$Translate$PMTCT = {$: 'PMTCT'}; var $author$project$Translate$Sorwathe = {$: 'Sorwathe'}; -var $author$project$Translate$Tuberculosis = {$: 'Tuberculosis'}; var $author$project$Translate$Unique = {$: 'Unique'}; var $author$project$Pages$Reports$View$generateDemographicsReportEncountersData = F2( function (language, records) { From 7966f26339b015ecb22b9a5966833b087f3af4d7 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 11 Sep 2024 21:18:25 +0300 Subject: [PATCH 134/185] Style [ci skip] --- server/hedley/modules/custom/hedley_general/css/elm.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/hedley/modules/custom/hedley_general/css/elm.css b/server/hedley/modules/custom/hedley_general/css/elm.css index 822d30d0b5..2e6b54c7b3 100644 --- a/server/hedley/modules/custom/hedley_general/css/elm.css +++ b/server/hedley/modules/custom/hedley_general/css/elm.css @@ -396,10 +396,12 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.acute-illness .table .row .item.row-label, .page-content .inputs .report.child-scoreboard .table .row .item.row-label, +.page-content .inputs .report.hiv .table .row .item.row-label, .page-content .inputs .report.home-visit .table .row .item.row-label, .page-content .inputs .report.ncd .table .row .item.row-label, .page-content .inputs .report.nutrition-group .table .row .item.row-label, .page-content .inputs .report.nutrition-individual .table .row .item.row-label, +.page-content .inputs .report.tuberculosis .table .row .item.row-label, .page-content .inputs .report.well-child .table .row .item.row-label { width: 30%; } @@ -408,6 +410,8 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.acute-illness .table .row .item.value, .page-content .inputs .report.child-scoreboard .table .row .item.heading, .page-content .inputs .report.child-scoreboard .table .row .item.value, +.page-content .inputs .report.hiv .table .row .item.heading, +.page-content .inputs .report.hiv .table .row .item.value, .page-content .inputs .report.home-visit .table .row .item.heading, .page-content .inputs .report.home-visit .table .row .item.value, .page-content .inputs .report.ncd .table .row .item.heading, @@ -416,6 +420,8 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.nutrition-group .table .row .item.value, .page-content .inputs .report.nutrition-individual .table .row .item.heading, .page-content .inputs .report.nutrition-individual .table .row .item.value, +.page-content .inputs .report.tuberculosis .table .row .item.heading, +.page-content .inputs .report.tuberculosis .table .row .item.value, .page-content .inputs .report.well-child .table .row .item.heading, .page-content .inputs .report.well-child .table .row .item.value { width: 20%; From e10458964d61c617161df2c5eadd061c8528f4fc Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 11 Sep 2024 21:18:34 +0300 Subject: [PATCH 135/185] Satisfy coder --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 1 - 1 file changed, 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 8743c09875..57fef70380 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5673,7 +5673,6 @@ function hedley_reports_generate_completion_data_for_tuberculosis($participant, } } - /** * Checks if a lab test was performed based on the test execution note. * From 661b9d141b94c88143d081b2066a40d7c2f68331 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 15 Sep 2024 11:42:00 +0300 Subject: [PATCH 136/185] Add completion data field to prenatal encounter CT [ci skip] --- ...edley_schedule.features.field_instance.inc | 50 +++++++++++++++++-- .../hedley_schedule/hedley_schedule.info | 1 + .../hedley_schedule.strongarm.inc | 2 +- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc index cfda1990e9..f20b63ac28 100644 --- a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc +++ b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.features.field_instance.inc @@ -2594,7 +2594,7 @@ Used to track location where pregnancies were completed.', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => 3, + 'weight' => 2, ), ); @@ -2632,7 +2632,47 @@ Used to track location where pregnancies were completed.', 'module' => 'options', 'settings' => array(), 'type' => 'options_select', - 'weight' => 4, + 'weight' => 3, + ), + ); + + // Exported field_instance: 'node-prenatal_encounter-field_reports_data'. + $field_instances['node-prenatal_encounter-field_reports_data'] = array( + 'bundle' => 'prenatal_encounter', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 18, + ), + 'teaser' => array( + 'label' => 'above', + 'settings' => array(), + 'type' => 'hidden', + 'weight' => 0, + ), + ), + 'entity_type' => 'node', + 'field_name' => 'field_reports_data', + 'label' => 'Completion Data', + 'required' => 0, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'rows' => 5, + ), + 'type' => 'text_textarea', + 'weight' => 7, ), ); @@ -2688,7 +2728,7 @@ Used to track location where pregnancies were completed.', 'year_range' => '-3:+3', ), 'type' => 'date_select', - 'weight' => 2, + 'weight' => 1, ), ); @@ -2733,7 +2773,7 @@ Used to track location where pregnancies were completed.', 'size' => 60, ), 'type' => 'entityreference_autocomplete', - 'weight' => 5, + 'weight' => 9, ), ); @@ -2773,7 +2813,7 @@ Used to track location where pregnancies were completed.', 'size' => 60, ), 'type' => 'text_textfield', - 'weight' => 0, + 'weight' => 8, ), ); diff --git a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.info b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.info index 22a358c514..6cc538748a 100644 --- a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.info +++ b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.info @@ -101,6 +101,7 @@ features[field_instance][] = node-pmtct_participant-field_shards features[field_instance][] = node-pmtct_participant-field_uuid features[field_instance][] = node-prenatal_encounter-field_individual_participant features[field_instance][] = node-prenatal_encounter-field_prenatal_encounter_type +features[field_instance][] = node-prenatal_encounter-field_reports_data features[field_instance][] = node-prenatal_encounter-field_scheduled_date features[field_instance][] = node-prenatal_encounter-field_shards features[field_instance][] = node-prenatal_encounter-field_uuid diff --git a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc index 5584e33fc7..0f81b6703c 100644 --- a/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc +++ b/server/hedley/modules/custom/hedley_schedule/hedley_schedule.strongarm.inc @@ -405,7 +405,7 @@ function hedley_schedule_strongarm() { 'display' => array(), 'form' => array( 'title' => array( - 'weight' => '1', + 'weight' => '0', ), ), ), From 9c0a22ab62d1cdeedb17bb7900e789cddbe76903 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 15 Sep 2024 12:03:00 +0300 Subject: [PATCH 137/185] Add script + infra [ci skip] --- .../hedley_reports/hedley_reports.module | 117 ++++++++++++++++++ .../completion-generate-prenatal-data.php | 86 +++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 server/hedley/modules/custom/hedley_reports/scripts/completion-generate-prenatal-data.php diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 57fef70380..86b1051c84 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5673,6 +5673,123 @@ function hedley_reports_generate_completion_data_for_tuberculosis($participant, } } +function hedley_reports_generate_completion_data_for_prenatal($participant, $exclude_set) { + // To reduce memory usage, mapping measurement types as single characters. + $mapping = [ + 'appointment_confirmation' => 'a', + 'birth_plan' => 'b', + 'breast_exam' => 'c', + 'core_physical_exam' => 'd', + 'danger_signs' => 'e', + 'last_menstrual_period' => 'f', + 'medical_history' => 'g', + 'medication' => 'h', + 'obstetric_history' => 'i', + 'obstetric_history_step2' => 'j', + 'obstetrical_exam' => 'k', + 'pregnancy_testing' => 'l', + 'prenatal_blood_gprs_test' => 'm', + 'prenatal_breastfeeding' => 'n', + 'prenatal_family_planning' => 'o', + 'prenatal_follow_up' => 'p', + 'prenatal_gu_exam' => 'q', + 'prenatal_health_education' => 'r', + 'prenatal_hemoglobin_test' => 's', + 'prenatal_hepatitis_b_test' => 't', + 'prenatal_hiv_pcr_test' => 'u', + 'prenatal_hiv_test' => 'v', + // Not a real activity. Used for data only. + 'prenatal_labs_results' => '', + 'prenatal_malaria_test' => 'w', + 'prenatal_medication_distribution' => 'x', + 'prenatal_mental_health' => 'y', + 'prenatal_nutrition' => 'z', + 'prenatal_outside_care' => '0', + 'prenatal_partner_hiv_test' => '1', + 'prenatal_photo' => '2', + 'prenatal_random_blood_sugar_test' => '3', + 'prenatal_send_to_hc' => '4', + 'prenatal_speciality_care' => '5', + 'prenatal_symptom_review' => '6', + 'prenatal_syphilis_test' => '7', + 'prenatal_tetanus_immunisation' => '8', + 'prenatal_urine_dipstick_test' => '9', + 'resource' => '@', + 'social_history' => '#', + 'vitals' => '$', + ]; + + // Load all encounters of current participant. + $query = new EntityFieldQuery(); + $result = $query + ->entityCondition('entity_type', 'node') + ->entityCondition('bundle', 'prenatal_encounter') + ->propertyCondition('status', NODE_PUBLISHED) + ->fieldCondition('field_individual_participant', 'target_id', $participant->nid) + ->propertyOrderBy('nid') + ->execute(); + + if (empty($result['node'])) { + return; + } + + // Encounters are sorted ASC. + $encounters = node_load_multiple(array_keys($result['node'])); + $encounters_data = []; + foreach ($encounters as $encounter) { + // Skip encounter if exclusion flag is raised and it's report data is set. + if ($exclude_set && !empty($encounter->field_reports_data[LANGUAGE_NONE][0]['value'])) { + continue; + } + + // If encounter type field is empty, we default to 'nurse'. + if (empty($encounter->field_prenatal_encounter_type)) { + $encounter_type = 'nurse'; + } + else { + $encounter_type = $encounter->field_prenatal_encounter_type[LANGUAGE_NONE][0]['value']; + } + + // Loading all measurements that belong to encounter. + $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); + $measurements = !empty($measurements_ids) ? node_load_multiple($measurements_ids) : []; + // Ordering measurements by type. + $measurements_by_type = []; + foreach ($measurements as $measurement) { + $measurements_by_type[$measurement->type] = $measurement; + } + + $encounters_data[] = [ + 'encounter' => $encounter, + 'encounter_type' => $encounter_type, + 'measurements_by_type' => $measurements_by_type, + ]; + } + + foreach ($encounters_data as $index => $encounter_data) { + $encounter = $encounter_data['encounter']; + $measurements_by_type = $encounter_data['measurements_by_type']; + + // Resolve encounter start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $previous_encounters_data = array_slice($encounters_data, 0, $index); + + // So far we were constructing data structures to resolve encounter data. + // Now we have enough info to determine which activities were expected. + $completed = array_keys($measurements_by_type); + + $expected = []; + + $completion_data = [ + 'start_date' => $start_date, + 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), + ]; + + $encounter->field_reports_data[LANGUAGE_NONE][0]['value'] = json_encode($completion_data); + node_save($encounter); + } +} + /** * Checks if a lab test was performed based on the test execution note. * diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-prenatal-data.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-prenatal-data.php new file mode 100644 index 0000000000..cfbfdeffae --- /dev/null +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-generate-prenatal-data.php @@ -0,0 +1,86 @@ +entityCondition('entity_type', 'node') + ->entityCondition('bundle', $type) + ->fieldCondition('field_encounter_type', 'value', 'antenatal') + ->propertyCondition('status', NODE_PUBLISHED) + ->addTag('exclude_deleted'); + +$count_query = clone $base_query; +$count_query->propertyCondition('nid', $nid, '>'); +$count = $count_query->count()->execute(); + +if ($count == 0) { + drush_print("There are no nodes of type $type for prenatal encounters in DB."); + exit; +} + +$total = 0; +drush_print("$count nodes of type $type for prenatal encounters located."); + +while (TRUE) { + $query = clone $base_query; + if ($nid) { + $query->propertyCondition('nid', $nid, '>'); + } + + $result = $query + ->range(0, $batch) + ->execute(); + + if (empty($result['node'])) { + // No more items left. + break; + } + + $ids = array_keys($result['node']); + $nodes = node_load_multiple($ids); + foreach ($nodes as $node) { + hedley_reports_generate_completion_data_for_prenatal($node, $exclude_set); + $total++; + + $memory = round(memory_get_usage() / 1048576); + if ($memory >= $memory_limit) { + drush_print(dt('Stopped before out of memory. Start process from the node ID @nid', ['@nid' => $nid])); + return; + } + } + + $memory = round(memory_get_usage() / 1048576); + drush_print("Calculated so far: $total, Memory: $memory"); + + // Free up memory. + drupal_static_reset(); + + $nid = end($ids); +} + +drush_print("Done! Completion data calculated for $total participants."); From 637624cca75d4eb90da420c5589f6a517c3601a9 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 15 Sep 2024 21:39:14 +0300 Subject: [PATCH 138/185] Pull data when recalculating large data sets [ci skip] --- .../scripts/completion-recalculate-large-datasets.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php index a0790c7e62..41716bd5a4 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php @@ -85,6 +85,8 @@ function generate_completion_results_data($health_center) { 'ncd_encounter', // Nutrition Individual data. 'nutrition_encounter', + // Prenatal Data. + 'prenatal_encounter', // Tuberculosis Data. 'tuberculosis_encounter', // Well Child data. @@ -111,6 +113,7 @@ function generate_completion_results_data($health_center) { 'ncd' => [], 'nutrition_individual' => [], 'nutrition_group' => [], + 'prenatal' => [], 'tuberculosis' => [], 'well_child' => [], ]; @@ -176,6 +179,10 @@ function generate_completion_results_data($health_center) { $data['nutrition_individual'][] = json_decode($json_data); break; + case 'prenatal_encounter': + $data['prenatal'][] = json_decode($json_data); + break; + case 'tuberculosis_encounter': $data['tuberculosis'][] = json_decode($json_data); break; From 2a4f3fb9ba948f44e480f9c07c6a15d0d6b74854 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 15 Sep 2024 22:50:38 +0300 Subject: [PATCH 139/185] More infra [ci skip] --- .../custom/hedley_reports/hedley_reports.module | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 86b1051c84..bc82ef4104 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5776,9 +5776,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. - $completed = array_keys($measurements_by_type); - - $expected = []; + $expected = hedley_reports_prenatal_generate_expected_initial_activities($encounter_data); $completion_data = [ 'start_date' => $start_date, @@ -5790,6 +5788,12 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc } } +function hedley_reports_prenatal_generate_expected_initial_activities($encounter_data) { + $expected = []; + + return $expected; +} + /** * Checks if a lab test was performed based on the test execution note. * From cfb4e2f05d5e705b4b6fc6f9632d5f4a605ca705 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 15 Sep 2024 23:20:04 +0300 Subject: [PATCH 140/185] More infra [ci skip] --- .../hedley_reports/hedley_reports.module | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index bc82ef4104..64a5f04eee 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5750,6 +5750,23 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc $encounter_type = $encounter->field_prenatal_encounter_type[LANGUAGE_NONE][0]['value']; } + $diagnoses = $past_diagnoses = []; + if (!empty($encounter->field_prenatal_diagnoses) && !empty($encounter->field_prenatal_diagnoses[LANGUAGE_NONE])) { + foreach ($encounter->field_prenatal_diagnoses[LANGUAGE_NONE] as $diagnosis) { + if ($diagnosis['value'] != 'none') { + $diagnoses[] = $diagnosis['value']; + } + } + } + + if (!empty($encounter->field_past_prenatal_diagnoses) && !empty($encounter->field_past_prenatal_diagnoses[LANGUAGE_NONE])) { + foreach ($encounter->field_past_prenatal_diagnoses[LANGUAGE_NONE] as $diagnosis) { + if ($diagnosis['value'] != 'none') { + $past_diagnoses[] = $diagnosis['value']; + } + } + } + // Loading all measurements that belong to encounter. $measurements_ids = hedley_reports_load_individual_encounter_measurements_ids($encounter); $measurements = !empty($measurements_ids) ? node_load_multiple($measurements_ids) : []; @@ -5762,6 +5779,8 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc $encounters_data[] = [ 'encounter' => $encounter, 'encounter_type' => $encounter_type, + 'diagnoses' => $diagnoses, + 'past_diagnoses' => $past_diagnoses, 'measurements_by_type' => $measurements_by_type, ]; } @@ -5773,6 +5792,18 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // Resolve encounter start date. $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; $previous_encounters_data = array_slice($encounters_data, 0, $index); + $previous_nurse_encounters_data = $previous_chw_encounters_data = []; + foreach ($previous_encounters_data as $previous_encounter_data) { + $encounter_type = $previous_encounter_data['encounter_type']; + if (in_array($encounter_type, ['nurse', 'nurse-postpartum'])) { + $previous_nurse_encounters_data[] = $previous_encounter_data; + } + else { + $previous_chw_encounters_data[] = $previous_encounter_data; + } + } + $encounter_data['previous_nurse_encounters_data'] = $previous_nurse_encounters_data; + $encounter_data['previous_chw_encounters_data'] = $previous_chw_encounters_data; // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. @@ -5788,6 +5819,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc } } + function hedley_reports_prenatal_generate_expected_initial_activities($encounter_data) { $expected = []; From 9157a8fd070bab09a3f5823741c4ac5e447e40d9 Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 16 Sep 2024 10:53:07 +0300 Subject: [PATCH 141/185] Complete assembling data [ci skip] --- .../hedley_reports/hedley_reports.module | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 64a5f04eee..6302127282 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5805,6 +5805,38 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc $encounter_data['previous_nurse_encounters_data'] = $previous_nurse_encounters_data; $encounter_data['previous_chw_encounters_data'] = $previous_chw_encounters_data; + // Resolving global LMP date. + // First, we check for value at previous nurse encounters. + $lmp_date = NULL; + foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { + $lmp_measurement = $previous_nurse_encounter_data['measurements_by_type']['last_menstrual_period']; + if (empty($lmp_measurement) || empty($lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE])) { + continue; + } + $lmp_date = explode(' ', $lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE][0]['value']); + break; + } + // No value found at previous nurse encounters - check current encounter. + if (empty($lmp_date)) { + $lmp_measurement = $measurements_by_type['last_menstrual_period']; + if (!empty($lmp_measurement) && !empty($lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE])) { + $lmp_date = explode(' ', $lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE][0]['value']); + } + } + // No value found at current encounter - check previous CHW encounters. + if (empty($lmp_date)) { + foreach ($previous_chw_encounters_data as $previous_chw_encounter_data) { + $lmp_measurement = $previous_chw_encounter_data['measurements_by_type']['last_menstrual_period']; + if (empty($lmp_measurement) || empty($lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE])) { + continue; + } + $lmp_date = explode(' ', $lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE][0]['value']); + break; + } + } + $encounter_data['lmp_date'] = $lmp_date; + + // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. $expected = hedley_reports_prenatal_generate_expected_initial_activities($encounter_data); From b290756535692e5b5d9441eb8bf3cc40472c48ed Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 16 Sep 2024 12:25:43 +0300 Subject: [PATCH 142/185] Activities logic WIP [ci skip] --- .../hedley_reports/hedley_reports.module | 130 +++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 6302127282..e903b178aa 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5791,6 +5791,10 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // Resolve encounter start date. $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + $start_date_obj = new DateTime($start_date); + $encounter_data['start_date_obj'] = $start_date_obj; + + // Resolve and partition previous encounters data. $previous_encounters_data = array_slice($encounters_data, 0, $index); $previous_nurse_encounters_data = $previous_chw_encounters_data = []; foreach ($previous_encounters_data as $previous_encounter_data) { @@ -5840,6 +5844,8 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. $expected = hedley_reports_prenatal_generate_expected_initial_activities($encounter_data); + hedley_reports_prenatal_add_history_activities($encounter_data, $expected); + hedley_reports_prenatal_add_examination_activities($encounter_data, $expected); $completion_data = [ 'start_date' => $start_date, @@ -5851,13 +5857,135 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc } } - +/** + * Generates the list of expected activities for a prenatal encounter. + * + * Here we add activities with simple logic from: + * - Pregnancy Dating. + * - Family Planning. + * - Medication. + * - Malaria prevention (Resource). + * - Danger Signs. + * - Symptom Review. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * + * @return array + * An array of expected activity names. + */ function hedley_reports_prenatal_generate_expected_initial_activities($encounter_data) { + $encounter_type = $encounter_data['encounter_type']; + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + $expected = []; + if ($encounter_type == 'chw-1' || ($encounter_type == 'nurse' && empty($previous_nurse_encounters_data))) { + $expected[] = 'last_menstrual_period'; + } + + if (in_array($encounter_type, ['nurse', 'nurse-postpartum'])) { + $expected[] = 'prenatal_family_planning'; + + // Symptom Review activity was added on Dec 19, 2021. + $launch_date = '2021-12-19'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] >= $launch_date_obj) { + $expected[] = 'prenatal_symptom_review'; + } + } + + if ($encounter_type == 'nurse' && empty($previous_nurse_encounters_data)) { + $expected[] = 'medication'; + } + + if ($encounter_type == 'nurse') { + $mosquito_net_supplied = FALSE; + foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { + $resource_measurement = $previous_nurse_encounter_data['measurements_by_type']['resource']; + + if (!empty($resource_measurement) && !empty($resource_measurement->field_resources)) { + if ($resource_measurement->field_resources[LANGUAGE_NONE][0]['value'] == 'mosquito-net') { + $mosquito_net_supplied = TRUE; + break; + } + } + } + if (!$mosquito_net_supplied) { + $expected[] = 'resource'; + } + } + + if ($encounter_type != 'nurse-postpartum') { + $expected[] = 'danger_signs'; + } return $expected; } +/** + * Adds History activities to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_prenatal_add_history_activities(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + if ($encounter_type == 'nurse') { + return; + } + + $expected[] = 'social_history'; + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + if (empty($previous_nurse_encounters_data)) { + $expected = array_merge( + $expected, + ['medical_history', 'obstetric_history', 'obstetric_history_step2'] + ); + } + else { + // Outside care activity was added on Dec 19, 2021. + $launch_date = '2021-12-19'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] >= $launch_date_obj) { + $expected[] = 'prenatal_outside_care'; + } + } +} + +/** + * Adds Examinations activities to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_prenatal_add_examination_activities(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + if (!in_array($encounter_type, ['nurse', 'nurse-postpartum'])) { + return; + } + + $expected = array_merge( + $expected, + ['vitals', 'prenatal_nutrition', 'core_physical_exam', 'breast_exam'] + ); + + if ($encounter_type == 'nurse') { + $expected[] = 'obstetrical_exam'; + } + else { + // GU Exam activity was added on Sept 25, 2022. + $launch_date = '2021-09-25'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] >= $launch_date_obj) { + $expected[] = 'prenatal_gu_exam'; + } + } +} + /** * Checks if a lab test was performed based on the test execution note. * From 7354e524365e6e8f85b8b5cbd334e202978a2a16 Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 16 Sep 2024 23:19:23 +0300 Subject: [PATCH 143/185] WIP [ci skip] --- .../hedley_reports/hedley_reports.module | 168 +++++++++++++++++- 1 file changed, 166 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index e903b178aa..e80991826a 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3599,6 +3599,12 @@ function hedley_reports_generate_vaccination_progress_data(array $immunisations_ case 'well-child': $prefix = 'well_child_'; $suffix = '_immunisation'; + break; + + case 'prenatal': + // No need to remove anything, since there's only single source + // of immunisations, and no merge is needed. + break; } foreach ($immunisations_by_type[$type]['doses'] as $index => $dose) { @@ -5840,12 +5846,13 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc } $encounter_data['lmp_date'] = $lmp_date; - // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. $expected = hedley_reports_prenatal_generate_expected_initial_activities($encounter_data); hedley_reports_prenatal_add_history_activities($encounter_data, $expected); hedley_reports_prenatal_add_examination_activities($encounter_data, $expected); + hedley_reports_prenatal_add_immunisation_activities($encounter_data, $expected); + hedley_reports_prenatal_add_mental_health_activity($encounter_data, $expected); $completion_data = [ 'start_date' => $start_date, @@ -5857,6 +5864,41 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc } } +/** + * Generates vaccination history data for a prenatal encounter. + * + * @param array $encounter_data + * An associative array containing details of the current encounter, + * including previous encounter data and measurements. + * + * @return array + * Vaccination history data. + */ +function hedley_reports_prenatal_generate_vaccination_history_data(array $encounter_data) { + $previous_encounters_data = $encounter_data['previous_nurse_encounters_data']; + + $immunisation_types = [ + 'prenatal_tetanus_immunisation', + ]; + + $immunisations_from_previous_encounters = []; + foreach ($immunisation_types as $immunisation_type) { + $immunisations_from_previous_encounters[$immunisation_type] = []; + } + + foreach ($previous_encounters_data as $previous_encounter_data) { + $measurements_by_type = $previous_encounter_data['measurements_by_type']; + foreach ($immunisation_types as $immunisation_type) { + if (empty($measurements_by_type[$immunisation_type])) { + continue; + } + $immunisations_from_previous_encounters[$immunisation_type][] = $measurements_by_type[$immunisation_type]; + } + } + + return hedley_reports_generate_vaccination_progress_data($immunisations_from_previous_encounters, 'prenatal'); +} + /** * Generates the list of expected activities for a prenatal encounter. * @@ -5978,7 +6020,7 @@ function hedley_reports_prenatal_add_examination_activities(array $encounter_dat } else { // GU Exam activity was added on Sept 25, 2022. - $launch_date = '2021-09-25'; + $launch_date = '2022-09-25'; $launch_date_obj = new DateTime($launch_date); if ($encounter_data['start_date_obj'] >= $launch_date_obj) { $expected[] = 'prenatal_gu_exam'; @@ -5986,6 +6028,128 @@ function hedley_reports_prenatal_add_examination_activities(array $encounter_dat } } +/** + * Adds Immunisation activities as expected, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_prenatal_add_immunisation_activities(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + if ($encounter_type != 'nurse') { + return; + } + + $vaccination_history = hedley_reports_prenatal_generate_vaccination_history_data($encounter_data); + $start_date_obj = $encounter_data['start_date_obj']; + + $immunisation_type = 'prenatal_tetanus_immunisation'; + + if (empty($vaccination_history)) { + $expected[] = $immunisation_type; + return; + } + + $performed = $vaccination_history[$immunisation_type]; + if (empty($performed)) { + $expected[] = $immunisation_type; + return; + } + + $doses = array_keys($performed); + sort($doses); + $last_dose = array_reverse($doses)[0]; + $last_dose_for_immunisation = 'dose-5'; + // If all doses we administered, skipping to next immunisation type. + if ($last_dose == $last_dose_for_immunisation) { + return; + } + + // Calculating when next dose is supposed to be administered. + $interval_between_dosed = ''; + switch ($last_dose) { + case 'dose-1': + $interval_between_dosed = '+4 weeks'; + break; + + case 'dose-2': + $interval_between_dosed = '+6 months'; + break; + + case 'dose-3': + case 'dose-4': + $interval_between_dosed = '+12 months'; + break; + } + + if (empty($interval_between_dosed)) { + return; + } + + $last_dose_date = $performed[$last_dose]; + $last_dose_date_obj = new DateTime($last_dose_date); + $next_dose_date_obj = clone $last_dose_date_obj; + $next_dose_date_obj->modify($interval_between_dosed); + + // If encounter started after the date when immunisation was supposed + // to be administered, adding it as expected. + if ($start_date_obj >= $next_dose_date_obj) { + $expected[] = $immunisation_type; + } +} + +/** + * Adds Mental Health activity to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_prenatal_add_mental_health_activity(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + if (!in_array($encounter_type, ['nurse', 'nurse-postpartum'])) { + return; + } + + $lmp_date = $encounter_data['lmp_date']; + if (empty($lmp_date)) { + return; + } + + $start_date_obj = $encounter_data['start_date_obj']; + // Mental Health activity was added on Sept 25, 2022. + $launch_date = '2022-09-25'; + $launch_date_obj = new DateTime($launch_date); + if ($start_date_obj < $launch_date_obj) { + return; + } + + $lmp_date_obj = new DateTime($lmp_date); + $interval = $start_date_obj->diff($lmp_date_obj, TRUE); + // Get the total number of days from the interval + $total_days = $interval->days; + $ega_in_weeks = floor($total_days / 7); + if ($ega_in_weeks < 28) { + return; + } + + $performed_previously = FALSE; + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { + if (!empty($previous_nurse_encounter_data['measurements_by_type']['prenatal_mental_health'])) { + $performed_previously = TRUE; + break; + } + } + + if (!$performed_previously) { + $expected[] = 'prenatal_mental_health'; + } +} + /** * Checks if a lab test was performed based on the test execution note. * From 7fadb5fbb4e48d5d5d820cc719e0a75c26e46d94 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 17 Sep 2024 11:33:51 +0300 Subject: [PATCH 144/185] Prenatal Photo activity logic [ci skip] --- .../hedley_reports/hedley_reports.module | 71 +++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index e80991826a..7a6a2da418 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5853,6 +5853,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc hedley_reports_prenatal_add_examination_activities($encounter_data, $expected); hedley_reports_prenatal_add_immunisation_activities($encounter_data, $expected); hedley_reports_prenatal_add_mental_health_activity($encounter_data, $expected); + hedley_reports_prenatal_add_prenatal_photo_activity($encounter_data, $expected); $completion_data = [ 'start_date' => $start_date, @@ -6128,10 +6129,7 @@ function hedley_reports_prenatal_add_mental_health_activity(array $encounter_dat } $lmp_date_obj = new DateTime($lmp_date); - $interval = $start_date_obj->diff($lmp_date_obj, TRUE); - // Get the total number of days from the interval - $total_days = $interval->days; - $ega_in_weeks = floor($total_days / 7); + $ega_in_weeks = hedley_reports_prenatal_calculate_ega_weeks($lmp_date_obj, $start_date_obj); if ($ega_in_weeks < 28) { return; } @@ -6150,6 +6148,71 @@ function hedley_reports_prenatal_add_mental_health_activity(array $encounter_dat } } +/** + * Adds Prenatal Photo activity to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_prenatal_add_prenatal_photo_activity(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + if ($encounter_type != 'nurse') { + return; + } + + $lmp_date = $encounter_data['lmp_date']; + if (empty($lmp_date)) { + return; + } + + $start_date_obj = $encounter_data['start_date_obj']; + $lmp_date_obj = new DateTime($lmp_date); + $ega_in_weeks = hedley_reports_prenatal_calculate_ega_weeks($lmp_date_obj, $start_date_obj); + + $photo_taken_for_period = FALSE; + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { + $prenatal_photo_measurement = $previous_nurse_encounter_data['measurements_by_type']['prenatal_photo']; + if (!empty($prenatal_photo_measurement)) { + $date_measured = explode(' ', $prenatal_photo_measurement->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; + if (empty($date_measured)) { + continue; + } + $date_measured_obj = new DateTime($date_measured); + $photo_ega_in_weeks = hedley_reports_prenatal_calculate_ega_weeks($lmp_date_obj, $date_measured_obj); + + // Periods, where we want to have 1 photo: + // 1. 12 weeks, or less. + // 2. Between week 13 and week 27. + // 3. Week 28, or more. + // If we found a photo that matches encounter period, + // activity is not expected. + if ( + ($ega_in_weeks <= 12 && $photo_ega_in_weeks <= 12) || + (($ega_in_weeks >= 13 && $photo_ega_in_weeks >= 13) && ($ega_in_weeks <= 27 && $photo_ega_in_weeks <= 27)) || + ($ega_in_weeks >= 28 && $photo_ega_in_weeks >= 28) + ) { + $photo_taken_for_period = TRUE; + break; + } + } + } + + // If we got so far, activity is expected. + if (!$photo_taken_for_period) { + $expected[] = 'prenatal_photo'; + } +} + +function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, DateTime $encounter_date_obj ) { + $interval = $encounter_date_obj->diff($lmp_date_obj, TRUE); + // Get the total number of days from the interval + $total_days = $interval->days; + return floor($total_days / 7); +} + /** * Checks if a lab test was performed based on the test execution note. * From ad86e63b99da70db2561d1d05218ef0617e62d96 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 18 Sep 2024 22:30:16 +0300 Subject: [PATCH 145/185] Postpartum activiites logic [ci skip] --- client/src/elm/Backend/Update.elm | 4 +- .../src/elm/Pages/NCD/ProgressReport/View.elm | 4 +- .../Pages/Prenatal/ProgressReport/View.elm | 8 +- client/src/elm/Pages/Prenatal/Utils.elm | 2 +- .../hedley_reports/hedley_reports.module | 177 +++++++++++++++++- 5 files changed, 184 insertions(+), 11 deletions(-) diff --git a/client/src/elm/Backend/Update.elm b/client/src/elm/Backend/Update.elm index 5632db1752..cc34355d9d 100644 --- a/client/src/elm/Backend/Update.elm +++ b/client/src/elm/Backend/Update.elm @@ -6790,7 +6790,7 @@ generatePrenatalAssessmentMsgs currentDate language site isChw isLabTech activeP let diagnosesBefore = -- At this stage new diagnoses were not updated yet, therefore, - -- we can use the dignoses set for the encounter. + -- we can use the diganoses set for the encounter. assembledAfter.encounter.diagnoses diagnosesAfter = @@ -7275,7 +7275,7 @@ generateNCDAssessmentMsgs currentDate language activePage after id = let diagnosesBefore = -- At this stage new diagnoses were not updated yet, therefore, - -- we can use the dignoses set for the encounter. + -- we can use the diganoses set for the encounter. assembledAfter.encounter.diagnoses diagnosesAfter = diff --git a/client/src/elm/Pages/NCD/ProgressReport/View.elm b/client/src/elm/Pages/NCD/ProgressReport/View.elm index 43913f58d3..a8db466494 100644 --- a/client/src/elm/Pages/NCD/ProgressReport/View.elm +++ b/client/src/elm/Pages/NCD/ProgressReport/View.elm @@ -487,7 +487,7 @@ viewMedicalDiagnosisPane language currentDate assembled = content = List.map (Translate.MedicalCondition >> translate language >> text >> List.singleton >> li []) coMorbidities - ++ dignoses + ++ diganoses |> ul [] |> List.singleton @@ -515,7 +515,7 @@ viewMedicalDiagnosisPane language currentDate assembled = ) |> Pages.Utils.unique - dignoses = + diganoses = List.concatMap (\data -> let diff --git a/client/src/elm/Pages/Prenatal/ProgressReport/View.elm b/client/src/elm/Pages/Prenatal/ProgressReport/View.elm index 709338569a..4bd6c90d6a 100644 --- a/client/src/elm/Pages/Prenatal/ProgressReport/View.elm +++ b/client/src/elm/Pages/Prenatal/ProgressReport/View.elm @@ -658,7 +658,7 @@ viewMedicalDiagnosisPane language currentDate isChw firstEncounterMeasurements a ) |> List.sortWith (sortByDateDesc .startDate) - dignoses = + diganoses = List.concatMap (\data -> let @@ -746,7 +746,7 @@ viewMedicalDiagnosisPane language currentDate isChw firstEncounterMeasurements a div [ class "medical-diagnosis" ] [ viewItemHeading language Translate.MedicalDiagnosis "blue" , div [ class "pane-content" ] <| - dignoses + diganoses :: alerts ] @@ -815,7 +815,7 @@ viewObstetricalDiagnosisPane language currentDate isChw firstEncounterMeasuremen Dict.empty allNurseEncountersData - dignoses = + diganoses = List.concatMap (\data -> let @@ -916,7 +916,7 @@ viewObstetricalDiagnosisPane language currentDate isChw firstEncounterMeasuremen common = ul [] <| - dignoses + diganoses ++ lmpDateNonConfidentEntry alerts = diff --git a/client/src/elm/Pages/Prenatal/Utils.elm b/client/src/elm/Pages/Prenatal/Utils.elm index 2946e8ffa5..23ed79cf53 100644 --- a/client/src/elm/Pages/Prenatal/Utils.elm +++ b/client/src/elm/Pages/Prenatal/Utils.elm @@ -2963,7 +2963,7 @@ resolveARVReferralDiagnosis nursePreviousEncountersData = if EverySet.member DiagnosisHIVInitialPhase data.diagnoses || knownAsHIVPositive data.measurements then Just DiagnosisHIVInitialPhase - else if EverySet.member DiagnosisHIVRecurrentPhase data.diagnoses || knownAsHIVPositive data.measurements then + else if EverySet.member DiagnosisHIVRecurrentPhase data.diagnoses then Just DiagnosisHIVRecurrentPhase else if EverySet.member DiagnosisDiscordantPartnershipInitialPhase data.diagnoses then diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 7a6a2da418..bb27aeb5ff 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5723,6 +5723,14 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc 'resource' => '@', 'social_history' => '#', 'vitals' => '$', + // Bellow are 'virtual' activities. + // Treatment Review is displayed for recurrent Nurse encounter. + // Its data is saved into Medication CT. + 'treatment_review' => '^', + // Recorded info is stored on participant node. + 'pregnancy_outcome' => '&', + // Similar to Treatment Review, but for postpartum encounter. + 'postpartum_treatment_review' => '*', ]; // Load all encounters of current participant. @@ -5853,7 +5861,11 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc hedley_reports_prenatal_add_examination_activities($encounter_data, $expected); hedley_reports_prenatal_add_immunisation_activities($encounter_data, $expected); hedley_reports_prenatal_add_mental_health_activity($encounter_data, $expected); - hedley_reports_prenatal_add_prenatal_photo_activity($encounter_data, $expected); + hedley_reports_prenatal_add_photo_activity($encounter_data, $expected); + hedley_reports_prenatal_add_treatment_review_activity($encounter_data, $expected); + hedley_reports_prenatal_add_pregnancy_outcome_activity($encounter_data, $expected); + hedley_reports_prenatal_add_postpartum_unique_nurse_activities($encounter_data, $expected); + hedley_reports_prenatal_add_postpartum_unique_chw_activities($encounter_data, $expected); $completion_data = [ 'start_date' => $start_date, @@ -6156,7 +6168,7 @@ function hedley_reports_prenatal_add_mental_health_activity(array $encounter_dat * @param array &$expected * An array of expected activity names, passed by reference. */ -function hedley_reports_prenatal_add_prenatal_photo_activity(array $encounter_data, array &$expected) { +function hedley_reports_prenatal_add_photo_activity(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; if ($encounter_type != 'nurse') { return; @@ -6206,6 +6218,111 @@ function hedley_reports_prenatal_add_prenatal_photo_activity(array $encounter_da } } +function hedley_reports_prenatal_add_treatment_review_activity(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + if ($encounter_type != 'nurse') { + return; + } + + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + if (empty($previous_nurse_encounters_data)) { + return; + } + + // There will always be at least the Prenatal Medication task to complete. + $expected[] = 'treatment_review'; +} +function hedley_reports_prenatal_add_pregnancy_outcome_activity(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + if (!in_array($encounter_type, ['nurse-postpartum', 'chw-postpartum'])) { + return; + } + + $expected[] = 'pregnancy_outcome'; +} + +function hedley_reports_prenatal_add_postpartum_unique_nurse_activities(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + if ($encounter_type != 'nurse-postpartum') { + return; + } + + $start_date_obj = $encounter_data['start_date_obj']; + // Postpartum Treatment Review, Breastfeeding and Speciality Care + // activities were added on Sept 25, 2022. + $launch_date = '2022-09-25'; + $launch_date_obj = new DateTime($launch_date); + if ($start_date_obj < $launch_date_obj) { + return; + } + + $expected = array_merge( + $expected, + ['postpartum_treatment_review', 'prenatal_breastfeeding'] + ); + + // Expect Speciality Care logic. + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { + $encounter = $previous_nurse_encounter_data['encounter']; + if (empty($encounter->field_prenatal_diagnoses) || empty($encounter->field_prenatal_diagnoses[LANGUAGE_NONE])) { + continue; + } + + $diagnoses = []; + foreach ($encounter->field_prenatal_diagnoses[LANGUAGE_NONE] as $diagnosis) { + if ($diagnosis != 'none') { + $diagnoses[] = $diagnosis; + } + } + + $triggering_diagnoses = [ + // HIV diagnoses. + 'hiv', + 'hiv-recurrent', + 'partner-hiv', + 'partner-hiv-recurrent', + // Hypertension-like diagnoses. + 'chronic-hypertension-immediate', + 'chronic-hypertension-recheck', + 'gestational-hypertension-immediate', + 'gestational-hypertension-recheck', + 'moderate-preeclampsia-initial', + 'moderate-preeclampsia-initial-ega-37+', + 'moderate-preeclampsia-recurrent', + 'moderate-preeclampsia-recurrent-ega-37+', + 'severe-preeclampsia-initial', + 'severe-preeclampsia-initial-ega-37+', + 'severe-preeclampsia-recurrent', + 'severe-preeclampsia-recurrent-ega-37+', + // Diabetes diagnoses. + 'diabetes-initial', + 'diabetes', + 'gestational-diabetes-initial', + 'gestational-diabetes', + ]; + + if (!empty(array_intersect($triggering_diagnoses, $diagnoses))) { + $expected[] = 'prenatal_speciality_care'; + return; + } + + $hiv_test_measurement = $previous_nurse_encounter_data['measurements_by_type']['prenatal_hiv_test']; + if (!empty($hiv_test_measurement)) { + $execution_note = $hiv_test_measurement->field_test_execution_note[LANGUAGE_NONE][0]['value']; + if ($execution_note == 'known-as-positive') { + $expected[] = 'prenatal_speciality_care'; + return; + } + } + } +} + +function hedley_reports_prenatal_add_postpartum_unique_chw_activities(array $encounter_data, array &$expected) { + +} + + function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, DateTime $encounter_date_obj ) { $interval = $encounter_date_obj->diff($lmp_date_obj, TRUE); // Get the total number of days from the interval @@ -6213,6 +6330,62 @@ function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, Dat return floor($total_days / 7); } +// @todo : is this needed? +function hedley_reports_prenatal_get_latest_treatment_from_options(array $encounter_data, array $treatment_options) { + $previous_nurse_encounters_data = array_reverse($encounter_data['previous_nurse_encounters_data']); + foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { + $medication_distribution_measurement = $previous_nurse_encounter_data['measurements_by_type']['prenatal_medication_distribution']; + if (!empty($medication_distribution_measurement)) { + if (empty($medication_distribution_measurement->field_recommended_treatment) || empty($medication_distribution_measurement->field_recommended_treatment[LANGUAGE_NONE])) { + continue; + } + + foreach ($medication_distribution_measurement->field_recommended_treatment[LANGUAGE_NONE] as $treatment) { + if (in_array($treatment, $treatment_options)) { + return $treatment; + } + } + } + } + + return FALSE; +} + +// @todo : is this needed? +function hedley_reports_prenatal_referred_to_hiv_program_previously(array $encounter_data) { + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { + $encounter = $previous_nurse_encounter_data['encounter']; + if (empty($encounter->field_prenatal_diagnoses) || empty($encounter->field_prenatal_diagnoses[LANGUAGE_NONE])) { + continue; + } + + $diagnoses = []; + foreach ($encounter->field_prenatal_diagnoses[LANGUAGE_NONE] as $diagnosis) { + if ($diagnosis != 'none') { + $diagnoses[] = $diagnosis; + } + } + + if (empty(array_intersect($diagnoses, ['hiv', 'hiv-recurrent']))) { + continue; + } + + $hiv_test_measurement = $previous_nurse_encounter_data['measurements_by_type']['prenatal_hiv_test']; + if (empty($hiv_test_measurement) || (empty($hiv_test_measurement->field_hiv_signs)) || (empty($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE]))) { + continue; + } + + foreach ($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE] as $sign) { + if ($sign == 'hiv-program-hc') { + return TRUE; + } + } + } + + return FALSE; +} + /** * Checks if a lab test was performed based on the test execution note. * From 167a84d21978c10609c6228bd23aa595bdf56994 Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 7 Oct 2024 16:13:26 +0300 Subject: [PATCH 146/185] Add Labs tests logic [ci skip] --- .../hedley_reports/hedley_reports.module | 222 +++++++++++++++++- 1 file changed, 221 insertions(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index bb27aeb5ff..62de0adde1 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5854,6 +5854,14 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc } $encounter_data['lmp_date'] = $lmp_date; + // Resolving all diagnoses that were made at previous encounters. + $diagnoses_so_far = []; + foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { + $encounter_diagnoses = array_merge($previous_nurse_encounter_data['diagnoses'], $previous_nurse_encounter_data['past_diagnoses']); + $diagnoses_so_far = array_merge($diagnoses_so_far, $encounter_diagnoses); + } + $encounter_data['diagnoses_so_far'] = array_unique($diagnoses_so_far); + // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. $expected = hedley_reports_prenatal_generate_expected_initial_activities($encounter_data); @@ -5863,6 +5871,8 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc hedley_reports_prenatal_add_mental_health_activity($encounter_data, $expected); hedley_reports_prenatal_add_photo_activity($encounter_data, $expected); hedley_reports_prenatal_add_treatment_review_activity($encounter_data, $expected); + hedley_reports_prenatal_add_labs_activities($encounter_data, $expected); + // Postpartum activities. hedley_reports_prenatal_add_pregnancy_outcome_activity($encounter_data, $expected); hedley_reports_prenatal_add_postpartum_unique_nurse_activities($encounter_data, $expected); hedley_reports_prenatal_add_postpartum_unique_chw_activities($encounter_data, $expected); @@ -6232,6 +6242,217 @@ function hedley_reports_prenatal_add_treatment_review_activity(array $encounter_ // There will always be at least the Prenatal Medication task to complete. $expected[] = 'treatment_review'; } + +function hedley_reports_prenatal_add_labs_activities(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + $start_date_obj = $encounter_data['start_date_obj']; + // Reversing, to have most recent dates first. + $previous_nurse_encounters_data = array_reverse($encounter_data['previous_nurse_encounters_data']); + + if ($encounter_type == 'chw-1' && empty($previous_nurse_encounters_data)) { + $launch_date = '2021-06-07'; + $launch_date_obj = new DateTime($launch_date); + if ($start_date_obj >= $launch_date_obj) { + $expected[] = 'pregnancy_testing'; + } + } + elseif ($encounter_type == 'nurse') { + $launch_date = '2021-12-22'; + $launch_date_obj = new DateTime($launch_date); + if ($start_date_obj < $launch_date_obj) { + return; + } + + $expected = array_merge( + $expected, + [ + 'prenatal_malaria_test', + 'prenatal_urine_dipstick_test', + 'prenatal_hemoglobin_test' + ] + ); + + $tests_dates_by_lab_type = [ + 'prenatal_blood_gprs_test' => [], + 'prenatal_hepatitis_b_test' => [], + 'prenatal_random_blood_sugar_test' => [], + 'prenatal_syphilis_test' => [], + 'prenatal_hiv_test' => [], + 'prenatal_partner_hiv_test' => [], + ]; + + $tests_with_results_field = [ + 'prenatal_blood_gprs_test' => 'field_blood_group', + 'prenatal_random_blood_sugar_test' => 'field_sugar_count', + 'prenatal_syphilis_test' => 'field_test_result', + 'prenatal_hiv_pcr_test' => 'field_hiv_viral_load', + ]; + + $tests_with_known_as_positive_option = [ + 'prenatal_hepatitis_b_test' => FALSE, + 'prenatal_hiv_test' => FALSE, + 'prenatal_partner_hiv_test' => FALSE, + ]; + + // Generating previous laboratory tests dates dict. + foreach ($previous_nurse_encounters_data as $previous_encounter_data) { + $measurements_by_type = $previous_encounter_data['measurements_by_type']; + + // Handling tests that don't have 'known as positive' option. + foreach ($tests_with_results_field as $test_name => $results_field) { + $test = $measurements_by_type[$test_name]; + if (hedley_reports_lab_test_performed_by_execution_note($test)) { + $date_measured = explode(' ', $test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; + $date_measured_obj = new DateTime($date_measured); + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj, TRUE)->days; + $results_exists = !empty($test->{$results_field}) && !empty($test->{$results_field}[LANGUAGE_NONE][0]['value']); + if ($results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { + $tests_dates_by_lab_type[$test_name][] = explode(' ', $test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; + } + } + } + + // Handling tests that got 'known as positive' option. + foreach ($tests_with_known_as_positive_option as $test_name => $known_as_positive) { + if ($known_as_positive) { + continue; + } + + $test = $measurements_by_type[$test_name]; + if (!empty($test) && !empty($test->field_test_execution_note)) { + $tests_with_known_as_positive_option[$test_name] = $test->field_test_execution_note[LANGUAGE_NONE][0]['value'] == 'known-as-positive'; + if (!$tests_with_known_as_positive_option[$test_name] && hedley_reports_lab_test_performed_by_execution_note($test)) { + $date_measured = explode(' ', $test->field_date_measured[LANGUAGE_NONE][0]['value'])[0]; + $date_measured_obj = new DateTime($date_measured); + $diff_days = $encounter_data['start_date_obj']->diff($date_measured_obj, TRUE)->days; + $valid_results_exists = + !empty($test->field_test_result) && + !empty($test->field_test_result[LANGUAGE_NONE][0]['value']) && + $test->field_test_result[LANGUAGE_NONE][0]['value'] != 'indeterminate'; + if ($valid_results_exists || $diff_days <= HEDLEY_GENERAL_LAB_EXPIRATION_PERIOD) { + $tests_dates_by_lab_type[$test_name][] = explode(' ', $test->field_execution_date[LANGUAGE_NONE][0]['value'])[0]; + } + } + } + } + } + + foreach ($tests_dates_by_lab_type as $test_name => $dates_by_lab_type) { + $last_date = reset($dates_by_lab_type); + switch ($test_name) { + case 'prenatal_hiv_test': + if (!$tests_with_known_as_positive_option['prenatal_hiv_test'] && empty($last_date)) { + $launch_date = '2022-09-25'; + $launch_date_obj = new DateTime($launch_date); + if ($start_date_obj >= $launch_date_obj) { + $expected[] = 'prenatal_hiv_test'; + } + } + break; + + case 'prenatal_hiv_pcr_test': + $launch_date = '2022-09-25'; + $launch_date_obj = new DateTime($launch_date); + if ($start_date_obj >= $launch_date_obj) { + if ( + $tests_with_known_as_positive_option['prenatal_hiv_test'] || + !empty( + array_intersect( + $encounter_data['diagnoses_so_far'], + ['hiv', 'hiv-recurrent'] + ) + ) + ) { + $expected[] = 'prenatal_hiv_pcr_test'; + } + } + break; + + case 'prenatal_partner_hiv_test': + if (!$tests_with_known_as_positive_option['prenatal_partner_hiv_test'] && empty($last_date)) { + $launch_date = '2023-03-12'; + $launch_date_obj = new DateTime($launch_date); + if ($start_date_obj >= $launch_date_obj) { + $expected[] = 'prenatal_partner_hiv_test'; + } + } + break; + + case 'prenatal_hepatitis_b_test': + if ( + !$tests_with_known_as_positive_option['prenatal_hepatitis_b_test'] && + empty($last_date) && + empty( + array_intersect( + $encounter_data['past_diagnoses'], + ['hepatitis-b-initial', 'hepatitis-b'] + ) + ) + ) { + $expected[] = 'prenatal_hepatitis_b_test'; + } + break; + + case 'prenatal_blood_gprs_test': + if (empty($last_date)) { + $expected[] = 'prenatal_blood_gprs_test'; + } + break; + + case 'prenatal_random_blood_sugar_test': + if ( + empty( + array_intersect( + $encounter_data['past_diagnoses'], + [ + 'diabetes-initial', + 'diabetes', + 'gestational-diabetes-initial', + 'gestational-diabetes', + ] + ) + ) + ) { + $expected[] = 'prenatal_random_blood_sugar_test'; + } + break; + + case 'prenatal_syphilis_test': + if ( + empty( + array_intersect( + $encounter_data['past_diagnoses'], + [ + 'syphilis-initial', + 'syphilis', + 'syphilis-complications-initial', + 'syphilis-complications', + 'neurosyphilis-initial', + 'neurosyphilis', + ] + ) + ) + ) { + if (empty($last_date)) { + $expected[] = 'prenatal_syphilis_test'; + } + else { + $start_date_obj = $encounter_data['start_date_obj']; + $lmp_date_obj = new DateTime($encounter_data['lmp_date']); + $last_test_date_obj = new DateTime($last_date); + $last_test_ega_in_weeks = hedley_reports_prenatal_calculate_ega_weeks($lmp_date_obj, $last_test_date_obj); + $ega_in_weeks = hedley_reports_prenatal_calculate_ega_weeks($lmp_date_obj, $start_date_obj); + if ($last_test_ega_in_weeks < 38 && $ega_in_weeks >= 38) { + $expected[] = 'prenatal_syphilis_test'; + } + } + } + break; + } + } + } +} + function hedley_reports_prenatal_add_pregnancy_outcome_activity(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; if (!in_array($encounter_type, ['nurse-postpartum', 'chw-postpartum'])) { @@ -6322,7 +6543,6 @@ function hedley_reports_prenatal_add_postpartum_unique_chw_activities(array $enc } - function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, DateTime $encounter_date_obj ) { $interval = $encounter_date_obj->diff($lmp_date_obj, TRUE); // Get the total number of days from the interval From f0d95e26a74b15efcf7f96c924fc3d77cd5c5221 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 8 Oct 2024 11:56:41 +0300 Subject: [PATCH 147/185] Add Birth plan logic [ci skip] --- .../src/elm/Pages/Prenatal/Activity/Utils.elm | 9 ++-- .../hedley_reports/hedley_reports.module | 42 ++++++++++++++++--- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/client/src/elm/Pages/Prenatal/Activity/Utils.elm b/client/src/elm/Pages/Prenatal/Activity/Utils.elm index bba65e0d00..5758236d67 100644 --- a/client/src/elm/Pages/Prenatal/Activity/Utils.elm +++ b/client/src/elm/Pages/Prenatal/Activity/Utils.elm @@ -1129,11 +1129,10 @@ mandatoryActivitiesForNextStepsCompleted currentDate site assembled = -- If we have emergency diagnosis that require immediate referral, -- we allow displaying Next steps right away. diagnosedAnyOf emergencyReferralDiagnoses assembled - || (-- Otherwise, we need all activities that will appear at - -- current encounter completed, besides Photo - -- and Next Steps itself. - mandatoryActivitiesForNurseCompleted - ) + || -- Otherwise, we need all activities that will appear at + -- current encounter completed, besides Photo + -- and Next Steps itself. + mandatoryActivitiesForNurseCompleted NursePostpartumEncounter -> mandatoryActivitiesForNurseCompleted diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 62de0adde1..f033e977ba 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5872,10 +5872,13 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc hedley_reports_prenatal_add_photo_activity($encounter_data, $expected); hedley_reports_prenatal_add_treatment_review_activity($encounter_data, $expected); hedley_reports_prenatal_add_labs_activities($encounter_data, $expected); + // Unique CHW activity. + hedley_reports_prenatal_add_birth_plan_activity($encounter_data, $expected); + + // Postpartum activities. hedley_reports_prenatal_add_pregnancy_outcome_activity($encounter_data, $expected); hedley_reports_prenatal_add_postpartum_unique_nurse_activities($encounter_data, $expected); - hedley_reports_prenatal_add_postpartum_unique_chw_activities($encounter_data, $expected); $completion_data = [ 'start_date' => $start_date, @@ -6453,6 +6456,39 @@ function hedley_reports_prenatal_add_labs_activities(array $encounter_data, arra } } +/** + * Birth plan is presented at second CHW encounter, in case no danger signs are recorded. + * + * @param $encounter_data + * @param $expected + * @return void + */ +function hedley_reports_prenatal_add_birth_plan_activity(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + if ($encounter_type != 'chw-2') { + return; + } + + $danger_signs_measurement = $encounter_data['measurements_by_type']['danger_signs']; + if (empty($danger_signs_measurement)) { + return; + } + + $danger_signs = $danger_signs_measurement->field_danger_signs[LANGUAGE_NONE]; + if (empty($danger_signs)) { + return; + } + + foreach ($danger_signs as $sign) { + if ($sign['value'] != 'none') { + return; + } + } + + // If we got so far, no danger signs were recorded. + $expected[] = 'birth_plan'; +} + function hedley_reports_prenatal_add_pregnancy_outcome_activity(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; if (!in_array($encounter_type, ['nurse-postpartum', 'chw-postpartum'])) { @@ -6539,10 +6575,6 @@ function hedley_reports_prenatal_add_postpartum_unique_nurse_activities(array $e } } -function hedley_reports_prenatal_add_postpartum_unique_chw_activities(array $encounter_data, array &$expected) { - -} - function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, DateTime $encounter_date_obj ) { $interval = $encounter_date_obj->diff($lmp_date_obj, TRUE); // Get the total number of days from the interval From e41f947a1acbbcc9e0fa7de1fa3460836e2c80fb Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 8 Oct 2024 12:08:10 +0300 Subject: [PATCH 148/185] Add logic for CHW Health Education [ci skip] --- .../hedley_reports/hedley_reports.module | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index f033e977ba..60f8f9bfd5 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5874,6 +5874,8 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc hedley_reports_prenatal_add_labs_activities($encounter_data, $expected); // Unique CHW activity. hedley_reports_prenatal_add_birth_plan_activity($encounter_data, $expected); + // Unique CHW activity. For Nurse, it's part of Next Steps. + hedley_reports_prenatal_add_health_education_activity_for_chw($encounter_data, $expected); // Postpartum activities. @@ -6469,24 +6471,40 @@ function hedley_reports_prenatal_add_birth_plan_activity(array $encounter_data, return; } + if (hedley_reports_prenatal_no_danger_signs_recorded($encounter_data)) { + $expected[] = 'birth_plan'; + } +} + +function hedley_reports_prenatal_add_health_education_activity_for_chw(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + if (!in_array($encounter_type, ['chw-1', 'chw-2', 'chw-3'])) { + return; + } + + if (hedley_reports_prenatal_no_danger_signs_recorded($encounter_data)) { + $expected[] = 'prenatal_health_education'; + } +} + +function hedley_reports_prenatal_no_danger_signs_recorded(array $encounter_data) { $danger_signs_measurement = $encounter_data['measurements_by_type']['danger_signs']; if (empty($danger_signs_measurement)) { - return; + return FALSE; } $danger_signs = $danger_signs_measurement->field_danger_signs[LANGUAGE_NONE]; if (empty($danger_signs)) { - return; + return FALSE; } foreach ($danger_signs as $sign) { if ($sign['value'] != 'none') { - return; + return FALSE; } } - // If we got so far, no danger signs were recorded. - $expected[] = 'birth_plan'; + return TRUE; } function hedley_reports_prenatal_add_pregnancy_outcome_activity(array $encounter_data, array &$expected) { From 16e954076985f3e8e2fe0bf84f85039c4981ec69 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 8 Oct 2024 22:43:59 +0300 Subject: [PATCH 149/185] Next steps logic WIP [ci skip] --- .../hedley_reports/hedley_reports.module | 283 +++++++++++++++++- 1 file changed, 281 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 60f8f9bfd5..406d593e43 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5876,11 +5876,12 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc hedley_reports_prenatal_add_birth_plan_activity($encounter_data, $expected); // Unique CHW activity. For Nurse, it's part of Next Steps. hedley_reports_prenatal_add_health_education_activity_for_chw($encounter_data, $expected); - - // Postpartum activities. hedley_reports_prenatal_add_pregnancy_outcome_activity($encounter_data, $expected); hedley_reports_prenatal_add_postpartum_unique_nurse_activities($encounter_data, $expected); + // This comes last, since it has mandatory activities to be completed, + // which we will be checking for withing $expected. + hedley_reports_prenatal_add_next_steps_activities($encounter_data, $expected); $completion_data = [ 'start_date' => $start_date, @@ -6487,6 +6488,26 @@ function hedley_reports_prenatal_add_health_education_activity_for_chw(array $en } } +function hedley_reports_prenatal_danger_signs_recorded(array $encounter_data) { + $danger_signs_measurement = $encounter_data['measurements_by_type']['danger_signs']; + if (empty($danger_signs_measurement)) { + return FALSE; + } + + $danger_signs = $danger_signs_measurement->field_danger_signs[LANGUAGE_NONE]; + if (empty($danger_signs)) { + return FALSE; + } + + foreach ($danger_signs as $sign) { + if ($sign['value'] != 'none') { + return TRUE; + } + } + + return FALSE; +} + function hedley_reports_prenatal_no_danger_signs_recorded(array $encounter_data) { $danger_signs_measurement = $encounter_data['measurements_by_type']['danger_signs']; if (empty($danger_signs_measurement)) { @@ -6593,6 +6614,264 @@ function hedley_reports_prenatal_add_postpartum_unique_nurse_activities(array $e } } +function hedley_reports_prenatal_add_next_steps_activities(array $encounter_data, array &$expected) { + if (!hedley_reports_prenatal_manadatory_activities_for_next_steps_completed($encounter_data, $expected)) { + return; + } + + $encounter_type = $encounter_data['encounter_type']; + if (in_array($encounter_type, ['nurse', 'nurse-postpartum'])) { + hedley_reports_prenatal_add_next_steps_activities_for_nurse($encounter_data, $expected); + } + else { + hedley_reports_prenatal_add_next_steps_activities_for_chw($encounter_data, $expected); + } + + + $measurements_by_type = $encounter_data['measurements_by_type']; + + switch ($encounter_type) { + case 'nurse': + + break; + + case 'nurse-postpartum': + + break; + + case 'chw-1': + + break; + + case 'chw-2': + + break; + + case 'chw-3': + + break; + + case 'chw-postpartum': + + break; + } + + +} + +function hedley_reports_prenatal_add_next_steps_activities_for_nurse(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + + switch ($encounter_type) { + case 'nurse': + + break; + + case 'nurse-postpartum': + + break; + + case 'chw-1': + + break; + + case 'chw-2': + + break; + + case 'chw-3': + + break; + + case 'chw-postpartum': + + break; + } + + +} + +function hedley_reports_prenatal_add_next_steps_activities_for_chw(array $encounter_data, array &$expected) { + $launch_date = '2021-06-07'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] < $launch_date_obj) { + return; + } + + $encounter_type = $encounter_data['encounter_type']; + if ($encounter_type != 'chw-postpartum' && hedley_reports_prenatal_no_danger_signs_recorded($encounter_data)) { + $expected[] = 'appointment_confirmation'; + } + + $danger_signs_recorded = hedley_reports_prenatal_danger_signs_recorded($encounter_data); + if ($danger_signs_recorded) { + $expected[] = 'prenatal_send_to_hc'; + } + + if ($encounter_type != 'chw-postpartum' || $danger_signs_recorded) { + $expected[] = 'prenatal_follow_up'; + } + + if ($encounter_type == 'chw-postpartum') { + $expected[] = 'prenatal_health_education'; + } +} + +function hedley_reports_prenatal_manadatory_activities_for_next_steps_completed(array $encounter_data, array $expected) { + $encounter_type = $encounter_data['encounter_type']; + switch ($encounter_type) { + case 'nurse': + $emergency_diagnoses = [ + 'moderate-preeclampsia-initial-ega-37+', + 'moderate-preeclampsia-recurrent-ega-37+', + 'severe-preeclampsia-initial-ega-37+', + 'severe-preeclampsia-recurrent-ega-37+', + 'eclampsia', + 'miscarriage', + 'molar-pregnancy', + 'placenta-previa', + 'placental-abruption', + 'uterine-rupture', + 'obstructed-labor', + 'post-abortion-sepsis', + 'ectopic-pregnancy', + 'prom', + 'pprom', + 'maternal-complications', + 'imminent-delivery', + 'labor', + 'hyperemesis-gravidum', + 'severe-vomiting', + 'severe-anemia-complications-initial', + 'severe-anemia-complications', + ]; + + if (!empty(array_intersect($encounter_data['diagnoses'], $emergency_diagnoses))) { + return TRUE; + } + + $mandatory_activities = [ + 'danger_signs', + 'prenatal_family_planning', + 'prenatal_symptom_review', + 'prenatal_tetanus_immunisation', + 'prenatal_mental_health', + // History: + 'social_history', + 'medical_history', + 'obstetric_history', + 'obstetric_history_step2', + 'prenatal_outside_care', + // Examination: + 'vitals', + 'prenatal_nutrition', + 'core_physical_exam', + 'breast_exam', + 'obstetrical_exam', + 'prenatal_gu_exam', + // Laboratory: + 'prenatal_malaria_test', + 'prenatal_urine_dipstick_test', + 'prenatal_hemoglobin_test', + 'prenatal_hiv_test', + 'prenatal_hiv_pcr_test', + 'prenatal_partner_hiv_test', + 'prenatal_hepatitis_b_test', + 'prenatal_blood_gprs_test', + 'prenatal_random_blood_sugar_test', + 'prenatal_syphilis_test', + ]; + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + if (empty($previous_nurse_encounters_data)) { + $mandatory_activities[] = 'last_menstrual_period'; + $mandatory_activities[] = 'medication'; + } + else { + $mandatory_activities[] = 'treatment_review'; + } + break; + + case 'nurse-postpartum': + $mandatory_activities = [ + 'pregnancy_outcome', + 'prenatal_symptom_review', + 'prenatal_mental_health', + 'prenatal_breastfeeding', + 'prenatal_family_planning', + 'postpartum_treatment_review', + 'prenatal_speciality_care', + // Examination: + 'vitals', + 'prenatal_nutrition', + 'core_physical_exam', + 'breast_exam', + 'obstetrical_exam', + 'prenatal_gu_exam', + ]; + break; + + case 'chw-1': + $mandatory_activities = [ + 'last_menstrual_period', + 'pregnancy_testing', + 'danger_signs', + 'prenatal_health_education', + ]; + break; + + case 'chw-2': + $mandatory_activities = [ + 'danger_signs', + 'birth_plan', + 'prenatal_health_education', + ]; + break; + + case 'chw-3': + $mandatory_activities = [ + 'danger_signs', + 'prenatal_health_education', + ]; + break; + + case 'chw-postpartum': + $mandatory_activities = [ + 'pregnancy_outcome', + 'danger_signs', + ]; + break; + } + + $measurements_by_type = $encounter_data['measurements_by_type']; + $completed = array_keys($measurements_by_type); + foreach ($mandatory_activities as $activity) { + switch ($activity) { + case 'treatment_review': + case 'postpartum_treatment_review': + if (in_array($activity, $expected) && !in_array('medication', $completed)) { + return FALSE; + } + break; + + case 'pregnancy_outcome': + $participant_id = $encounter_data['encounter']->field_individual_participant[LANGUAGE_NONE][0]['target_id']; + $participant = node_load($participant_id); + $outcome = $participant->field_outcome[LANGUAGE_NONE][0]['value']; + if (empty($outcome)) { + return FALSE; + } + break; + + default: + if (in_array($activity, $expected) && !in_array($activity, $completed)) { + return FALSE; + } + } + } + + return TRUE; +} + function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, DateTime $encounter_date_obj ) { $interval = $encounter_date_obj->diff($lmp_date_obj, TRUE); // Get the total number of days from the interval From 368ad6b82ff718452cb7478a8d3a3f671c6a1035 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 9 Oct 2024 23:55:28 +0300 Subject: [PATCH 150/185] Drop unneeded code [ci skip] --- .../hedley_reports/hedley_reports.module | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 406d593e43..3ac556f39d 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6626,37 +6626,6 @@ function hedley_reports_prenatal_add_next_steps_activities(array $encounter_data else { hedley_reports_prenatal_add_next_steps_activities_for_chw($encounter_data, $expected); } - - - $measurements_by_type = $encounter_data['measurements_by_type']; - - switch ($encounter_type) { - case 'nurse': - - break; - - case 'nurse-postpartum': - - break; - - case 'chw-1': - - break; - - case 'chw-2': - - break; - - case 'chw-3': - - break; - - case 'chw-postpartum': - - break; - } - - } function hedley_reports_prenatal_add_next_steps_activities_for_nurse(array $encounter_data, array &$expected) { From 5f70174484687a18d9e64fe039ec36b20c3f77e8 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 29 Oct 2024 19:06:56 +0200 Subject: [PATCH 151/185] Calcualte data fro Global scope last, to avoid script failure [ci skip] --- .../scripts/completion-recalculate-large-datasets.php | 10 +++++----- .../scripts/recalculate-large-datasets.php | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php index a0790c7e62..accec608c1 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/completion-recalculate-large-datasets.php @@ -18,10 +18,6 @@ return; } -drush_print("Running calculation for Global scope."); -$duration = create_or_update_results_data_node('global'); -drush_print("Calculation completed within $duration seconds."); - // Resolving all health centers. $health_center_ids = hedley_health_center_get_all_health_centers_ids(); foreach ($health_center_ids as $health_center_id) { @@ -30,6 +26,10 @@ drush_print("Calculation completed within $duration seconds."); } +drush_print("Running calculation for Global scope."); +$duration = create_or_update_results_data_node('global'); +drush_print("Calculation completed within $duration seconds."); + drush_print(''); drush_print('All calculations completed!'); @@ -195,7 +195,7 @@ function generate_completion_results_data($health_center) { // Explicitly unset large variables after use for memory optimization. unset($nodes); - if ($processed % 5000 == 0) { + if ($processed % 2000 == 0) { drush_print("Processed $processed out of $total."); } } diff --git a/server/hedley/modules/custom/hedley_reports/scripts/recalculate-large-datasets.php b/server/hedley/modules/custom/hedley_reports/scripts/recalculate-large-datasets.php index 41f3ddeb4c..d22077592c 100644 --- a/server/hedley/modules/custom/hedley_reports/scripts/recalculate-large-datasets.php +++ b/server/hedley/modules/custom/hedley_reports/scripts/recalculate-large-datasets.php @@ -20,10 +20,6 @@ return; } -drush_print("Running calculation for Global scope."); -$duration = create_or_update_results_data_node('global', NULL, NULL, NULL); -drush_print("Calculation completed within $duration seconds."); - // Resolving unique provinces as they appear at DB. $query = db_select('field_data_field_province', 'fp') ->fields('fp', array('field_province_value')) @@ -65,6 +61,10 @@ drush_print("Calculation completed within $duration seconds."); } +drush_print("Running calculation for Global scope."); +$duration = create_or_update_results_data_node('global', NULL, NULL, NULL); +drush_print("Calculation completed within $duration seconds."); + drush_print(''); drush_print('All calculations completed!'); From 8c9e9902609b235a5ec7c66e0198bcead26e085a Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 29 Oct 2024 23:07:48 +0200 Subject: [PATCH 152/185] Nurse Next Steps WIP [ci skip] --- .../hedley_reports/hedley_reports.module | 119 ++++++++++++++---- 1 file changed, 94 insertions(+), 25 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 3ac556f39d..be1663e677 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6690,31 +6690,7 @@ function hedley_reports_prenatal_manadatory_activities_for_next_steps_completed( $encounter_type = $encounter_data['encounter_type']; switch ($encounter_type) { case 'nurse': - $emergency_diagnoses = [ - 'moderate-preeclampsia-initial-ega-37+', - 'moderate-preeclampsia-recurrent-ega-37+', - 'severe-preeclampsia-initial-ega-37+', - 'severe-preeclampsia-recurrent-ega-37+', - 'eclampsia', - 'miscarriage', - 'molar-pregnancy', - 'placenta-previa', - 'placental-abruption', - 'uterine-rupture', - 'obstructed-labor', - 'post-abortion-sepsis', - 'ectopic-pregnancy', - 'prom', - 'pprom', - 'maternal-complications', - 'imminent-delivery', - 'labor', - 'hyperemesis-gravidum', - 'severe-vomiting', - 'severe-anemia-complications-initial', - 'severe-anemia-complications', - ]; - + $emergency_diagnoses = hedley_reports_prenatal_emergency_diagnoses(); if (!empty(array_intersect($encounter_data['diagnoses'], $emergency_diagnoses))) { return TRUE; } @@ -6848,6 +6824,99 @@ function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, Dat return floor($total_days / 7); } +function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase($phase) { + return array_merge( + hedley_reports_prenatal_emergency_diagnoses_initial_phase(), + [ + 'moderate-preeclampsia-initial', + 'severe-preeclampsia-initial', + 'hyperemesis-gravidum-by-symptoms', + 'severe-vomiting-by-symptoms', + 'heartburn-persistent', + 'dvt', + 'pelvic-pain-intense', + 'pelvic-pain-continued', + 'pyelonephritis', + 'urinary-tract-infection-continued', + 'candidiasis-continued', + 'gonorrhea-continued', + 'trichomonas-or-bv-continued', + 'postpartum-urinary-incontinence', + 'postpartum-infection', + 'postpartum-excessive-bleeding', + 'hepatitis-b-initial', + 'neurosyphilis-initial', + 'malaria-severe-anemia', + 'severe-anemia-initial', + 'moderate-preeclampsia-initial', + 'severe-preeclampsia-initial', + 'diabetes-initial', + 'gestational-diabetes-initial', + 'rhesus-negative-initial', + 'malaria-continued', + 'malaria-anemia-continued', + ] + ); +} + +function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_recurrent_phase($phase) { + return array_merge( + hedley_reports_prenatal_emergency_diagnoses_recurrent_phase(), + [ + 'hepatitis-b', + 'neurosyphilis', + 'malaria-severe-anemia-recurrent', + 'severe-anemia', + 'moderate-preeclampsia-recurrent', + 'severe-preeclampsia-recurrent', + 'diabetes', + 'gestational-diabetes', + 'rhesus-negative', + 'malaria-continued-recurrent', + 'malaria-anemia-continued-recurrent', + ] + ); +} + +function hedley_reports_prenatal_emergency_diagnoses() { + return array_merge( + hedley_reports_prenatal_emergency_diagnoses_initial_phase(), + hedley_reports_prenatal_emergency_diagnoses_recurrent_phase() + ); +} + +function hedley_reports_prenatal_emergency_diagnoses_initial_phase() { + return [ + 'moderate-preeclampsia-initial-ega-37+', + 'severe-preeclampsia-initial-ega-37+', + 'eclampsia', + 'miscarriage', + 'molar-pregnancy', + 'placenta-previa', + 'placental-abruption', + 'uterine-rupture', + 'obstructed-labor', + 'post-abortion-sepsis', + 'ectopic-pregnancy', + 'prom', + 'pprom', + 'maternal-complications', + 'imminent-delivery', + 'labor', + 'hyperemesis-gravidum', + 'severe-vomiting', + 'severe-anemia-complications-initial', + ]; +} + +function hedley_reports_prenatal_emergency_diagnoses_recurrent_phase() { + return [ + 'moderate-preeclampsia-recurrent-ega-37+', + 'severe-preeclampsia-recurrent-ega-37+', + 'severe-anemia-complications', + ]; +} + // @todo : is this needed? function hedley_reports_prenatal_get_latest_treatment_from_options(array $encounter_data, array $treatment_options) { $previous_nurse_encounters_data = array_reverse($encounter_data['previous_nurse_encounters_data']); From 912a14a774f157b1104e483b7ac010f07ee7cc0e Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 30 Oct 2024 16:27:15 +0200 Subject: [PATCH 153/185] Referral activity logic WIP [ci skip] --- .../hedley_reports/hedley_reports.module | 332 +++++++++++++++++- 1 file changed, 317 insertions(+), 15 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index be1663e677..13ebdd7ef4 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6629,35 +6629,338 @@ function hedley_reports_prenatal_add_next_steps_activities(array $encounter_data } function hedley_reports_prenatal_add_next_steps_activities_for_nurse(array $encounter_data, array &$expected) { + // Checking Referral activity. + $launch_date = '2021-06-07'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] < $launch_date_obj) { + return; + } + + // Checking referral to hospital + $referral_expected = hedley_reports_prenatal_hospital_referral_expected($encounter_data); + // Checking referral to mental health specialist. + if (!$referral_expected) { + $mental_health_measurement = $encounter_data['measurements_by_type']['prenatal_mental_health']; + if (!empty($mental_health_measurement)) { + $specialist_at_hc = $mental_health_measurement->field_specialist_at_hc[LANGUAGE_NONE][0]['value']; + if ($specialist_at_hc === TRUE) { + $triggering_diagnoses = [ + 'depression-possible', + 'depression-highly-possible', + 'depression-probable', + 'suicide-risk', + ]; + $referral_expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + } + } + } + + // Checking referral to ARV program. + if (!$referral_expected) { + // First option is that HIV is diagnosed and there's an HIV + // program at health center. + if (in_array('hiv', $encounter_data['diagnoses'])) { + $hiv_test_measurement = $encounter_data['measurements_by_type']['prenatal_hiv_test']; + if (!empty($hiv_test_measurement) && !empty($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE])) { + foreach ($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE] as $sign) { + if ($sign == 'hiv-program-hc') { + $referral_expected = TRUE; + break; + } + } + } + } + + // Second option - EnrolledToARVProgram section appears at + // speciality care activity, and patient was referred to that program. + if (!$referral_expected) { + $section_expected = FALSE; + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + foreach ($previous_nurse_encounters_data as $previous_encounter_data) { + $hiv_test_measurement = $previous_encounter_data['measurements_by_type']['prenatal_hiv_test']; + if (!empty($hiv_test_measurement)) { + if ($hiv_test_measurement->field_test_execution_note[LANGUAGE_NONE][0]['value'] == 'known-as-positive') { + $section_expected = TRUE; + break; + } + } + // If not known as HIV positive, check by diagnosis. + $triggering_diagnoses = [ + 'hiv', + 'hiv-recurrent', + 'partner-hiv', + 'partner-hiv-recurrent', + ]; + if (!empty(array_intersect($previous_encounter_data['diagnoses'], $triggering_diagnoses))) { + $section_expected = TRUE; + break; + } + } + + // If section was shown, check if patient was referred to program. + if ($section_expected) { + $speciality_care_measurement = $previous_encounter_data['measurements_by_type']['prenatal_speciality_care']; + if (!empty($speciality_care_measurement) && !empty($speciality_care_measurement->field_speciality_care_signs[LANGUAGE_NONE])) { + foreach ($speciality_care_measurement->field_speciality_care_signs[LANGUAGE_NONE] as $sign) { + if ($sign['value'] == 'arv') { + $referral_expected = TRUE; + break; + } + } + } + } + } + } + + + if ($referral_expected) { + $expected[] = 'prenatal_send_to_hc'; + } + + + // Checking Medication Distribution activity. + $launch_date = '2022-09-25'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] < $launch_date_obj) { + return; + } + + + +} + +function hedley_reports_prenatal_hospital_referral_expected(array $encounter_data) { $encounter_type = $encounter_data['encounter_type']; + $triggering_diagnoses = hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase(); + $referred_to_hospital_by_immediate_diagnosis = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + // At postpartum encounter, only option for hospital referral is by + // immediate diagnosis. At nurse encounter, there are more options, + // when there's no referral by immediate diagnosis. + $referred_to_hospital = $referred_to_hospital_by_immediate_diagnosis; + if ($encounter_type == 'nurse' && !$referred_to_hospital) { + $mental_health_measurement = $encounter_data['measurements_by_type']['prenatal_mental_health']; + // Checking if referral to hospital is required by Mental Health. + if (!empty($mental_health_measurement)) { + $specialist_at_hc = $mental_health_measurement->field_specialist_at_hc[LANGUAGE_NONE][0]['value']; + if ($specialist_at_hc === FALSE) { + $triggering_diagnoses = [ + 'depression-possible', + 'depression-highly-possible', + 'depression-probable', + 'suicide-risk', + ]; + $referred_to_hospital = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + } + } - switch ($encounter_type) { - case 'nurse': + // Checking if referral to hospital is required by Malaria Treatment - + // Malaria diagnosed and suggested treatment was hospital referral. + if (!$referred_to_hospital) { + $triggering_diagnoses = [ + 'malaria', + 'malaria-recurrent', + 'malaria-anemia', + 'malaria-anemia-recurrent', + 'malaria-severe-anemia', + 'malaria-severe-anemia-recurrent', + ]; + if (!empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses))) { + $medication_distribution_measurement = $encounter_data['measurements_by_type']['prenatal_medication_distribution']; + if (!empty($medication_distribution_measurement)) { + $recommended_treatments = $medication_distribution_measurement->field_recommended_treatment[LANGUAGE_NONE]; + foreach ($recommended_treatments as $recommended_treatment) { + if ($recommended_treatment['value'] == 'refer-to-hospital') { + $referred_to_hospital = TRUE; + break; + } + } + } + } + } - break; + // Checking if referral to hospital is required by Hypertension or + // Moderated Preeclampisa treatments. + if (!$referred_to_hospital) { + $referred_to_hospital = hedley_reports_prenatal_hospitalizaton_due_to_hypertension_treatment_update($encounter_data); + if (!$referred_to_hospital) { + $currently_diagnosed_with_moderate_preeclampsia = + hedley_reports_prenatal_diagnosed_previously_with_any_of( + $encounter_data, + ['moderate-preeclampsia-initial', 'moderate-preeclampsia-recurrent'] + ) && + !hedley_reports_prenatal_diagnosed_previously_with_any_of( + $encounter_data, + [ + 'moderate-preeclampsia-initial', + 'moderate-preeclampsia-recurrent', + 'severe-preeclampsia-initial', + 'severe-preeclampsia-recurrent', + 'moderate-preeclampsia-initial-ega-37+', + 'moderate-preeclampsia-recurrent-ega-37+', + 'severe-preeclampsia-initial-ega-37+', + 'severe-preeclampsia-recurrent-ega-37+', + 'eclampsia', + ] + ); - case 'nurse-postpartum': + if ($currently_diagnosed_with_moderate_preeclampsia) { + $vitals_measurement = $encounter_data['measurements_by_type']['vitals']; + if (!empty($vitals_measurement)) { + $sys = $vitals_measurement->field_sys[LANGUAGE_NONE][0]['value']; + $dia = $vitals_measurement->field_dia[LANGUAGE_NONE][0]['value']; - break; + if (!empty($sys) && !empty($dia)) { + $referred_to_hospital = $sys >= 180 || $dia >= 110; + } + } + } + } + } - case 'chw-1': + // Checking if referral to hospital is required by adverse event. + if (!$referred_to_hospital) { + $medication_measurement = $encounter_data['measurements_by_type']['medication']; + if (!empty($medication_measurement)) { + $treatments = [ + $medication_measurement->field_hiv_treatment[LANGUAGE_NONE], + $medication_measurement->field_hypertension_treatment[LANGUAGE_NONE], + $medication_measurement->field_malaria_treatment[LANGUAGE_NONE], + $medication_measurement->field_anemia_treatment[LANGUAGE_NONE], + $medication_measurement->field_syphilis_treatment[LANGUAGE_NONE], + ]; + + foreach ($treatments as $treatment_signs) { + foreach ($treatment_signs as $sign) { + if ($sign['value'] == 'adverse-events-hospitalization') { + $referred_to_hospital = TRUE; + break; + } + } + if ($referred_to_hospital) { + break; + } + } + } + } - break; + // Checking if referral to hospital is required by past diagnoses. + if (!$referred_to_hospital) { + $triggering_diagnoses = [ + 'syphilis-initial', + 'syphilis', + 'syphilis-complications-initial', + 'syphilis-complications', + 'neurosyphilis-initial', + 'neurosyphilis', + 'diabetes-initial', + 'diabetes', + 'gestational-diabetes-initial', + 'gestational-diabetes', + 'hepatitis-b', + 'rhesus-negative', + ]; + } - case 'chw-2': + $referred_to_hospital = !empty(array_intersect($encounter_data['past_diagnoses'], $triggering_diagnoses)); + } - break; + return $referred_to_hospital; +} - case 'chw-3': +function hedley_reports_prenatal_hospitalizaton_due_to_hypertension_treatment_update(array $encounter_data) { + $treatment_options = [ + 'methyldopa-2', + 'methyldopa-3', + 'methyldopa-4', + 'add-carvedilol', + 'add-amlodipine', + 'no-treatment-hypertension', + ]; + $current_treatment = hedley_reports_prenatal_get_latest_treatment_from_options($encounter_data, $treatment_options); + if (!$current_treatment) { + return; + } - break; + $triggering_diagnoses = [ + 'chronic-hypertension-immediate', + 'gestational-hypertension-immediate', + 'chronic-hypertension-recheck', + 'gestational-hypertension-recheck', + 'moderate-preeclampsia-initial', + 'moderate-preeclampsia-recurrent', + 'moderate-preeclampsia-initial-ega-37+', + 'moderate-preeclampsia-recurrent-ega-37+', + ]; + if (!hedley_reports_prenatal_diagnosed_previously_with_any_of($encounter_data, $triggering_diagnoses)) { + return; + } - case 'chw-postpartum': + $vitals_measurement = $encounter_data['measurements_by_type']['vitals']; + if (empty($vitals_measurement)) { + return; + } - break; + $sys = $vitals_measurement->field_sys[LANGUAGE_NONE][0]['value']; + $dia = $vitals_measurement->field_dia[LANGUAGE_NONE][0]['value']; + if (empty($sys) || empty($dia)) { + return; + } + + if ($sys < 140) { + // Maintain treatment as is. + $by_sys = 0; + } + elseif ($sys < 160) { + // Up 1 step. + $by_sys = 1; + } + elseif ($sys < 180) { + // Up 2 steps. + $by_sys = 2; + } + else { + // Hospitalization. + $by_sys = 9; + } + + if ($dia < 90) { + // Maintain treatment as is. + $by_dia = 0; + } + elseif ($dia < 100) { + // Up 1 step. + $by_dia = 1; + } + elseif ($dia < 110) { + // Up 2 steps. + $by_dia = 2; + } + else { + // Hospitalization. + $by_dia = 9; } + $treatment_update_recommendation = max($by_sys, $by_dia); + return ( + (($current_treatment == 'no-treatment-hypertension') && ($treatment_update_recommendation == 9)) || + (($current_treatment == 'methyldopa-2') && ($treatment_update_recommendation == 9)) || + (($current_treatment == 'methyldopa-3') && ($treatment_update_recommendation == 9)) || + (($current_treatment == 'methyldopa-4') && ($treatment_update_recommendation == 9)) || + (($current_treatment == 'add-carvedilol') && ($treatment_update_recommendation >= 2)) || + (($current_treatment == 'add-amlodipine') && ($treatment_update_recommendation >= 1)) + ); +} + +function hedley_reports_prenatal_diagnosed_previously_with_any_of(array $encounter_data, $diagnoses) { + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + foreach ($previous_nurse_encounters_data as $encounter_data) { + if (!empty(array_intersect($encounter_data['diagnoses'], $diagnoses))) { + return TRUE; + } + } + + return FALSE; } function hedley_reports_prenatal_add_next_steps_activities_for_chw(array $encounter_data, array &$expected) { @@ -6824,7 +7127,7 @@ function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, Dat return floor($total_days / 7); } -function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase($phase) { +function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase() { return array_merge( hedley_reports_prenatal_emergency_diagnoses_initial_phase(), [ @@ -6917,7 +7220,6 @@ function hedley_reports_prenatal_emergency_diagnoses_recurrent_phase() { ]; } -// @todo : is this needed? function hedley_reports_prenatal_get_latest_treatment_from_options(array $encounter_data, array $treatment_options) { $previous_nurse_encounters_data = array_reverse($encounter_data['previous_nurse_encounters_data']); foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { From 0a27628d6848052e6db9dd00782250002a4d9db1 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 30 Oct 2024 18:46:21 +0200 Subject: [PATCH 154/185] Complete Referral activity logic [ci skip] --- client/src/elm/Pages/Prenatal/Utils.elm | 32 +-- .../hedley_reports/hedley_reports.module | 230 +++++++++++------- 2 files changed, 161 insertions(+), 101 deletions(-) diff --git a/client/src/elm/Pages/Prenatal/Utils.elm b/client/src/elm/Pages/Prenatal/Utils.elm index 3f805a0e46..cc42a6a07d 100644 --- a/client/src/elm/Pages/Prenatal/Utils.elm +++ b/client/src/elm/Pages/Prenatal/Utils.elm @@ -2953,15 +2953,6 @@ diagnosedModeratePreeclampsiaPrevoiusly assembled = diagnosedPreviouslyAnyOf moderatePreeclampsiaDiagnoses assembled -moderatePreeclampsiaDiagnoses : List PrenatalDiagnosis -moderatePreeclampsiaDiagnoses = - [ DiagnosisModeratePreeclampsiaInitialPhase - , DiagnosisModeratePreeclampsiaRecurrentPhase - , DiagnosisModeratePreeclampsiaInitialPhaseEGA37Plus - , DiagnosisModeratePreeclampsiaRecurrentPhaseEGA37Plus - ] - - resolveARVReferralDiagnosis : List PreviousEncounterData -> Maybe PrenatalDiagnosis resolveARVReferralDiagnosis nursePreviousEncountersData = List.filterMap @@ -3020,13 +3011,8 @@ resolvePreviousHypertensionlikeDiagnosis nursePreviousEncountersData = hypertensionlikeDiagnoses : List PrenatalDiagnosis hypertensionlikeDiagnoses = hypertensionDiagnoses - ++ moderatePreeclampsiaDiagnoses - ++ [ DiagnosisSeverePreeclampsiaInitialPhase - , DiagnosisSeverePreeclampsiaInitialPhaseEGA37Plus - , DiagnosisSeverePreeclampsiaRecurrentPhase - , DiagnosisSeverePreeclampsiaRecurrentPhaseEGA37Plus - , DiagnosisEclampsia - ] + ++ preeclampsiaDiagnoses + ++ [ DiagnosisEclampsia ] resolvePreviousDiabetesDiagnosis : List PreviousEncounterData -> Maybe PrenatalDiagnosis @@ -3173,6 +3159,20 @@ outsideCareDiagnosesWithPossibleMedication = preeclampsiaDiagnoses : List PrenatalDiagnosis preeclampsiaDiagnoses = + moderatePreeclampsiaDiagnoses ++ severePreeclampsiaDiagnoses + + +moderatePreeclampsiaDiagnoses : List PrenatalDiagnosis +moderatePreeclampsiaDiagnoses = + [ DiagnosisModeratePreeclampsiaInitialPhase + , DiagnosisModeratePreeclampsiaRecurrentPhase + , DiagnosisModeratePreeclampsiaInitialPhaseEGA37Plus + , DiagnosisModeratePreeclampsiaRecurrentPhaseEGA37Plus + ] + + +severePreeclampsiaDiagnoses : List PrenatalDiagnosis +severePreeclampsiaDiagnoses = [ DiagnosisSeverePreeclampsiaInitialPhase , DiagnosisSeverePreeclampsiaInitialPhaseEGA37Plus , DiagnosisSeverePreeclampsiaRecurrentPhase diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 13ebdd7ef4..0d7bada050 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6410,12 +6410,7 @@ function hedley_reports_prenatal_add_labs_activities(array $encounter_data, arra empty( array_intersect( $encounter_data['past_diagnoses'], - [ - 'diabetes-initial', - 'diabetes', - 'gestational-diabetes-initial', - 'gestational-diabetes', - ] + hedley_reports_prenatal_diabetes_diagnoses() ) ) ) { @@ -6428,14 +6423,7 @@ function hedley_reports_prenatal_add_labs_activities(array $encounter_data, arra empty( array_intersect( $encounter_data['past_diagnoses'], - [ - 'syphilis-initial', - 'syphilis', - 'syphilis-complications-initial', - 'syphilis-complications', - 'neurosyphilis-initial', - 'neurosyphilis', - ] + hedley_reports_prenatal_syphilislike_diagnoses() ) ) ) { @@ -6572,31 +6560,14 @@ function hedley_reports_prenatal_add_postpartum_unique_nurse_activities(array $e } } - $triggering_diagnoses = [ - // HIV diagnoses. - 'hiv', - 'hiv-recurrent', - 'partner-hiv', - 'partner-hiv-recurrent', - // Hypertension-like diagnoses. - 'chronic-hypertension-immediate', - 'chronic-hypertension-recheck', - 'gestational-hypertension-immediate', - 'gestational-hypertension-recheck', - 'moderate-preeclampsia-initial', - 'moderate-preeclampsia-initial-ega-37+', - 'moderate-preeclampsia-recurrent', - 'moderate-preeclampsia-recurrent-ega-37+', - 'severe-preeclampsia-initial', - 'severe-preeclampsia-initial-ega-37+', - 'severe-preeclampsia-recurrent', - 'severe-preeclampsia-recurrent-ega-37+', - // Diabetes diagnoses. - 'diabetes-initial', - 'diabetes', - 'gestational-diabetes-initial', - 'gestational-diabetes', - ]; + $triggering_diagnoses = array_merge( + hedley_reports_prenatal_hiv_diagnoses(), + hedley_reports_prenatal_diabetes_diagnoses() + ); + $triggering_diagnoses = array_merge( + $triggering_diagnoses, + hedley_reports_prenatal_preeclempsia_diagnoses() + ); if (!empty(array_intersect($triggering_diagnoses, $diagnoses))) { $expected[] = 'prenatal_speciality_care'; @@ -6629,7 +6600,7 @@ function hedley_reports_prenatal_add_next_steps_activities(array $encounter_data } function hedley_reports_prenatal_add_next_steps_activities_for_nurse(array $encounter_data, array &$expected) { - // Checking Referral activity. + // Referral activity logic. $launch_date = '2021-06-07'; $launch_date_obj = new DateTime($launch_date); if ($encounter_data['start_date_obj'] < $launch_date_obj) { @@ -6638,6 +6609,7 @@ function hedley_reports_prenatal_add_next_steps_activities_for_nurse(array $enco // Checking referral to hospital $referral_expected = hedley_reports_prenatal_hospital_referral_expected($encounter_data); + // Checking referral to mental health specialist. if (!$referral_expected) { $mental_health_measurement = $encounter_data['measurements_by_type']['prenatal_mental_health']; @@ -6685,12 +6657,7 @@ function hedley_reports_prenatal_add_next_steps_activities_for_nurse(array $enco } } // If not known as HIV positive, check by diagnosis. - $triggering_diagnoses = [ - 'hiv', - 'hiv-recurrent', - 'partner-hiv', - 'partner-hiv-recurrent', - ]; + $triggering_diagnoses = hedley_reports_prenatal_hiv_diagnoses(); if (!empty(array_intersect($previous_encounter_data['diagnoses'], $triggering_diagnoses))) { $section_expected = TRUE; break; @@ -6698,8 +6665,9 @@ function hedley_reports_prenatal_add_next_steps_activities_for_nurse(array $enco } // If section was shown, check if patient was referred to program. + // Note the that check is at current encounter. if ($section_expected) { - $speciality_care_measurement = $previous_encounter_data['measurements_by_type']['prenatal_speciality_care']; + $speciality_care_measurement = $encounter_data['measurements_by_type']['prenatal_speciality_care']; if (!empty($speciality_care_measurement) && !empty($speciality_care_measurement->field_speciality_care_signs[LANGUAGE_NONE])) { foreach ($speciality_care_measurement->field_speciality_care_signs[LANGUAGE_NONE] as $sign) { if ($sign['value'] == 'arv') { @@ -6712,13 +6680,55 @@ function hedley_reports_prenatal_add_next_steps_activities_for_nurse(array $enco } } + // Checking referral to NCD program. + if (!$referral_expected) { + $section_expected = FALSE; + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + foreach ($previous_nurse_encounters_data as $previous_encounter_data) { + // If not known as HIV positive, check by diagnosis. + $triggering_diagnoses = array_merge( + hedley_reports_prenatal_hypertensionlike_diagnoses(), + hedley_reports_prenatal_diabetes_diagnoses() + ); + if (!empty(array_intersect($previous_encounter_data['diagnoses'], $triggering_diagnoses))) { + $section_expected = TRUE; + break; + } + } + + // If section was shown, check if patient was referred to program. + // Note the that check is at current encounter. + if ($section_expected) { + $speciality_care_measurement = $encounter_data['measurements_by_type']['prenatal_speciality_care']; + if (!empty($speciality_care_measurement) && !empty($speciality_care_measurement->field_speciality_care_signs[LANGUAGE_NONE])) { + foreach ($speciality_care_measurement->field_speciality_care_signs[LANGUAGE_NONE] as $sign) { + if ($sign['value'] == 'ncd') { + $referral_expected = TRUE; + break; + } + } + } + } + } + + // Checking referral to Ultrasound. + if (!$referral_expected) { + $lmp_measurement = $encounter_data['measurements_by_type']['last_menstrual_period']; + if (!empty($lmp_measurement)) { + if ($lmp_measurement->field_confident[LANGUAGE_NONE][0]['value'] === FALSE) { + if (!empty($lmp_measurement->field_not_confident_reason[LANGUAGE_NONE][0]['value'])) { + $referral_expected = TRUE; + } + } + } + } if ($referral_expected) { $expected[] = 'prenatal_send_to_hc'; } - // Checking Medication Distribution activity. + // Medication Distribution activity logic. $launch_date = '2022-09-25'; $launch_date_obj = new DateTime($launch_date); if ($encounter_data['start_date_obj'] < $launch_date_obj) { @@ -6790,17 +6800,7 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat ) && !hedley_reports_prenatal_diagnosed_previously_with_any_of( $encounter_data, - [ - 'moderate-preeclampsia-initial', - 'moderate-preeclampsia-recurrent', - 'severe-preeclampsia-initial', - 'severe-preeclampsia-recurrent', - 'moderate-preeclampsia-initial-ega-37+', - 'moderate-preeclampsia-recurrent-ega-37+', - 'severe-preeclampsia-initial-ega-37+', - 'severe-preeclampsia-recurrent-ega-37+', - 'eclampsia', - ] + hedley_reports_prenatal_hypertensionlike_diagnoses() ); if ($currently_diagnosed_with_moderate_preeclampsia) { @@ -6845,20 +6845,14 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat // Checking if referral to hospital is required by past diagnoses. if (!$referred_to_hospital) { - $triggering_diagnoses = [ - 'syphilis-initial', - 'syphilis', - 'syphilis-complications-initial', - 'syphilis-complications', - 'neurosyphilis-initial', - 'neurosyphilis', - 'diabetes-initial', - 'diabetes', - 'gestational-diabetes-initial', - 'gestational-diabetes', - 'hepatitis-b', - 'rhesus-negative', - ]; + $triggering_diagnoses = array_merge( + hedley_reports_prenatal_syphilislike_diagnoses(), + hedley_reports_prenatal_diabetes_diagnoses() + ); + $triggering_diagnoses = array_merge( + $triggering_diagnoses, + ['hepatitis-b', 'rhesus-negative'] + ); } $referred_to_hospital = !empty(array_intersect($encounter_data['past_diagnoses'], $triggering_diagnoses)); @@ -6881,16 +6875,11 @@ function hedley_reports_prenatal_hospitalizaton_due_to_hypertension_treatment_up return; } - $triggering_diagnoses = [ - 'chronic-hypertension-immediate', - 'gestational-hypertension-immediate', - 'chronic-hypertension-recheck', - 'gestational-hypertension-recheck', - 'moderate-preeclampsia-initial', - 'moderate-preeclampsia-recurrent', - 'moderate-preeclampsia-initial-ega-37+', - 'moderate-preeclampsia-recurrent-ega-37+', - ]; + $triggering_diagnoses = array_merge( + hedley_reports_prenatal_hypertension_diagnoses(), + hedley_reports_prenatal_moderate_preeclempsia_diagnoses() + ); + if (!hedley_reports_prenatal_diagnosed_previously_with_any_of($encounter_data, $triggering_diagnoses)) { return; } @@ -7151,8 +7140,6 @@ function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_i 'neurosyphilis-initial', 'malaria-severe-anemia', 'severe-anemia-initial', - 'moderate-preeclampsia-initial', - 'severe-preeclampsia-initial', 'diabetes-initial', 'gestational-diabetes-initial', 'rhesus-negative-initial', @@ -7220,6 +7207,79 @@ function hedley_reports_prenatal_emergency_diagnoses_recurrent_phase() { ]; } +function hedley_reports_prenatal_hypertensionlike_diagnoses() { + $hypertensionlike_daignoses = array_merge( + hedley_reports_prenatal_hypertension_diagnoses(), + hedley_reports_prenatal_preeclempsia_diagnoses() + ); + $hypertensionlike_daignoses[] = 'eclampsia'; + + return $hypertensionlike_daignoses; +} + +function hedley_reports_prenatal_hypertension_diagnoses() { + return [ + 'chronic-hypertension-immediate', + 'chronic-hypertension-recheck', + 'gestational-hypertension-immediate', + 'gestational-hypertension-recheck', + ]; +} + +function hedley_reports_prenatal_preeclempsia_diagnoses() { + return array_merge( + hedley_reports_prenatal_moderate_preeclempsia_diagnoses(), + hedley_reports_prenatal_severe_preeclempsia_diagnoses() + ); +} + +function hedley_reports_prenatal_moderate_preeclempsia_diagnoses() { + return [ + 'moderate-preeclampsia-initial', + 'moderate-preeclampsia-initial-ega-37+', + 'moderate-preeclampsia-recurrent', + 'moderate-preeclampsia-recurrent-ega-37+', + ]; +} + +function hedley_reports_prenatal_severe_preeclempsia_diagnoses() { + return [ + 'severe-preeclampsia-initial', + 'severe-preeclampsia-initial-ega-37+', + 'severe-preeclampsia-recurrent', + 'severe-preeclampsia-recurrent-ega-37+', + ]; +} + +function hedley_reports_prenatal_diabetes_diagnoses() { + return [ + 'diabetes-initial', + 'diabetes', + 'gestational-diabetes-initial', + 'gestational-diabetes', + ]; +} + +function hedley_reports_prenatal_hiv_diagnoses() { + return [ + 'hiv', + 'hiv-recurrent', + 'partner-hiv', + 'partner-hiv-recurrent', + ]; +} + +function hedley_reports_prenatal_syphilislike_diagnoses() { + return [ + 'syphilis-initial', + 'syphilis', + 'syphilis-complications-initial', + 'syphilis-complications', + 'neurosyphilis-initial', + 'neurosyphilis', + ]; +} + function hedley_reports_prenatal_get_latest_treatment_from_options(array $encounter_data, array $treatment_options) { $previous_nurse_encounters_data = array_reverse($encounter_data['previous_nurse_encounters_data']); foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { From 4e018196c4f4953fe261dcc885701a0d3e723a56 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 30 Oct 2024 23:00:51 +0200 Subject: [PATCH 155/185] WIP: Health education activity [ci skip] --- .../hedley_reports/hedley_reports.module | 73 ++++++++++++++++++- 1 file changed, 69 insertions(+), 4 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 0d7bada050..ba909da340 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6600,7 +6600,12 @@ function hedley_reports_prenatal_add_next_steps_activities(array $encounter_data } function hedley_reports_prenatal_add_next_steps_activities_for_nurse(array $encounter_data, array &$expected) { - // Referral activity logic. + hedley_reports_prenatal_add_send_to_hc_activity_for_nurse($encounter_data, $expected); + hedley_reports_prenatal_add_health_education_activity_for_nurse($encounter_data, $expected); + hedley_reports_prenatal_add_medication_distribution_activity_for_nurse($encounter_data, $expected); +} + +function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encounter_data, array &$expected) { $launch_date = '2021-06-07'; $launch_date_obj = new DateTime($launch_date); if ($encounter_data['start_date_obj'] < $launch_date_obj) { @@ -6726,17 +6731,77 @@ function hedley_reports_prenatal_add_next_steps_activities_for_nurse(array $enco if ($referral_expected) { $expected[] = 'prenatal_send_to_hc'; } +} - - // Medication Distribution activity logic. - $launch_date = '2022-09-25'; +function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $encounter_data, array &$expected) { + $launch_date = '2021-06-07'; $launch_date_obj = new DateTime($launch_date); if ($encounter_data['start_date_obj'] < $launch_date_obj) { return; } + $emergency_diagnoses = hedley_reports_prenatal_emergency_diagnoses(); + if (!empty(array_intersect($encounter_data['diagnoses'], $emergency_diagnoses))) { + // Emergency diagnosis present - no health education. + return; + } + + $encounter_type = $encounter_data['encounter_type']; + $expected = FALSE; + + if ($encounter_type == 'nurse') { + // HIV education. + $hiv_test_measurement = $encounter_data['measurements_by_type']['prenatal_hiv_test']; + if (!empty($hiv_test_measurement)) { + $expected = !empty($hiv_test_measurement->field_test_result[LANGUAGE_NONE][0]['value']); + } + // Partner presence education. + if (!$expected) { + $partner_hiv_test_measurement = $encounter_data['measurements_by_type']['prenatal_partner_hiv_test']; + if (!empty($partner_hiv_test_measurement)) { + $expected = $partner_hiv_test_measurement->field_test_execution_note[LANGUAGE_NONE][0]['value'] == 'not-present'; + } + } + // By encounter diagnoses. + if (!$expected) { + $triggering_diagnoses = array_merge( + hedley_reports_prenatal_diabetes_diagnoses(), + [ + 'heartburn', + 'candidiasis', + 'gonorrhea', + 'trichomonas-or-bv', + 'hiv-detectable-viral-load-initial', + 'hiv-detectable-viral-load', + ] + ); + $expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + } + } + // Postpartum encounter. + else { + $triggering_diagnoses = [ + 'heartburn', + 'candidiasis', + 'gonorrhea', + 'trichomonas-or-bv', + 'postpartum-early-mastitis-engorgment', + 'postpartum-mastitis', + ]; + $expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + } + if (!$expected) { + + } +} +function hedley_reports_prenatal_add_medication_distribution_activity_for_nurse(array $encounter_data, array &$expected) { + $launch_date = '2022-09-25'; + $launch_date_obj = new DateTime($launch_date); + if ($encounter_data['start_date_obj'] < $launch_date_obj) { + return; + } } function hedley_reports_prenatal_hospital_referral_expected(array $encounter_data) { From f99a08e22e130fa21ff109c3f9072dfd7d79f31a Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 31 Oct 2024 11:56:31 +0200 Subject: [PATCH 156/185] Complete Health education activity logic [ci skip] --- .../src/elm/Pages/Prenatal/Activity/Utils.elm | 1 - .../hedley_reports/hedley_reports.module | 200 +++++++++++++++--- 2 files changed, 173 insertions(+), 28 deletions(-) diff --git a/client/src/elm/Pages/Prenatal/Activity/Utils.elm b/client/src/elm/Pages/Prenatal/Activity/Utils.elm index e53df82d66..51334ef2f2 100644 --- a/client/src/elm/Pages/Prenatal/Activity/Utils.elm +++ b/client/src/elm/Pages/Prenatal/Activity/Utils.elm @@ -444,7 +444,6 @@ expectNextStepsTask currentDate assembled task = , DiagnosisPostpartumMastitis ] assembled - || provideMentalHealthEducation assembled ) ChwPostpartumEncounter -> diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index ba909da340..5ebc8b5937 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6621,12 +6621,7 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun if (!empty($mental_health_measurement)) { $specialist_at_hc = $mental_health_measurement->field_specialist_at_hc[LANGUAGE_NONE][0]['value']; if ($specialist_at_hc === TRUE) { - $triggering_diagnoses = [ - 'depression-possible', - 'depression-highly-possible', - 'depression-probable', - 'suicide-risk', - ]; + $triggering_diagnoses = hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment(); $referral_expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); } } @@ -6747,23 +6742,25 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ } $encounter_type = $encounter_data['encounter_type']; - $expected = FALSE; + $activity_expected = FALSE; if ($encounter_type == 'nurse') { // HIV education. $hiv_test_measurement = $encounter_data['measurements_by_type']['prenatal_hiv_test']; if (!empty($hiv_test_measurement)) { - $expected = !empty($hiv_test_measurement->field_test_result[LANGUAGE_NONE][0]['value']); + $activity_expected = !empty($hiv_test_measurement->field_test_result[LANGUAGE_NONE][0]['value']); } + // Partner presence education. - if (!$expected) { + if (!$activity_expected) { $partner_hiv_test_measurement = $encounter_data['measurements_by_type']['prenatal_partner_hiv_test']; if (!empty($partner_hiv_test_measurement)) { - $expected = $partner_hiv_test_measurement->field_test_execution_note[LANGUAGE_NONE][0]['value'] == 'not-present'; + $activity_expected = $partner_hiv_test_measurement->field_test_execution_note[LANGUAGE_NONE][0]['value'] == 'not-present'; } } - // By encounter diagnoses. - if (!$expected) { + + // Education per encounter diagnoses. + if (!$activity_expected) { $triggering_diagnoses = array_merge( hedley_reports_prenatal_diabetes_diagnoses(), [ @@ -6775,11 +6772,21 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ 'hiv-detectable-viral-load', ] ); - $expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + $activity_expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + } + + // Mental health education. + // Mental health survey is filled and none of mental health + // diagnoses requiring tratment was recorded. + $mental_health_measurement = $encounter_data['measurements_by_type']['prenatal_mental_health']; + if (!empty($mental_health_measurement)) { + $mental_health_diagnoses_requiring_treatment = hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment(); + $activity_expected = empty(array_intersect($encounter_data['diagnoses'], $mental_health_diagnoses_requiring_treatment)); } } // Postpartum encounter. else { + // Education per encounter diagnoses. $triggering_diagnoses = [ 'heartburn', 'candidiasis', @@ -6788,11 +6795,129 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ 'postpartum-early-mastitis-engorgment', 'postpartum-mastitis', ]; - $expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + $activity_expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + } + + // Nausea and Vomiting education. + $symptom_review_measurement = $encounter_data['measurements_by_type']['prenatal_symptom_review']; + if (!$activity_expected) { + // First, checking by current encounter. + // We need to make sure that nausea-and-vomiting symptom is recorded, and + // neither of follow-up questions (dizziness, low-urine-output and dark-urine) + // are answered positively. + // Then, we make sure that Nausea and Vomiting symptom was not recorded during + // previous encounters. + if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { + $symptom_recorded = FALSE; + foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { + if ($symptom['value'] === 'nausea-and-vomiting') { + $symptom_recorded = TRUE; + break; + } + } + + if ($symptom_recorded) { + $symptom_questions = $symptom_review_measurement->field_prenatal_symptom_questions[LANGUAGE_NONE]; + if (!empty($symptom_questions)) { + $question_recorded = FALSE; + foreach ($symptom_questions as $question) { + if (in_array($question['value'], ['dizziness', 'low-urine-output', 'dark-urine'])) { + $question_recorded = TRUE; + break; + } + } + + if (!$question_recorded) { + $activity_expected = !hedley_reports_prenatal_symptom_recorded_previously($encounter_data, 'nausea-and-vomiting'); + } + } + } + } } - if (!$expected) { - + // Education for Leg Cramps, Lower Back Pain, Constipation and + // Varicose Veins symptoms. + if (!$activity_expected) { + if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { + foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { + if (in_array($symptom['value'], ['leg-cramps', 'low-back-pain', 'constipation', 'varicose-veins'])) { + $activity_expected = TRUE; + break; + } + } + } + } + + // Leg pain / redness education. + if (!$activity_expected) { + // We need to make sure that leg-pain-redness symptom is recorded, and + // neither of follow-up questions (leg-painful, leg-swollen and leg-warm) + // are answered positively. + // Then, we make sure that Nausea and Vomiting symptom was not recorded during + // previous encounters. + if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { + $symptom_recorded = FALSE; + foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { + if ($symptom['value'] === 'leg-pain-redness') { + $symptom_recorded = TRUE; + break; + } + } + + if ($symptom_recorded) { + $symptom_questions = $symptom_review_measurement->field_prenatal_symptom_questions[LANGUAGE_NONE]; + if (!empty($symptom_questions)) { + $question_recorded = FALSE; + foreach ($symptom_questions as $question) { + if (in_array($question['value'], ['leg-painful', 'leg-swollen', 'leg-warm'])) { + $question_recorded = TRUE; + break; + } + } + + $activity_expected = !$question_recorded; + } + } + } + } + + // Pelvic pain education. + if (!$activity_expected) { + // First, checking by current encounter. + // We need to make sure that pelvic-pain symptom is recorded, and + // follow-up question (pelvic-pain-hospitalization) is answered negatively. + // Then, we make sure that pelvic-pain symptom was not recorded during + // previous encounters. + if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { + $symptom_recorded = FALSE; + foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { + if ($symptom['value'] === 'pelvic-pain') { + $symptom_recorded = TRUE; + break; + } + } + + if ($symptom_recorded) { + $symptom_questions = $symptom_review_measurement->field_prenatal_symptom_questions[LANGUAGE_NONE]; + if (!empty($symptom_questions)) { + $question_recorded = FALSE; + foreach ($symptom_questions as $question) { + if ($question['value'] === 'pelvic-pain-hospitalization') { + $question_recorded = TRUE; + break; + } + } + + if (!$question_recorded) { + $activity_expected = !hedley_reports_prenatal_symptom_recorded_previously($encounter_data, 'pelvic-pain'); + } + } + } + } + } + + if ($activity_expected) { + $expected[] = 'prenatal_health_education'; } } @@ -6818,12 +6943,7 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat if (!empty($mental_health_measurement)) { $specialist_at_hc = $mental_health_measurement->field_specialist_at_hc[LANGUAGE_NONE][0]['value']; if ($specialist_at_hc === FALSE) { - $triggering_diagnoses = [ - 'depression-possible', - 'depression-highly-possible', - 'depression-probable', - 'suicide-risk', - ]; + $triggering_diagnoses = hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment(); $referred_to_hospital = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); } } @@ -6856,7 +6976,7 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat // Checking if referral to hospital is required by Hypertension or // Moderated Preeclampisa treatments. if (!$referred_to_hospital) { - $referred_to_hospital = hedley_reports_prenatal_hospitalizaton_due_to_hypertension_treatment_update($encounter_data); + $referred_to_hospital = hedley_reports_prenatal_hospitalization_due_to_hypertension_treatment_update($encounter_data); if (!$referred_to_hospital) { $currently_diagnosed_with_moderate_preeclampsia = hedley_reports_prenatal_diagnosed_previously_with_any_of( @@ -6926,7 +7046,7 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat return $referred_to_hospital; } -function hedley_reports_prenatal_hospitalizaton_due_to_hypertension_treatment_update(array $encounter_data) { +function hedley_reports_prenatal_hospitalization_due_to_hypertension_treatment_update(array $encounter_data) { $treatment_options = [ 'methyldopa-2', 'methyldopa-3', @@ -7006,10 +7126,10 @@ function hedley_reports_prenatal_hospitalizaton_due_to_hypertension_treatment_up ); } -function hedley_reports_prenatal_diagnosed_previously_with_any_of(array $encounter_data, $diagnoses) { +function hedley_reports_prenatal_diagnosed_previously_with_any_of(array $encounter_data, array $diagnoses) { $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; - foreach ($previous_nurse_encounters_data as $encounter_data) { - if (!empty(array_intersect($encounter_data['diagnoses'], $diagnoses))) { + foreach ($previous_nurse_encounters_data as $previous_encounter_data) { + if (!empty(array_intersect($previous_encounter_data['diagnoses'], $diagnoses))) { return TRUE; } } @@ -7017,6 +7137,23 @@ function hedley_reports_prenatal_diagnosed_previously_with_any_of(array $encount return FALSE; } +function hedley_reports_prenatal_symptom_recorded_previously(array $encounter_data, $symptom_value) { + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + foreach ($previous_nurse_encounters_data as $previous_encounter_data) { + $symptom_review_measurement = $previous_encounter_data['measurements_by_type']['prenatal_symptom_review']; + if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { + continue; + } + foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { + if ($symptom['value'] === $symptom_value) { + return TRUE; + } + } + } + + return FALSE; +} + function hedley_reports_prenatal_add_next_steps_activities_for_chw(array $encounter_data, array &$expected) { $launch_date = '2021-06-07'; $launch_date_obj = new DateTime($launch_date); @@ -7334,6 +7471,15 @@ function hedley_reports_prenatal_hiv_diagnoses() { ]; } +function hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment() { + return [ + 'depression-possible', + 'depression-highly-possible', + 'depression-probable', + 'suicide-risk', + ]; +} + function hedley_reports_prenatal_syphilislike_diagnoses() { return [ 'syphilis-initial', From 84ced24dd42fe29445073c672db8cb025af96061 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 31 Oct 2024 16:26:03 +0200 Subject: [PATCH 157/185] WIP: Medication distribution activity logic [ci skip] --- client/src/elm/Pages/Prenatal/Utils.elm | 2 +- .../hedley_reports/hedley_reports.module | 228 ++++++++++++++++-- 2 files changed, 215 insertions(+), 15 deletions(-) diff --git a/client/src/elm/Pages/Prenatal/Utils.elm b/client/src/elm/Pages/Prenatal/Utils.elm index cc42a6a07d..27b4fcec5e 100644 --- a/client/src/elm/Pages/Prenatal/Utils.elm +++ b/client/src/elm/Pages/Prenatal/Utils.elm @@ -1772,9 +1772,9 @@ resolveRequiredMedicationsSet language currentDate phase assembled = Nothing in case phase of - -- Not for Postpartum encounter. PrenatalEncounterPhaseInitial -> let + -- Not for Postpartum encounter. mebendazoleSet = let prescribeMebendazole = diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 5ebc8b5937..fa2e2a3c62 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6613,30 +6613,30 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun } // Checking referral to hospital - $referral_expected = hedley_reports_prenatal_hospital_referral_expected($encounter_data); + $activity_expected = hedley_reports_prenatal_hospital_referral_expected($encounter_data); // Checking referral to mental health specialist. - if (!$referral_expected) { + if (!$activity_expected) { $mental_health_measurement = $encounter_data['measurements_by_type']['prenatal_mental_health']; if (!empty($mental_health_measurement)) { $specialist_at_hc = $mental_health_measurement->field_specialist_at_hc[LANGUAGE_NONE][0]['value']; if ($specialist_at_hc === TRUE) { $triggering_diagnoses = hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment(); - $referral_expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + $activity_expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); } } } // Checking referral to ARV program. - if (!$referral_expected) { + if (!$activity_expected) { // First option is that HIV is diagnosed and there's an HIV // program at health center. if (in_array('hiv', $encounter_data['diagnoses'])) { $hiv_test_measurement = $encounter_data['measurements_by_type']['prenatal_hiv_test']; if (!empty($hiv_test_measurement) && !empty($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE])) { foreach ($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE] as $sign) { - if ($sign == 'hiv-program-hc') { - $referral_expected = TRUE; + if ($sign['value'] == 'hiv-program-hc') { + $activity_expected = TRUE; break; } } @@ -6645,7 +6645,7 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun // Second option - EnrolledToARVProgram section appears at // speciality care activity, and patient was referred to that program. - if (!$referral_expected) { + if (!$activity_expected) { $section_expected = FALSE; $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; foreach ($previous_nurse_encounters_data as $previous_encounter_data) { @@ -6671,7 +6671,7 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun if (!empty($speciality_care_measurement) && !empty($speciality_care_measurement->field_speciality_care_signs[LANGUAGE_NONE])) { foreach ($speciality_care_measurement->field_speciality_care_signs[LANGUAGE_NONE] as $sign) { if ($sign['value'] == 'arv') { - $referral_expected = TRUE; + $activity_expected = TRUE; break; } } @@ -6681,7 +6681,7 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun } // Checking referral to NCD program. - if (!$referral_expected) { + if (!$activity_expected) { $section_expected = FALSE; $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; foreach ($previous_nurse_encounters_data as $previous_encounter_data) { @@ -6703,7 +6703,7 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun if (!empty($speciality_care_measurement) && !empty($speciality_care_measurement->field_speciality_care_signs[LANGUAGE_NONE])) { foreach ($speciality_care_measurement->field_speciality_care_signs[LANGUAGE_NONE] as $sign) { if ($sign['value'] == 'ncd') { - $referral_expected = TRUE; + $activity_expected = TRUE; break; } } @@ -6712,18 +6712,18 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun } // Checking referral to Ultrasound. - if (!$referral_expected) { + if (!$activity_expected) { $lmp_measurement = $encounter_data['measurements_by_type']['last_menstrual_period']; if (!empty($lmp_measurement)) { if ($lmp_measurement->field_confident[LANGUAGE_NONE][0]['value'] === FALSE) { if (!empty($lmp_measurement->field_not_confident_reason[LANGUAGE_NONE][0]['value'])) { - $referral_expected = TRUE; + $activity_expected = TRUE; } } } } - if ($referral_expected) { + if ($activity_expected) { $expected[] = 'prenatal_send_to_hc'; } } @@ -6927,6 +6927,206 @@ function hedley_reports_prenatal_add_medication_distribution_activity_for_nurse( if ($encounter_data['start_date_obj'] < $launch_date_obj) { return; } + + $emergency_diagnoses = hedley_reports_prenatal_emergency_diagnoses(); + if (!empty(array_intersect($encounter_data['diagnoses'], $emergency_diagnoses))) { + // Emergency diagnosis present - no medication distribution. + return; + } + + // Checking by medication set. + $activity_expected = hedley_reports_prenatal_medication_distribution_expected_per_medication_set($encounter_data); + + // Checking by diagnosis. + if (!$activity_expected) { + + } + + if ($activity_expected) { + $expected[] = 'prenatal_medication_distribution'; + } +} + +function hedley_reports_prenatal_medication_distribution_expected_per_medication_set(array $encounter_data) { + // HIV medication set. + // First option - HIV diagnosed and no HIV program at HC. + $hiv_diagnosed = !empty(array_intersect($encounter_data['diagnoses'], ['hiv', 'hiv-recurrent'])); + if ($hiv_diagnosed) { + $hiv_test_measurement = $encounter_data['measurements_by_type']['prenatal_hiv_test']; + if (!empty($hiv_test_measurement) && !empty($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE])) { + $hiv_program_at_hc = FALSE; + foreach ($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE] as $sign) { + if ($sign['value'] == 'hiv-program-hc') { + $hiv_program_at_hc = TRUE; + break; + } + } + if (!$hiv_program_at_hc) { + return TRUE; + } + } + } + // Second option - patient reported not getting any medicine from PMTCT. + $medication_measurement = $encounter_data['measurements_by_type']['medication']; + if (!empty($medication_measurement)) { + $treatments = $medication_measurement->field_hiv_treatment[LANGUAGE_NONE]; + if (!empty($treatments)) { + foreach ($treatments as $sign) { + if (in_array( + $sign['value'], + [ + 'no-medicine-not-seen', + 'no-medicine-out-of-stock', + 'no-medicine-patient-refused', + 'no-medicine-other', + ] + ) + ) { + return TRUE; + } + } + } + } + + // Discordant Partnership medication set. + $discordant_partnership_diagnosed = !empty(array_intersect( + $encounter_data['diagnoses'], + ['partner-hiv', 'partner-hiv-recurrent'] + )); + if ($discordant_partnership_diagnosed) { + return TRUE; + } + + // Moderate Anemia medication set. + $moderate_anemia_diagnosed = !empty(array_intersect( + $encounter_data['diagnoses'], + ['anemia', 'anemia-initial'] + )); + if ($moderate_anemia_diagnosed) { + $treatments = $medication_measurement->field_anemia_treatment[LANGUAGE_NONE]; + if (!empty($treatments)) { + foreach ($treatments as $treatment_signs) { + $referred = FALSE; + foreach ($treatment_signs as $sign) { + if ($sign['value'] == 'adverse-events-hospitalization') { + $referred = TRUE; + } + } + if (!$referred) { + return TRUE; + } + } + } + } + + // Mebendazole medication set. + $encounter_type = $encounter_data['encounter_type']; + if ($encounter_type == 'nurse') { + $lmp_date = $encounter_data['lmp_date']; + if (!empty($lmp_date)) { + $start_date_obj = $encounter_data['start_date_obj']; + $lmp_date_obj = new DateTime($lmp_date); + $ega_in_weeks = hedley_reports_prenatal_calculate_ega_weeks($lmp_date_obj, $start_date_obj); + if ($ega_in_weeks >= 24) { + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + $prescribed = FALSE; + foreach ($previous_nurse_encounters_data as $previous_encounter_data) { + // First option. + $medication_measurement = $previous_encounter_data['measurements_by_type']['medication']; + if (!empty($medication_measurement)) { + $medications = $medication_measurement->field_medication[LANGUAGE_NONE]; + if (!empty($medications)) { + foreach ($medications as $sign) { + if ($sign['value'] == 'deworming-pill') { + $prescribed = TRUE; + break; + } + } + } + } + + if (!$prescribed) { + // Second option - only check if not prescribed by first option. + $medication_distribution_measurement = $encounter_data['measurements_by_type']['prenatal_medication_distribution']; + if (!empty($medication_distribution_measurement)) { + $prescribed_medications = $medication_distribution_measurement->field_prescribed_medication[LANGUAGE_NONE]; + if (!empty($prescribed_medications)) { + foreach ($prescribed_medications as $prescribed_medication) { + if ($prescribed_medication['value'] == 'mebendezole') { + $prescribed = TRUE; + break; + } + } + } + } + } + + // If prescribed by first or second option, no point of checking + // additional encounters. + if ($prescribed) { + break; + } + } + + // Now we check that Mebendazole was prescribed at current encounter. + if (!$prescribed) { + $medication_measurement = $encounter_data['measurements_by_type']['medication']; + if (!empty($medication_measurement)) { + $medications = $medication_measurement->field_medication[LANGUAGE_NONE]; + if (!empty($medications)) { + foreach ($medications as $sign) { + if ($sign['value'] == 'mebendezole') { + $prescribed = TRUE; + break; + } + } + } + } + } + + // Finally, since Mebendazole was not prescribed at current, + // we know it's required. + if (!$prescribed) { + return TRUE; + } + } + } + } + + // Gonorhea medication set. + $gonorhea_diagnosed = in_array('gonorrhea', $encounter_data['diagnoses']); + if ($gonorhea_diagnosed) { + return TRUE; + } + + // Trichomonas or Bacterial Vaginosis medication set. + $trichomonas_diagnosed = in_array('trichomonas-or-bv', $encounter_data['diagnoses']); + if ($trichomonas_diagnosed) { + return TRUE; + } + + // Vitamin A medication set. + if ($encounter_type == 'nurse-postpartum') { + $medication_measurement = $encounter_data['measurements_by_type']['medication']; + if (!empty($medication_measurement)) { + $medications = $medication_measurement->field_medication[LANGUAGE_NONE]; + if (!empty($medications)) { + $prescribed = FALSE; + foreach ($medications as $sign) { + if ($sign['value'] == 'vitamin-a') { + $prescribed = TRUE; + break; + } + } + + if (!$prescribed) { + return TRUE; + } + } + } + } + + return FALSE; } function hedley_reports_prenatal_hospital_referral_expected(array $encounter_data) { @@ -7537,7 +7737,7 @@ function hedley_reports_prenatal_referred_to_hiv_program_previously(array $encou } foreach ($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE] as $sign) { - if ($sign == 'hiv-program-hc') { + if ($sign['value'] == 'hiv-program-hc') { return TRUE; } } From 72eaf745d5ff44193314b0ccddd91db77a95c076 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 3 Nov 2024 12:34:55 +0200 Subject: [PATCH 158/185] WIP [ci skip] --- .../hedley_reports/hedley_reports.module | 138 +++++++++++++----- 1 file changed, 98 insertions(+), 40 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index fa2e2a3c62..b5f5b6a19a 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6622,7 +6622,7 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun $specialist_at_hc = $mental_health_measurement->field_specialist_at_hc[LANGUAGE_NONE][0]['value']; if ($specialist_at_hc === TRUE) { $triggering_diagnoses = hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment(); - $activity_expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + $activity_expected = hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses); } } } @@ -6658,7 +6658,7 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun } // If not known as HIV positive, check by diagnosis. $triggering_diagnoses = hedley_reports_prenatal_hiv_diagnoses(); - if (!empty(array_intersect($previous_encounter_data['diagnoses'], $triggering_diagnoses))) { + if (hedley_reports_prenatal_diagnosed_any_of($previous_encounter_data, $triggering_diagnoses)) { $section_expected = TRUE; break; } @@ -6690,7 +6690,7 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun hedley_reports_prenatal_hypertensionlike_diagnoses(), hedley_reports_prenatal_diabetes_diagnoses() ); - if (!empty(array_intersect($previous_encounter_data['diagnoses'], $triggering_diagnoses))) { + if (hedley_reports_prenatal_diagnosed_any_of($previous_encounter_data, $triggering_diagnoses)) { $section_expected = TRUE; break; } @@ -6736,7 +6736,7 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ } $emergency_diagnoses = hedley_reports_prenatal_emergency_diagnoses(); - if (!empty(array_intersect($encounter_data['diagnoses'], $emergency_diagnoses))) { + if (hedley_reports_prenatal_diagnosed_any_of($encounter_data, $emergency_diagnoses)) { // Emergency diagnosis present - no health education. return; } @@ -6772,7 +6772,7 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ 'hiv-detectable-viral-load', ] ); - $activity_expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + $activity_expected = hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses); } // Mental health education. @@ -6781,7 +6781,7 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ $mental_health_measurement = $encounter_data['measurements_by_type']['prenatal_mental_health']; if (!empty($mental_health_measurement)) { $mental_health_diagnoses_requiring_treatment = hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment(); - $activity_expected = empty(array_intersect($encounter_data['diagnoses'], $mental_health_diagnoses_requiring_treatment)); + $activity_expected = !hedley_reports_prenatal_diagnosed_any_of($encounter_data, $mental_health_diagnoses_requiring_treatment); } } // Postpartum encounter. @@ -6795,7 +6795,7 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ 'postpartum-early-mastitis-engorgment', 'postpartum-mastitis', ]; - $activity_expected = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + $activity_expected = hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses); } // Nausea and Vomiting education. @@ -6929,7 +6929,7 @@ function hedley_reports_prenatal_add_medication_distribution_activity_for_nurse( } $emergency_diagnoses = hedley_reports_prenatal_emergency_diagnoses(); - if (!empty(array_intersect($encounter_data['diagnoses'], $emergency_diagnoses))) { + if (hedley_reports_prenatal_diagnosed_any_of($encounter_data, $emergency_diagnoses)) { // Emergency diagnosis present - no medication distribution. return; } @@ -6937,9 +6937,54 @@ function hedley_reports_prenatal_add_medication_distribution_activity_for_nurse( // Checking by medication set. $activity_expected = hedley_reports_prenatal_medication_distribution_expected_per_medication_set($encounter_data); - // Checking by diagnosis. + // Checking by diagnoses. if (!$activity_expected) { + $triggering_diagnoses = [ + 'heartburn', + 'urinary-tract-infection', + 'candidiasis', + 'gonorrhea', + 'trichomonas-or-bv', + ]; + $encounter_type = $encounter_data['encounter_type']; + if ($encounter_type == 'nurse') { + $triggering_diagnoses = array_merge( + $triggering_diagnoses, + hedley_reports_prenatal_syphilis_diagnoses() + ); + $triggering_diagnoses = array_merge( + $triggering_diagnoses, + hedley_reports_prenatal_hypertension_diagnoses() + ); + } + else { + $triggering_diagnoses = array_merge( + $triggering_diagnoses, + ['postpartum-early-mastitis-engorgment', 'postpartum-mastitis'] + ); + } + $activity_expected = hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses); + } + + // Checking for Malaria medication. + if (!$activity_expected) { + $triggering_diagnoses = hedley_reports_prenatal_malaria_diagnoses(); + if (hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses)) { + $medication_measurement = $encounter_data['measurements_by_type']['medication']; + $treatments = $medication_measurement->field_malaria_treatment[LANGUAGE_NONE]; + if (!empty($treatments)) { + $referred = FALSE; + foreach ($treatments as $treatment) { + if ($treatment['value'] == 'adverse-events-hospitalization') { + $referred = TRUE; + break; + } + } + + $activity_expected = !$referred; + } + } } if ($activity_expected) { @@ -6950,7 +6995,7 @@ function hedley_reports_prenatal_add_medication_distribution_activity_for_nurse( function hedley_reports_prenatal_medication_distribution_expected_per_medication_set(array $encounter_data) { // HIV medication set. // First option - HIV diagnosed and no HIV program at HC. - $hiv_diagnosed = !empty(array_intersect($encounter_data['diagnoses'], ['hiv', 'hiv-recurrent'])); + $hiv_diagnosed = hedley_reports_prenatal_diagnosed_any_of($encounter_data, ['hiv', 'hiv-recurrent']); if ($hiv_diagnosed) { $hiv_test_measurement = $encounter_data['measurements_by_type']['prenatal_hiv_test']; if (!empty($hiv_test_measurement) && !empty($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE])) { @@ -6989,33 +7034,33 @@ function hedley_reports_prenatal_medication_distribution_expected_per_medication } // Discordant Partnership medication set. - $discordant_partnership_diagnosed = !empty(array_intersect( - $encounter_data['diagnoses'], + $discordant_partnership_diagnosed = hedley_reports_prenatal_diagnosed_any_of( + $encounter_data, ['partner-hiv', 'partner-hiv-recurrent'] - )); + ); if ($discordant_partnership_diagnosed) { return TRUE; } // Moderate Anemia medication set. - $moderate_anemia_diagnosed = !empty(array_intersect( - $encounter_data['diagnoses'], + $moderate_anemia_diagnosed = hedley_reports_prenatal_diagnosed_any_of( + $encounter_data, ['anemia', 'anemia-initial'] - )); + ); if ($moderate_anemia_diagnosed) { $treatments = $medication_measurement->field_anemia_treatment[LANGUAGE_NONE]; if (!empty($treatments)) { - foreach ($treatments as $treatment_signs) { - $referred = FALSE; - foreach ($treatment_signs as $sign) { - if ($sign['value'] == 'adverse-events-hospitalization') { - $referred = TRUE; - } - } - if (!$referred) { - return TRUE; + $referred = FALSE; + foreach ($treatments as $treatment) { + if ($treatment['value'] == 'adverse-events-hospitalization') { + $referred = TRUE; + break; } } + + if (!$referred) { + return TRUE; + } } } @@ -7132,7 +7177,7 @@ function hedley_reports_prenatal_medication_distribution_expected_per_medication function hedley_reports_prenatal_hospital_referral_expected(array $encounter_data) { $encounter_type = $encounter_data['encounter_type']; $triggering_diagnoses = hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase(); - $referred_to_hospital_by_immediate_diagnosis = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + $referred_to_hospital_by_immediate_diagnosis = hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses); // At postpartum encounter, only option for hospital referral is by // immediate diagnosis. At nurse encounter, there are more options, // when there's no referral by immediate diagnosis. @@ -7144,22 +7189,15 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat $specialist_at_hc = $mental_health_measurement->field_specialist_at_hc[LANGUAGE_NONE][0]['value']; if ($specialist_at_hc === FALSE) { $triggering_diagnoses = hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment(); - $referred_to_hospital = !empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses)); + $referred_to_hospital = hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses)); } } // Checking if referral to hospital is required by Malaria Treatment - // Malaria diagnosed and suggested treatment was hospital referral. if (!$referred_to_hospital) { - $triggering_diagnoses = [ - 'malaria', - 'malaria-recurrent', - 'malaria-anemia', - 'malaria-anemia-recurrent', - 'malaria-severe-anemia', - 'malaria-severe-anemia-recurrent', - ]; - if (!empty(array_intersect($encounter_data['diagnoses'], $triggering_diagnoses))) { + $triggering_diagnoses = hedley_reports_prenatal_malaria_diagnoses(); + if (hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses)) { $medication_distribution_measurement = $encounter_data['measurements_by_type']['prenatal_medication_distribution']; if (!empty($medication_distribution_measurement)) { $recommended_treatments = $medication_distribution_measurement->field_recommended_treatment[LANGUAGE_NONE]; @@ -7329,7 +7367,7 @@ function hedley_reports_prenatal_hospitalization_due_to_hypertension_treatment_u function hedley_reports_prenatal_diagnosed_previously_with_any_of(array $encounter_data, array $diagnoses) { $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; foreach ($previous_nurse_encounters_data as $previous_encounter_data) { - if (!empty(array_intersect($previous_encounter_data['diagnoses'], $diagnoses))) { + if (hedley_reports_prenatal_diagnosed_any_of($previous_encounter_data, $diagnoses)) { return TRUE; } } @@ -7337,6 +7375,10 @@ function hedley_reports_prenatal_diagnosed_previously_with_any_of(array $encount return FALSE; } +function hedley_reports_prenatal_diagnosed_any_of(array $encounter_data, array $diagnoses) { + return !empty(array_intersect($encounter_data['diagnoses'], $diagnoses)); +} + function hedley_reports_prenatal_symptom_recorded_previously(array $encounter_data, $symptom_value) { $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; foreach ($previous_nurse_encounters_data as $previous_encounter_data) { @@ -7385,7 +7427,7 @@ function hedley_reports_prenatal_manadatory_activities_for_next_steps_completed( switch ($encounter_type) { case 'nurse': $emergency_diagnoses = hedley_reports_prenatal_emergency_diagnoses(); - if (!empty(array_intersect($encounter_data['diagnoses'], $emergency_diagnoses))) { + if (hedley_reports_prenatal_diagnosed_any_of($encounter_data, $emergency_diagnoses)) { return TRUE; } @@ -7671,6 +7713,17 @@ function hedley_reports_prenatal_hiv_diagnoses() { ]; } +function hedley_reports_prenatal_malaria_diagnoses() { + return [ + 'malaria', + 'malaria-recurrent', + 'malaria-anemia', + 'malaria-anemia-recurrent', + 'malaria-severe-anemia', + 'malaria-severe-anemia-recurrent', + ]; +} + function hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment() { return [ 'depression-possible', @@ -7681,13 +7734,18 @@ function hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment() { } function hedley_reports_prenatal_syphilislike_diagnoses() { + return array_merge( + hedley_reports_prenatal_syphilis_diagnoses(), + ['neurosyphilis-initial', 'neurosyphilis'] + ); +} + +function hedley_reports_prenatal_syphilis_diagnoses() { return [ 'syphilis-initial', 'syphilis', 'syphilis-complications-initial', 'syphilis-complications', - 'neurosyphilis-initial', - 'neurosyphilis', ]; } From 2b356e485adad2eef3782421696139f8a69678a4 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 3 Nov 2024 13:44:57 +0200 Subject: [PATCH 159/185] Complete Medication distribution activity logic [ci skip] --- .../hedley_reports/hedley_reports.module | 163 ++++++++++++++++-- 1 file changed, 145 insertions(+), 18 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index b5f5b6a19a..29169c70cf 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6949,11 +6949,11 @@ function hedley_reports_prenatal_add_medication_distribution_activity_for_nurse( $encounter_type = $encounter_data['encounter_type']; if ($encounter_type == 'nurse') { - $triggering_diagnoses = array_merge( + $triggering_diagnoses = array_merge( $triggering_diagnoses, hedley_reports_prenatal_syphilis_diagnoses() ); - $triggering_diagnoses = array_merge( + $triggering_diagnoses = array_merge( $triggering_diagnoses, hedley_reports_prenatal_hypertension_diagnoses() ); @@ -6987,6 +6987,11 @@ function hedley_reports_prenatal_add_medication_distribution_activity_for_nurse( } } + // Checking for continuous Hypertension treatment medication. + if (!$activity_expected) { + $activity_expected = hedley_reports_prenatal_medication_distribution_expected_for_continues_hypertension_treatment($encounter_data); + } + if ($activity_expected) { $expected[] = 'prenatal_medication_distribution'; } @@ -7174,6 +7179,74 @@ function hedley_reports_prenatal_medication_distribution_expected_per_medication return FALSE; } +function hedley_reports_prenatal_medication_distribution_expected_for_continues_hypertension_treatment(array $encounter_data) { + // If any of preeclampsia diagnosed - no medication as patient + // is referred to hospital. + if ( + hedley_reports_prenatal_diagnosed_previously_with_any_of( + $encounter_data, + hedley_reports_prenatal_preeclempsia_diagnoses() + ) + ) { + return FALSE; + } + + // First use-case - hypertension treatment update requires medication and + // patient was not referred to hospital due to adverse event related to + // hypertension. + if (hedley_reports_prenatal_medication_due_to_hypertension_treatment_update($encounter_data)) { + $medication_measurement = $encounter_data['measurements_by_type']['medication']; + $treatments = $medication_measurement->field_hypertension_treatment[LANGUAGE_NONE]; + if (!empty($treatments)) { + $referred = FALSE; + foreach ($treatments as $treatment) { + if ($treatment['value'] == 'adverse-events-hospitalization') { + $referred = TRUE; + break; + } + } + + if (!$referred) { + return TRUE; + }; + } + } + + // Second use-case - currently diagnosed was moderate preeclampsia + // (diagnosed previously with moderate, but no not with severe + // preeclampsia or eclampsia),and blood pressure requires hospitalization. + $currently_diagnosed_with_moderate_preeclampsia = + hedley_reports_prenatal_diagnosed_previously_with_any_of( + $encounter_data, + ['moderate-preeclampsia-initial', 'moderate-preeclampsia-recurrent'] + ) && + !hedley_reports_prenatal_diagnosed_previously_with_any_of( + $encounter_data, + [ + 'severe-preeclampsia-initial', + 'severe-preeclampsia-recurrent', + 'eclampsia' + ] + ); + + if ($currently_diagnosed_with_moderate_preeclampsia) { + $vitals_measurement = $encounter_data['measurements_by_type']['vitals']; + if (!empty($vitals_measurement)) { + $sys = $vitals_measurement->field_sys[LANGUAGE_NONE][0]['value']; + $dia = $vitals_measurement->field_dia[LANGUAGE_NONE][0]['value']; + + if (!empty($sys) && !empty($dia)) { + if ($sys >= 180 || $dia >= 110) { + return TRUE; + } + } + } + } + + // None of the use-cases produced positive result. + return FALSE; +} + function hedley_reports_prenatal_hospital_referral_expected(array $encounter_data) { $encounter_type = $encounter_data['encounter_type']; $triggering_diagnoses = hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase(); @@ -7189,7 +7262,7 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat $specialist_at_hc = $mental_health_measurement->field_specialist_at_hc[LANGUAGE_NONE][0]['value']; if ($specialist_at_hc === FALSE) { $triggering_diagnoses = hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment(); - $referred_to_hospital = hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses)); + $referred_to_hospital = hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses); } } @@ -7223,7 +7296,11 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat ) && !hedley_reports_prenatal_diagnosed_previously_with_any_of( $encounter_data, - hedley_reports_prenatal_hypertensionlike_diagnoses() + [ + 'severe-preeclampsia-initial', + 'severe-preeclampsia-recurrent', + 'eclampsia' + ] ); if ($currently_diagnosed_with_moderate_preeclampsia) { @@ -7295,7 +7372,7 @@ function hedley_reports_prenatal_hospitalization_due_to_hypertension_treatment_u ]; $current_treatment = hedley_reports_prenatal_get_latest_treatment_from_options($encounter_data, $treatment_options); if (!$current_treatment) { - return; + return FALSE; } $triggering_diagnoses = array_merge( @@ -7304,20 +7381,79 @@ function hedley_reports_prenatal_hospitalization_due_to_hypertension_treatment_u ); if (!hedley_reports_prenatal_diagnosed_previously_with_any_of($encounter_data, $triggering_diagnoses)) { - return; + return FALSE; } $vitals_measurement = $encounter_data['measurements_by_type']['vitals']; if (empty($vitals_measurement)) { - return; + return FALSE; } $sys = $vitals_measurement->field_sys[LANGUAGE_NONE][0]['value']; $dia = $vitals_measurement->field_dia[LANGUAGE_NONE][0]['value']; if (empty($sys) || empty($dia)) { - return; + return FALSE; } + $treatment_update_recommendation = hedley_reports_prenatal_resolve_hypertension_treatment_update_recommendation($sys, $dia); + + return ( + (($current_treatment == 'no-treatment-hypertension') && ($treatment_update_recommendation == 9)) || + (($current_treatment == 'methyldopa-2') && ($treatment_update_recommendation == 9)) || + (($current_treatment == 'methyldopa-3') && ($treatment_update_recommendation == 9)) || + (($current_treatment == 'methyldopa-4') && ($treatment_update_recommendation == 9)) || + (($current_treatment == 'add-carvedilol') && ($treatment_update_recommendation >= 2)) || + (($current_treatment == 'add-amlodipine') && ($treatment_update_recommendation >= 1)) + ); +} + +function hedley_reports_prenatal_medication_due_to_hypertension_treatment_update(array $encounter_data) { + $treatment_options = [ + 'methyldopa-2', + 'methyldopa-3', + 'methyldopa-4', + 'add-carvedilol', + 'add-amlodipine', + 'no-treatment-hypertension', + ]; + $current_treatment = hedley_reports_prenatal_get_latest_treatment_from_options($encounter_data, $treatment_options); + if (!$current_treatment) { + return FALSE; + } + + $triggering_diagnoses = array_merge( + hedley_reports_prenatal_hypertension_diagnoses(), + hedley_reports_prenatal_moderate_preeclempsia_diagnoses() + ); + + if (!hedley_reports_prenatal_diagnosed_previously_with_any_of($encounter_data, $triggering_diagnoses)) { + return FALSE; + } + + $vitals_measurement = $encounter_data['measurements_by_type']['vitals']; + if (empty($vitals_measurement)) { + return FALSE; + } + + $sys = $vitals_measurement->field_sys[LANGUAGE_NONE][0]['value']; + $dia = $vitals_measurement->field_dia[LANGUAGE_NONE][0]['value']; + if (empty($sys) || empty($dia)) { + return FALSE; + } + + $treatment_update_recommendation = hedley_reports_prenatal_resolve_hypertension_treatment_update_recommendation($sys, $dia); + + return ( + (($current_treatment == 'no-treatment-hypertension') && ($treatment_update_recommendation != 9)) || + (($current_treatment == 'methyldopa-2') && ($treatment_update_recommendation != 9)) || + (($current_treatment == 'methyldopa-3') && ($treatment_update_recommendation != 9)) || + (($current_treatment == 'methyldopa-4') && ($treatment_update_recommendation != 9)) || + (($current_treatment == 'add-carvedilol') && ($treatment_update_recommendation <= 1)) || + (($current_treatment == 'add-amlodipine') && ($treatment_update_recommendation == 0)) + ); +} + +function hedley_reports_prenatal_resolve_hypertension_treatment_update_recommendation($sys, $dia) { if ($sys < 140) { // Maintain treatment as is. $by_sys = 0; @@ -7352,16 +7488,7 @@ function hedley_reports_prenatal_hospitalization_due_to_hypertension_treatment_u $by_dia = 9; } - $treatment_update_recommendation = max($by_sys, $by_dia); - - return ( - (($current_treatment == 'no-treatment-hypertension') && ($treatment_update_recommendation == 9)) || - (($current_treatment == 'methyldopa-2') && ($treatment_update_recommendation == 9)) || - (($current_treatment == 'methyldopa-3') && ($treatment_update_recommendation == 9)) || - (($current_treatment == 'methyldopa-4') && ($treatment_update_recommendation == 9)) || - (($current_treatment == 'add-carvedilol') && ($treatment_update_recommendation >= 2)) || - (($current_treatment == 'add-amlodipine') && ($treatment_update_recommendation >= 1)) - ); + return max($by_sys, $by_dia); } function hedley_reports_prenatal_diagnosed_previously_with_any_of(array $encounter_data, array $diagnoses) { From 2b2142279c04beba73af9f16827ebd69e6214186 Mon Sep 17 00:00:00 2001 From: anvmn Date: Sun, 3 Nov 2024 20:40:23 +0200 Subject: [PATCH 160/185] Update for 'Send to HC' activity on recurrent phase [ci skip] --- .../custom/hedley_reports/hedley_reports.module | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 29169c70cf..eaab18bc83 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6631,7 +6631,7 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun if (!$activity_expected) { // First option is that HIV is diagnosed and there's an HIV // program at health center. - if (in_array('hiv', $encounter_data['diagnoses'])) { + if (hedley_reports_prenatal_diagnosed_any_of($encounter_data, ['hiv', 'hiv-recurrent'])) { $hiv_test_measurement = $encounter_data['measurements_by_type']['prenatal_hiv_test']; if (!empty($hiv_test_measurement) && !empty($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE])) { foreach ($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE] as $sign) { @@ -7249,7 +7249,7 @@ function hedley_reports_prenatal_medication_distribution_expected_for_continues_ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_data) { $encounter_type = $encounter_data['encounter_type']; - $triggering_diagnoses = hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase(); + $triggering_diagnoses = hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral(); $referred_to_hospital_by_immediate_diagnosis = hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses); // At postpartum encounter, only option for hospital referral is by // immediate diagnosis. At nurse encounter, there are more options, @@ -7687,6 +7687,13 @@ function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, Dat return floor($total_days / 7); } +function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral() { + array_merge( + hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase(), + hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_recurrent_phase() + ); +} + function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase() { return array_merge( hedley_reports_prenatal_emergency_diagnoses_initial_phase(), @@ -7720,7 +7727,7 @@ function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_i ); } -function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_recurrent_phase($phase) { +function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_recurrent_phase() { return array_merge( hedley_reports_prenatal_emergency_diagnoses_recurrent_phase(), [ From e1866807bc458ba07c56381aeeabd303a926df4c Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 4 Nov 2024 21:22:54 +0200 Subject: [PATCH 161/185] Vitals recheck activity logic [ci skip] --- .../hedley_reports/hedley_reports.module | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index eaab18bc83..d0e83e4c63 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5731,6 +5731,8 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc 'pregnancy_outcome' => '&', // Similar to Treatment Review, but for postpartum encounter. 'postpartum_treatment_review' => '*', + // Blood pressure re-check on recurrent phase of encounter. + 'vitals_recheck' => '!', ]; // Load all encounters of current participant. @@ -5864,6 +5866,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. + // Now we have enough info to determine which activities were expected. $expected = hedley_reports_prenatal_generate_expected_initial_activities($encounter_data); hedley_reports_prenatal_add_history_activities($encounter_data, $expected); hedley_reports_prenatal_add_examination_activities($encounter_data, $expected); @@ -5882,6 +5885,8 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // This comes last, since it has mandatory activities to be completed, // which we will be checking for withing $expected. hedley_reports_prenatal_add_next_steps_activities($encounter_data, $expected); + // Vitals recheck (recurrent phase). + hedley_reports_prenatal_add_vitals_reckeck_activity($encounter_data, $expected); $completion_data = [ 'start_date' => $start_date, @@ -6525,6 +6530,38 @@ function hedley_reports_prenatal_add_pregnancy_outcome_activity(array $encounter $expected[] = 'pregnancy_outcome'; } +function hedley_reports_prenatal_add_vitals_reckeck_activity(array $encounter_data, array &$expected) { + $triggering_diagnoses = hedley_reports_prenatal_hypertension_diagnoses(); + if (hedley_reports_prenatal_diagnosed_previously_with_any_of($encounter_data, $triggering_diagnoses)) { + return; + }; + + $triggering_diagnoses = [ + 'eclampsia', + 'moderate-preeclampsia-initial', + 'moderate-preeclampsia-initial-ega-37+', + 'severe-preeclampsia-initial', + 'severe-preeclampsia-initial-ega-37+', + 'chronic-hypertension-immediate', + 'gestational-hypertension-immediate', + ]; + if (hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses)) { + return; + } + + $vitals_measurement = $encounter_data['measurements_by_type']['vitals']; + $sys = $vitals_measurement->field_sys[LANGUAGE_NONE][0]['value']; + $dia = $vitals_measurement->field_dia[LANGUAGE_NONE][0]['value']; + + if (empty($sys) || empty($dia)) { + return; + } + + if (($sys <= 140 && $sys < 160) || ($dia >= 90 && $dia < 110)) { + $expected[] = 'vitals_recheck'; + } +} + function hedley_reports_prenatal_add_postpartum_unique_nurse_activities(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; if ($encounter_type != 'nurse-postpartum') { From d5c136fe6be972c9f8c337d208b3005a28f48c8a Mon Sep 17 00:00:00 2001 From: anvmn Date: Mon, 4 Nov 2024 21:43:33 +0200 Subject: [PATCH 162/185] Labs test results activities [ci skip] --- .../hedley_reports/hedley_reports.module | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index d0e83e4c63..6b222f5f10 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5733,6 +5733,17 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc 'postpartum_treatment_review' => '*', // Blood pressure re-check on recurrent phase of encounter. 'vitals_recheck' => '!', + // Labs results. + 'prenatal_blood_gprs_test_result' => 'm+', + 'prenatal_hemoglobin_test_result' => 's+', + 'prenatal_hepatitis_b_test_result' => 't+', + 'prenatal_hiv_pcr_test_result' => 'u+', + 'prenatal_hiv_test_result' => 'v+', + 'prenatal_malaria_test_result' => 'w+', + 'prenatal_partner_hiv_test_result' => '1+', + 'prenatal_random_blood_sugar_test_result' => '3+', + 'prenatal_syphilis_test_result' => '7+', + 'prenatal_urine_dipstick_test_result' => '9+', ]; // Load all encounters of current participant. @@ -5888,6 +5899,98 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // Vitals recheck (recurrent phase). hedley_reports_prenatal_add_vitals_reckeck_activity($encounter_data, $expected); + // Adding labs test results activities. Since those are logically derived, + // and not actual content, we apply proprietary logic per records recorded + // at labs results content. + $labs_results = $measurements_by_type['prenatal_labs_results']; + if (!empty($labs_results)) { + if (!empty($labs_results->field_performed_tests)) { + $performed_tests = $labs_results->field_performed_tests[LANGUAGE_NONE]; + foreach ($performed_tests as $performed_test) { + switch ($performed_test['value']) { + case 'hiv': + $expected[] = 'prenatal_hiv_test_result'; + break; + + case 'partner-hiv': + $expected[] = 'prenatal_partner_hiv_test_result'; + break; + + case 'malaria': + $expected[] = 'prenatal_malaria_test_resul'; + break; + + case 'syphilis': + $expected[] = 'prenatal_syphilis_test_result'; + break; + + case 'hepatitis-b': + $expected[] = 'prenatal_hepatitis_b_test_result'; + break; + + case 'blood-group': + $expected[] = 'prenatal_blood_gprs_test_result'; + break; + + case 'hemoglobin': + $expected[] = 'prenatal_hemoglobin_test_result'; + break; + + case 'hiv-pcr': + $expected[] = 'prenatal_hiv_pcr_test_result'; + break; + + case 'urine-dipstick': + $expected[] = 'prenatal_urine_dipstick_test_result'; + break; + } + } + } + + if (!empty($labs_results->field_completed_tests)) { + $completed_tests = $labs_results->field_completed_tests[LANGUAGE_NONE]; + foreach ($completed_tests as $completed_test) { + switch ($completed_test['value']) { + case 'hiv': + $measurements_by_type['prenatal_hiv_test_result'] = 'dummy'; + break; + + case 'partner-hiv': + $measurements_by_type['prenatal_partner_hiv_test_result'] = 'dummy'; + break; + + case 'malaria': + $measurements_by_type['prenatal_malaria_test_resul'] = 'dummy'; + break; + + case 'syphilis': + $$measurements_by_type['prenatal_syphilis_test_result'] = 'dummy'; + break; + + case 'hepatitis-b': + $measurements_by_type['prenatal_hepatitis_b_test_result'] = 'dummy'; + break; + + case 'blood-group': + $measurements_by_type['prenatal_blood_gprs_test_result'] = 'dummy'; + break; + + case 'hemoglobin': + $measurements_by_type['prenatal_hemoglobin_test_result'] = 'dummy'; + break; + + case 'hiv-pcr': + $measurements_by_type['prenatal_hiv_pcr_test_result'] = 'dummy'; + break; + + case 'urine-dipstick': + $measurements_by_type['prenatal_urine_dipstick_test_result'] = 'dummy'; + break; + } + } + } + } + $completion_data = [ 'start_date' => $start_date, 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), From e9dffe1984c8792366228faec003bbab1586e9ce Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 5 Nov 2024 11:27:50 +0200 Subject: [PATCH 163/185] Logic to determine if virtual activities are completed [ci skip] --- .../hedley_reports/hedley_reports.module | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 6b222f5f10..2cc804f026 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5732,7 +5732,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // Similar to Treatment Review, but for postpartum encounter. 'postpartum_treatment_review' => '*', // Blood pressure re-check on recurrent phase of encounter. - 'vitals_recheck' => '!', + 'vitals_recheck' => '$+', // Labs results. 'prenatal_blood_gprs_test_result' => 'm+', 'prenatal_hemoglobin_test_result' => 's+', @@ -5893,12 +5893,8 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // Postpartum activities. hedley_reports_prenatal_add_pregnancy_outcome_activity($encounter_data, $expected); hedley_reports_prenatal_add_postpartum_unique_nurse_activities($encounter_data, $expected); - // This comes last, since it has mandatory activities to be completed, - // which we will be checking for withing $expected. - hedley_reports_prenatal_add_next_steps_activities($encounter_data, $expected); // Vitals recheck (recurrent phase). hedley_reports_prenatal_add_vitals_reckeck_activity($encounter_data, $expected); - // Adding labs test results activities. Since those are logically derived, // and not actual content, we apply proprietary logic per records recorded // at labs results content. @@ -5991,6 +5987,42 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc } } + // This comes last, since it has mandatory activities to be completed, + // which we will be checking for withing $expected. + hedley_reports_prenatal_add_next_steps_activities($encounter_data, $expected); + + // Logic to determine if virtual activities are completed. + // Treatment Review data is saved into Medication CT. + if (!empty($expected['treatment_review'])) { + if (!empty($measurements_by_type['medication'])) { + $measurements_by_type['treatment_review'] = 'dummy'; + } + } + // Postpartum treatment data is similar to Treatment Review, + // but at postpartum encounter. + if (!empty($expected['postpartum_treatment_review'])) { + if (!empty($measurements_by_type['medication'])) { + $measurements_by_type['postpartum_treatment_review'] = 'dummy'; + } + } + // Pregnancy Outcome data is stored on participant node. + if (!empty($expected['pregnancy_outcome'])) { + $outcome = $participant->field_outcome[LANGUAGE_NONE][0]['value']; + if (!empty($outcome)) { + $measurements_by_type['pregnancy_outcome'] = 'dummy'; + } + } + // Blood pressure re-check is done if dia_repeated and + // sys_repeated fields are set on vitals measurement. + if (!empty($expected['vitals_recheck'])) { + $vitals_measurement = $encounter_data['measurements_by_type']['vitals']; + $sys_repeated = $vitals_measurement->field_sys_repeated[LANGUAGE_NONE][0]['value']; + $dia_repeated = $vitals_measurement->field_dia_repeated[LANGUAGE_NONE][0]['value']; + if (!empty($sys_repeated) && !empty($dia_repeated)) { + $measurements_by_type['vitals_recheck'] = 'dummy'; + } + } + $completion_data = [ 'start_date' => $start_date, 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), From d84dd00ba000d68388542b92dd4ee66f298d4dc5 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 5 Nov 2024 14:45:26 +0200 Subject: [PATCH 164/185] View logic [ci skip] --- server/elm/src/Backend/Completion/Decoder.elm | 1 + server/elm/src/Backend/Completion/Model.elm | 57 ++ server/elm/src/Backend/Completion/Utils.elm | 166 ++++++ server/elm/src/Pages/Completion/Model.elm | 1 + server/elm/src/Pages/Completion/Utils.elm | 65 +++ server/elm/src/Pages/Completion/View.elm | 40 ++ server/elm/src/Translate.elm | 348 ++++++++++-- .../custom/hedley_general/js/elm-main.js | 503 ++++++++++++++++-- 8 files changed, 1111 insertions(+), 70 deletions(-) diff --git a/server/elm/src/Backend/Completion/Decoder.elm b/server/elm/src/Backend/Completion/Decoder.elm index fe0b264e3f..78f1908be8 100644 --- a/server/elm/src/Backend/Completion/Decoder.elm +++ b/server/elm/src/Backend/Completion/Decoder.elm @@ -32,6 +32,7 @@ decodeCompletionData = nutritionChildActivityFromMapping ) ) + |> requiredAt [ "results", "prenatal" ] (list (decodeEncounterData prenatalActivityFromMapping)) |> requiredAt [ "results", "tuberculosis" ] (list (decodeEncounterData tuberculosisActivityFromMapping)) |> requiredAt [ "results", "well_child" ] (list decodeWellChildEncounterData) diff --git a/server/elm/src/Backend/Completion/Model.elm b/server/elm/src/Backend/Completion/Model.elm index 718c1caa8c..2e57356860 100644 --- a/server/elm/src/Backend/Completion/Model.elm +++ b/server/elm/src/Backend/Completion/Model.elm @@ -18,6 +18,7 @@ type alias CompletionData = , ncdData : List (EncounterData NCDActivity) , nutritionIndividualData : List (EncounterData NutritionChildActivity) , nutritionGroupData : List (NutritionGroupEncounterData NutritionMotherActivity NutritionChildActivity) + , prenatalData : List (EncounterData PrenatalActivity) , tuberculosisData : List (EncounterData TuberculosisActivity) , wellChildData : List WellChildEncounterData } @@ -212,6 +213,62 @@ type TuberculosisActivity | TuberculosisTreatmentReview +type PrenatalActivity + = PrenatalAppointmentConfirmation + | PrenatalBirthPlan + | PrenatalBloodGprsTest + | PrenatalBloodGprsTestResult + | PrenatalBreastExam + | PrenatalBreastfeeding + | PrenatalCorePhysicalExam + | PrenatalDangerSigns + | PrenatalFamilyPlanning + | PrenatalFollowUp + | PrenatalGuExam + | PrenatalHealthEducation + | PrenatalHemoglobinTest + | PrenatalHemoglobinTestResult + | PrenatalHepatitisBTest + | PrenatalHepatitisBTestResult + | PrenatalHIVPCRTest + | PrenatalHIVPCRTestResult + | PrenatalHIVTest + | PrenatalHIVTestResult + | PrenatalLastMenstrualPeriod + | PrenatalMalariaTest + | PrenatalMalariaTestResult + | PrenatalMedicalHistory + | PrenatalMedication + | PrenatalMedicationDistribution + | PrenatalMentalHealth + | PrenatalNutrition + | PrenatalObstetricalExam + | PrenatalObstetricHistory + | PrenatalObstetricHistoryStep2 + | PrenatalOutsideCare + | PrenatalPartnerHIVTest + | PrenatalPartnerHIVTestResult + | PrenatalPhoto + | PrenatalPostpartumTreatmentReview + | PrenatalPregnancyOutcome + | PrenatalPregnancyTesting + | PrenatalRandomBloodSugarTest + | PrenatalRandomBloodSugarTestResult + | PrenatalResource + | PrenatalSendToHC + | PrenatalSocialHistory + | PrenatalSpecialityCare + | PrenatalSymptomReview + | PrenatalSyphilisTest + | PrenatalSyphilisTestResult + | PrenatalTetanusImmunisation + | PrenatalTreatmentReview + | PrenatalUrineDipstickTest + | PrenatalUrineDipstickTestResult + | PrenatalVitals + | PrenatalVitalsRecheck + + type TakenBy = TakenByNurse | TakenByCHW diff --git a/server/elm/src/Backend/Completion/Utils.elm b/server/elm/src/Backend/Completion/Utils.elm index e177445d36..d7f832d87f 100644 --- a/server/elm/src/Backend/Completion/Utils.elm +++ b/server/elm/src/Backend/Completion/Utils.elm @@ -435,6 +435,172 @@ tuberculosisActivityFromMapping mapped = Nothing +prenatalActivityFromMapping : String -> Maybe PrenatalActivity +prenatalActivityFromMapping mapped = + case mapped of + "a" -> + Just PrenatalAppointmentConfirmation + + "b" -> + Just PrenatalBirthPlan + + "c" -> + Just PrenatalBreastExam + + "d" -> + Just PrenatalCorePhysicalExam + + "e" -> + Just PrenatalDangerSigns + + "f" -> + Just PrenatalLastMenstrualPeriod + + "g" -> + Just PrenatalMedicalHistory + + "h" -> + Just PrenatalMedication + + "i" -> + Just PrenatalObstetricHistory + + "j" -> + Just PrenatalObstetricHistoryStep2 + + "k" -> + Just PrenatalObstetricalExam + + "l" -> + Just PrenatalPregnancyTesting + + "m" -> + Just PrenatalBloodGprsTest + + "n" -> + Just PrenatalBreastfeeding + + "o" -> + Just PrenatalFamilyPlanning + + "p" -> + Just PrenatalFollowUp + + "q" -> + Just PrenatalGuExam + + "r" -> + Just PrenatalHealthEducation + + "s" -> + Just PrenatalHemoglobinTest + + "t" -> + Just PrenatalHepatitisBTest + + "u" -> + Just PrenatalHIVPCRTest + + "v" -> + Just PrenatalHIVTest + + "w" -> + Just PrenatalMalariaTest + + "x" -> + Just PrenatalMedicationDistribution + + "y" -> + Just PrenatalMentalHealth + + "z" -> + Just PrenatalNutrition + + "0" -> + Just PrenatalOutsideCare + + "1" -> + Just PrenatalPartnerHIVTest + + "2" -> + Just PrenatalPhoto + + "3" -> + Just PrenatalRandomBloodSugarTest + + "4" -> + Just PrenatalSendToHC + + "5" -> + Just PrenatalSpecialityCare + + "6" -> + Just PrenatalSymptomReview + + "7" -> + Just PrenatalSyphilisTest + + "8" -> + Just PrenatalTetanusImmunisation + + "9" -> + Just PrenatalUrineDipstickTest + + "@" -> + Just PrenatalResource + + "#" -> + Just PrenatalSocialHistory + + "$" -> + Just PrenatalVitals + + "^" -> + Just PrenatalTreatmentReview + + "&" -> + Just PrenatalPregnancyOutcome + + "*" -> + Just PrenatalPostpartumTreatmentReview + + "$+" -> + Just PrenatalVitalsRecheck + + "m+" -> + Just PrenatalBloodGprsTestResult + + "s+" -> + Just PrenatalHemoglobinTestResult + + "t+" -> + Just PrenatalHepatitisBTestResult + + "u+" -> + Just PrenatalHIVPCRTestResult + + "v+" -> + Just PrenatalHIVTestResult + + "w+" -> + Just PrenatalMalariaTestResult + + "1+" -> + Just PrenatalPartnerHIVTestResult + + "3+" -> + Just PrenatalRandomBloodSugarTestResult + + "7+" -> + Just PrenatalSyphilisTestResult + + "9+" -> + Just PrenatalUrineDipstickTestResult + + _ -> + Nothing + + takenByToString : TakenBy -> String takenByToString value = case value of diff --git a/server/elm/src/Pages/Completion/Model.elm b/server/elm/src/Pages/Completion/Model.elm index c3520561d8..2f7db49181 100644 --- a/server/elm/src/Pages/Completion/Model.elm +++ b/server/elm/src/Pages/Completion/Model.elm @@ -35,6 +35,7 @@ type ReportType | ReportNewbornExam | ReportNutritionGroup | ReportNutritionIndividual + | ReportPrenatal | ReportTuberculosis | ReportWellChild diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index 43fd2624b6..afbb15c3d1 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -10,6 +10,7 @@ import Backend.Completion.Model , NCDActivity(..) , NutritionChildActivity(..) , NutritionMotherActivity(..) + , PrenatalActivity(..) , TakenBy(..) , TuberculosisActivity(..) , WellChildActivity(..) @@ -45,6 +46,9 @@ reportTypeToString reportType = ReportNutritionIndividual -> "nutrition-individual" + ReportPrenatal -> + "prenatal" + ReportTuberculosis -> "tuberculosis" @@ -79,6 +83,9 @@ reportTypeFromString reportType = "nutrition-individual" -> Just ReportNutritionIndividual + "prenatal" -> + Just ReportPrenatal + "tuberculosis" -> Just ReportTuberculosis @@ -290,3 +297,61 @@ allTuberculosisActivities = , TuberculosisSymptomReview , TuberculosisTreatmentReview ] + + +allPrenatalActivities : List PrenatalActivity +allPrenatalActivities = + [ PrenatalAppointmentConfirmation + , PrenatalBirthPlan + , PrenatalBloodGprsTest + , PrenatalBloodGprsTestResult + , PrenatalBreastExam + , PrenatalBreastfeeding + , PrenatalCorePhysicalExam + , PrenatalDangerSigns + , PrenatalFamilyPlanning + , PrenatalFollowUp + , PrenatalGuExam + , PrenatalHealthEducation + , PrenatalHemoglobinTest + , PrenatalHemoglobinTestResult + , PrenatalHepatitisBTest + , PrenatalHepatitisBTestResult + , PrenatalHIVPCRTest + , PrenatalHIVPCRTestResult + , PrenatalHIVTest + , PrenatalHIVTestResult + , PrenatalLastMenstrualPeriod + , PrenatalMalariaTest + , PrenatalMalariaTestResult + , PrenatalMedicalHistory + , PrenatalMedication + , PrenatalMedicationDistribution + , PrenatalMentalHealth + , PrenatalNutrition + , PrenatalObstetricalExam + , PrenatalObstetricHistory + , PrenatalObstetricHistoryStep2 + , PrenatalOutsideCare + , PrenatalPartnerHIVTest + , PrenatalPartnerHIVTestResult + , PrenatalPhoto + , PrenatalPostpartumTreatmentReview + , PrenatalPregnancyOutcome + , PrenatalPregnancyTesting + , PrenatalRandomBloodSugarTest + , PrenatalRandomBloodSugarTestResult + , PrenatalResource + , PrenatalSendToHC + , PrenatalSocialHistory + , PrenatalSpecialityCare + , PrenatalSymptomReview + , PrenatalSyphilisTest + , PrenatalSyphilisTestResult + , PrenatalTetanusImmunisation + , PrenatalTreatmentReview + , PrenatalUrineDipstickTest + , PrenatalUrineDipstickTestResult + , PrenatalVitals + , PrenatalVitalsRecheck + ] diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index 97541c10bf..93862c3279 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -14,6 +14,7 @@ import Backend.Completion.Model , NutritionChildActivity(..) , NutritionGroupEncounterData , NutritionMotherActivity(..) + , PrenatalActivity(..) , SelectedEntity(..) , TakenBy(..) , TuberculosisActivity(..) @@ -227,6 +228,9 @@ viewCompletionData language currentDate themePath data model = ReportNutritionIndividual -> viewNutritionIndividualReport language startDate limitDate model.takenBy data.nutritionIndividualData + ReportPrenatal -> + viewPrenatalReport language startDate limitDate model.takenBy data.prenatalData + ReportTuberculosis -> viewTuberculosisReport language startDate limitDate model.takenBy data.tuberculosisData @@ -375,6 +379,15 @@ viewTuberculosisReport language startDate limitDate mTakenBy reportData = |> div [ class "report tuberculosis" ] +viewPrenatalReport : Language -> NominalDate -> NominalDate -> Maybe TakenBy -> List (EncounterData PrenatalActivity) -> Html Msg +viewPrenatalReport language startDate limitDate mTakenBy reportData = + eliminateEmptyEncounters reportData + |> applyFilters startDate limitDate mTakenBy + |> generatePrenatalReportData language + |> viewMetricsResultsTable + |> div [ class "report prenatal" ] + + eliminateEmptyEncounters : List { c | completion : { b | completedActivities : List a } } -> List { c | completion : { b | completedActivities : List a } } @@ -692,6 +705,33 @@ generateTuberculosisReportData language records = } +generatePrenatalReportData : + Language + -> List (EncounterData PrenatalActivity) + -> MetricsResultsTableData +generatePrenatalReportData language records = + { heading = translate language Translate.Antenatal + , captions = generateCaptionsList language + , rows = + List.map + (\activity -> + let + expected = + countOccurrences (.completion >> .expectedActivities) activity records + + completed = + countOccurrences (.completion >> .completedActivities) activity records + in + [ translate language <| Translate.PrenatalActivity activity + , String.fromInt expected + , String.fromInt completed + , calcualtePercentage completed expected + ] + ) + allPrenatalActivities + } + + -- Helper functions. diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index 1d05b1aa13..f0e2eff874 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -14,6 +14,7 @@ import Backend.Completion.Model , NCDActivity(..) , NutritionChildActivity(..) , NutritionMotherActivity(..) + , PrenatalActivity(..) , TakenBy(..) , TuberculosisActivity(..) , WellChildActivity(..) @@ -73,6 +74,7 @@ type TranslationId | AcuteIllnessTotal | AcuteMalnutrition | AggregatedChildScoreboard + | Antenatal | All | ANCNewborn | ANCTotal @@ -160,6 +162,7 @@ type TranslationId | None | NumberOfVisits Int | NumberOfVisitsLabel + | Nutrition | NutritionChildActivity NutritionChildActivity | NutritionMotherActivity NutritionMotherActivity | NutritionBehavior @@ -167,6 +170,8 @@ type TranslationId | NutritionGroup | NutritionReportTableType NutritionReportTableType | NutritionTotal + | OutsideCare + | Photo | PleaseWaitMessage | PMTCT | PopulationSelectionOption PopulationSelectionOption @@ -174,6 +179,7 @@ type TranslationId | PregnanciesAll | PregnanciesCompleted | PregnancyTest + | PrenatalActivity PrenatalActivity | PrevalenceByMonthOneVisitOrMore | PrevalenceByMonthTwoVisitsOrMore | Province @@ -196,6 +202,7 @@ type TranslationId | SelectStartDate | SelectScope | SelectViewMode + | SocialHistory | Sorwathe | StandardPediatricVisit | Stunting @@ -279,10 +286,7 @@ translationSet transId = } AcuteIllnessNutrition -> - { english = "Nutrition" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Nutrition AcuteIllnessVitals -> translationSet Vitals @@ -481,6 +485,12 @@ translationSet transId = , kirundi = Nothing } + Antenatal -> + { english = "Antenatal" + , kinyarwanda = Nothing + , kirundi = Nothing + } + All -> { english = "All" , kinyarwanda = Nothing @@ -561,6 +571,9 @@ translationSet transId = Pages.Completion.Model.ReportNutritionIndividual -> translationSet NutritionIndividual + Pages.Completion.Model.ReportPrenatal -> + translationSet Antenatal + Pages.Completion.Model.ReportTuberculosis -> translationSet Tuberculosis @@ -1035,10 +1048,7 @@ translationSet transId = } NCDOutsideCare -> - { english = "Outside Care" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet OutsideCare NCDPregnancyTest -> translationSet PregnancyTest @@ -1050,10 +1060,7 @@ translationSet transId = translationSet Referral NCDSocialHistory -> - { english = "Social History" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet SocialHistory NCDSymptomReview -> translationSet SymptomsReview @@ -1345,6 +1352,12 @@ translationSet transId = , kirundi = Nothing } + Nutrition -> + { english = "Nutrition" + , kinyarwanda = Nothing + , kirundi = Nothing + } + NutritionChildActivity activity -> case activity of NutritionHeight -> @@ -1354,16 +1367,10 @@ translationSet transId = } NutritionNutrition -> - { english = "Nutrition" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Nutrition NutritionPhoto -> - { english = "Photo" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Photo NutritionWeight -> { english = "Weight" @@ -1471,6 +1478,18 @@ translationSet transId = , kirundi = Nothing } + OutsideCare -> + { english = "Outside Care" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + Photo -> + { english = "Photo" + , kinyarwanda = Nothing + , kirundi = Nothing + } + PleaseWaitMessage -> { english = "This action may take several minutes to complete." , kinyarwanda = Nothing @@ -1527,6 +1546,269 @@ translationSet transId = , kirundi = Nothing } + PrenatalActivity activity -> + case activity of + PrenatalAppointmentConfirmation -> + { english = "Appointment Confirmation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalBirthPlan -> + { english = "Birth Plan" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalBloodGprsTest -> + { english = "Blood Group and Rhesus Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalBloodGprsTestResult -> + { english = "Blood Group and Rhesus Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalBreastExam -> + { english = "Breast Exam" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalBreastfeeding -> + { english = "Breastfeeding" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalCorePhysicalExam -> + { english = "Core Physical Exam" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalDangerSigns -> + translationSet DangerSigns + + PrenatalFamilyPlanning -> + translationSet FamilyPlanning + + PrenatalFollowUp -> + translationSet FollowUp + + PrenatalGuExam -> + { english = "GU Exam" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalHealthEducation -> + translationSet HealthEducation + + PrenatalHemoglobinTest -> + { english = "Hemoglobin Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalHemoglobinTestResult -> + { english = "Hemoglobin Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalHepatitisBTest -> + { english = "Hepatitis B Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalHepatitisBTestResult -> + { english = "Hepatitis B Result Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalHIVPCRTest -> + { english = "HIV PCR Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalHIVPCRTestResult -> + { english = "HIV PCR Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalHIVTest -> + translationSet HIVTest + + PrenatalHIVTestResult -> + { english = "HIV Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalLastMenstrualPeriod -> + { english = "Last Menstrual Period" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalMalariaTest -> + { english = "Malaria Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalMalariaTestResult -> + { english = "Malaria Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalMedicalHistory -> + { english = "Medical History" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalMedication -> + translationSet Medication + + PrenatalMedicationDistribution -> + translationSet MedicationDistribution + + PrenatalMentalHealth -> + { english = "Mental Health" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalNutrition -> + translationSet Nutrition + + PrenatalObstetricalExam -> + { english = "Obstetrical Exam" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalObstetricHistory -> + { english = "Obstetric History" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalObstetricHistoryStep2 -> + { english = "Obstetric History Second Step" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalOutsideCare -> + translationSet OutsideCare + + PrenatalPartnerHIVTest -> + { english = "Partner HIV Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalPartnerHIVTestResult -> + { english = "Partner HIV Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalPhoto -> + translationSet Photo + + PrenatalPostpartumTreatmentReview -> + { english = "Postpartum Treatment Review" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalPregnancyOutcome -> + { english = "Pregnancy Outcome" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalPregnancyTesting -> + { english = "Pregnancy Testing" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalRandomBloodSugarTest -> + translationSet RandomBloodSugarTest + + PrenatalRandomBloodSugarTestResult -> + translationSet RandomBloodSugarTestResult + + PrenatalResource -> + { english = "Resource" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalSendToHC -> + translationSet Referral + + PrenatalSocialHistory -> + translationSet SocialHistory + + PrenatalSpecialityCare -> + { english = "Speciality Care" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalSymptomReview -> + translationSet SymptomsReview + + PrenatalSyphilisTest -> + { english = "Syphilis Test" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalSyphilisTestResult -> + { english = "Syphilis Test Result" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalTetanusImmunisation -> + { english = "Tetanus Immunisation" + , kinyarwanda = Nothing + , kirundi = Nothing + } + + PrenatalTreatmentReview -> + translationSet TreatmentReview + + PrenatalUrineDipstickTest -> + translationSet UrineDipstickTest + + PrenatalUrineDipstickTestResult -> + translationSet UrineDipstickTestResult + + PrenatalVitals -> + translationSet Vitals + + PrenatalVitalsRecheck -> + { english = "Vitals Recheck" + , kinyarwanda = Nothing + , kirundi = Nothing + } + PrevalenceByMonthOneVisitOrMore -> { english = "Prevalence by month - one visit or more" , kinyarwanda = Nothing @@ -1593,16 +1875,10 @@ translationSet transId = } ReportNutrition -> - { english = "Nutrition" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Nutrition ReportPrenatal -> - { english = "Antenatal" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Antenatal ReportTypeLabel -> { english = "Report Type" @@ -1698,6 +1974,12 @@ translationSet transId = , kirundi = Nothing } + SocialHistory -> + { english = "Social History" + , kinyarwanda = Nothing + , kirundi = Nothing + } + Sorwathe -> { english = "Sorwathe" , kinyarwanda = Nothing @@ -1975,10 +2257,7 @@ translationSet transId = } WellChildNutrition -> - { english = "Nutrition" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Nutrition WellChildOPVImmunisation -> translationSet ImmunisationOPV @@ -1987,10 +2266,7 @@ translationSet transId = translationSet ImmunisationPCV13 WellChildPhoto -> - { english = "Photo" - , kinyarwanda = Nothing - , kirundi = Nothing - } + translationSet Photo WellChildPregnancySummary -> { english = "Pregnancy Summary" diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 10e9e81a99..4de59fe7d7 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -5833,6 +5833,7 @@ var $author$project$Pages$Completion$Model$ReportNCD = {$: 'ReportNCD'}; var $author$project$Pages$Completion$Model$ReportNewbornExam = {$: 'ReportNewbornExam'}; var $author$project$Pages$Completion$Model$ReportNutritionGroup = {$: 'ReportNutritionGroup'}; var $author$project$Pages$Completion$Model$ReportNutritionIndividual = {$: 'ReportNutritionIndividual'}; +var $author$project$Pages$Completion$Model$ReportPrenatal = {$: 'ReportPrenatal'}; var $author$project$Pages$Completion$Model$ReportTuberculosis = {$: 'ReportTuberculosis'}; var $author$project$Pages$Completion$Model$ReportWellChild = {$: 'ReportWellChild'}; var $author$project$Pages$Completion$Utils$reportTypeFromString = function (reportType) { @@ -5853,6 +5854,8 @@ var $author$project$Pages$Completion$Utils$reportTypeFromString = function (repo return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionGroup); case 'nutrition-individual': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportNutritionIndividual); + case 'prenatal': + return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportPrenatal); case 'tuberculosis': return $elm$core$Maybe$Just($author$project$Pages$Completion$Model$ReportTuberculosis); case 'well-child': @@ -6873,9 +6876,11 @@ var $author$project$Backend$Completion$Model$CompletionData = function (site) { return function (ncdData) { return function (nutritionIndividualData) { return function (nutritionGroupData) { - return function (tuberculosisData) { - return function (wellChildData) { - return {acuteIllnessData: acuteIllnessData, childScoreboardData: childScoreboardData, entityName: entityName, entityType: entityType, hivData: hivData, homeVisitData: homeVisitData, ncdData: ncdData, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, site: site, tuberculosisData: tuberculosisData, wellChildData: wellChildData}; + return function (prenatalData) { + return function (tuberculosisData) { + return function (wellChildData) { + return {acuteIllnessData: acuteIllnessData, childScoreboardData: childScoreboardData, entityName: entityName, entityType: entityType, hivData: hivData, homeVisitData: homeVisitData, ncdData: ncdData, nutritionGroupData: nutritionGroupData, nutritionIndividualData: nutritionIndividualData, prenatalData: prenatalData, site: site, tuberculosisData: tuberculosisData, wellChildData: wellChildData}; + }; }; }; }; @@ -8317,6 +8322,171 @@ var $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping return $elm$core$Maybe$Nothing; } }; +var $author$project$Backend$Completion$Model$PrenatalAppointmentConfirmation = {$: 'PrenatalAppointmentConfirmation'}; +var $author$project$Backend$Completion$Model$PrenatalBirthPlan = {$: 'PrenatalBirthPlan'}; +var $author$project$Backend$Completion$Model$PrenatalBloodGprsTest = {$: 'PrenatalBloodGprsTest'}; +var $author$project$Backend$Completion$Model$PrenatalBloodGprsTestResult = {$: 'PrenatalBloodGprsTestResult'}; +var $author$project$Backend$Completion$Model$PrenatalBreastExam = {$: 'PrenatalBreastExam'}; +var $author$project$Backend$Completion$Model$PrenatalBreastfeeding = {$: 'PrenatalBreastfeeding'}; +var $author$project$Backend$Completion$Model$PrenatalCorePhysicalExam = {$: 'PrenatalCorePhysicalExam'}; +var $author$project$Backend$Completion$Model$PrenatalDangerSigns = {$: 'PrenatalDangerSigns'}; +var $author$project$Backend$Completion$Model$PrenatalFamilyPlanning = {$: 'PrenatalFamilyPlanning'}; +var $author$project$Backend$Completion$Model$PrenatalFollowUp = {$: 'PrenatalFollowUp'}; +var $author$project$Backend$Completion$Model$PrenatalGuExam = {$: 'PrenatalGuExam'}; +var $author$project$Backend$Completion$Model$PrenatalHIVPCRTest = {$: 'PrenatalHIVPCRTest'}; +var $author$project$Backend$Completion$Model$PrenatalHIVPCRTestResult = {$: 'PrenatalHIVPCRTestResult'}; +var $author$project$Backend$Completion$Model$PrenatalHIVTest = {$: 'PrenatalHIVTest'}; +var $author$project$Backend$Completion$Model$PrenatalHIVTestResult = {$: 'PrenatalHIVTestResult'}; +var $author$project$Backend$Completion$Model$PrenatalHealthEducation = {$: 'PrenatalHealthEducation'}; +var $author$project$Backend$Completion$Model$PrenatalHemoglobinTest = {$: 'PrenatalHemoglobinTest'}; +var $author$project$Backend$Completion$Model$PrenatalHemoglobinTestResult = {$: 'PrenatalHemoglobinTestResult'}; +var $author$project$Backend$Completion$Model$PrenatalHepatitisBTest = {$: 'PrenatalHepatitisBTest'}; +var $author$project$Backend$Completion$Model$PrenatalHepatitisBTestResult = {$: 'PrenatalHepatitisBTestResult'}; +var $author$project$Backend$Completion$Model$PrenatalLastMenstrualPeriod = {$: 'PrenatalLastMenstrualPeriod'}; +var $author$project$Backend$Completion$Model$PrenatalMalariaTest = {$: 'PrenatalMalariaTest'}; +var $author$project$Backend$Completion$Model$PrenatalMalariaTestResult = {$: 'PrenatalMalariaTestResult'}; +var $author$project$Backend$Completion$Model$PrenatalMedicalHistory = {$: 'PrenatalMedicalHistory'}; +var $author$project$Backend$Completion$Model$PrenatalMedication = {$: 'PrenatalMedication'}; +var $author$project$Backend$Completion$Model$PrenatalMedicationDistribution = {$: 'PrenatalMedicationDistribution'}; +var $author$project$Backend$Completion$Model$PrenatalMentalHealth = {$: 'PrenatalMentalHealth'}; +var $author$project$Backend$Completion$Model$PrenatalNutrition = {$: 'PrenatalNutrition'}; +var $author$project$Backend$Completion$Model$PrenatalObstetricHistory = {$: 'PrenatalObstetricHistory'}; +var $author$project$Backend$Completion$Model$PrenatalObstetricHistoryStep2 = {$: 'PrenatalObstetricHistoryStep2'}; +var $author$project$Backend$Completion$Model$PrenatalObstetricalExam = {$: 'PrenatalObstetricalExam'}; +var $author$project$Backend$Completion$Model$PrenatalOutsideCare = {$: 'PrenatalOutsideCare'}; +var $author$project$Backend$Completion$Model$PrenatalPartnerHIVTest = {$: 'PrenatalPartnerHIVTest'}; +var $author$project$Backend$Completion$Model$PrenatalPartnerHIVTestResult = {$: 'PrenatalPartnerHIVTestResult'}; +var $author$project$Backend$Completion$Model$PrenatalPhoto = {$: 'PrenatalPhoto'}; +var $author$project$Backend$Completion$Model$PrenatalPostpartumTreatmentReview = {$: 'PrenatalPostpartumTreatmentReview'}; +var $author$project$Backend$Completion$Model$PrenatalPregnancyOutcome = {$: 'PrenatalPregnancyOutcome'}; +var $author$project$Backend$Completion$Model$PrenatalPregnancyTesting = {$: 'PrenatalPregnancyTesting'}; +var $author$project$Backend$Completion$Model$PrenatalRandomBloodSugarTest = {$: 'PrenatalRandomBloodSugarTest'}; +var $author$project$Backend$Completion$Model$PrenatalRandomBloodSugarTestResult = {$: 'PrenatalRandomBloodSugarTestResult'}; +var $author$project$Backend$Completion$Model$PrenatalResource = {$: 'PrenatalResource'}; +var $author$project$Backend$Completion$Model$PrenatalSendToHC = {$: 'PrenatalSendToHC'}; +var $author$project$Backend$Completion$Model$PrenatalSocialHistory = {$: 'PrenatalSocialHistory'}; +var $author$project$Backend$Completion$Model$PrenatalSpecialityCare = {$: 'PrenatalSpecialityCare'}; +var $author$project$Backend$Completion$Model$PrenatalSymptomReview = {$: 'PrenatalSymptomReview'}; +var $author$project$Backend$Completion$Model$PrenatalSyphilisTest = {$: 'PrenatalSyphilisTest'}; +var $author$project$Backend$Completion$Model$PrenatalSyphilisTestResult = {$: 'PrenatalSyphilisTestResult'}; +var $author$project$Backend$Completion$Model$PrenatalTetanusImmunisation = {$: 'PrenatalTetanusImmunisation'}; +var $author$project$Backend$Completion$Model$PrenatalTreatmentReview = {$: 'PrenatalTreatmentReview'}; +var $author$project$Backend$Completion$Model$PrenatalUrineDipstickTest = {$: 'PrenatalUrineDipstickTest'}; +var $author$project$Backend$Completion$Model$PrenatalUrineDipstickTestResult = {$: 'PrenatalUrineDipstickTestResult'}; +var $author$project$Backend$Completion$Model$PrenatalVitals = {$: 'PrenatalVitals'}; +var $author$project$Backend$Completion$Model$PrenatalVitalsRecheck = {$: 'PrenatalVitalsRecheck'}; +var $author$project$Backend$Completion$Utils$prenatalActivityFromMapping = function (mapped) { + switch (mapped) { + case 'a': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalAppointmentConfirmation); + case 'b': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalBirthPlan); + case 'c': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalBreastExam); + case 'd': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalCorePhysicalExam); + case 'e': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalDangerSigns); + case 'f': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalLastMenstrualPeriod); + case 'g': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalMedicalHistory); + case 'h': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalMedication); + case 'i': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalObstetricHistory); + case 'j': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalObstetricHistoryStep2); + case 'k': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalObstetricalExam); + case 'l': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalPregnancyTesting); + case 'm': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalBloodGprsTest); + case 'n': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalBreastfeeding); + case 'o': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalFamilyPlanning); + case 'p': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalFollowUp); + case 'q': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalGuExam); + case 'r': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalHealthEducation); + case 's': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalHemoglobinTest); + case 't': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalHepatitisBTest); + case 'u': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalHIVPCRTest); + case 'v': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalHIVTest); + case 'w': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalMalariaTest); + case 'x': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalMedicationDistribution); + case 'y': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalMentalHealth); + case 'z': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalNutrition); + case '0': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalOutsideCare); + case '1': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalPartnerHIVTest); + case '2': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalPhoto); + case '3': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalRandomBloodSugarTest); + case '4': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalSendToHC); + case '5': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalSpecialityCare); + case '6': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalSymptomReview); + case '7': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalSyphilisTest); + case '8': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalTetanusImmunisation); + case '9': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalUrineDipstickTest); + case '@': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalResource); + case '#': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalSocialHistory); + case '$': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalVitals); + case '^': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalTreatmentReview); + case '&': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalPregnancyOutcome); + case '*': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalPostpartumTreatmentReview); + case '$+': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalVitalsRecheck); + case 'm+': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalBloodGprsTestResult); + case 's+': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalHemoglobinTestResult); + case 't+': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalHepatitisBTestResult); + case 'u+': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalHIVPCRTestResult); + case 'v+': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalHIVTestResult); + case 'w+': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalMalariaTestResult); + case '1+': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalPartnerHIVTestResult); + case '3+': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalRandomBloodSugarTestResult); + case '7+': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalSyphilisTestResult); + case '9+': + return $elm$core$Maybe$Just($author$project$Backend$Completion$Model$PrenatalUrineDipstickTestResult); + default: + return $elm$core$Maybe$Nothing; + } +}; var $elm$json$Json$Decode$at = F2( function (fields, decoder) { return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields); @@ -8372,58 +8542,64 @@ var $author$project$Backend$Completion$Decoder$decodeCompletionData = A3( A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'nutrition_group']), + ['results', 'prenatal']), $elm$json$Json$Decode$list( - A2($author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData, $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping, $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$prenatalActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'nutrition_individual']), + ['results', 'nutrition_group']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), + A2($author$project$Backend$Completion$Decoder$decodeNutritionGroupEncounterData, $author$project$Backend$Completion$Utils$nutritionMotherActivityFromMapping, $author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'ncd']), + ['results', 'nutrition_individual']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$ncdActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$nutritionChildActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'home_visit']), + ['results', 'ncd']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$homeVisitActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$ncdActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'hiv']), + ['results', 'home_visit']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$hivActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$homeVisitActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'child_scoreboard']), + ['results', 'hiv']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$childScoreboardActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$hivActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, _List_fromArray( - ['results', 'acute_illness']), + ['results', 'child_scoreboard']), $elm$json$Json$Decode$list( - $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$childScoreboardActivityFromMapping)), A3( - $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_type', - $author$project$Backend$Completion$Decoder$decodeSelectedEntity, + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$requiredAt, + _List_fromArray( + ['results', 'acute_illness']), + $elm$json$Json$Decode$list( + $author$project$Backend$Completion$Decoder$decodeEncounterData($author$project$Backend$Completion$Utils$acuteIllnessActivityFromMapping)), A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'entity_name', - $elm$json$Json$Decode$string, + 'entity_type', + $author$project$Backend$Completion$Decoder$decodeSelectedEntity, A3( $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, - 'site', - $author$project$Backend$Decoder$decodeSite, - $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData))))))))))))); + 'entity_name', + $elm$json$Json$Decode$string, + A3( + $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required, + 'site', + $author$project$Backend$Decoder$decodeSite, + $elm$json$Json$Decode$succeed($author$project$Backend$Completion$Model$CompletionData)))))))))))))); var $author$project$Backend$Completion$Update$update = F3( function (currentDate, msg, model) { var value = msg.a; @@ -10180,6 +10356,7 @@ var $author$project$Translate$HttpError = function (a) { }; var $elm$json$Json$Decode$decodeString = _Json_runOnString; var $author$project$Translate$AcuteIllness = {$: 'AcuteIllness'}; +var $author$project$Translate$Antenatal = {$: 'Antenatal'}; var $author$project$Translate$Caring = {$: 'Caring'}; var $author$project$Translate$Cell = {$: 'Cell'}; var $author$project$Translate$ChildScorecard = {$: 'ChildScorecard'}; @@ -10218,8 +10395,11 @@ var $author$project$Translate$MedicationDistribution = {$: 'MedicationDistributi var $author$project$Translate$NCD = {$: 'NCD'}; var $author$project$Translate$NCDA = {$: 'NCDA'}; var $author$project$Translate$NewbornExam = {$: 'NewbornExam'}; +var $author$project$Translate$Nutrition = {$: 'Nutrition'}; var $author$project$Translate$NutritionGroup = {$: 'NutritionGroup'}; var $author$project$Translate$NutritionIndividual = {$: 'NutritionIndividual'}; +var $author$project$Translate$OutsideCare = {$: 'OutsideCare'}; +var $author$project$Translate$Photo = {$: 'Photo'}; var $author$project$Translate$PregnancyTest = {$: 'PregnancyTest'}; var $author$project$Translate$PrevalenceByMonthOneVisitOrMore = {$: 'PrevalenceByMonthOneVisitOrMore'}; var $author$project$Translate$PrevalenceByMonthTwoVisitsOrMore = {$: 'PrevalenceByMonthTwoVisitsOrMore'}; @@ -10228,6 +10408,7 @@ var $author$project$Translate$RandomBloodSugarTest = {$: 'RandomBloodSugarTest'} var $author$project$Translate$RandomBloodSugarTestResult = {$: 'RandomBloodSugarTestResult'}; var $author$project$Translate$Referral = {$: 'Referral'}; var $author$project$Translate$Sector = {$: 'Sector'}; +var $author$project$Translate$SocialHistory = {$: 'SocialHistory'}; var $author$project$Translate$StandardPediatricVisit = {$: 'StandardPediatricVisit'}; var $author$project$Translate$SymptomsReview = {$: 'SymptomsReview'}; var $author$project$Translate$TreatmentReview = {$: 'TreatmentReview'}; @@ -10433,7 +10614,9 @@ var $author$project$Translate$translationSet = function (transId) { case 'AcuteIllnessMUAC': return {english: 'MUAC', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AcuteIllnessNutrition': - return {english: 'Nutrition', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Nutrition; + transId = $temp$transId; + continue translationSet; case 'AcuteIllnessVitals': var $temp$transId = $author$project$Translate$Vitals; transId = $temp$transId; @@ -10569,6 +10752,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Acute Malnutrition', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'AggregatedChildScoreboard': return {english: 'Aggregated Child Scoreboard', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Antenatal': + return {english: 'Antenatal', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'All': return {english: 'All', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'ANCNewborn': @@ -10626,6 +10811,10 @@ var $author$project$Translate$translationSet = function (transId) { var $temp$transId = $author$project$Translate$NutritionIndividual; transId = $temp$transId; continue translationSet; + case 'ReportPrenatal': + var $temp$transId = $author$project$Translate$Antenatal; + transId = $temp$transId; + continue translationSet; case 'ReportTuberculosis': var $temp$transId = $author$project$Translate$Tuberculosis; transId = $temp$transId; @@ -10894,7 +11083,9 @@ var $author$project$Translate$translationSet = function (transId) { case 'NCDMedicationHistory': return {english: 'Medication History', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NCDOutsideCare': - return {english: 'Outside Care', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$OutsideCare; + transId = $temp$transId; + continue translationSet; case 'NCDPregnancyTest': var $temp$transId = $author$project$Translate$PregnancyTest; transId = $temp$transId; @@ -10908,7 +11099,9 @@ var $author$project$Translate$translationSet = function (transId) { transId = $temp$transId; continue translationSet; case 'NCDSocialHistory': - return {english: 'Social History', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$SocialHistory; + transId = $temp$transId; + continue translationSet; case 'NCDSymptomReview': var $temp$transId = $author$project$Translate$SymptomsReview; transId = $temp$transId; @@ -11128,15 +11321,21 @@ var $author$project$Translate$translationSet = function (transId) { }); case 'NumberOfVisitsLabel': return {english: '# Visits', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Nutrition': + return {english: 'Nutrition', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NutritionChildActivity': var activity = transId.a; switch (activity.$) { case 'NutritionHeight': return {english: 'Height', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NutritionNutrition': - return {english: 'Nutrition', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Nutrition; + transId = $temp$transId; + continue translationSet; case 'NutritionPhoto': - return {english: 'Photo', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Photo; + transId = $temp$transId; + continue translationSet; case 'NutritionWeight': return {english: 'Weight', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'NutritionMUAC': @@ -11216,6 +11415,10 @@ var $author$project$Translate$translationSet = function (transId) { } case 'NutritionTotal': return {english: 'Nutrition (total)', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'OutsideCare': + return {english: 'Outside Care', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'Photo': + return {english: 'Photo', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'PleaseWaitMessage': return {english: 'This action may take several minutes to complete.', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'PMTCT': @@ -11238,6 +11441,154 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Completed Pregnancies', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'PregnancyTest': return {english: 'Pregnancy Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalActivity': + var activity = transId.a; + switch (activity.$) { + case 'PrenatalAppointmentConfirmation': + return {english: 'Appointment Confirmation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalBirthPlan': + return {english: 'Birth Plan', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalBloodGprsTest': + return {english: 'Blood Group and Rhesus Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalBloodGprsTestResult': + return {english: 'Blood Group and Rhesus Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalBreastExam': + return {english: 'Breast Exam', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalBreastfeeding': + return {english: 'Breastfeeding', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalCorePhysicalExam': + return {english: 'Core Physical Exam', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalDangerSigns': + var $temp$transId = $author$project$Translate$DangerSigns; + transId = $temp$transId; + continue translationSet; + case 'PrenatalFamilyPlanning': + var $temp$transId = $author$project$Translate$FamilyPlanning; + transId = $temp$transId; + continue translationSet; + case 'PrenatalFollowUp': + var $temp$transId = $author$project$Translate$FollowUp; + transId = $temp$transId; + continue translationSet; + case 'PrenatalGuExam': + return {english: 'GU Exam', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalHealthEducation': + var $temp$transId = $author$project$Translate$HealthEducation; + transId = $temp$transId; + continue translationSet; + case 'PrenatalHemoglobinTest': + return {english: 'Hemoglobin Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalHemoglobinTestResult': + return {english: 'Hemoglobin Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalHepatitisBTest': + return {english: 'Hepatitis B Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalHepatitisBTestResult': + return {english: 'Hepatitis B Result Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalHIVPCRTest': + return {english: 'HIV PCR Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalHIVPCRTestResult': + return {english: 'HIV PCR Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalHIVTest': + var $temp$transId = $author$project$Translate$HIVTest; + transId = $temp$transId; + continue translationSet; + case 'PrenatalHIVTestResult': + return {english: 'HIV Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalLastMenstrualPeriod': + return {english: 'Last Menstrual Period', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalMalariaTest': + return {english: 'Malaria Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalMalariaTestResult': + return {english: 'Malaria Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalMedicalHistory': + return {english: 'Medical History', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalMedication': + var $temp$transId = $author$project$Translate$Medication; + transId = $temp$transId; + continue translationSet; + case 'PrenatalMedicationDistribution': + var $temp$transId = $author$project$Translate$MedicationDistribution; + transId = $temp$transId; + continue translationSet; + case 'PrenatalMentalHealth': + return {english: 'Mental Health', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalNutrition': + var $temp$transId = $author$project$Translate$Nutrition; + transId = $temp$transId; + continue translationSet; + case 'PrenatalObstetricalExam': + return {english: 'Obstetrical Exam', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalObstetricHistory': + return {english: 'Obstetric History', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalObstetricHistoryStep2': + return {english: 'Obstetric History Second Step', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalOutsideCare': + var $temp$transId = $author$project$Translate$OutsideCare; + transId = $temp$transId; + continue translationSet; + case 'PrenatalPartnerHIVTest': + return {english: 'Partner HIV Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalPartnerHIVTestResult': + return {english: 'Partner HIV Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalPhoto': + var $temp$transId = $author$project$Translate$Photo; + transId = $temp$transId; + continue translationSet; + case 'PrenatalPostpartumTreatmentReview': + return {english: 'Postpartum Treatment Review', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalPregnancyOutcome': + return {english: 'Pregnancy Outcome', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalPregnancyTesting': + return {english: 'Pregnancy Testing', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalRandomBloodSugarTest': + var $temp$transId = $author$project$Translate$RandomBloodSugarTest; + transId = $temp$transId; + continue translationSet; + case 'PrenatalRandomBloodSugarTestResult': + var $temp$transId = $author$project$Translate$RandomBloodSugarTestResult; + transId = $temp$transId; + continue translationSet; + case 'PrenatalResource': + return {english: 'Resource', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalSendToHC': + var $temp$transId = $author$project$Translate$Referral; + transId = $temp$transId; + continue translationSet; + case 'PrenatalSocialHistory': + var $temp$transId = $author$project$Translate$SocialHistory; + transId = $temp$transId; + continue translationSet; + case 'PrenatalSpecialityCare': + return {english: 'Speciality Care', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalSymptomReview': + var $temp$transId = $author$project$Translate$SymptomsReview; + transId = $temp$transId; + continue translationSet; + case 'PrenatalSyphilisTest': + return {english: 'Syphilis Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalSyphilisTestResult': + return {english: 'Syphilis Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalTetanusImmunisation': + return {english: 'Tetanus Immunisation', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'PrenatalTreatmentReview': + var $temp$transId = $author$project$Translate$TreatmentReview; + transId = $temp$transId; + continue translationSet; + case 'PrenatalUrineDipstickTest': + var $temp$transId = $author$project$Translate$UrineDipstickTest; + transId = $temp$transId; + continue translationSet; + case 'PrenatalUrineDipstickTestResult': + var $temp$transId = $author$project$Translate$UrineDipstickTestResult; + transId = $temp$transId; + continue translationSet; + case 'PrenatalVitals': + var $temp$transId = $author$project$Translate$Vitals; + transId = $temp$transId; + continue translationSet; + default: + return {english: 'Vitals Recheck', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + } case 'PrevalenceByMonthOneVisitOrMore': return {english: 'Prevalence by month - one visit or more', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'PrevalenceByMonthTwoVisitsOrMore': @@ -11272,9 +11623,13 @@ var $author$project$Translate$translationSet = function (transId) { case 'ReportDemographics': return {english: 'Demographics', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'ReportNutrition': - return {english: 'Nutrition', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Nutrition; + transId = $temp$transId; + continue translationSet; default: - return {english: 'Antenatal', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Antenatal; + transId = $temp$transId; + continue translationSet; } case 'ReportTypeLabel': return {english: 'Report Type', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; @@ -11354,6 +11709,8 @@ var $author$project$Translate$translationSet = function (transId) { return {english: 'Please select desired scope', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'SelectViewMode': return {english: 'Please select desired view mode', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + case 'SocialHistory': + return {english: 'Social History', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Sorwathe': return {english: 'Sorwathe', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'StandardPediatricVisit': @@ -11516,7 +11873,9 @@ var $author$project$Translate$translationSet = function (transId) { case 'WellChildNextVisit': return {english: 'Next Visit', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildNutrition': - return {english: 'Nutrition', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Nutrition; + transId = $temp$transId; + continue translationSet; case 'WellChildOPVImmunisation': var $temp$transId = $author$project$Translate$ImmunisationOPV; transId = $temp$transId; @@ -11526,7 +11885,9 @@ var $author$project$Translate$translationSet = function (transId) { transId = $temp$transId; continue translationSet; case 'WellChildPhoto': - return {english: 'Photo', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + var $temp$transId = $author$project$Translate$Photo; + transId = $temp$transId; + continue translationSet; case 'WellChildPregnancySummary': return {english: 'Pregnancy Summary', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WellChildRotarixImmunisation': @@ -12459,6 +12820,8 @@ var $author$project$Pages$Completion$Utils$reportTypeToString = function (report return 'nutrition-group'; case 'ReportNutritionIndividual': return 'nutrition-individual'; + case 'ReportPrenatal': + return 'prenatal'; case 'ReportTuberculosis': return 'tuberculosis'; default: @@ -14477,6 +14840,76 @@ var $author$project$Pages$Completion$View$viewNutritionIndividualReport = F5( mTakenBy, $author$project$Pages$Completion$View$eliminateEmptyEncounters(reportData))))); }); +var $author$project$Translate$PrenatalActivity = function (a) { + return {$: 'PrenatalActivity', a: a}; +}; +var $author$project$Pages$Completion$Utils$allPrenatalActivities = _List_fromArray( + [$author$project$Backend$Completion$Model$PrenatalAppointmentConfirmation, $author$project$Backend$Completion$Model$PrenatalBirthPlan, $author$project$Backend$Completion$Model$PrenatalBloodGprsTest, $author$project$Backend$Completion$Model$PrenatalBloodGprsTestResult, $author$project$Backend$Completion$Model$PrenatalBreastExam, $author$project$Backend$Completion$Model$PrenatalBreastfeeding, $author$project$Backend$Completion$Model$PrenatalCorePhysicalExam, $author$project$Backend$Completion$Model$PrenatalDangerSigns, $author$project$Backend$Completion$Model$PrenatalFamilyPlanning, $author$project$Backend$Completion$Model$PrenatalFollowUp, $author$project$Backend$Completion$Model$PrenatalGuExam, $author$project$Backend$Completion$Model$PrenatalHealthEducation, $author$project$Backend$Completion$Model$PrenatalHemoglobinTest, $author$project$Backend$Completion$Model$PrenatalHemoglobinTestResult, $author$project$Backend$Completion$Model$PrenatalHepatitisBTest, $author$project$Backend$Completion$Model$PrenatalHepatitisBTestResult, $author$project$Backend$Completion$Model$PrenatalHIVPCRTest, $author$project$Backend$Completion$Model$PrenatalHIVPCRTestResult, $author$project$Backend$Completion$Model$PrenatalHIVTest, $author$project$Backend$Completion$Model$PrenatalHIVTestResult, $author$project$Backend$Completion$Model$PrenatalLastMenstrualPeriod, $author$project$Backend$Completion$Model$PrenatalMalariaTest, $author$project$Backend$Completion$Model$PrenatalMalariaTestResult, $author$project$Backend$Completion$Model$PrenatalMedicalHistory, $author$project$Backend$Completion$Model$PrenatalMedication, $author$project$Backend$Completion$Model$PrenatalMedicationDistribution, $author$project$Backend$Completion$Model$PrenatalMentalHealth, $author$project$Backend$Completion$Model$PrenatalNutrition, $author$project$Backend$Completion$Model$PrenatalObstetricalExam, $author$project$Backend$Completion$Model$PrenatalObstetricHistory, $author$project$Backend$Completion$Model$PrenatalObstetricHistoryStep2, $author$project$Backend$Completion$Model$PrenatalOutsideCare, $author$project$Backend$Completion$Model$PrenatalPartnerHIVTest, $author$project$Backend$Completion$Model$PrenatalPartnerHIVTestResult, $author$project$Backend$Completion$Model$PrenatalPhoto, $author$project$Backend$Completion$Model$PrenatalPostpartumTreatmentReview, $author$project$Backend$Completion$Model$PrenatalPregnancyOutcome, $author$project$Backend$Completion$Model$PrenatalPregnancyTesting, $author$project$Backend$Completion$Model$PrenatalRandomBloodSugarTest, $author$project$Backend$Completion$Model$PrenatalRandomBloodSugarTestResult, $author$project$Backend$Completion$Model$PrenatalResource, $author$project$Backend$Completion$Model$PrenatalSendToHC, $author$project$Backend$Completion$Model$PrenatalSocialHistory, $author$project$Backend$Completion$Model$PrenatalSpecialityCare, $author$project$Backend$Completion$Model$PrenatalSymptomReview, $author$project$Backend$Completion$Model$PrenatalSyphilisTest, $author$project$Backend$Completion$Model$PrenatalSyphilisTestResult, $author$project$Backend$Completion$Model$PrenatalTetanusImmunisation, $author$project$Backend$Completion$Model$PrenatalTreatmentReview, $author$project$Backend$Completion$Model$PrenatalUrineDipstickTest, $author$project$Backend$Completion$Model$PrenatalUrineDipstickTestResult, $author$project$Backend$Completion$Model$PrenatalVitals, $author$project$Backend$Completion$Model$PrenatalVitalsRecheck]); +var $author$project$Pages$Completion$View$generatePrenatalReportData = F2( + function (language, records) { + return { + captions: $author$project$Pages$Completion$View$generateCaptionsList(language), + heading: A2($author$project$Translate$translate, language, $author$project$Translate$Antenatal), + rows: A2( + $elm$core$List$map, + function (activity) { + var expected = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.expectedActivities; + }), + activity, + records); + var completed = A3( + $author$project$Pages$Completion$View$countOccurrences, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.completion; + }, + function ($) { + return $.completedActivities; + }), + activity, + records); + return _List_fromArray( + [ + A2( + $author$project$Translate$translate, + language, + $author$project$Translate$PrenatalActivity(activity)), + $elm$core$String$fromInt(expected), + $elm$core$String$fromInt(completed), + A2($author$project$Pages$Completion$View$calcualtePercentage, completed, expected) + ]); + }, + $author$project$Pages$Completion$Utils$allPrenatalActivities) + }; + }); +var $author$project$Pages$Completion$View$viewPrenatalReport = F5( + function (language, startDate, limitDate, mTakenBy, reportData) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('report prenatal') + ]), + $author$project$Pages$Components$View$viewMetricsResultsTable( + A2( + $author$project$Pages$Completion$View$generatePrenatalReportData, + language, + A4( + $author$project$Pages$Completion$View$applyFilters, + startDate, + limitDate, + mTakenBy, + $author$project$Pages$Completion$View$eliminateEmptyEncounters(reportData))))); + }); var $author$project$Pages$Completion$Utils$resolveSPVActivities = function (site) { return _Utils_ap( _List_fromArray( @@ -14859,6 +15292,8 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( return A5($author$project$Pages$Completion$View$viewNutritionGroupReport, language, startDate, limitDate, model.takenBy, data.nutritionGroupData); case 'ReportNutritionIndividual': return A5($author$project$Pages$Completion$View$viewNutritionIndividualReport, language, startDate, limitDate, model.takenBy, data.nutritionIndividualData); + case 'ReportPrenatal': + return A5($author$project$Pages$Completion$View$viewPrenatalReport, language, startDate, limitDate, model.takenBy, data.prenatalData); case 'ReportTuberculosis': return A5($author$project$Pages$Completion$View$viewTuberculosisReport, language, startDate, limitDate, model.takenBy, data.tuberculosisData); default: From 82b0462ebcdc7be6a44ebe1146019bf0ed02efd4 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 5 Nov 2024 19:30:51 +0200 Subject: [PATCH 165/185] Fixes [ci skip] --- .../custom/hedley_reports/hedley_reports.module | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 2cc804f026..7c9c38e43f 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5844,14 +5844,14 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc if (empty($lmp_measurement) || empty($lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE])) { continue; } - $lmp_date = explode(' ', $lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE][0]['value']); + $lmp_date = explode(' ', $lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE][0]['value'])[0]; break; } // No value found at previous nurse encounters - check current encounter. if (empty($lmp_date)) { $lmp_measurement = $measurements_by_type['last_menstrual_period']; if (!empty($lmp_measurement) && !empty($lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE])) { - $lmp_date = explode(' ', $lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE][0]['value']); + $lmp_date = explode(' ', $lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE][0]['value'])[0]; } } // No value found at current encounter - check previous CHW encounters. @@ -5861,7 +5861,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc if (empty($lmp_measurement) || empty($lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE])) { continue; } - $lmp_date = explode(' ', $lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE][0]['value']); + $lmp_date = explode(' ', $lmp_measurement->field_last_menstrual_period[LANGUAGE_NONE][0]['value'])[0]; break; } } @@ -6025,6 +6025,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc $completion_data = [ 'start_date' => $start_date, + 'taken_by' => in_array($encounter_type, ['nurse', 'nurse-postpartum']) ? 'nurse' : 'chw', 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), ]; @@ -7502,6 +7503,10 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat ]; foreach ($treatments as $treatment_signs) { + if (empty($treatment_signs)) { + continue; + } + foreach ($treatment_signs as $sign) { if ($sign['value'] == 'adverse-events-hospitalization') { $referred_to_hospital = TRUE; @@ -7860,7 +7865,7 @@ function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, Dat } function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral() { - array_merge( + return array_merge( hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase(), hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_recurrent_phase() ); From eb1683c3d5960b276f00219cfb351fe11ac91163 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 6 Nov 2024 00:43:12 +0200 Subject: [PATCH 166/185] Another fix [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 7c9c38e43f..665f706146 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -8365,6 +8365,10 @@ function hedley_reports_ends_with($haystack, $needle) { * string if the prefix or suffix is not found. */ function hedley_reports_drop_prefix_and_suffix(string $string, string $pref, string $suff) { + if (empty($pref) && empty($suff)) { + return $string; + } + if (strpos($string, $pref) !== 0 || substr($string, -strlen($suff)) !== $suff) { return $string; } From 55449ab51467102bdfa5d2d439cb72e8e969ce7a Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 6 Nov 2024 12:53:48 +0200 Subject: [PATCH 167/185] Style [ci skip] --- server/elm/src/Pages/Completion/View.elm | 3 ++- server/hedley/modules/custom/hedley_general/css/elm.css | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server/elm/src/Pages/Completion/View.elm b/server/elm/src/Pages/Completion/View.elm index 93862c3279..3262999993 100644 --- a/server/elm/src/Pages/Completion/View.elm +++ b/server/elm/src/Pages/Completion/View.elm @@ -248,6 +248,7 @@ viewCompletionData language currentDate themePath data model = [ viewSelectListInput language model.reportType [ ReportAcuteIllness + , ReportPrenatal , ReportChildScoreboard , ReportHIV , ReportHomeVisit @@ -255,8 +256,8 @@ viewCompletionData language currentDate themePath data model = , ReportNewbornExam , ReportNutritionGroup , ReportNutritionIndividual - , ReportTuberculosis , ReportWellChild + , ReportTuberculosis ] reportTypeToString SetReportType diff --git a/server/hedley/modules/custom/hedley_general/css/elm.css b/server/hedley/modules/custom/hedley_general/css/elm.css index 2e6b54c7b3..fdd67b9557 100644 --- a/server/hedley/modules/custom/hedley_general/css/elm.css +++ b/server/hedley/modules/custom/hedley_general/css/elm.css @@ -328,6 +328,7 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report .table { border: 2px solid #3b3b3b; + display: block; margin-bottom: 20px; padding: 15px; } @@ -401,6 +402,7 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.ncd .table .row .item.row-label, .page-content .inputs .report.nutrition-group .table .row .item.row-label, .page-content .inputs .report.nutrition-individual .table .row .item.row-label, +.page-content .inputs .report.prenatal .table .row .item.row-label, .page-content .inputs .report.tuberculosis .table .row .item.row-label, .page-content .inputs .report.well-child .table .row .item.row-label { width: 30%; @@ -420,6 +422,8 @@ body.admin-menu #page-wrapper #header { .page-content .inputs .report.nutrition-group .table .row .item.value, .page-content .inputs .report.nutrition-individual .table .row .item.heading, .page-content .inputs .report.nutrition-individual .table .row .item.value, +.page-content .inputs .report.prenatal .table .row .item.heading, +.page-content .inputs .report.prenatal .table .row .item.value, .page-content .inputs .report.tuberculosis .table .row .item.heading, .page-content .inputs .report.tuberculosis .table .row .item.value, .page-content .inputs .report.well-child .table .row .item.heading, From a1916197d49279e7468d64415486c637ba537cd3 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 6 Nov 2024 14:03:04 +0200 Subject: [PATCH 168/185] Drop unneeded code [ci skip] --- .../custom/hedley_general/js/elm-main.js | 2 +- .../hedley_reports/hedley_reports.module | 35 ------------------- 2 files changed, 1 insertion(+), 36 deletions(-) diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 4de59fe7d7..51e7fec4ee 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -15331,7 +15331,7 @@ var $author$project$Pages$Completion$View$viewCompletionData = F5( language, model.reportType, _List_fromArray( - [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHIV, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNCD, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportTuberculosis, $author$project$Pages$Completion$Model$ReportWellChild]), + [$author$project$Pages$Completion$Model$ReportAcuteIllness, $author$project$Pages$Completion$Model$ReportPrenatal, $author$project$Pages$Completion$Model$ReportChildScoreboard, $author$project$Pages$Completion$Model$ReportHIV, $author$project$Pages$Completion$Model$ReportHomeVisit, $author$project$Pages$Completion$Model$ReportNCD, $author$project$Pages$Completion$Model$ReportNewbornExam, $author$project$Pages$Completion$Model$ReportNutritionGroup, $author$project$Pages$Completion$Model$ReportNutritionIndividual, $author$project$Pages$Completion$Model$ReportWellChild, $author$project$Pages$Completion$Model$ReportTuberculosis]), $author$project$Pages$Completion$Utils$reportTypeToString, $author$project$Pages$Completion$Model$SetReportType, $author$project$Translate$CompletionReportType, diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 665f706146..10b7df47ac 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -8080,41 +8080,6 @@ function hedley_reports_prenatal_get_latest_treatment_from_options(array $encoun return FALSE; } -// @todo : is this needed? -function hedley_reports_prenatal_referred_to_hiv_program_previously(array $encounter_data) { - $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; - foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { - $encounter = $previous_nurse_encounter_data['encounter']; - if (empty($encounter->field_prenatal_diagnoses) || empty($encounter->field_prenatal_diagnoses[LANGUAGE_NONE])) { - continue; - } - - $diagnoses = []; - foreach ($encounter->field_prenatal_diagnoses[LANGUAGE_NONE] as $diagnosis) { - if ($diagnosis != 'none') { - $diagnoses[] = $diagnosis; - } - } - - if (empty(array_intersect($diagnoses, ['hiv', 'hiv-recurrent']))) { - continue; - } - - $hiv_test_measurement = $previous_nurse_encounter_data['measurements_by_type']['prenatal_hiv_test']; - if (empty($hiv_test_measurement) || (empty($hiv_test_measurement->field_hiv_signs)) || (empty($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE]))) { - continue; - } - - foreach ($hiv_test_measurement->field_hiv_signs[LANGUAGE_NONE] as $sign) { - if ($sign['value'] == 'hiv-program-hc') { - return TRUE; - } - } - } - - return FALSE; -} - /** * Checks if a lab test was performed based on the test execution note. * From 6f8ec7bdbc29bafb9d2e234939f1ea3f4d287198 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 6 Nov 2024 15:54:02 +0200 Subject: [PATCH 169/185] Fix Obstetric History [ci skip] --- .../hedley/modules/custom/hedley_reports/hedley_reports.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 10b7df47ac..711d1d1ae6 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6144,7 +6144,7 @@ function hedley_reports_prenatal_generate_expected_initial_activities($encounter */ function hedley_reports_prenatal_add_history_activities(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; - if ($encounter_type == 'nurse') { + if ($encounter_type != 'nurse') { return; } From b0453c1e8842f71287248ac478adfcbcb93a2a05 Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 6 Nov 2024 20:16:14 +0200 Subject: [PATCH 170/185] Fix Syphilis Test Result [ci skip] --- .../custom/hedley_reports/hedley_reports.module | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 711d1d1ae6..2db51262f1 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5960,7 +5960,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc break; case 'syphilis': - $$measurements_by_type['prenatal_syphilis_test_result'] = 'dummy'; + $measurements_by_type['prenatal_syphilis_test_result'] = 'dummy'; break; case 'hepatitis-b': @@ -8280,12 +8280,12 @@ function hedley_reports_generate_completion_result(array $expected, array $measu } } - foreach ($expected as $index => $measurement_type) { - $expected[$index] = $mapping[$measurement_type]; + foreach ($expected as $key => $measurement_type) { + $expected[$key] = $mapping[$measurement_type]; } - foreach ($completed as $index => $measurement_type) { - $completed[$index] = $mapping[$measurement_type]; + foreach ($completed as $key => $measurement_type) { + $completed[$key] = $mapping[$measurement_type]; } return implode(',', $expected) . '|' . implode(',', $completed); From 90aabf23530c748e38aa927569cd76e6866e0adb Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 7 Nov 2024 09:51:07 +0200 Subject: [PATCH 171/185] More fixes [ci skip] --- .../hedley_reports/hedley_reports.module | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 2db51262f1..7e423956f7 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5913,7 +5913,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc break; case 'malaria': - $expected[] = 'prenatal_malaria_test_resul'; + $expected[] = 'prenatal_malaria_test_result'; break; case 'syphilis': @@ -5932,6 +5932,10 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc $expected[] = 'prenatal_hemoglobin_test_result'; break; + case 'random-blood-sugar': + $expected[] = 'prenatal_random_blood_sugar_test_result'; + break; + case 'hiv-pcr': $expected[] = 'prenatal_hiv_pcr_test_result'; break; @@ -5956,7 +5960,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc break; case 'malaria': - $measurements_by_type['prenatal_malaria_test_resul'] = 'dummy'; + $measurements_by_type['prenatal_malaria_test_result'] = 'dummy'; break; case 'syphilis': @@ -5975,6 +5979,10 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc $measurements_by_type['prenatal_hemoglobin_test_result'] = 'dummy'; break; + case 'random-blood-sugar': + $measurements_by_type['prenatal_random_blood_sugar_test_result'] = 'dummy'; + break; + case 'hiv-pcr': $measurements_by_type['prenatal_hiv_pcr_test_result'] = 'dummy'; break; @@ -5993,20 +6001,20 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // Logic to determine if virtual activities are completed. // Treatment Review data is saved into Medication CT. - if (!empty($expected['treatment_review'])) { + if (in_array('treatment_review', $expected)) { if (!empty($measurements_by_type['medication'])) { $measurements_by_type['treatment_review'] = 'dummy'; } } // Postpartum treatment data is similar to Treatment Review, // but at postpartum encounter. - if (!empty($expected['postpartum_treatment_review'])) { + if (in_array('postpartum_treatment_review', $expected)) { if (!empty($measurements_by_type['medication'])) { $measurements_by_type['postpartum_treatment_review'] = 'dummy'; } } // Pregnancy Outcome data is stored on participant node. - if (!empty($expected['pregnancy_outcome'])) { + if (in_array('pregnancy_outcome', $expected)) { $outcome = $participant->field_outcome[LANGUAGE_NONE][0]['value']; if (!empty($outcome)) { $measurements_by_type['pregnancy_outcome'] = 'dummy'; @@ -6014,7 +6022,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc } // Blood pressure re-check is done if dia_repeated and // sys_repeated fields are set on vitals measurement. - if (!empty($expected['vitals_recheck'])) { + if (in_array('vitals_recheck', $expected)) { $vitals_measurement = $encounter_data['measurements_by_type']['vitals']; $sys_repeated = $vitals_measurement->field_sys_repeated[LANGUAGE_NONE][0]['value']; $dia_repeated = $vitals_measurement->field_dia_repeated[LANGUAGE_NONE][0]['value']; From 255993750cd0fbe13abc56c5e504395081ed8f89 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 7 Nov 2024 13:12:07 +0200 Subject: [PATCH 172/185] Yet more fixes [ci skip] --- server/elm/src/Translate.elm | 4 ++-- server/hedley/modules/custom/hedley_general/js/elm-main.js | 4 ++-- .../modules/custom/hedley_reports/hedley_reports.module | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index f0e2eff874..b1ec71d01b 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -1621,13 +1621,13 @@ translationSet transId = } PrenatalHepatitisBTest -> - { english = "Hepatitis B Result" + { english = "Hepatitis B Test" , kinyarwanda = Nothing , kirundi = Nothing } PrenatalHepatitisBTestResult -> - { english = "Hepatitis B Result Result" + { english = "Hepatitis B Test Result" , kinyarwanda = Nothing , kirundi = Nothing } diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 51e7fec4ee..676a00a509 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -11481,9 +11481,9 @@ var $author$project$Translate$translationSet = function (transId) { case 'PrenatalHemoglobinTestResult': return {english: 'Hemoglobin Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'PrenatalHepatitisBTest': - return {english: 'Hepatitis B Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Hepatitis B Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'PrenatalHepatitisBTestResult': - return {english: 'Hepatitis B Result Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Hepatitis B Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'PrenatalHIVPCRTest': return {english: 'HIV PCR Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'PrenatalHIVPCRTestResult': diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 7e423956f7..3bf4ee257a 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6434,6 +6434,7 @@ function hedley_reports_prenatal_add_labs_activities(array $encounter_data, arra 'prenatal_syphilis_test' => [], 'prenatal_hiv_test' => [], 'prenatal_partner_hiv_test' => [], + 'prenatal_hiv_pcr_test' => [], ]; $tests_with_results_field = [ @@ -6701,7 +6702,7 @@ function hedley_reports_prenatal_add_vitals_reckeck_activity(array $encounter_da return; } - if (($sys <= 140 && $sys < 160) || ($dia >= 90 && $dia < 110)) { + if (($sys >= 140 && $sys < 160) || ($dia >= 90 && $dia < 110)) { $expected[] = 'vitals_recheck'; } } @@ -6736,7 +6737,7 @@ function hedley_reports_prenatal_add_postpartum_unique_nurse_activities(array $e $diagnoses = []; foreach ($encounter->field_prenatal_diagnoses[LANGUAGE_NONE] as $diagnosis) { - if ($diagnosis != 'none') { + if ($diagnosis['value'] != 'none') { $diagnoses[] = $diagnosis; } } @@ -8078,7 +8079,7 @@ function hedley_reports_prenatal_get_latest_treatment_from_options(array $encoun } foreach ($medication_distribution_measurement->field_recommended_treatment[LANGUAGE_NONE] as $treatment) { - if (in_array($treatment, $treatment_options)) { + if (in_array($treatment['value'], $treatment_options)) { return $treatment; } } From 858c31017fbf21d3d7d9db23abadcf5a58754e69 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 7 Nov 2024 21:52:09 +0200 Subject: [PATCH 173/185] Fixes for Next steps activities [ci skip] --- .../hedley_reports/hedley_reports.module | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 3bf4ee257a..323a1cf05b 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -7737,6 +7737,8 @@ function hedley_reports_prenatal_add_next_steps_activities_for_chw(array $encoun function hedley_reports_prenatal_manadatory_activities_for_next_steps_completed(array $encounter_data, array $expected) { $encounter_type = $encounter_data['encounter_type']; + $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; + switch ($encounter_type) { case 'nurse': $emergency_diagnoses = hedley_reports_prenatal_emergency_diagnoses(); @@ -7762,7 +7764,6 @@ function hedley_reports_prenatal_manadatory_activities_for_next_steps_completed( 'core_physical_exam', 'breast_exam', 'obstetrical_exam', - 'prenatal_gu_exam', // Laboratory: 'prenatal_malaria_test', 'prenatal_urine_dipstick_test', @@ -7775,7 +7776,6 @@ function hedley_reports_prenatal_manadatory_activities_for_next_steps_completed( 'prenatal_random_blood_sugar_test', 'prenatal_syphilis_test', ]; - $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; if (empty($previous_nurse_encounters_data)) { $mandatory_activities[] = 'last_menstrual_period'; $mandatory_activities[] = 'medication'; @@ -7793,39 +7793,39 @@ function hedley_reports_prenatal_manadatory_activities_for_next_steps_completed( 'prenatal_breastfeeding', 'prenatal_family_planning', 'postpartum_treatment_review', - 'prenatal_speciality_care', // Examination: 'vitals', 'prenatal_nutrition', 'core_physical_exam', 'breast_exam', - 'obstetrical_exam', 'prenatal_gu_exam', ]; break; case 'chw-1': - $mandatory_activities = [ - 'last_menstrual_period', - 'pregnancy_testing', - 'danger_signs', - 'prenatal_health_education', - ]; + $mandatory_activities = ['danger_signs']; + if (empty($previous_nurse_encounters_data)) { + $mandatory_activities[] = 'last_menstrual_period'; + $mandatory_activities[] = 'pregnancy_testing'; + } + if (hedley_reports_prenatal_danger_signs_recorded($encounter_data)) { + $mandatory_activities[] = 'prenatal_health_education'; + } break; case 'chw-2': - $mandatory_activities = [ - 'danger_signs', - 'birth_plan', - 'prenatal_health_education', - ]; + $mandatory_activities = ['danger_signs']; + if (!hedley_reports_prenatal_danger_signs_recorded($encounter_data)) { + $mandatory_activities[] = 'birth_plan'; + $mandatory_activities[] = 'prenatal_health_education'; + } break; case 'chw-3': - $mandatory_activities = [ - 'danger_signs', - 'prenatal_health_education', - ]; + $mandatory_activities = ['danger_signs']; + if (!hedley_reports_prenatal_danger_signs_recorded($encounter_data)) { + $mandatory_activities[] = 'prenatal_health_education'; + } break; case 'chw-postpartum': From 8ff3bda157f706fb907b7a1ed545a76d5116263b Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 7 Nov 2024 22:03:09 +0200 Subject: [PATCH 174/185] Docs WIP [ci skip] --- .../hedley_reports/hedley_reports.module | 142 +++++++++++++++--- 1 file changed, 122 insertions(+), 20 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 323a1cf05b..95134e94c5 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -7873,6 +7873,32 @@ function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, Dat return floor($total_days / 7); } +function hedley_reports_prenatal_get_latest_treatment_from_options(array $encounter_data, array $treatment_options) { + $previous_nurse_encounters_data = array_reverse($encounter_data['previous_nurse_encounters_data']); + foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { + $medication_distribution_measurement = $previous_nurse_encounter_data['measurements_by_type']['prenatal_medication_distribution']; + if (!empty($medication_distribution_measurement)) { + if (empty($medication_distribution_measurement->field_recommended_treatment) || empty($medication_distribution_measurement->field_recommended_treatment[LANGUAGE_NONE])) { + continue; + } + + foreach ($medication_distribution_measurement->field_recommended_treatment[LANGUAGE_NONE] as $treatment) { + if (in_array($treatment['value'], $treatment_options)) { + return $treatment; + } + } + } + } + + return FALSE; +} + +/** + * Returns a list of prenatal diagnoses requiring immediate hospital referral. + * + * @return array + * The list of diagnoses causing immediate hospital referral. + */ function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral() { return array_merge( hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase(), @@ -7880,6 +7906,12 @@ function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral() ); } +/** + * Returns a list of diagnoses causing immediate hospital referral in the initial phase. + * + * @return array + * The list of initial-phase diagnoses causing immediate hospital referral. + */ function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_initial_phase() { return array_merge( hedley_reports_prenatal_emergency_diagnoses_initial_phase(), @@ -7913,6 +7945,12 @@ function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_i ); } +/** + * Returns a list of diagnoses causing immediate hospital referral in the recurrent phase. + * + * @return array + * The list of recurrent-phase diagnoses causing immediate hospital referral. + */ function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_recurrent_phase() { return array_merge( hedley_reports_prenatal_emergency_diagnoses_recurrent_phase(), @@ -7932,6 +7970,12 @@ function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_r ); } +/** + * Returns an array of all emergency prenatal diagnoses. + * + * @return array + * The list of all prenatal emergency diagnoses. + */ function hedley_reports_prenatal_emergency_diagnoses() { return array_merge( hedley_reports_prenatal_emergency_diagnoses_initial_phase(), @@ -7939,6 +7983,12 @@ function hedley_reports_prenatal_emergency_diagnoses() { ); } +/** + * Returns an array of all emergency prenatal diagnoses in the initial phase. + * + * @return array + * The list of initial-phase prenatal emergency diagnoses. + */ function hedley_reports_prenatal_emergency_diagnoses_initial_phase() { return [ 'moderate-preeclampsia-initial-ega-37+', @@ -7963,6 +8013,12 @@ function hedley_reports_prenatal_emergency_diagnoses_initial_phase() { ]; } +/** + * Returns an array of all emergency prenatal diagnoses in the recurrent phase. + * + * @return array + * The list of recurrent-phase prenatal emergency diagnoses. + */ function hedley_reports_prenatal_emergency_diagnoses_recurrent_phase() { return [ 'moderate-preeclampsia-recurrent-ega-37+', @@ -7971,6 +8027,12 @@ function hedley_reports_prenatal_emergency_diagnoses_recurrent_phase() { ]; } +/** + * Returns an array of hypertension-like diagnoses related to prenatal care. + * + * @return array + * The list of hypertension-like prenatal diagnoses. + */ function hedley_reports_prenatal_hypertensionlike_diagnoses() { $hypertensionlike_daignoses = array_merge( hedley_reports_prenatal_hypertension_diagnoses(), @@ -7981,6 +8043,12 @@ function hedley_reports_prenatal_hypertensionlike_diagnoses() { return $hypertensionlike_daignoses; } +/** + * Returns an array of hypertension-related prenatal diagnoses. + * + * @return array + * The list of hypertension-related prenatal diagnoses. + */ function hedley_reports_prenatal_hypertension_diagnoses() { return [ 'chronic-hypertension-immediate', @@ -7990,6 +8058,12 @@ function hedley_reports_prenatal_hypertension_diagnoses() { ]; } +/** + * Returns an array of preeclampsia-related prenatal diagnoses. + * + * @return array + * The list of preeclampsia-related prenatal diagnoses. + */ function hedley_reports_prenatal_preeclempsia_diagnoses() { return array_merge( hedley_reports_prenatal_moderate_preeclempsia_diagnoses(), @@ -7997,6 +8071,12 @@ function hedley_reports_prenatal_preeclempsia_diagnoses() { ); } +/** + * Returns an array of moderate preeclampsia-related prenatal diagnoses. + * + * @return array + * The list of moderate preeclampsia prenatal diagnoses. + */ function hedley_reports_prenatal_moderate_preeclempsia_diagnoses() { return [ 'moderate-preeclampsia-initial', @@ -8006,6 +8086,12 @@ function hedley_reports_prenatal_moderate_preeclempsia_diagnoses() { ]; } +/** + * Returns an array of severe preeclampsia-related prenatal diagnoses. + * + * @return array + * The list of severe preeclampsia prenatal diagnoses. + */ function hedley_reports_prenatal_severe_preeclempsia_diagnoses() { return [ 'severe-preeclampsia-initial', @@ -8015,6 +8101,12 @@ function hedley_reports_prenatal_severe_preeclempsia_diagnoses() { ]; } +/** + * Returns an array of diabetes-related prenatal diagnoses. + * + * @return array + * The list of diabetes-related prenatal diagnoses. + */ function hedley_reports_prenatal_diabetes_diagnoses() { return [ 'diabetes-initial', @@ -8024,6 +8116,12 @@ function hedley_reports_prenatal_diabetes_diagnoses() { ]; } +/** + * Returns an array of HIV-related prenatal diagnoses. + * + * @return array + * The list of HIV-related prenatal diagnoses. + */ function hedley_reports_prenatal_hiv_diagnoses() { return [ 'hiv', @@ -8033,6 +8131,12 @@ function hedley_reports_prenatal_hiv_diagnoses() { ]; } +/** + * Returns an array of malaria-related prenatal diagnoses. + * + * @return array + * The list of malaria-related prenatal diagnoses. + */ function hedley_reports_prenatal_malaria_diagnoses() { return [ 'malaria', @@ -8044,6 +8148,12 @@ function hedley_reports_prenatal_malaria_diagnoses() { ]; } +/** + * Returns an array of mental health diagnoses requiring treatment during prenatal care. + * + * @return array + * The list of mental health-related prenatal diagnoses. + */ function hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment() { return [ 'depression-possible', @@ -8053,6 +8163,12 @@ function hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment() { ]; } +/** + * Returns an array of syphilis-like diagnoses related to prenatal care. + * + * @return array + * The list of syphilis-like prenatal diagnoses. + */ function hedley_reports_prenatal_syphilislike_diagnoses() { return array_merge( hedley_reports_prenatal_syphilis_diagnoses(), @@ -8060,6 +8176,12 @@ function hedley_reports_prenatal_syphilislike_diagnoses() { ); } +/** + * Returns an array of syphilis-related prenatal diagnoses. + * + * @return array + * The list of syphilis-related prenatal diagnoses. + */ function hedley_reports_prenatal_syphilis_diagnoses() { return [ 'syphilis-initial', @@ -8069,26 +8191,6 @@ function hedley_reports_prenatal_syphilis_diagnoses() { ]; } -function hedley_reports_prenatal_get_latest_treatment_from_options(array $encounter_data, array $treatment_options) { - $previous_nurse_encounters_data = array_reverse($encounter_data['previous_nurse_encounters_data']); - foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { - $medication_distribution_measurement = $previous_nurse_encounter_data['measurements_by_type']['prenatal_medication_distribution']; - if (!empty($medication_distribution_measurement)) { - if (empty($medication_distribution_measurement->field_recommended_treatment) || empty($medication_distribution_measurement->field_recommended_treatment[LANGUAGE_NONE])) { - continue; - } - - foreach ($medication_distribution_measurement->field_recommended_treatment[LANGUAGE_NONE] as $treatment) { - if (in_array($treatment['value'], $treatment_options)) { - return $treatment; - } - } - } - } - - return FALSE; -} - /** * Checks if a lab test was performed based on the test execution note. * From cc30df13ba0a93131bc79cf67ae72d573392ed13 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 7 Nov 2024 22:46:45 +0200 Subject: [PATCH 175/185] More docs [ci skip] --- .../hedley_reports/hedley_reports.module | 165 +++++++++++++++++- 1 file changed, 158 insertions(+), 7 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 95134e94c5..9a4da6cd56 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6597,13 +6597,6 @@ function hedley_reports_prenatal_add_labs_activities(array $encounter_data, arra } } -/** - * Birth plan is presented at second CHW encounter, in case no danger signs are recorded. - * - * @param $encounter_data - * @param $expected - * @return void - */ function hedley_reports_prenatal_add_birth_plan_activity(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; if ($encounter_type != 'chw-2') { @@ -7429,6 +7422,18 @@ function hedley_reports_prenatal_medication_distribution_expected_for_continues_ return FALSE; } +/** + * Determines if a hospital referral is expected based on encounter data. + * + * The function evaluates various encounter measurements and diagnoses to + * identify conditions warranting a hospital referral. + * + * @param array $encounter_data + * The encounter data array containing type, measurements, and diagnoses. + * + * @return bool + * TRUE if hospital referral is expected, FALSE otherwise. + */ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_data) { $encounter_type = $encounter_data['encounter_type']; $triggering_diagnoses = hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral(); @@ -7547,6 +7552,18 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat return $referred_to_hospital; } +/** + * Determines if hospitalization required as hypertension treatment updates. + * + * Evaluates the latest treatment option for hypertension and the current + * blood pressure to determine if a hospital referral is necessary. + * + * @param array $encounter_data + * The encounter data including vital signs and treatment history. + * + * @return bool + * TRUE if hospitalization is needed; FALSE otherwise. + */ function hedley_reports_prenatal_hospitalization_due_to_hypertension_treatment_update(array $encounter_data) { $treatment_options = [ 'methyldopa-2', @@ -7593,6 +7610,18 @@ function hedley_reports_prenatal_hospitalization_due_to_hypertension_treatment_u ); } +/** + * Determines if medication required as hypertension treatment updates. + * + * This function checks the latest hypertension treatment, past diagnoses, and current + * vital signs (blood pressure) to assess whether the treatment needs to be updated. + * + * @param array $encounter_data + * The encounter data array, containing treatment options, diagnoses, and vital signs. + * + * @return bool + * TRUE if the hypertension treatment requires an update with medication. + */ function hedley_reports_prenatal_medication_due_to_hypertension_treatment_update(array $encounter_data) { $treatment_options = [ 'methyldopa-2', @@ -7639,6 +7668,25 @@ function hedley_reports_prenatal_medication_due_to_hypertension_treatment_update ); } +/** + * Resolves how to update hypertension treatment based on systolic and + * diastolic blood pressure levels. + * + * This function assesses systolic and diastolic values and determines the + * appropriate treatment recommendation level. + * + * @param int $sys + * The systolic blood pressure reading. + * @param int $dia + * The diastolic blood pressure reading. + * + * @return int + * Treatment recommendation level: + * - 0: Maintain treatment. + * - 1: Increase by 1 step. + * - 2: Increase by 2 steps. + * - 9: Hospitalization required. + */ function hedley_reports_prenatal_resolve_hypertension_treatment_update_recommendation($sys, $dia) { if ($sys < 140) { // Maintain treatment as is. @@ -7677,6 +7725,22 @@ function hedley_reports_prenatal_resolve_hypertension_treatment_update_recommend return max($by_sys, $by_dia); } +/** + * Checks if any of the specified diagnoses were recorded in previous + * encounters. + * + * This function iterates through previous nurse encounters to determine if + * any specified diagnosis was documented. + * + * @param array $encounter_data + * The encounter data, including previous nurse encounters. + * @param array $diagnoses + * An array of diagnoses to search for in previous encounters. + * + * @return bool + * TRUE if any of the diagnoses were recorded in previous encounters; + * FALSE otherwise. + */ function hedley_reports_prenatal_diagnosed_previously_with_any_of(array $encounter_data, array $diagnoses) { $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; foreach ($previous_nurse_encounters_data as $previous_encounter_data) { @@ -7688,10 +7752,39 @@ function hedley_reports_prenatal_diagnosed_previously_with_any_of(array $encount return FALSE; } +/** + * Checks if any of the specified diagnoses were recorded in current + * encounter. + * + * This function compares the provided diagnoses array with the diagnoses + * recorded in the current encounter. + * + * @param array $encounter_data + * The encounter data, including recorded diagnoses. + * @param array $diagnoses + * An array of diagnoses to search for in the current encounter data. + * + * @return bool + * TRUE if any of the specified diagnoses match; FALSE otherwise. + */ function hedley_reports_prenatal_diagnosed_any_of(array $encounter_data, array $diagnoses) { return !empty(array_intersect($encounter_data['diagnoses'], $diagnoses)); } +/** + * Checks if a specific prenatal symptom was recorded in previous encounters. + * + * This function iterates over previous nurse encounters to determine if a + * specified symptom was recorded in any of them. + * + * @param array $encounter_data + * The encounter data, including previous nurse encounters. + * @param string $symptom_value + * The symptom value to search for in previous encounters. + * + * @return bool + * TRUE if the symptom was recorded previously; FALSE otherwise. + */ function hedley_reports_prenatal_symptom_recorded_previously(array $encounter_data, $symptom_value) { $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; foreach ($previous_nurse_encounters_data as $previous_encounter_data) { @@ -7709,6 +7802,19 @@ function hedley_reports_prenatal_symptom_recorded_previously(array $encounter_da return FALSE; } +/** + * Adds next steps activities for a Community Health Worker (CHW) encounter. + * + * This function determines additional activities for the CHW's next steps + * based on the type of encounter, whether danger signs were recorded, and + * the encounter's start date relative to the launch date. + * + * @param array $encounter_data + * The encounter data, including the encounter type and start date object. + * @param array &$expected + * A reference to an array of expected activities, which will be modified + * with additional activities as required. + */ function hedley_reports_prenatal_add_next_steps_activities_for_chw(array $encounter_data, array &$expected) { $launch_date = '2021-06-07'; $launch_date_obj = new DateTime($launch_date); @@ -7735,6 +7841,22 @@ function hedley_reports_prenatal_add_next_steps_activities_for_chw(array $encoun } } +/** + * Determines if all mandatory activities for the next steps are completed. + * + * This function checks the current encounter type and expected mandatory + * activities, validating whether all required activities are completed based + * on the type of encounter and previous encounters. + * + * @param array $encounter_data + * An array containing details of the encounter, including encounter type, + * previous nurse encounters, and measurements by type. + * @param array $expected + * An array of expected mandatory activities. + * + * @return bool + * TRUE if all mandatory activities are completed; FALSE otherwise. + */ function hedley_reports_prenatal_manadatory_activities_for_next_steps_completed(array $encounter_data, array $expected) { $encounter_type = $encounter_data['encounter_type']; $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; @@ -7866,6 +7988,20 @@ function hedley_reports_prenatal_manadatory_activities_for_next_steps_completed( return TRUE; } +/** + * Calculates the estimated gestational age (EGA) in weeks. + * + * This function calculates the EGA by finding the difference in weeks + * between the last menstrual period (LMP) and the encounter date. + * + * @param DateTime $lmp_date_obj + * The last menstrual period date. + * @param DateTime $encounter_date_obj + * The encounter date. + * + * @return int + * The estimated gestational age in weeks. + */ function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, DateTime $encounter_date_obj ) { $interval = $encounter_date_obj->diff($lmp_date_obj, TRUE); // Get the total number of days from the interval @@ -7873,6 +8009,21 @@ function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, Dat return floor($total_days / 7); } +/** + * Retrieves the latest applicable treatment from a list of options. + * + * This function searches through previous nurse encounters to find the latest + * recommended treatment that matches one of the specified treatment options. + * + * @param array $encounter_data + * An array of encounter data, including previous nurse encounters. + * @param array $treatment_options + * An array of treatment options to search for. + * + * @return array|bool + * The latest treatment that matches one of the treatment options, + * or FALSE if no matching treatment is found. + */ function hedley_reports_prenatal_get_latest_treatment_from_options(array $encounter_data, array $treatment_options) { $previous_nurse_encounters_data = array_reverse($encounter_data['previous_nurse_encounters_data']); foreach ($previous_nurse_encounters_data as $previous_nurse_encounter_data) { From ac1c11c763c0c3cd94e4e7fd70978df00312feb9 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 7 Nov 2024 23:21:51 +0200 Subject: [PATCH 176/185] Complete comments --- .../hedley_reports/hedley_reports.module | 275 +++++++++++++++--- 1 file changed, 228 insertions(+), 47 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 9a4da6cd56..22d47900aa 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5679,6 +5679,14 @@ function hedley_reports_generate_completion_data_for_tuberculosis($participant, } } +/** + * Generates completion data for acute prenatal encounters during pregnancy. + * + * @param object $participant + * The participant node object representing pregnancy. + * @param bool $exclude_set + * Indicate whether to exclude encounters with report data already set. + */ function hedley_reports_generate_completion_data_for_prenatal($participant, $exclude_set) { // To reduce memory usage, mapping measurement types as single characters. $mapping = [ @@ -5823,7 +5831,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // Resolve and partition previous encounters data. $previous_encounters_data = array_slice($encounters_data, 0, $index); - $previous_nurse_encounters_data = $previous_chw_encounters_data = []; + $previous_nurse_encounters_data = $previous_chw_encounters_data = []; foreach ($previous_encounters_data as $previous_encounter_data) { $encounter_type = $previous_encounter_data['encounter_type']; if (in_array($encounter_type, ['nurse', 'nurse-postpartum'])) { @@ -6094,7 +6102,7 @@ function hedley_reports_prenatal_generate_vaccination_history_data(array $encoun * @return array * An array of expected activity names. */ -function hedley_reports_prenatal_generate_expected_initial_activities($encounter_data) { +function hedley_reports_prenatal_generate_expected_initial_activities(array $encounter_data) { $encounter_type = $encounter_data['encounter_type']; $previous_nurse_encounters_data = $encounter_data['previous_nurse_encounters_data']; @@ -6361,9 +6369,9 @@ function hedley_reports_prenatal_add_photo_activity(array $encounter_data, array $photo_ega_in_weeks = hedley_reports_prenatal_calculate_ega_weeks($lmp_date_obj, $date_measured_obj); // Periods, where we want to have 1 photo: - // 1. 12 weeks, or less. - // 2. Between week 13 and week 27. - // 3. Week 28, or more. + // 1. 12 weeks, or less. + // 2. Between week 13 and week 27. + // 3. Week 28, or more. // If we found a photo that matches encounter period, // activity is not expected. if ( @@ -6383,6 +6391,14 @@ function hedley_reports_prenatal_add_photo_activity(array $encounter_data, array } } +/** + * Adds Treatment Review activity to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_prenatal_add_treatment_review_activity(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; if ($encounter_type != 'nurse') { @@ -6398,6 +6414,14 @@ function hedley_reports_prenatal_add_treatment_review_activity(array $encounter_ $expected[] = 'treatment_review'; } +/** + * Adds Labs activities to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_prenatal_add_labs_activities(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; $start_date_obj = $encounter_data['start_date_obj']; @@ -6423,7 +6447,7 @@ function hedley_reports_prenatal_add_labs_activities(array $encounter_data, arra [ 'prenatal_malaria_test', 'prenatal_urine_dipstick_test', - 'prenatal_hemoglobin_test' + 'prenatal_hemoglobin_test', ] ); @@ -6597,6 +6621,14 @@ function hedley_reports_prenatal_add_labs_activities(array $encounter_data, arra } } +/** + * Adds Birth Plan activity to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_prenatal_add_birth_plan_activity(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; if ($encounter_type != 'chw-2') { @@ -6608,6 +6640,16 @@ function hedley_reports_prenatal_add_birth_plan_activity(array $encounter_data, } } +/** + * Adds Health Education activity to the expected list, if conditions match. + * + * This one is unique for CHW. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_prenatal_add_health_education_activity_for_chw(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; if (!in_array($encounter_type, ['chw-1', 'chw-2', 'chw-3'])) { @@ -6619,6 +6661,21 @@ function hedley_reports_prenatal_add_health_education_activity_for_chw(array $en } } +/** + * Checks if any danger signs have been recorded during the encounter. + * + * This function checks if any danger signs, other than "none", have + * been recorded in the danger signs measurement field for the given + * encounter data. If at least one danger sign is recorded, the function + * returns TRUE. + * + * @param array $encounter_data + * The encounter data array, including the danger signs + * measurement information. + * + * @return bool + * TRUE if any danger sign other than "none" is recorded, FALSE otherwise. + */ function hedley_reports_prenatal_danger_signs_recorded(array $encounter_data) { $danger_signs_measurement = $encounter_data['measurements_by_type']['danger_signs']; if (empty($danger_signs_measurement)) { @@ -6639,6 +6696,21 @@ function hedley_reports_prenatal_danger_signs_recorded(array $encounter_data) { return FALSE; } +/** + * Checks if no danger signs have been recorded during the encounter. + * + * This function checks if all the recorded danger signs are "none" in the + * danger signs measurement field for the given encounter data. If there are + * no danger signs recorded or if all signs are "none", it returns TRUE. + * Otherwise, it returns FALSE. + * + * @param array $encounter_data + * The encounter data array, including the danger signs + * measurement information. + * + * @return bool + * TRUE if no danger signs (all "none") are recorded, FALSE otherwise. + */ function hedley_reports_prenatal_no_danger_signs_recorded(array $encounter_data) { $danger_signs_measurement = $encounter_data['measurements_by_type']['danger_signs']; if (empty($danger_signs_measurement)) { @@ -6659,6 +6731,14 @@ function hedley_reports_prenatal_no_danger_signs_recorded(array $encounter_data) return TRUE; } +/** + * Adds Pregnancy Outcome activity to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_prenatal_add_pregnancy_outcome_activity(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; if (!in_array($encounter_type, ['nurse-postpartum', 'chw-postpartum'])) { @@ -6668,6 +6748,14 @@ function hedley_reports_prenatal_add_pregnancy_outcome_activity(array $encounter $expected[] = 'pregnancy_outcome'; } +/** + * Adds Vitals Recheck activity to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_prenatal_add_vitals_reckeck_activity(array $encounter_data, array &$expected) { $triggering_diagnoses = hedley_reports_prenatal_hypertension_diagnoses(); if (hedley_reports_prenatal_diagnosed_previously_with_any_of($encounter_data, $triggering_diagnoses)) { @@ -6700,6 +6788,14 @@ function hedley_reports_prenatal_add_vitals_reckeck_activity(array $encounter_da } } +/** + * Adds nurse unique postpartum activities, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_prenatal_add_postpartum_unique_nurse_activities(array $encounter_data, array &$expected) { $encounter_type = $encounter_data['encounter_type']; if ($encounter_type != 'nurse-postpartum') { @@ -6760,6 +6856,14 @@ function hedley_reports_prenatal_add_postpartum_unique_nurse_activities(array $e } } +/** + * Adds Next Steps activities to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_prenatal_add_next_steps_activities(array $encounter_data, array &$expected) { if (!hedley_reports_prenatal_manadatory_activities_for_next_steps_completed($encounter_data, $expected)) { return; @@ -6774,20 +6878,36 @@ function hedley_reports_prenatal_add_next_steps_activities(array $encounter_data } } +/** + * Adds nurse Next Steps activities to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_prenatal_add_next_steps_activities_for_nurse(array $encounter_data, array &$expected) { - hedley_reports_prenatal_add_send_to_hc_activity_for_nurse($encounter_data, $expected); + hedley_reports_prenatal_add_referral_activity_for_nurse($encounter_data, $expected); hedley_reports_prenatal_add_health_education_activity_for_nurse($encounter_data, $expected); hedley_reports_prenatal_add_medication_distribution_activity_for_nurse($encounter_data, $expected); } -function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encounter_data, array &$expected) { +/** + * Adds nurse Referral activity to the expected list, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_prenatal_add_referral_activity_for_nurse(array $encounter_data, array &$expected) { $launch_date = '2021-06-07'; $launch_date_obj = new DateTime($launch_date); if ($encounter_data['start_date_obj'] < $launch_date_obj) { return; } - // Checking referral to hospital + // Checking referral to hospital. $activity_expected = hedley_reports_prenatal_hospital_referral_expected($encounter_data); // Checking referral to mental health specialist. @@ -6903,6 +7023,14 @@ function hedley_reports_prenatal_add_send_to_hc_activity_for_nurse(array $encoun } } +/** + * Adds nurse Health Education activity, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $encounter_data, array &$expected) { $launch_date = '2021-06-07'; $launch_date_obj = new DateTime($launch_date); @@ -6978,10 +7106,10 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ if (!$activity_expected) { // First, checking by current encounter. // We need to make sure that nausea-and-vomiting symptom is recorded, and - // neither of follow-up questions (dizziness, low-urine-output and dark-urine) - // are answered positively. - // Then, we make sure that Nausea and Vomiting symptom was not recorded during - // previous encounters. + // neither of follow-up questions (dizziness, low-urine-output + // and dark-urine) are answered positively. + // Then, we make sure that Nausea and Vomiting symptom was not recorded + // during previous encounters. if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { $symptom_recorded = FALSE; foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { @@ -6996,7 +7124,10 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ if (!empty($symptom_questions)) { $question_recorded = FALSE; foreach ($symptom_questions as $question) { - if (in_array($question['value'], ['dizziness', 'low-urine-output', 'dark-urine'])) { + if (in_array( + $question['value'], + ['dizziness', 'low-urine-output', 'dark-urine'] + )) { $question_recorded = TRUE; break; } @@ -7015,7 +7146,10 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ if (!$activity_expected) { if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { - if (in_array($symptom['value'], ['leg-cramps', 'low-back-pain', 'constipation', 'varicose-veins'])) { + if (in_array( + $symptom['value'], + ['leg-cramps', 'low-back-pain', 'constipation', 'varicose-veins'] + )) { $activity_expected = TRUE; break; } @@ -7028,8 +7162,8 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ // We need to make sure that leg-pain-redness symptom is recorded, and // neither of follow-up questions (leg-painful, leg-swollen and leg-warm) // are answered positively. - // Then, we make sure that Nausea and Vomiting symptom was not recorded during - // previous encounters. + // Then, we make sure that Nausea and Vomiting symptom was not recorded + // during previous encounters. if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { $symptom_recorded = FALSE; foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { @@ -7044,7 +7178,10 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ if (!empty($symptom_questions)) { $question_recorded = FALSE; foreach ($symptom_questions as $question) { - if (in_array($question['value'], ['leg-painful', 'leg-swollen', 'leg-warm'])) { + if (in_array( + $question['value'], + ['leg-painful', 'leg-swollen', 'leg-warm'] + )) { $question_recorded = TRUE; break; } @@ -7096,6 +7233,14 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ } } +/** + * Adds nurse Medication distribution activity, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ function hedley_reports_prenatal_add_medication_distribution_activity_for_nurse(array $encounter_data, array &$expected) { $launch_date = '2022-09-25'; $launch_date_obj = new DateTime($launch_date); @@ -7172,6 +7317,24 @@ function hedley_reports_prenatal_add_medication_distribution_activity_for_nurse( } } +/** + * Determines if medication distribution is expected. + * + * Based on diagnosis and treatment information. + * + * This function checks various medication sets based on the patient's + * diagnosis and treatment history. It evaluates HIV, discordant + * partnership, anemia, mebendazole, gonorrhea, trichomonas, bacterial + * vaginosis, and vitamin A medication sets to determine if the medication + * distribution is required. + * + * @param array $encounter_data + * The encounter data array, containing diagnoses, treatments, + * and other relevant information for the encounter. + * + * @return bool + * TRUE if medication distribution is expected, FALSE otherwise. + */ function hedley_reports_prenatal_medication_distribution_expected_per_medication_set(array $encounter_data) { // HIV medication set. // First option - HIV diagnosed and no HIV program at HC. @@ -7205,8 +7368,7 @@ function hedley_reports_prenatal_medication_distribution_expected_per_medication 'no-medicine-patient-refused', 'no-medicine-other', ] - ) - ) { + )) { return TRUE; } } @@ -7354,6 +7516,25 @@ function hedley_reports_prenatal_medication_distribution_expected_per_medication return FALSE; } +/** + * Determines if medication distribution is expected. + * + * For patients with ongoing hypertension treatment. + * + * This function checks for cases where medication distribution is + * required based on: + * - Hypertension treatment updates. + * - Referred hospitalizations due to adverse events. + * - Blood pressure readings for patients diagnosed with moderate preeclampsia. + * + * @param array $encounter_data + * The encounter data array, including diagnoses, blood pressure measurements, + * and other relevant information. + * + * @return bool + * TRUE if medication distribution is expected for continued hypertension + * treatment, FALSE otherwise. + */ function hedley_reports_prenatal_medication_distribution_expected_for_continues_hypertension_treatment(array $encounter_data) { // If any of preeclampsia diagnosed - no medication as patient // is referred to hospital. @@ -7381,9 +7562,9 @@ function hedley_reports_prenatal_medication_distribution_expected_for_continues_ } } - if (!$referred) { - return TRUE; - }; + if (!$referred) { + return TRUE; + }; } } @@ -7400,7 +7581,7 @@ function hedley_reports_prenatal_medication_distribution_expected_for_continues_ [ 'severe-preeclampsia-initial', 'severe-preeclampsia-recurrent', - 'eclampsia' + 'eclampsia', ] ); @@ -7486,7 +7667,7 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat [ 'severe-preeclampsia-initial', 'severe-preeclampsia-recurrent', - 'eclampsia' + 'eclampsia', ] ); @@ -7613,11 +7794,13 @@ function hedley_reports_prenatal_hospitalization_due_to_hypertension_treatment_u /** * Determines if medication required as hypertension treatment updates. * - * This function checks the latest hypertension treatment, past diagnoses, and current - * vital signs (blood pressure) to assess whether the treatment needs to be updated. + * This function checks the latest hypertension treatment, past diagnoses, + * and current vital signs (blood pressure) to assess whether the treatment + * needs to be updated. * * @param array $encounter_data - * The encounter data array, containing treatment options, diagnoses, and vital signs. + * The encounter data array, containing treatment options, diagnoses, + * and vital signs. * * @return bool * TRUE if the hypertension treatment requires an update with medication. @@ -7669,8 +7852,9 @@ function hedley_reports_prenatal_medication_due_to_hypertension_treatment_update } /** - * Resolves how to update hypertension treatment based on systolic and - * diastolic blood pressure levels. + * Resolves how to update hypertension treatment. + * + * Based on systolic and diastolic blood pressure levels. * * This function assesses systolic and diastolic values and determines the * appropriate treatment recommendation level. @@ -7726,8 +7910,7 @@ function hedley_reports_prenatal_resolve_hypertension_treatment_update_recommend } /** - * Checks if any of the specified diagnoses were recorded in previous - * encounters. + * Checks if any of specified diagnoses were recorded in previous encounters. * * This function iterates through previous nurse encounters to determine if * any specified diagnosis was documented. @@ -7753,8 +7936,7 @@ function hedley_reports_prenatal_diagnosed_previously_with_any_of(array $encount } /** - * Checks if any of the specified diagnoses were recorded in current - * encounter. + * Checks if any of the specified diagnoses were recorded in current encounter. * * This function compares the provided diagnoses array with the diagnoses * recorded in the current encounter. @@ -7803,17 +7985,12 @@ function hedley_reports_prenatal_symptom_recorded_previously(array $encounter_da } /** - * Adds next steps activities for a Community Health Worker (CHW) encounter. - * - * This function determines additional activities for the CHW's next steps - * based on the type of encounter, whether danger signs were recorded, and - * the encounter's start date relative to the launch date. + * Adds CHW Next Steps activities to the expected list, if conditions match. * * @param array $encounter_data - * The encounter data, including the encounter type and start date object. + * An associative array containing data about the encounter. * @param array &$expected - * A reference to an array of expected activities, which will be modified - * with additional activities as required. + * An array of expected activity names, passed by reference. */ function hedley_reports_prenatal_add_next_steps_activities_for_chw(array $encounter_data, array &$expected) { $launch_date = '2021-06-07'; @@ -8002,9 +8179,9 @@ function hedley_reports_prenatal_manadatory_activities_for_next_steps_completed( * @return int * The estimated gestational age in weeks. */ -function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, DateTime $encounter_date_obj ) { +function hedley_reports_prenatal_calculate_ega_weeks(DateTime $lmp_date_obj, DateTime $encounter_date_obj) { $interval = $encounter_date_obj->diff($lmp_date_obj, TRUE); - // Get the total number of days from the interval + // Get the total number of days from the interval. $total_days = $interval->days; return floor($total_days / 7); } @@ -8058,7 +8235,9 @@ function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral() } /** - * Returns a list of diagnoses causing immediate hospital referral in the initial phase. + * Returns a list of diagnoses causing immediate hospital referral. + * + * In the initial phase. * * @return array * The list of initial-phase diagnoses causing immediate hospital referral. @@ -8097,7 +8276,9 @@ function hedley_reports_prenatal_diagnoses_causing_immediate_hospital_referral_i } /** - * Returns a list of diagnoses causing immediate hospital referral in the recurrent phase. + * Returns a list of diagnoses causing immediate hospital referral. + * + * In the recurrent phase. * * @return array * The list of recurrent-phase diagnoses causing immediate hospital referral. @@ -8300,7 +8481,7 @@ function hedley_reports_prenatal_malaria_diagnoses() { } /** - * Returns an array of mental health diagnoses requiring treatment during prenatal care. + * Returns an array of mental health diagnoses requiring treatment. * * @return array * The list of mental health-related prenatal diagnoses. From 4e902f4eda7d81f4351a22408d33149b3526164f Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 8 Nov 2024 21:33:49 +0200 Subject: [PATCH 177/185] Referral fixes [ci skip] --- .../hedley_reports/hedley_reports.module | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 22d47900aa..0c61f9d586 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -6682,7 +6682,19 @@ function hedley_reports_prenatal_danger_signs_recorded(array $encounter_data) { return FALSE; } - $danger_signs = $danger_signs_measurement->field_danger_signs[LANGUAGE_NONE]; + $encounter_type = $encounter_data['encounter_type']; + if (in_array($encounter_type, ['nurse-postpartum', 'chw-postpartum'])) { + $child_signs = $danger_signs_measurement->field_postpartum_child[LANGUAGE_NONE]; + $danger_signs = !empty($child_signs) ? $child_signs : []; + $mother_signs = $danger_signs_measurement->field_postpartum_mother[LANGUAGE_NONE]; + if (!empty($mother_signs)) { + $danger_signs = array_merge($danger_signs, $mother_signs); + } + } + else { + $danger_signs = $danger_signs_measurement->field_danger_signs[LANGUAGE_NONE]; + } + if (empty($danger_signs)) { return FALSE; } @@ -6915,7 +6927,7 @@ function hedley_reports_prenatal_add_referral_activity_for_nurse(array $encounte $mental_health_measurement = $encounter_data['measurements_by_type']['prenatal_mental_health']; if (!empty($mental_health_measurement)) { $specialist_at_hc = $mental_health_measurement->field_specialist_at_hc[LANGUAGE_NONE][0]['value']; - if ($specialist_at_hc === TRUE) { + if ($specialist_at_hc) { $triggering_diagnoses = hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment(); $activity_expected = hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses); } @@ -7010,7 +7022,8 @@ function hedley_reports_prenatal_add_referral_activity_for_nurse(array $encounte if (!$activity_expected) { $lmp_measurement = $encounter_data['measurements_by_type']['last_menstrual_period']; if (!empty($lmp_measurement)) { - if ($lmp_measurement->field_confident[LANGUAGE_NONE][0]['value'] === FALSE) { + $confident = $lmp_measurement->field_confident[LANGUAGE_NONE][0]['value']; + if (!$confident) { if (!empty($lmp_measurement->field_not_confident_reason[LANGUAGE_NONE][0]['value'])) { $activity_expected = TRUE; } @@ -7628,7 +7641,7 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat // Checking if referral to hospital is required by Mental Health. if (!empty($mental_health_measurement)) { $specialist_at_hc = $mental_health_measurement->field_specialist_at_hc[LANGUAGE_NONE][0]['value']; - if ($specialist_at_hc === FALSE) { + if (!$specialist_at_hc) { $triggering_diagnoses = hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment(); $referred_to_hospital = hedley_reports_prenatal_diagnosed_any_of($encounter_data, $triggering_diagnoses); } @@ -7725,9 +7738,9 @@ function hedley_reports_prenatal_hospital_referral_expected(array $encounter_dat $triggering_diagnoses, ['hepatitis-b', 'rhesus-negative'] ); - } - $referred_to_hospital = !empty(array_intersect($encounter_data['past_diagnoses'], $triggering_diagnoses)); + $referred_to_hospital = !empty(array_intersect($encounter_data['past_diagnoses'], $triggering_diagnoses)); + } } return $referred_to_hospital; @@ -8056,7 +8069,6 @@ function hedley_reports_prenatal_manadatory_activities_for_next_steps_completed( 'medical_history', 'obstetric_history', 'obstetric_history_step2', - 'prenatal_outside_care', // Examination: 'vitals', 'prenatal_nutrition', From d12f3528a291499a12b19c993501167542f1fae2 Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 12 Nov 2024 19:29:07 +0200 Subject: [PATCH 178/185] More medication distribution fixes --- server/elm/src/Translate.elm | 4 +-- .../custom/hedley_general/js/elm-main.js | 4 +-- .../hedley_reports/hedley_reports.module | 31 ++++++++++++++++--- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/server/elm/src/Translate.elm b/server/elm/src/Translate.elm index b1ec71d01b..c86bcbf57f 100644 --- a/server/elm/src/Translate.elm +++ b/server/elm/src/Translate.elm @@ -1840,7 +1840,7 @@ translationSet transId = } RandomBloodSugarTestResult -> - { english = "Random Blood Sugar Result" + { english = "Random Blood Sugar Test Result" , kinyarwanda = Nothing , kirundi = Nothing } @@ -2150,7 +2150,7 @@ translationSet transId = } UrineDipstickTestResult -> - { english = "Urine Dipstick Result" + { english = "Urine Dipstick Test Result" , kinyarwanda = Nothing , kirundi = Nothing } diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 676a00a509..2aefbc4740 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -11606,7 +11606,7 @@ var $author$project$Translate$translationSet = function (transId) { case 'RandomBloodSugarTest': return {english: 'Random Blood Sugar Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'RandomBloodSugarTestResult': - return {english: 'Random Blood Sugar Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Random Blood Sugar Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Referral': return {english: 'Referral', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'Registered': @@ -11796,7 +11796,7 @@ var $author$project$Translate$translationSet = function (transId) { case 'UrineDipstickTest': return {english: 'Urine Dipstick Test', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'UrineDipstickTestResult': - return {english: 'Urine Dipstick Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; + return {english: 'Urine Dipstick Test Result', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WastingModerate': return {english: 'Wasting Moderate', kinyarwanda: $elm$core$Maybe$Nothing, kirundi: $elm$core$Maybe$Nothing}; case 'WastingSevere': diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 0c61f9d586..971a05afb4 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -5825,7 +5825,15 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc $measurements_by_type = $encounter_data['measurements_by_type']; // Resolve encounter start date. - $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + // We check if end date exists and use it, to avoid possibility + // where activities recorded close to end of encounter will + // be disregarded, since they were not yet delivered on encounter + // start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value2'])[0]; + if (empty($start_date)) { + // If end date is not set, default to start date. + $start_date = explode(' ', $encounter->field_scheduled_date[LANGUAGE_NONE][0]['value'])[0]; + } $start_date_obj = new DateTime($start_date); $encounter_data['start_date_obj'] = $start_date_obj; @@ -7317,6 +7325,11 @@ function hedley_reports_prenatal_add_medication_distribution_activity_for_nurse( $activity_expected = !$referred; } + // No treatment recorded, so, we assume that no hospitalization + // took place as treatment for diagnosis. + else { + $activity_expected = TRUE; + } } } @@ -7417,6 +7430,11 @@ function hedley_reports_prenatal_medication_distribution_expected_per_medication return TRUE; } } + // No treatment recorded, so, we assume that no hospitalization + // took place as treatment for diagnosis. + else { + return TRUE; + } } // Mebendazole medication set. @@ -7447,7 +7465,7 @@ function hedley_reports_prenatal_medication_distribution_expected_per_medication if (!$prescribed) { // Second option - only check if not prescribed by first option. - $medication_distribution_measurement = $encounter_data['measurements_by_type']['prenatal_medication_distribution']; + $medication_distribution_measurement = $previous_encounter_data['measurements_by_type']['prenatal_medication_distribution']; if (!empty($medication_distribution_measurement)) { $prescribed_medications = $medication_distribution_measurement->field_prescribed_medication[LANGUAGE_NONE]; if (!empty($prescribed_medications)) { @@ -7484,7 +7502,7 @@ function hedley_reports_prenatal_medication_distribution_expected_per_medication } } - // Finally, since Mebendazole was not prescribed at current, + // Finally, since Mebendazole was not prescribed at current, // we know it's required. if (!$prescribed) { return TRUE; @@ -7579,6 +7597,11 @@ function hedley_reports_prenatal_medication_distribution_expected_for_continues_ return TRUE; }; } + // No treatment recorded, so, we assume that no hospitalization + // took place as treatment for diagnosis. + else { + return TRUE; + } } // Second use-case - currently diagnosed was moderate preeclampsia @@ -8224,7 +8247,7 @@ function hedley_reports_prenatal_get_latest_treatment_from_options(array $encoun foreach ($medication_distribution_measurement->field_recommended_treatment[LANGUAGE_NONE] as $treatment) { if (in_array($treatment['value'], $treatment_options)) { - return $treatment; + return $treatment['value']; } } } From 425dcf3ba94b2a9ba2cf6d8e9c421214fc69871a Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 13 Nov 2024 12:09:01 +0200 Subject: [PATCH 179/185] Code review fix [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 971a05afb4..745e04034c 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -7131,7 +7131,7 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ // and dark-urine) are answered positively. // Then, we make sure that Nausea and Vomiting symptom was not recorded // during previous encounters. - if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { + if (!empty($symptom_review_measurement) && !empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { $symptom_recorded = FALSE; foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { if ($symptom['value'] === 'nausea-and-vomiting') { @@ -7165,7 +7165,7 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ // Education for Leg Cramps, Lower Back Pain, Constipation and // Varicose Veins symptoms. if (!$activity_expected) { - if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { + if (!empty($symptom_review_measurement) && !empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { if (in_array( $symptom['value'], @@ -7185,7 +7185,7 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ // are answered positively. // Then, we make sure that Nausea and Vomiting symptom was not recorded // during previous encounters. - if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { + if (!empty($symptom_review_measurement) && !empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { $symptom_recorded = FALSE; foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { if ($symptom['value'] === 'leg-pain-redness') { @@ -7221,7 +7221,7 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ // follow-up question (pelvic-pain-hospitalization) is answered negatively. // Then, we make sure that pelvic-pain symptom was not recorded during // previous encounters. - if (empty($symptom_review_measurement) || empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { + if (!empty($symptom_review_measurement) && !empty($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE])) { $symptom_recorded = FALSE; foreach ($symptom_review_measurement->field_prenatal_symptoms[LANGUAGE_NONE] as $symptom) { if ($symptom['value'] === 'pelvic-pain') { From f0110ee03f62d06b8136b656c912fddf0e55ab1d Mon Sep 17 00:00:00 2001 From: anvmn Date: Wed, 13 Nov 2024 18:31:06 +0200 Subject: [PATCH 180/185] Drop @todo --- .../modules/custom/hedley_reports/hedley_reports.module | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 745e04034c..fa3a209bde 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -86,7 +86,6 @@ function hedley_reports_menu() { 'title' => 'Completion report', 'description' => 'View Completion report', 'page callback' => 'hedley_reports_completion_report_callback_menu', - // @todo : what access do we need here? 'access callback' => 'hedley_reports_statistical_queries_report_access', ); @@ -94,7 +93,6 @@ function hedley_reports_menu() { 'title' => 'Entire Population', 'description' => 'View Completion report for Entire Population', 'page callback' => 'hedley_reports_completion_report_callback_global', - // @todo : what access do we need here? 'access callback' => 'hedley_reports_statistical_queries_report_access', ); @@ -103,7 +101,6 @@ function hedley_reports_menu() { 'description' => 'View Completion report for health center', 'page callback' => 'hedley_reports_completion_report_callback_health_center', 'page arguments' => [4], - // @todo : what access do we need here? 'access callback' => 'hedley_reports_statistical_queries_report_access', ); @@ -111,7 +108,7 @@ function hedley_reports_menu() { } /** - * Grants access to Statistical Queries viewers, superuser and administrators. + * Grants access to Statistical Queries and Completion Report. * * @return bool * TRUE if the user has access, FALSE otherwise. From 32f3d4994406dc7b2d0f323b0d965fb369d5cc0b Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 14 Nov 2024 18:25:10 +0200 Subject: [PATCH 181/185] ECD activity logic [ci skip] --- .../hedley_reports/hedley_reports.module | 261 +++++++++++++++++- 1 file changed, 260 insertions(+), 1 deletion(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index fa3a209bde..e8dc6efe41 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3428,6 +3428,8 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e // So far we were constructing data structures to resolve encounter data. // Now we have enough info to determine which activities were expected. $expected = hedley_reports_well_child_generate_expected_initial_activities($encounter_data); + // If conditions match, add ECD activity. + hedley_reports_well_child_add_ecd_activities($encounter_data, $birth_date_obj, $gender, $expected); // If conditions match, add immunisation activities. hedley_reports_well_child_add_immunisation_activities($encounter_data, $birth_date_obj, $gender, $expected); // If conditions match, add medication activities. @@ -3912,6 +3914,258 @@ function hedley_reports_well_child_add_immunisation_activities(array $encounter_ } } +/** + * Adds ECD activity as expected, if conditions match. + * + * @param array $encounter_data + * An associative array containing data about the encounter. + * @param DateTime $birth_date_obj + * The DateTime object representing the child's birth date. + * @param string $gender + * The gender of the child, used to determine gender-specific immunisations. + * @param array &$expected + * An array of expected activity names, passed by reference. + */ +function hedley_reports_well_child_add_ecd_activities(array $encounter_data, DateTime $birth_date_obj, $gender, array &$expected) { + if (empty($birth_date_obj)) { + return; + } + + $encounter_type = $encounter_data['encounter_type']; + if ($encounter_type != 'pediatric-care') { + return; + } + + $completed_signs = hedley_reports_well_child_generate_completed_ecd_signs($encounter_data); + $expected_signs = hedley_reports_well_child_generate_expected_ecd_signs($encounter_data, $birth_date_obj); + + if (!empty(array_diff($expected_signs, $completed_signs))) { + $expected[] = 'well_child_ecd'; + } +} + +function hedley_reports_well_child_generate_completed_ecd_signs(array $encounter_data) { + $previous_encounters_data = $encounter_data['previous_encounters_data']; + $completed_signs = []; + foreach ($previous_encounters_data as $previous_encounter_data) { + $ecd_measurement = $previous_encounter_data['measurements_by_type']['well_child_ecd']; + if (empty($ecd_measurement) || empty($ecd_measurement->field_ecd_signs[LANGUAGE_NONE])) { + continue; + } + + foreach ($ecd_measurement->field_ecd_signs[LANGUAGE_NONE] as $sign) { + if ($sign['value'] != 'none') { + $completed_signs[] = $sign['value']; + } + } + } + + return array_unique($completed_signs); +} + +function hedley_reports_well_child_generate_expected_ecd_signs(array $encounter_data, DateTime $birth_date_obj) { + $start_date_obj = $encounter_data['start_date_obj']; + $interval = $start_date_obj->diff($birth_date_obj, TRUE); + + $age_in_weeks = $interval->days / 7; + if ($age_in_weeks < 5) { + return []; + } + + $age_in_months = ($interval->y * 12) + $interval->m; + + $last_ecd_assessment_date = NULL; + $previous_encounters_data = array_reverse($encounter_data['previous_encounters_data']); + foreach ($previous_encounters_data as $previous_encounter_data) { + $ecd_measurement = $previous_encounter_data['measurements_by_type']['well_child_ecd']; + if (!empty($ecd_measurement) && !empty($ecd_measurement->field_date_measured[LANGUAGE_NONE][0]['value'])) { + $last_ecd_assessment_date = $ecd_measurement->field_date_measured[LANGUAGE_NONE][0]['value']; + break; + } + } + + $age_in_months_at_last_assessment = NULL; + if (!empty($last_ecd_assessment_date)) { + $last_ecd_assessment_date_obj = new DateTime($last_ecd_assessment_date); + $interval = $last_ecd_assessment_date_obj->diff($birth_date_obj, TRUE); + $age_in_months_at_last_assessment = ($interval->y * 12) + $interval->m; + } + + $grouped_ecd_signs = hedley_reports_well_child_generate_grouped_ecd_signs($age_in_months, $age_in_months_at_last_assessment); + if ($age_in_weeks < 13) { + $groups_to_take = 1; + } + elseif ($age_in_months < 6) { + $groups_to_take = 2; + } + elseif ($age_in_months < 15) { + $groups_to_take = 3; + } + elseif ($age_in_months < 18) { + $groups_to_take = 4; + } + elseif ($age_in_months < 24) { + $groups_to_take = 5; + } + elseif ($age_in_months < 36) { + $groups_to_take = 6; + } + elseif ($age_in_months < 48) { + $groups_to_take = 7; + } + else { + $groups_to_take = 8; + } + + $expected_groups = array_slice($grouped_ecd_signs, 0, $groups_to_take); + $expected_signs = []; + foreach ($expected_groups as $group) { + $expected_signs = array_merge($expected_signs, $group); + } + + return $expected_signs; +} + +function hedley_reports_well_child_generate_grouped_ecd_signs($age_in_months, $age_in_months_at_last_assessment) { + if (empty($age_in_months_at_last_assessment) || $age_in_months_at_last_assessment < 6) { + $signs_from_5_weeks = hedley_reports_well_child_ecd_signs_from_5_weeks(); + $signs_from_13_weeks = hedley_reports_well_child_ecd_signs_from_13_weeks(); + } + else { + $signs_from_5_weeks = $signs_from_13_weeks = []; + } + + if (empty($age_in_months_at_last_assessment)) { + $signs_6_to_12_months = array_merge( + hedley_reports_well_child_ecd_signs_6_to_12_months_minor(), + hedley_reports_well_child_ecd_signs_6_to_12_months_major() + ); + } + elseif ($age_in_months_at_last_assessment > 12) { + $signs_6_to_12_months = []; + } + elseif ($age_in_months_at_last_assessment >= 9) { + $signs_6_to_12_months = hedley_reports_well_child_ecd_signs_6_to_12_months_major(); + } + elseif ($age_in_months_at_last_assessment >= 6) { + if ($age_in_months > 12) { + $signs_6_to_12_months = []; + } + elseif ($age_in_months >= 9) { + $signs_6_to_12_months = hedley_reports_well_child_ecd_signs_6_to_12_months_major(); + } + else { + $signs_6_to_12_months = array_merge( + hedley_reports_well_child_ecd_signs_6_to_12_months_minor(), + hedley_reports_well_child_ecd_signs_6_to_12_months_major() + ); + } + } + else { + $signs_6_to_12_months = array_merge( + hedley_reports_well_child_ecd_signs_6_to_12_months_minor(), + hedley_reports_well_child_ecd_signs_6_to_12_months_major() + ); + } + + return [ + $signs_from_5_weeks, + $signs_from_13_weeks, + $signs_6_to_12_months, + hedley_reports_well_child_ecd_signs_from_15_months(), + hedley_reports_well_child_ecd_signs_from_18_months(), + hedley_reports_well_child_ecd_signs_from_2_years(), + hedley_reports_well_child_ecd_signs_from_3_years(), + hedley_reports_well_child_ecd_signs_from_4_years(), + ]; +} + +function hedley_reports_well_child_ecd_signs_from_5_weeks() { + return [ + 'follow-mothers-eyes', + 'move-arms-and-legs', + ]; +} + +function hedley_reports_well_child_ecd_signs_from_13_weeks() { + return [ + 'raise-hands-up', + 'smile', + 'roll-sideways', + ]; +} + +function hedley_reports_well_child_ecd_signs_6_to_12_months_minor() { + return [ + 'bring-hands-to-mouth', + 'hold-head-without-support', + 'hold-and-shake-toys', + 'react-to-sudden-sounds', + 'use-consonant-sounds', + ]; +} + +function hedley_reports_well_child_ecd_signs_6_to_12_months_major() { + return [ + 'respond-to-sound-with-sound', + 'turn-head-when-called', + 'sit-without-support', + 'smile-back', + 'roll-tummy-to-back', + 'reach-for-toys', + ]; +} + +function hedley_reports_well_child_ecd_signs_from_15_months() { + return [ + 'use-simple-gestures', + 'stand-on-their-own', + 'copy-during-play', + 'say-mama-dada', + 'can-hold-small-objects', + ]; +} + +function hedley_reports_well_child_ecd_signs_from_18_months() { + return [ + 'looks-when-pointed-at', + 'use-single-words', + 'walk-without-help', + 'play-pretend', + 'point-to-things-of-interest', + ]; +} + +function hedley_reports_well_child_ecd_signs_from_2_years() { + return [ + 'use-short-phrases', + 'interested-in-other-children', + 'follow-simple-instructions', + 'kick-ball', + 'point-at-named-objects', + ]; +} + +function hedley_reports_well_child_ecd_signs_from_3_years() { + return [ + 'dress-themselves', + 'wash-hands-go-to-toiled', + 'knows-colors-and-numbers', + 'use-medium-phrases', + 'play-make-believe', + ]; +} + +function hedley_reports_well_child_ecd_signs_from_4_years() { + return [ + 'follow-three-step-instructions', + 'stand-on-one-foot-five-seconds', + 'use-long-phrases', + 'share-with-other-children', + 'count-to-ten', + ]; +} + /** * Generates a list of expected well-child immunisation activities. * @@ -4154,6 +4408,11 @@ function hedley_reports_get_interval_for_vaccine($immunisation_type, $site) { * An array of expected activity names, passed by reference. */ function hedley_reports_well_child_add_medication_activities(array $encounter_data, array &$expected) { + $encounter_type = $encounter_data['encounter_type']; + if ($encounter_type != 'pediatric-care') { + return; + } + $age_in_months = $encounter_data['age_in_months']; $start_date_obj = $encounter_data['start_date_obj']; // Reversing array, to have the encounters sorted DESC. @@ -4471,7 +4730,7 @@ function hedley_reports_generate_completion_data_for_child_scoreboard_encounter( $encounter_data['age_in_months'] = hedley_reports_resolve_age_in_months_for_individual_encounter($encounter, $start_date_obj); $encounter_data['previous_encounters_data'] = array_slice($encounters_data, 0, $index); - list($encounter_data['vaccination_history'], $encounter_data['vaccination_progress']) = hedley_reports_child_scoreboard_generate_vaccination_progress_data($person_id, $encounter_data); + [$encounter_data['vaccination_history'], $encounter_data['vaccination_progress']] = hedley_reports_child_scoreboard_generate_vaccination_progress_data($person_id, $encounter_data); $expected_immunisation_activities = hedley_reports_child_scoreboard_get_expected_immunisation_activities($encounter_data, $birth_date_obj, $gender, 'history'); $expected = array_merge($expected, $expected_immunisation_activities); From 990e55f5cdc3ebe33d563b33b9bc0b11d18490d4 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 14 Nov 2024 18:25:26 +0200 Subject: [PATCH 182/185] Allow ECD activity on front-end [ci skip] --- server/elm/src/Pages/Completion/Utils.elm | 4 +--- server/hedley/modules/custom/hedley_general/js/elm-main.js | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/server/elm/src/Pages/Completion/Utils.elm b/server/elm/src/Pages/Completion/Utils.elm index afbb15c3d1..072519e733 100644 --- a/server/elm/src/Pages/Completion/Utils.elm +++ b/server/elm/src/Pages/Completion/Utils.elm @@ -159,9 +159,7 @@ resolveSPVActivities site = , WellChildCaring , WellChildContributingFactors , WellChildDTPImmunisation - - -- Not implemented at current phase. - -- , WellChildECD + , WellChildECD , WellChildFeeding , WellChildFollowUp , WellChildFoodSecurity diff --git a/server/hedley/modules/custom/hedley_general/js/elm-main.js b/server/hedley/modules/custom/hedley_general/js/elm-main.js index 2aefbc4740..f85ad59d10 100644 --- a/server/hedley/modules/custom/hedley_general/js/elm-main.js +++ b/server/hedley/modules/custom/hedley_general/js/elm-main.js @@ -14913,7 +14913,7 @@ var $author$project$Pages$Completion$View$viewPrenatalReport = F5( var $author$project$Pages$Completion$Utils$resolveSPVActivities = function (site) { return _Utils_ap( _List_fromArray( - [$author$project$Backend$Completion$Model$WellChildAlbendazole, $author$project$Backend$Completion$Model$WellChildBCGImmunisation, $author$project$Backend$Completion$Model$WellChildCaring, $author$project$Backend$Completion$Model$WellChildContributingFactors, $author$project$Backend$Completion$Model$WellChildDTPImmunisation, $author$project$Backend$Completion$Model$WellChildFeeding, $author$project$Backend$Completion$Model$WellChildFollowUp, $author$project$Backend$Completion$Model$WellChildFoodSecurity, $author$project$Backend$Completion$Model$WellChildHeadCircumference, $author$project$Backend$Completion$Model$WellChildHealthEducation, $author$project$Backend$Completion$Model$WellChildHeight, $author$project$Backend$Completion$Model$WellChildHygiene, $author$project$Backend$Completion$Model$WellChildIPVImmunisation, $author$project$Backend$Completion$Model$WellChildMebendezole, $author$project$Backend$Completion$Model$WellChildMRImmunisation, $author$project$Backend$Completion$Model$WellChildMUAC, $author$project$Backend$Completion$Model$WellChildNCDA, $author$project$Backend$Completion$Model$WellChildNutrition, $author$project$Backend$Completion$Model$WellChildOPVImmunisation, $author$project$Backend$Completion$Model$WellChildPCV13Immunisation, $author$project$Backend$Completion$Model$WellChildPhoto, $author$project$Backend$Completion$Model$WellChildRotarixImmunisation, $author$project$Backend$Completion$Model$WellChildSendToHC, $author$project$Backend$Completion$Model$WellChildSymptomsReview, $author$project$Backend$Completion$Model$WellChildVitals, $author$project$Backend$Completion$Model$WellChildVitaminA, $author$project$Backend$Completion$Model$WellChildWeight]), + [$author$project$Backend$Completion$Model$WellChildAlbendazole, $author$project$Backend$Completion$Model$WellChildBCGImmunisation, $author$project$Backend$Completion$Model$WellChildCaring, $author$project$Backend$Completion$Model$WellChildContributingFactors, $author$project$Backend$Completion$Model$WellChildDTPImmunisation, $author$project$Backend$Completion$Model$WellChildECD, $author$project$Backend$Completion$Model$WellChildFeeding, $author$project$Backend$Completion$Model$WellChildFollowUp, $author$project$Backend$Completion$Model$WellChildFoodSecurity, $author$project$Backend$Completion$Model$WellChildHeadCircumference, $author$project$Backend$Completion$Model$WellChildHealthEducation, $author$project$Backend$Completion$Model$WellChildHeight, $author$project$Backend$Completion$Model$WellChildHygiene, $author$project$Backend$Completion$Model$WellChildIPVImmunisation, $author$project$Backend$Completion$Model$WellChildMebendezole, $author$project$Backend$Completion$Model$WellChildMRImmunisation, $author$project$Backend$Completion$Model$WellChildMUAC, $author$project$Backend$Completion$Model$WellChildNCDA, $author$project$Backend$Completion$Model$WellChildNutrition, $author$project$Backend$Completion$Model$WellChildOPVImmunisation, $author$project$Backend$Completion$Model$WellChildPCV13Immunisation, $author$project$Backend$Completion$Model$WellChildPhoto, $author$project$Backend$Completion$Model$WellChildRotarixImmunisation, $author$project$Backend$Completion$Model$WellChildSendToHC, $author$project$Backend$Completion$Model$WellChildSymptomsReview, $author$project$Backend$Completion$Model$WellChildVitals, $author$project$Backend$Completion$Model$WellChildVitaminA, $author$project$Backend$Completion$Model$WellChildWeight]), function () { if (site.$ === 'SiteBurundi') { return _List_fromArray( From c8ba2dbbce5e6ea49b6f7ddabc3f97e2f703d932 Mon Sep 17 00:00:00 2001 From: anvmn Date: Thu, 14 Nov 2024 18:30:56 +0200 Subject: [PATCH 183/185] A fix [ci skip] --- .../modules/custom/hedley_reports/hedley_reports.module | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index e8dc6efe41..1c5d0fbb9e 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3429,7 +3429,7 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e // Now we have enough info to determine which activities were expected. $expected = hedley_reports_well_child_generate_expected_initial_activities($encounter_data); // If conditions match, add ECD activity. - hedley_reports_well_child_add_ecd_activities($encounter_data, $birth_date_obj, $gender, $expected); + hedley_reports_well_child_add_ecd_activities($encounter_data, $birth_date_obj, $expected); // If conditions match, add immunisation activities. hedley_reports_well_child_add_immunisation_activities($encounter_data, $birth_date_obj, $gender, $expected); // If conditions match, add medication activities. @@ -3921,12 +3921,10 @@ function hedley_reports_well_child_add_immunisation_activities(array $encounter_ * An associative array containing data about the encounter. * @param DateTime $birth_date_obj * The DateTime object representing the child's birth date. - * @param string $gender - * The gender of the child, used to determine gender-specific immunisations. * @param array &$expected * An array of expected activity names, passed by reference. */ -function hedley_reports_well_child_add_ecd_activities(array $encounter_data, DateTime $birth_date_obj, $gender, array &$expected) { +function hedley_reports_well_child_add_ecd_activities(array $encounter_data, DateTime $birth_date_obj, array &$expected) { if (empty($birth_date_obj)) { return; } From c89c9078623f3c8addf6891369f620d757ea5409 Mon Sep 17 00:00:00 2001 From: anvmn Date: Fri, 15 Nov 2024 10:14:22 +0200 Subject: [PATCH 184/185] Docs --- .../hedley_reports/hedley_reports.module | 94 ++++++++++++++++++- 1 file changed, 92 insertions(+), 2 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index 1c5d0fbb9e..29b4237fc4 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -3429,7 +3429,7 @@ function hedley_reports_generate_completion_data_for_well_child($participant, $e // Now we have enough info to determine which activities were expected. $expected = hedley_reports_well_child_generate_expected_initial_activities($encounter_data); // If conditions match, add ECD activity. - hedley_reports_well_child_add_ecd_activities($encounter_data, $birth_date_obj, $expected); + hedley_reports_well_child_add_ecd_activity($encounter_data, $birth_date_obj, $expected); // If conditions match, add immunisation activities. hedley_reports_well_child_add_immunisation_activities($encounter_data, $birth_date_obj, $gender, $expected); // If conditions match, add medication activities. @@ -3924,7 +3924,7 @@ function hedley_reports_well_child_add_immunisation_activities(array $encounter_ * @param array &$expected * An array of expected activity names, passed by reference. */ -function hedley_reports_well_child_add_ecd_activities(array $encounter_data, DateTime $birth_date_obj, array &$expected) { +function hedley_reports_well_child_add_ecd_activity(array $encounter_data, DateTime $birth_date_obj, array &$expected) { if (empty($birth_date_obj)) { return; } @@ -3942,6 +3942,16 @@ function hedley_reports_well_child_add_ecd_activities(array $encounter_data, Dat } } +/** + * Generates a list of ECD signs completed during previous encounters. + * + * @param array $encounter_data + * An associative array containing data about the encounter and + * previous encounters. + * + * @return array + * An array of unique ECD signs that were completed. + */ function hedley_reports_well_child_generate_completed_ecd_signs(array $encounter_data) { $previous_encounters_data = $encounter_data['previous_encounters_data']; $completed_signs = []; @@ -3961,6 +3971,18 @@ function hedley_reports_well_child_generate_completed_ecd_signs(array $encounter return array_unique($completed_signs); } +/** + * Generates a list of ECD signs expected at current encounter. + * + * @param array $encounter_data + * An associative array containing data about the encounter and + * previous encounters. + * @param DateTime $birth_date_obj + * The birth date of the child as a DateTime object. + * + * @return array + * An array of expected ECD signs at current encounter. + */ function hedley_reports_well_child_generate_expected_ecd_signs(array $encounter_data, DateTime $birth_date_obj) { $start_date_obj = $encounter_data['start_date_obj']; $interval = $start_date_obj->diff($birth_date_obj, TRUE); @@ -4024,6 +4046,20 @@ function hedley_reports_well_child_generate_expected_ecd_signs(array $encounter_ return $expected_signs; } +/** + * Generates array with groups of ECD signs. + * + * Based on the child's age at time of encounter and that of + * encounter with last ECD assessment. + * + * @param int $age_in_months + * The age of the child in months. + * @param int|null $age_in_months_at_last_assessment + * The age of the child in months at the last ECD assessment, if available. + * + * @return array + * An array of grouped ECD signs for the specified age. + */ function hedley_reports_well_child_generate_grouped_ecd_signs($age_in_months, $age_in_months_at_last_assessment) { if (empty($age_in_months_at_last_assessment) || $age_in_months_at_last_assessment < 6) { $signs_from_5_weeks = hedley_reports_well_child_ecd_signs_from_5_weeks(); @@ -4078,6 +4114,12 @@ function hedley_reports_well_child_generate_grouped_ecd_signs($age_in_months, $a ]; } +/** + * Returns the ECD signs for children aged 5 weeks. + * + * @return array + * An array of ECD signs expected at 5 weeks. + */ function hedley_reports_well_child_ecd_signs_from_5_weeks() { return [ 'follow-mothers-eyes', @@ -4085,6 +4127,12 @@ function hedley_reports_well_child_ecd_signs_from_5_weeks() { ]; } +/** + * Returns the ECD signs for children aged 13 weeks. + * + * @return array + * An array of ECD signs expected at 13 weeks. + */ function hedley_reports_well_child_ecd_signs_from_13_weeks() { return [ 'raise-hands-up', @@ -4093,6 +4141,12 @@ function hedley_reports_well_child_ecd_signs_from_13_weeks() { ]; } +/** + * Returns minor ECD signs for children aged 6 to 12 months. + * + * @return array + * An array of minor ECD signs for 6 to 12 months. + */ function hedley_reports_well_child_ecd_signs_6_to_12_months_minor() { return [ 'bring-hands-to-mouth', @@ -4103,6 +4157,12 @@ function hedley_reports_well_child_ecd_signs_6_to_12_months_minor() { ]; } +/** + * Returns major ECD signs for children aged 6 to 12 months. + * + * @return array + * An array of major ECD signs for 6 to 12 months. + */ function hedley_reports_well_child_ecd_signs_6_to_12_months_major() { return [ 'respond-to-sound-with-sound', @@ -4114,6 +4174,12 @@ function hedley_reports_well_child_ecd_signs_6_to_12_months_major() { ]; } +/** + * Returns the ECD signs for children aged 15 months. + * + * @return array + * An array of ECD signs expected at 15 months. + */ function hedley_reports_well_child_ecd_signs_from_15_months() { return [ 'use-simple-gestures', @@ -4124,6 +4190,12 @@ function hedley_reports_well_child_ecd_signs_from_15_months() { ]; } +/** + * Returns the ECD signs for children aged 18 months. + * + * @return array + * An array of ECD signs expected at 18 months. + */ function hedley_reports_well_child_ecd_signs_from_18_months() { return [ 'looks-when-pointed-at', @@ -4134,6 +4206,12 @@ function hedley_reports_well_child_ecd_signs_from_18_months() { ]; } +/** + * Returns the ECD signs for children aged 2 years. + * + * @return array + * An array of ECD signs expected at 2 years. + */ function hedley_reports_well_child_ecd_signs_from_2_years() { return [ 'use-short-phrases', @@ -4144,6 +4222,12 @@ function hedley_reports_well_child_ecd_signs_from_2_years() { ]; } +/** + * Returns the ECD signs for children aged 3 years. + * + * @return array + * An array of ECD signs expected at 3 years. + */ function hedley_reports_well_child_ecd_signs_from_3_years() { return [ 'dress-themselves', @@ -4154,6 +4238,12 @@ function hedley_reports_well_child_ecd_signs_from_3_years() { ]; } +/** + * Returns the ECD signs for children aged 4 years. + * + * @return array + * An array of ECD signs expected at 4 years. + */ function hedley_reports_well_child_ecd_signs_from_4_years() { return [ 'follow-three-step-instructions', From b0ac51464187f6dd680c0e0f1465faf34cfc21ad Mon Sep 17 00:00:00 2001 From: anvmn Date: Tue, 19 Nov 2024 13:13:24 +0200 Subject: [PATCH 185/185] Address code review --- .../hedley_reports/hedley_reports.module | 420 ++++++++++-------- 1 file changed, 233 insertions(+), 187 deletions(-) diff --git a/server/hedley/modules/custom/hedley_reports/hedley_reports.module b/server/hedley/modules/custom/hedley_reports/hedley_reports.module index fa3a209bde..53230f80eb 100644 --- a/server/hedley/modules/custom/hedley_reports/hedley_reports.module +++ b/server/hedley/modules/custom/hedley_reports/hedley_reports.module @@ -4938,62 +4938,7 @@ function hedley_reports_generate_completion_data_for_ncd($participant, $exclude_ // Adding labs test results activities. Since those are logically derived, // and not actual content, we apply proprietary logic per records recorded // at labs results content. - $labs_results = $measurements_by_type['ncd_labs_results']; - if (!empty($labs_results)) { - if (!empty($labs_results->field_performed_tests)) { - $performed_tests = $labs_results->field_performed_tests[LANGUAGE_NONE]; - foreach ($performed_tests as $performed_test) { - switch ($performed_test['value']) { - case 'creatinine': - $expected[] = 'ncd_creatinine_test_result'; - break; - - case 'lipid-panel': - $expected[] = 'ncd_lipid_panel_test_result'; - break; - - case 'liver-function': - $expected[] = 'ncd_liver_function_test_result'; - break; - - case 'random-blood-sugar': - $expected[] = 'ncd_random_blood_sugar_test_result'; - break; - - case 'urine-dipstick': - $expected[] = 'ncd_urine_dipstick_test_result'; - break; - } - } - } - - if (!empty($labs_results->field_completed_tests)) { - $completed_tests = $labs_results->field_completed_tests[LANGUAGE_NONE]; - foreach ($completed_tests as $completed_test) { - switch ($completed_test['value']) { - case 'creatinine': - $measurements_by_type['ncd_creatinine_test_result'] = 'dummy'; - break; - - case 'lipid-panel': - $measurements_by_type['ncd_lipid_panel_test_result'] = 'dummy'; - break; - - case 'liver-function': - $measurements_by_type['ncd_liver_function_test_result'] = 'dummy'; - break; - - case 'random-blood-sugar': - $measurements_by_type['ncd_random_blood_sugar_test_result'] = 'dummy'; - break; - - case 'urine-dipstick': - $measurements_by_type['ncd_urine_dipstick_test_result'] = 'dummy'; - break; - } - } - } - } + hedley_reports_ncd_add_labs_results_activities($expected, $measurements_by_type); $completion_data = [ 'start_date' => $start_date, @@ -5376,6 +5321,75 @@ function hedley_reports_ncd_add_next_steps_activities(array $encounter_data, arr } } +/** + * Adds NCD lab results activities to the expected and measurements arrays. + * + * @param array $expected + * An array of expected activities to update. + * @param array $measurements_by_type + * An array of measurements grouped by type, including lab results. + */ +function hedley_reports_ncd_add_labs_results_activities(array &$expected, array &$measurements_by_type) { + $labs_results = $measurements_by_type['ncd_labs_results']; + if (empty($labs_results) || empty($labs_results->field_performed_tests)) { + return; + } + + $performed_tests = $labs_results->field_performed_tests[LANGUAGE_NONE]; + foreach ($performed_tests as $performed_test) { + switch ($performed_test['value']) { + case 'creatinine': + $expected[] = 'ncd_creatinine_test_result'; + break; + + case 'lipid-panel': + $expected[] = 'ncd_lipid_panel_test_result'; + break; + + case 'liver-function': + $expected[] = 'ncd_liver_function_test_result'; + break; + + case 'random-blood-sugar': + $expected[] = 'ncd_random_blood_sugar_test_result'; + break; + + case 'urine-dipstick': + $expected[] = 'ncd_urine_dipstick_test_result'; + break; + } + } + + if (empty($labs_results->field_completed_tests)) { + return; + } + + $completed_tests = $labs_results->field_completed_tests[LANGUAGE_NONE]; + foreach ($completed_tests as $completed_test) { + switch ($completed_test['value']) { + case 'creatinine': + $measurements_by_type['ncd_creatinine_test_result'] = 'dummy'; + break; + + case 'lipid-panel': + $measurements_by_type['ncd_lipid_panel_test_result'] = 'dummy'; + break; + + case 'liver-function': + $measurements_by_type['ncd_liver_function_test_result'] = 'dummy'; + break; + + case 'random-blood-sugar': + $measurements_by_type['ncd_random_blood_sugar_test_result'] = 'dummy'; + break; + + case 'urine-dipstick': + $measurements_by_type['ncd_urine_dipstick_test_result'] = 'dummy'; + break; + } + } +} + /** * Generates completion data for HIV encounters for patient. * @@ -5768,6 +5782,7 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // Encounters are sorted ASC. $encounters = node_load_multiple(array_keys($result['node'])); $encounters_data = []; + // Assembling needed data for each encounter. foreach ($encounters as $encounter) { // Skip encounter if exclusion flag is raised and it's report data is set. if ($exclude_set && !empty($encounter->field_reports_data[LANGUAGE_NONE][0]['value'])) { @@ -5909,144 +5924,18 @@ function hedley_reports_generate_completion_data_for_prenatal($participant, $exc // Vitals recheck (recurrent phase). hedley_reports_prenatal_add_vitals_reckeck_activity($encounter_data, $expected); // Adding labs test results activities. Since those are logically derived, - // and not actual content, we apply proprietary logic per records recorded + // and not actual content, we apply proprietary logic per data recorded // at labs results content. - $labs_results = $measurements_by_type['prenatal_labs_results']; - if (!empty($labs_results)) { - if (!empty($labs_results->field_performed_tests)) { - $performed_tests = $labs_results->field_performed_tests[LANGUAGE_NONE]; - foreach ($performed_tests as $performed_test) { - switch ($performed_test['value']) { - case 'hiv': - $expected[] = 'prenatal_hiv_test_result'; - break; - - case 'partner-hiv': - $expected[] = 'prenatal_partner_hiv_test_result'; - break; - - case 'malaria': - $expected[] = 'prenatal_malaria_test_result'; - break; - - case 'syphilis': - $expected[] = 'prenatal_syphilis_test_result'; - break; - - case 'hepatitis-b': - $expected[] = 'prenatal_hepatitis_b_test_result'; - break; - - case 'blood-group': - $expected[] = 'prenatal_blood_gprs_test_result'; - break; - - case 'hemoglobin': - $expected[] = 'prenatal_hemoglobin_test_result'; - break; - - case 'random-blood-sugar': - $expected[] = 'prenatal_random_blood_sugar_test_result'; - break; - - case 'hiv-pcr': - $expected[] = 'prenatal_hiv_pcr_test_result'; - break; - - case 'urine-dipstick': - $expected[] = 'prenatal_urine_dipstick_test_result'; - break; - } - } - } - - if (!empty($labs_results->field_completed_tests)) { - $completed_tests = $labs_results->field_completed_tests[LANGUAGE_NONE]; - foreach ($completed_tests as $completed_test) { - switch ($completed_test['value']) { - case 'hiv': - $measurements_by_type['prenatal_hiv_test_result'] = 'dummy'; - break; - - case 'partner-hiv': - $measurements_by_type['prenatal_partner_hiv_test_result'] = 'dummy'; - break; - - case 'malaria': - $measurements_by_type['prenatal_malaria_test_result'] = 'dummy'; - break; - - case 'syphilis': - $measurements_by_type['prenatal_syphilis_test_result'] = 'dummy'; - break; - - case 'hepatitis-b': - $measurements_by_type['prenatal_hepatitis_b_test_result'] = 'dummy'; - break; - - case 'blood-group': - $measurements_by_type['prenatal_blood_gprs_test_result'] = 'dummy'; - break; - - case 'hemoglobin': - $measurements_by_type['prenatal_hemoglobin_test_result'] = 'dummy'; - break; - - case 'random-blood-sugar': - $measurements_by_type['prenatal_random_blood_sugar_test_result'] = 'dummy'; - break; - - case 'hiv-pcr': - $measurements_by_type['prenatal_hiv_pcr_test_result'] = 'dummy'; - break; - - case 'urine-dipstick': - $measurements_by_type['prenatal_urine_dipstick_test_result'] = 'dummy'; - break; - } - } - } - } - + hedley_reports_prenatal_add_labs_results_activities($expected, $measurements_by_type); // This comes last, since it has mandatory activities to be completed, // which we will be checking for withing $expected. hedley_reports_prenatal_add_next_steps_activities($encounter_data, $expected); - // Logic to determine if virtual activities are completed. - // Treatment Review data is saved into Medication CT. - if (in_array('treatment_review', $expected)) { - if (!empty($measurements_by_type['medication'])) { - $measurements_by_type['treatment_review'] = 'dummy'; - } - } - // Postpartum treatment data is similar to Treatment Review, - // but at postpartum encounter. - if (in_array('postpartum_treatment_review', $expected)) { - if (!empty($measurements_by_type['medication'])) { - $measurements_by_type['postpartum_treatment_review'] = 'dummy'; - } - } - // Pregnancy Outcome data is stored on participant node. - if (in_array('pregnancy_outcome', $expected)) { - $outcome = $participant->field_outcome[LANGUAGE_NONE][0]['value']; - if (!empty($outcome)) { - $measurements_by_type['pregnancy_outcome'] = 'dummy'; - } - } - // Blood pressure re-check is done if dia_repeated and - // sys_repeated fields are set on vitals measurement. - if (in_array('vitals_recheck', $expected)) { - $vitals_measurement = $encounter_data['measurements_by_type']['vitals']; - $sys_repeated = $vitals_measurement->field_sys_repeated[LANGUAGE_NONE][0]['value']; - $dia_repeated = $vitals_measurement->field_dia_repeated[LANGUAGE_NONE][0]['value']; - if (!empty($sys_repeated) && !empty($dia_repeated)) { - $measurements_by_type['vitals_recheck'] = 'dummy'; - } - } + hedley_reports_prenatal_update_virtual_activities_completed($participant, $expected, $measurements_by_type); $completion_data = [ 'start_date' => $start_date, - 'taken_by' => in_array($encounter_type, ['nurse', 'nurse-postpartum']) ? 'nurse' : 'chw', + 'taken_by' => in_array($encounter_data['encounter_type'], ['nurse', 'nurse-postpartum']) ? 'nurse' : 'chw', 'completion' => hedley_reports_generate_completion_result($expected, $measurements_by_type, $mapping), ]; @@ -6805,6 +6694,163 @@ function hedley_reports_prenatal_add_vitals_reckeck_activity(array $encounter_da } } +/** + * Adds Prenatal lab results activities to the expected and measurements arrays. + * + * @param array $expected + * An array of expected activities to update. + * @param array $measurements_by_type + * An array of measurements grouped by type, including lab results. + */ +function hedley_reports_prenatal_add_labs_results_activities(array &$expected, array &$measurements_by_type) { + $labs_results = $measurements_by_type['prenatal_labs_results']; + if (empty($labs_results) || empty($labs_results->field_performed_tests)) { + return; + } + + $performed_tests = $labs_results->field_performed_tests[LANGUAGE_NONE]; + foreach ($performed_tests as $performed_test) { + switch ($performed_test['value']) { + case 'hiv': + $expected[] = 'prenatal_hiv_test_result'; + break; + + case 'partner-hiv': + $expected[] = 'prenatal_partner_hiv_test_result'; + break; + + case 'malaria': + $expected[] = 'prenatal_malaria_test_result'; + break; + + case 'syphilis': + $expected[] = 'prenatal_syphilis_test_result'; + break; + + case 'hepatitis-b': + $expected[] = 'prenatal_hepatitis_b_test_result'; + break; + + case 'blood-group': + $expected[] = 'prenatal_blood_gprs_test_result'; + break; + + case 'hemoglobin': + $expected[] = 'prenatal_hemoglobin_test_result'; + break; + + case 'random-blood-sugar': + $expected[] = 'prenatal_random_blood_sugar_test_result'; + break; + + case 'hiv-pcr': + $expected[] = 'prenatal_hiv_pcr_test_result'; + break; + + case 'urine-dipstick': + $expected[] = 'prenatal_urine_dipstick_test_result'; + break; + } + } + + if (empty($labs_results->field_completed_tests)) { + return; + } + + $completed_tests = $labs_results->field_completed_tests[LANGUAGE_NONE]; + foreach ($completed_tests as $completed_test) { + switch ($completed_test['value']) { + case 'hiv': + $measurements_by_type['prenatal_hiv_test_result'] = 'dummy'; + break; + + case 'partner-hiv': + $measurements_by_type['prenatal_partner_hiv_test_result'] = 'dummy'; + break; + + case 'malaria': + $measurements_by_type['prenatal_malaria_test_result'] = 'dummy'; + break; + + case 'syphilis': + $measurements_by_type['prenatal_syphilis_test_result'] = 'dummy'; + break; + + case 'hepatitis-b': + $measurements_by_type['prenatal_hepatitis_b_test_result'] = 'dummy'; + break; + + case 'blood-group': + $measurements_by_type['prenatal_blood_gprs_test_result'] = 'dummy'; + break; + + case 'hemoglobin': + $measurements_by_type['prenatal_hemoglobin_test_result'] = 'dummy'; + break; + + case 'random-blood-sugar': + $measurements_by_type['prenatal_random_blood_sugar_test_result'] = 'dummy'; + break; + + case 'hiv-pcr': + $measurements_by_type['prenatal_hiv_pcr_test_result'] = 'dummy'; + break; + + case 'urine-dipstick': + $measurements_by_type['prenatal_urine_dipstick_test_result'] = 'dummy'; + break; + } + } +} + +/** + * Updates data for virtual activities completion. + * + * This function checks the participant data and measurements to mark + * virtual activities as completed if certain conditions are met. + * If virtual activity is completed, adding 'dummy' indication for + * activity, to match hedley_reports_generate_completion_result() logic. + * + * @param object $participant + * The participant entity containing relevant fields. + * @param array $expected + * An array of expected activities. + * @param array $measurements_by_type + * An array of measurements grouped by type. Updated by reference. + */ +function hedley_reports_prenatal_update_virtual_activities_completed($participant, array $expected, array &$measurements_by_type) { + // Treatment Review data is saved into Medication CT. + if (in_array('treatment_review', $expected)) { + if (!empty($measurements_by_type['medication'])) { + $measurements_by_type['treatment_review'] = 'dummy'; + } + } + // Postpartum treatment data is similar to Treatment Review, + // but at postpartum encounter. + if (in_array('postpartum_treatment_review', $expected)) { + if (!empty($measurements_by_type['medication'])) { + $measurements_by_type['postpartum_treatment_review'] = 'dummy'; + } + } + // Pregnancy Outcome data is stored on participant node. + if (in_array('pregnancy_outcome', $expected)) { + $outcome = $participant->field_outcome[LANGUAGE_NONE][0]['value']; + if (!empty($outcome)) { + $measurements_by_type['pregnancy_outcome'] = 'dummy'; + } + } + // Blood pressure re-check is done if dia_repeated and + // sys_repeated fields are set on vitals measurement. + if (in_array('vitals_recheck', $expected)) { + $vitals_measurement = $measurements_by_type['vitals']; + $sys_repeated = $vitals_measurement->field_sys_repeated[LANGUAGE_NONE][0]['value']; + $dia_repeated = $vitals_measurement->field_dia_repeated[LANGUAGE_NONE][0]['value']; + if (!empty($sys_repeated) && !empty($dia_repeated)) { + $measurements_by_type['vitals_recheck'] = 'dummy'; + } + } +} + /** * Adds nurse unique postpartum activities, if conditions match. * @@ -7098,7 +7144,7 @@ function hedley_reports_prenatal_add_health_education_activity_for_nurse(array $ // Mental health education. // Mental health survey is filled and none of mental health - // diagnoses requiring tratment was recorded. + // diagnoses requiring treatment was recorded. $mental_health_measurement = $encounter_data['measurements_by_type']['prenatal_mental_health']; if (!empty($mental_health_measurement)) { $mental_health_diagnoses_requiring_treatment = hedley_reports_prenatal_mental_health_diagnoses_requiring_treatment();