Skip to content

Commit

Permalink
Merge pull request #812 from TIP-Global-Health/issue-811
Browse files Browse the repository at this point in the history
Statistic generation - optimise hedley_stats_get_total_encounters()
  • Loading branch information
anvmn authored Aug 1, 2023
2 parents c969b6a + 1ed042d commit 9948c39
Showing 1 changed file with 140 additions and 71 deletions.
211 changes: 140 additions & 71 deletions server/hedley/modules/custom/hedley_stats/hedley_stats.module
Original file line number Diff line number Diff line change
Expand Up @@ -358,11 +358,10 @@ function hedley_stats_calculate_stats_for_health_center($health_center_id) {
// Calculate statistics that are provided for FBF clinics only.
hedley_stats_get_session_attendance_stats_by_health_center($health_center_id, $fbf_clinics);

$villages_with_residents = hedley_stats_get_villages_with_residents($health_center_id);

hedley_stats_get_case_management($health_center_id);
hedley_stats_get_children_beneficiaries_stats_by_period($health_center_id);
hedley_stats_get_family_planning_stats_by_period($health_center_id, HEDLEY_STATS_PERIOD_PAST_THREE_MONTHS);
$villages_with_residents = hedley_stats_get_villages_with_residents($health_center_id);
hedley_stats_get_total_encounters($health_center_id, $villages_with_residents);
hedley_stats_get_acute_illness_data($health_center_id);
hedley_stats_get_prenatal_data($health_center_id);
Expand Down Expand Up @@ -1264,11 +1263,20 @@ function hedley_stats_get_total_encounters($health_center_id, $villages_with_res
return $cache_data;
}

$result['global'] = hedley_stats_get_total_encounters_for_residents($health_center_id);
$total_by_patient_at_clinic = [
'last_year' => hedley_stats_get_total_encounters_by_patients_at_clinic($health_center_id, HEDLEY_STATS_PERIOD_LAST_YEAR),
'this_year' => hedley_stats_get_total_encounters_by_patients_at_clinic($health_center_id, HEDLEY_STATS_PERIOD_ONE_YEAR),
];

$total_by_patient_individual = [
'last_year' => hedley_stats_get_total_nutrition_encounters_by_patient($health_center_id, HEDLEY_STATS_PERIOD_LAST_YEAR),
'this_year' => hedley_stats_get_total_nutrition_encounters_by_patient($health_center_id, HEDLEY_STATS_PERIOD_ONE_YEAR),
];

$result['global'] = hedley_stats_get_total_encounters_for_residents($total_by_patient_at_clinic, $total_by_patient_individual);
$result['villages'] = [];
foreach ($villages_with_residents as $village_uuid => $residents_ids) {
$result['villages'][$village_uuid] = hedley_stats_get_total_encounters_for_residents($health_center_id, $residents_ids);
$result['villages'][$village_uuid] = hedley_stats_get_total_encounters_for_residents($total_by_patient_at_clinic, $total_by_patient_individual, $residents_ids);
}

// Free up memory.
Expand All @@ -1289,8 +1297,10 @@ function hedley_stats_get_total_encounters($health_center_id, $villages_with_res
* Includes total number of encounters for each type of clinic, and
* total number of individual nutrition encounters.
*
* @param int $health_center_id
* The Health center node ID.
* @param array $total_by_patient_at_clinic
* For each of clinics, total number of sessions for each patient.
* @param array $total_by_patient_individual
* Total number of Nutrition encounters for each patient.
* @param bool|array $patients_ids
* Optional; a list of patients IDs, for which totals are counted.
*
Expand All @@ -1299,15 +1309,9 @@ function hedley_stats_get_total_encounters($health_center_id, $villages_with_res
*
* @throws \Exception
*/
function hedley_stats_get_total_encounters_for_residents($health_center_id, $patients_ids = FALSE) {
$clinic_types = hedley_stats_get_all_clinic_types();

$result = [];
foreach ($clinic_types as $clinic_type) {
$result[$clinic_type] = hedley_stats_get_total_encounters_by_clinic_type($health_center_id, $clinic_type, $patients_ids);
}

$result['individual'] = hedley_stats_get_total_nutrition_encounters($health_center_id, $patients_ids);
function hedley_stats_get_total_encounters_for_residents(array $total_by_patient_at_clinic, array $total_by_patient_individual, $patients_ids = FALSE) {
$result = hedley_stats_get_total_encounters_by_clinic_type($total_by_patient_at_clinic, $patients_ids);
$result['individual'] = hedley_stats_get_total_nutrition_encounters($total_by_patient_individual, $patients_ids);

return $result;
}
Expand All @@ -1318,10 +1322,8 @@ function hedley_stats_get_total_encounters_for_residents($health_center_id, $pat
* If patients list is not provided (defaults to False),
* overall totals are calculated.
*
* @param int $health_center_id
* The Health center node ID.
* @param string $clinic_type
* The type of the clinic.
* @param array $total_by_patient_at_clinic
* For each of clinics, total number of sessions for each patient.
* @param bool|array $patients_ids
* Optional; a list of patients IDs, for which totals are counted.
*
Expand All @@ -1330,45 +1332,69 @@ function hedley_stats_get_total_encounters_for_residents($health_center_id, $pat
*
* @throws \Exception
*/
function hedley_stats_get_total_encounters_by_clinic_type($health_center_id, $clinic_type, $patients_ids = FALSE) {
$result = [
'last_year' => 0,
'this_year' => 0,
];

function hedley_stats_get_total_encounters_by_clinic_type(array $total_by_patient_at_clinic, $patients_ids = FALSE) {
$result = [];
$clinic_types = hedley_stats_get_all_clinic_types();
if (is_array($patients_ids) && empty($patients_ids)) {
// Patients list is empty. Return empty result.
// Patients list is empty. No encounters. Return empty result.
foreach ($clinic_types as $clinic_type) {
$result[$clinic_type] = [
'last_year' => 0,
'this_year' => 0,
];
}

return $result;
}

$queries['last_year'] = hedley_stats_get_base_query($health_center_id, 'attendance', HEDLEY_STATS_PERIOD_LAST_YEAR);
$queries['this_year'] = hedley_stats_get_base_query($health_center_id, 'attendance', HEDLEY_STATS_PERIOD_ONE_YEAR);

foreach ($queries as $key => $query) {
// Get the group type.
hedley_general_join_field_to_query($query, 'node', 'field_session');
hedley_general_join_field_to_query($query, 'node', 'field_attended');
hedley_general_join_field_to_query($query, 'node', 'field_clinic', TRUE, 'field_session.field_session_target_id');
hedley_general_join_field_to_query($query, 'node', 'field_group_type', TRUE, 'field_clinic.field_clinic_target_id');
foreach ($clinic_types as $clinic_type) {
$result[$clinic_type] = [
'last_year' => hedley_stats_total_encounters_from_breakdown_by_patient($total_by_patient_at_clinic['last_year'][$clinic_type], $patients_ids),
'this_year' => hedley_stats_total_encounters_from_breakdown_by_patient($total_by_patient_at_clinic['this_year'][$clinic_type], $patients_ids),
];
}

// Only participants who actually attended the sessions.
$query->condition('field_attended.field_attended_value', TRUE);
return $result;
}

// Only of specific clinic type.
$query->condition('field_group_type.field_group_type_value', $clinic_type);
/**
* Generates data structure with number of Group encounters per patient.
*
* Keys - patients IDs, Values - number of encounters.
* Broken down by clinics types.
*
* @param int $health_center_id
* The health center node ID.
* @param string $period
* The period for the data.
*
* @return array
* Array with number of Nutrition encounters per patient, within period.
*
* @throws Exception
*/
function hedley_stats_get_total_encounters_by_patients_at_clinic($health_center_id, $period) {
$query = hedley_stats_get_base_query($health_center_id, 'attendance', $period);
hedley_general_join_field_to_query($query, 'node', 'field_session');
hedley_general_join_field_to_query($query, 'node', 'field_attended');
hedley_general_join_field_to_query($query, 'node', 'field_clinic', TRUE, 'field_session.field_session_target_id');
hedley_general_join_field_to_query($query, 'node', 'field_group_type', TRUE, 'field_clinic.field_clinic_target_id');
hedley_general_join_field_to_query($query, 'node', 'field_person');
// Only participants who actually attended the sessions.
$query->condition('field_attended.field_attended_value', TRUE);
$result = $query->execute()->fetchAll();

// If patients list specified values.
if (is_array($patients_ids)) {
hedley_general_join_field_to_query($query, 'node', 'field_person');
$query->condition('field_person.field_person_target_id', $patients_ids, 'IN');
}
$total_by_patient_at_clinic = [];
$clinic_types = hedley_stats_get_all_clinic_types();
foreach ($clinic_types as $clinic_type) {
$total_by_patient_at_clinic[$clinic_type] = [];
}

$result[$key] = $query
->execute()
->rowCount();
foreach ($result as $row) {
$total_by_patient_at_clinic[$row->field_group_type][$row->field_person] = isset($total_by_patient_at_clinic[$row->field_group_type][$row->field_person]) ? $total_by_patient_at_clinic[$row->field_group_type][$row->field_person] + 1 : 1;
}

return $result;
return $total_by_patient_at_clinic;
}

/**
Expand All @@ -1377,8 +1403,8 @@ function hedley_stats_get_total_encounters_by_clinic_type($health_center_id, $cl
* If patients list is not provided (defaults to False),
* overall totals are calculated.
*
* @param int $health_center_id
* The Health center node ID.
* @param array $total_by_patient
* Total number of Nutrition encounters for each patient.
* @param bool|array $patients_ids
* Optional; a list of patients IDs, for which totals are counted.
*
Expand All @@ -1387,35 +1413,78 @@ function hedley_stats_get_total_encounters_by_clinic_type($health_center_id, $cl
*
* @throws \Exception
*/
function hedley_stats_get_total_nutrition_encounters($health_center_id, $patients_ids = FALSE) {
$result = [
'last_year' => 0,
'this_year' => 0,
];

function hedley_stats_get_total_nutrition_encounters(array $total_by_patient, $patients_ids = FALSE) {
if (is_array($patients_ids) && empty($patients_ids)) {
// Patients list is empty. Return empty result.
return $result;
// Patients list is empty. No encounters. Return empty result.
return [
'last_year' => 0,
'this_year' => 0,
];
}

$queries['last_year'] = hedley_stats_get_base_query($health_center_id, 'nutrition_encounter', HEDLEY_STATS_PERIOD_LAST_YEAR);
$queries['this_year'] = hedley_stats_get_base_query($health_center_id, 'nutrition_encounter', HEDLEY_STATS_PERIOD_ONE_YEAR);
return [
'last_year' => hedley_stats_total_encounters_from_breakdown_by_patient($total_by_patient['last_year'], $patients_ids),
'this_year' => hedley_stats_total_encounters_from_breakdown_by_patient($total_by_patient['this_year'], $patients_ids),
];
}

/**
* Counts total number of encounters from data structure.
*
* If patients IDs list is provided, counts only for those patients.
*
* @param array $total_by_patient
* Total number of Nutrition encounters for each patient.
* @param array|bool $patients_ids
* Optional; a list of patients IDs, for which total is counted.
*
* @return int
* Total number of encounters at data structure.
*/
function hedley_stats_total_encounters_from_breakdown_by_patient(array $total_by_patient, $patients_ids = FALSE) {
if ($patients_ids === FALSE) {
return array_sum($total_by_patient);
}

return array_sum(
array_filter(
$total_by_patient,
function ($key) use ($patients_ids) {
return in_array($key, $patients_ids);
},
ARRAY_FILTER_USE_KEY
)
);
}

foreach ($queries as $key => $query) {
// If patients list specified values.
if (is_array($patients_ids)) {
hedley_general_join_field_to_query($query, 'node', 'field_individual_participant');
hedley_general_join_field_to_query($query, 'node', 'field_person', TRUE, 'field_individual_participant.field_individual_participant_target_id');
/**
* Generates data structure with number of Nutrition encounters per patient.
*
* Keys - patients IDs, Values - number of encounters.
*
* @param int $health_center_id
* The health center node ID.
* @param string $period
* The period for the data.
*
* @return array
* Array with number of Nutrition encounters per patient, within period.
*
* @throws Exception
*/
function hedley_stats_get_total_nutrition_encounters_by_patient($health_center_id, $period) {
$query = hedley_stats_get_base_query($health_center_id, 'nutrition_encounter', $period);
hedley_general_join_field_to_query($query, 'node', 'field_individual_participant');
hedley_general_join_field_to_query($query, 'node', 'field_person', TRUE, 'field_individual_participant.field_individual_participant_target_id');
$result = $query->execute()->fetchAll();

$query->condition('field_person.field_person_target_id', $patients_ids, 'IN');
}
$total_by_patient = [];
foreach ($result as $row) {
$total_by_patient[$row->field_person] = !empty($total_by_patient[$row->field_person]) ? $total_by_patient[$row->field_person] + 1 : 1;

$result[$key] = $query
->execute()
->rowCount();
}

return $result;
return $total_by_patient;
}

/**
Expand Down

0 comments on commit 9948c39

Please sign in to comment.