function farm_livestock_weight_group_report in farmOS 7
Generate Animal Weight Group Report
2 calls to farm_livestock_weight_group_report()
- farm_livestock_weight_group_report_csv in modules/
farm/ farm_livestock/ farm_livestock_weight/ farm_livestock_weight.module - Animal Weight Group Report CSV Export
- farm_livestock_weight_group_report_form_submit in modules/
farm/ farm_livestock/ farm_livestock_weight/ farm_livestock_weight.module - Submit handler for the weight report form
File
- modules/
farm/ farm_livestock/ farm_livestock_weight/ farm_livestock_weight.module, line 453 - Farm livestock weight module.
Code
function farm_livestock_weight_group_report(&$form_state) {
// Get the submitted group IDs to include in the report.
$group_ids = $form_state['values']['group'];
// Check if we should include archived assets.
$include_archived = (bool) $form_state['values']['archived'];
$only_archived = $form_state['values']['archived'] == 1;
// Get list of flags to filter by.
$flags = $form_state['values']['flags'];
// Get date of birth filters.
$earliest_birth = strtotime($form_state['values']['earliest_birth']);
$latest_birth = strtotime($form_state['values']['latest_birth']);
// Get the start and end dates.
$start_date = strtotime($form_state['values']['start_date']);
$end_date = strtotime($form_state['values']['end_date']);
// Array to store dates of animal weight logs for CSV export.
$date_format = 'Y-m-d';
$all_log_dates = array();
// Array to store animals and log data
$animals = array();
// Loop through each group, its members, and all weight logs.
foreach ($group_ids as $id) {
// Load the farm group asset.
$group = farm_asset_load($id);
// Load the farm group members.
$members = farm_group_members($group, REQUEST_TIME, TRUE, $include_archived);
// Loop through members.
foreach ($members as $asset) {
// If member is not an animal, bail.
if ($asset->type != 'animal') {
continue;
}
// Skip non-archived assets if only displaying archived assets.
if ($only_archived && !$asset->archived) {
continue;
}
// Check if asset has required flags.
if (!empty($flags)) {
// Compare asset flags to required flags.
$asset_flags = farm_flags_load($asset);
$diff = array_diff($flags, $asset_flags);
// Skip the asset if it doesn't have required flags.
if (!empty($diff)) {
continue;
}
}
// Check if a birth date filter is specified.
if ($earliest_birth || $latest_birth) {
// Get the assets birth date.
$birth_date = NULL;
if (!empty($asset->field_farm_date[LANGUAGE_NONE][0]['value'])) {
$birth_date = $asset->field_farm_date[LANGUAGE_NONE][0]['value'];
}
// Skip assets without a birth date.
if (empty($birth_date)) {
continue;
}
// Skip assets born before earliest birth date.
if ($earliest_birth) {
if ($birth_date < $earliest_birth) {
continue;
}
}
// Skip assets born after latest birth date.
if ($latest_birth) {
if ($birth_date > $latest_birth) {
continue;
}
}
}
// Save the animal info
$asset->group = $group;
// Load the group member's weights
$time = REQUEST_TIME;
if (!empty($end_date)) {
$time = $end_date;
}
$logs = farm_quantity_log_asset($asset, 'weight', NULL, $time, TRUE, 'farm_observation', FALSE);
// Array to save log dates for this one animal.
$log_dates = array();
// Array to save data from animal logs.
$all_log_data = array();
// Loop through weight logs.
foreach ($logs as $log) {
// Get the date of the log from the timestamp.
$log_date = date($date_format, $log->timestamp);
// Check that the log timestamp fits the date parameters. Note that we
// only need to check the start date bound, because end date is already
// filtered by farm_quantity_log_asset().
if ($log->timestamp < $start_date) {
continue;
}
// Add the log date to the array if not already included.
if (!in_array($log_date, $log_dates)) {
$log_dates[] = $log_date;
}
else {
continue;
}
// Extract quantity data from the log.
$data = farm_quantity_log_data($log, 'weight');
// Iterate through the data and return the first one with a value.
foreach ($data as $quantity) {
if (!empty($quantity['value'])) {
$value = $quantity['value'];
$units = $quantity['units'];
// Add the log data to array of logs.
$log_data = array();
$log_data['date'] = $log_date;
$log_data['value'] = $value;
$log_data['units'] = $units;
$all_log_data[] = $log_data;
}
}
}
// Merge animal's log dates with all_log_dates.
$all_log_dates = array_unique(array_merge($all_log_dates, $log_dates));
// Save all log data with the animal.
$asset->all_log_data = $all_log_data;
// Add animal data to array of all animals.
$animals[] = $asset;
}
}
// Sort all collected log_dates.
sort($all_log_dates);
// Create a header for CSV and HTML Table
$header = array(
t('Asset ID'),
t('Asset Name'),
t('Group'),
);
// Add columns for each date collected.
foreach ($all_log_dates as $date) {
$header[] = t('Date - ') . $date;
$header[] = t('Weight');
$header[] = t('Units');
}
// Add the CSV header.
$csvdata = implode(',', $header) . PHP_EOL;
// Initialize array for Date Averages
$group_date_averages = array();
foreach ($group_ids as $id) {
$group_date_averages[$id] = array(
'group' => farm_asset_load($id),
'dates' => array(),
);
}
foreach ($animals as $animal) {
// Add a row of data.
$row = array();
$name_label = htmlspecialchars(entity_label('farm_asset', $animal));
if ($animal->archived) {
$date = strftime('%Y-%m-%d', $animal->archived);
$name_label = $name_label . ' (' . t('archived') . ' ' . $date . ')';
}
$row[] = $animal->id;
$row[] = $name_label;
$row[] = htmlspecialchars(entity_label('farm_asset', $animal->group));
// Save the logs.
$logs = $animal->all_log_data;
// Skip adding logs if the animal has no logs
if (sizeof($logs) == 0) {
// Add Animal info to results.
$table_data[] = $row;
$csvdata .= implode(',', $row) . PHP_EOL;
continue;
}
// Sort the logs by date.
usort($logs, "farm_livestock_weight_log_array_sort_date");
// Save a counter for which log to compare.
$curr_log_index = 0;
// Save a counter for which column to compare.
$curr_column_index = 0;
// Walk through each column and add log data if log date == column date.
// Note that each date requires 3 columns in the CSV file to display the
// date, value and units of recorded log weights.
while ($curr_log_index < sizeof($logs) && $curr_column_index < sizeof($all_log_dates)) {
// Conert the dates to times for easier comparison.
$column_time = strtotime($all_log_dates[$curr_column_index]);
$log_time = strtotime($logs[$curr_log_index]['date']);
// If the log_time is less than column_time, then there are multiple logs
// on the same date for the animal. The first one has already been saved,
// skip any additional logs with the same date.
if ($column_time > $log_time) {
$curr_log_index += 1;
// Set empty values if the times don't match.
// Move to next column
}
else {
if ($column_time != $log_time) {
$row[] = '';
$row[] = '';
$row[] = '';
$curr_column_index += 1;
}
else {
$log_date = $logs[$curr_log_index]['date'];
$log_value = $logs[$curr_log_index]['value'];
$log_units = $logs[$curr_log_index]['units'];
// Save the log date, value and units if the times match.
$row[] = $log_date;
$row[] = $log_value;
$row[] = $log_units;
// For displaying graphs of average weights
// Tally the weight of the animal in the All Log Dates array
// Initialize the Group's average weight array for the log date.
if (!isset($group_date_averages[$animal->group->id]['dates'][$log_date])) {
$group_date_averages[$animal->group->id]['dates'][$log_date] = array(
'units' => $log_units,
'total_weight' => $log_value,
'animal_count' => 1,
);
}
else {
$group_date_averages[$animal->group->id]['dates'][$log_date]['total_weight'] += $log_value;
$group_date_averages[$animal->group->id]['dates'][$log_date]['animal_count'] += 1;
}
// Move to next column, and next log.
$curr_column_index += 1;
$curr_log_index += 1;
}
}
}
// Add row to HTML Table
$table_data[] = $row;
// Add to CSV string
$csvdata .= implode(',', $row) . PHP_EOL;
}
$table = '<div class="alert alert-danger">' . t('No animal assets match the above criteria.') . '</div>';
if (!empty($table_data)) {
// Create HTML Table
$table = theme('table', array(
'header' => $header,
'rows' => $table_data,
));
}
// Create the div to hold report graphs.
$graph_markup = array();
// Create a graph object to pass to JS.
$graphs = array();
// Create graphs for each group
foreach ($group_date_averages as $group) {
$group_name = $group['group']->name;
// Sort the array by date
ksort($group['dates']);
$dates = array_keys($group['dates']);
for ($i = 0; $i < count($group['dates']); $i++) {
$date = $dates[$i];
// Calculate average weight.
$date_average = $group['dates'][$date]['total_weight'] / $group['dates'][$date]['animal_count'];
$group['dates'][$date]['average_weight'] = $date_average;
// Calculate Average Daily Gain after the first date.
if ($i > 0) {
$previous_date = $dates[$i - 1];
$previous_average = $group['dates'][$previous_date]['average_weight'];
// Calculate gain between the two dates.
$gain = $date_average - $previous_average;
// Calculate days elapsed.
$dStart = new DateTime($previous_date);
$dEnd = new DateTime($date);
$days_elapsed = (int) $dStart
->diff($dEnd)
->format("%a");
// Save the daily gain value within the 'date' array.
$group['dates'][$date]['gain'] = $gain / $days_elapsed;
}
}
// Create Average Weight Graph
$graph = array(
'name' => t('Average Weight - ') . $group_name,
'id' => 'farm-livestock-average-weight-' . $group_name . '-graph',
'data' => $group['dates'],
);
$graphs[] = $graph;
$graph_markup[] = '<div id="farm-livestock-average-weight-' . $group_name . '-graph" class="farm-report-graph"></div>';
}
$graph_settings = array(
'farm_livestock_report' => array(
'graphs' => $graphs,
),
);
return array(
'graph-settings' => $graph_settings,
'graph-markup' => $graph_markup,
'table' => $table,
'csv' => $csvdata,
);
}