mirror of
https://github.com/wavelog/wavelog.git
synced 2026-03-22 10:24:14 +00:00
@@ -837,10 +837,11 @@ class API extends CI_Controller {
|
||||
$this->load->model('api_model');
|
||||
if ((($key ?? '') != '') && ($this->api_model->authorize($key) != 0)) {
|
||||
$this->load->model('logbook_model');
|
||||
$data['todays_qsos'] = $this->logbook_model->todays_qsos(null, $key);
|
||||
$data['total_qsos'] = $this->logbook_model->total_qsos(null, $key);
|
||||
$data['month_qsos'] = $this->logbook_model->month_qsos(null, $key);
|
||||
$data['year_qsos'] = $this->logbook_model->year_qsos(null, $key);
|
||||
$qso_counts = $this->logbook_model->get_qso_counts(null, $key);
|
||||
$data['todays_qsos'] = $qso_counts['today'];
|
||||
$data['total_qsos'] = $qso_counts['total'];
|
||||
$data['month_qsos'] = $qso_counts['month'];
|
||||
$data['year_qsos'] = $qso_counts['year'];
|
||||
} else { # for Downcompat
|
||||
$data['todays_qsos'] = 0;
|
||||
$data['total_qsos'] = 0;
|
||||
|
||||
@@ -97,11 +97,11 @@ class Dashboard extends CI_Controller {
|
||||
|
||||
$data['radio_status'] = $this->cat->recent_status();
|
||||
|
||||
// Store info
|
||||
$data['todays_qsos'] = $this->logbook_model->todays_qsos($logbooks_locations_array);
|
||||
$data['total_qsos'] = $this->logbook_model->total_qsos($logbooks_locations_array);
|
||||
$data['month_qsos'] = $this->logbook_model->month_qsos($logbooks_locations_array);
|
||||
$data['year_qsos'] = $this->logbook_model->year_qsos($logbooks_locations_array);
|
||||
$qso_counts = $this->logbook_model->get_qso_counts($logbooks_locations_array);
|
||||
$data['todays_qsos'] = $qso_counts['today'];
|
||||
$data['total_qsos'] = $qso_counts['total'];
|
||||
$data['month_qsos'] = $qso_counts['month'];
|
||||
$data['year_qsos'] = $qso_counts['year'];
|
||||
|
||||
$rawstreak=$this->dayswithqso_model->getAlmostCurrentStreak();
|
||||
if (is_array($rawstreak)) {
|
||||
@@ -110,37 +110,38 @@ class Dashboard extends CI_Controller {
|
||||
$data['current_streak']=0;
|
||||
}
|
||||
|
||||
// Load Countries Breakdown data into array
|
||||
$CountriesBreakdown = $this->logbook_model->total_countries_confirmed($logbooks_locations_array);
|
||||
// Load Dashboard stats (countries + QSL stats in one query)
|
||||
$stats = $this->logbook_model->dashboard_stats_batch($logbooks_locations_array);
|
||||
|
||||
$data['total_countries'] = $CountriesBreakdown['Countries_Worked'];
|
||||
$data['total_countries_confirmed_paper'] = $CountriesBreakdown['Countries_Worked_QSL'];
|
||||
$data['total_countries_confirmed_eqsl'] = $CountriesBreakdown['Countries_Worked_EQSL'];
|
||||
$data['total_countries_confirmed_lotw'] = $CountriesBreakdown['Countries_Worked_LOTW'];
|
||||
// Country stats
|
||||
$data['total_countries'] = $stats['Countries_Worked'];
|
||||
$data['total_countries_confirmed_paper'] = $stats['Countries_Worked_QSL'];
|
||||
$data['total_countries_confirmed_eqsl'] = $stats['Countries_Worked_EQSL'];
|
||||
$data['total_countries_confirmed_lotw'] = $stats['Countries_Worked_LOTW'];
|
||||
$current = $stats['Countries_Current'];
|
||||
|
||||
$QSLStatsBreakdownArray = $this->logbook_model->get_QSLStats($logbooks_locations_array);
|
||||
// QSL stats
|
||||
$data['total_qsl_sent'] = $stats['QSL_Sent'];
|
||||
$data['total_qsl_rcvd'] = $stats['QSL_Received'];
|
||||
$data['total_qsl_requested'] = $stats['QSL_Requested'];
|
||||
$data['qsl_sent_today'] = $stats['QSL_Sent_today'];
|
||||
$data['qsl_rcvd_today'] = $stats['QSL_Received_today'];
|
||||
$data['qsl_requested_today'] = $stats['QSL_Requested_today'];
|
||||
|
||||
$data['total_qsl_sent'] = $QSLStatsBreakdownArray['QSL_Sent'];
|
||||
$data['total_qsl_rcvd'] = $QSLStatsBreakdownArray['QSL_Received'];
|
||||
$data['total_qsl_requested'] = $QSLStatsBreakdownArray['QSL_Requested'];
|
||||
$data['qsl_sent_today'] = $QSLStatsBreakdownArray['QSL_Sent_today'];
|
||||
$data['qsl_rcvd_today'] = $QSLStatsBreakdownArray['QSL_Received_today'];
|
||||
$data['qsl_requested_today'] = $QSLStatsBreakdownArray['QSL_Requested_today'];
|
||||
$data['total_eqsl_sent'] = $stats['eQSL_Sent'];
|
||||
$data['total_eqsl_rcvd'] = $stats['eQSL_Received'];
|
||||
$data['eqsl_sent_today'] = $stats['eQSL_Sent_today'];
|
||||
$data['eqsl_rcvd_today'] = $stats['eQSL_Received_today'];
|
||||
|
||||
$data['total_eqsl_sent'] = $QSLStatsBreakdownArray['eQSL_Sent'];
|
||||
$data['total_eqsl_rcvd'] = $QSLStatsBreakdownArray['eQSL_Received'];
|
||||
$data['eqsl_sent_today'] = $QSLStatsBreakdownArray['eQSL_Sent_today'];
|
||||
$data['eqsl_rcvd_today'] = $QSLStatsBreakdownArray['eQSL_Received_today'];
|
||||
$data['total_lotw_sent'] = $stats['LoTW_Sent'];
|
||||
$data['total_lotw_rcvd'] = $stats['LoTW_Received'];
|
||||
$data['lotw_sent_today'] = $stats['LoTW_Sent_today'];
|
||||
$data['lotw_rcvd_today'] = $stats['LoTW_Received_today'];
|
||||
|
||||
$data['total_lotw_sent'] = $QSLStatsBreakdownArray['LoTW_Sent'];
|
||||
$data['total_lotw_rcvd'] = $QSLStatsBreakdownArray['LoTW_Received'];
|
||||
$data['lotw_sent_today'] = $QSLStatsBreakdownArray['LoTW_Sent_today'];
|
||||
$data['lotw_rcvd_today'] = $QSLStatsBreakdownArray['LoTW_Received_today'];
|
||||
|
||||
$data['total_qrz_sent'] = $QSLStatsBreakdownArray['QRZ_Sent'];
|
||||
$data['total_qrz_rcvd'] = $QSLStatsBreakdownArray['QRZ_Received'];
|
||||
$data['qrz_sent_today'] = $QSLStatsBreakdownArray['QRZ_Sent_today'];
|
||||
$data['qrz_rcvd_today'] = $QSLStatsBreakdownArray['QRZ_Received_today'];
|
||||
$data['total_qrz_sent'] = $stats['QRZ_Sent'];
|
||||
$data['total_qrz_rcvd'] = $stats['QRZ_Received'];
|
||||
$data['qrz_sent_today'] = $stats['QRZ_Sent_today'];
|
||||
$data['qrz_rcvd_today'] = $stats['QRZ_Received_today'];
|
||||
|
||||
$data['last_qso_count'] = empty($this->session->userdata('dashboard_last_qso_count')) ? DASHBOARD_DEFAULT_QSOS_COUNT : $this->session->userdata('dashboard_last_qso_count');
|
||||
$data['last_qsos_list'] = $this->logbook_model->get_last_qsos(
|
||||
@@ -156,8 +157,6 @@ class Dashboard extends CI_Controller {
|
||||
$this->load->model('dxcc');
|
||||
$dxcc = $this->dxcc->list_current();
|
||||
|
||||
$current = $this->logbook_model->total_countries_current($logbooks_locations_array);
|
||||
|
||||
$footerData['scripts'] = [
|
||||
'assets/js/sections/dashboard.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/sections/dashboard.js")),
|
||||
];
|
||||
|
||||
@@ -97,37 +97,37 @@ class Visitor extends CI_Controller {
|
||||
|
||||
$this->pagination->initialize($config);
|
||||
|
||||
// Store info
|
||||
$data['todays_qsos'] = $this->logbook_model->todays_qsos($logbooks_locations_array);
|
||||
$data['total_qsos'] = $this->logbook_model->total_qsos($logbooks_locations_array);
|
||||
$data['month_qsos'] = $this->logbook_model->month_qsos($logbooks_locations_array);
|
||||
$data['year_qsos'] = $this->logbook_model->year_qsos($logbooks_locations_array);
|
||||
$qso_counts = $this->logbook_model->get_qso_counts($logbooks_locations_array);
|
||||
$data['todays_qsos'] = $qso_counts['today'];
|
||||
$data['total_qsos'] = $qso_counts['total'];
|
||||
$data['month_qsos'] = $qso_counts['month'];
|
||||
$data['year_qsos'] = $qso_counts['year'];
|
||||
|
||||
$data['user_map_custom'] = $this->optionslib->get_map_custom(true,$public_slug);
|
||||
|
||||
// Load Countries Breakdown data into array
|
||||
$CountriesBreakdown = $this->logbook_model->total_countries_confirmed($logbooks_locations_array);
|
||||
// Load Dashboard stats (countries + QSL stats in one query)
|
||||
$stats = $this->logbook_model->dashboard_stats_batch($logbooks_locations_array);
|
||||
|
||||
$data['total_countries'] = $CountriesBreakdown['Countries_Worked'];
|
||||
$data['total_countries_confirmed_paper'] = $CountriesBreakdown['Countries_Worked_QSL'];
|
||||
$data['total_countries_confirmed_eqsl'] = $CountriesBreakdown['Countries_Worked_EQSL'];
|
||||
$data['total_countries_confirmed_lotw'] = $CountriesBreakdown['Countries_Worked_LOTW'];
|
||||
// Country stats
|
||||
$data['total_countries'] = $stats['Countries_Worked'];
|
||||
$data['total_countries_confirmed_paper'] = $stats['Countries_Worked_QSL'];
|
||||
$data['total_countries_confirmed_eqsl'] = $stats['Countries_Worked_EQSL'];
|
||||
$data['total_countries_confirmed_lotw'] = $stats['Countries_Worked_LOTW'];
|
||||
$current = $stats['Countries_Current'];
|
||||
|
||||
$dxcc = $this->dxcc->list_current();
|
||||
$current = $this->logbook_model->total_countries_current($logbooks_locations_array);
|
||||
$data['total_countries_needed'] = count($dxcc->result()) - $current;
|
||||
|
||||
$QSLStatsBreakdownArray =$this->logbook_model->get_QSLStats($logbooks_locations_array);
|
||||
// QSL stats
|
||||
$data['total_qsl_sent'] = $stats['QSL_Sent'];
|
||||
$data['total_qsl_rcvd'] = $stats['QSL_Received'];
|
||||
$data['total_qsl_requested'] = $stats['QSL_Requested'];
|
||||
|
||||
$data['total_qsl_sent'] = $QSLStatsBreakdownArray['QSL_Sent'];
|
||||
$data['total_qsl_rcvd'] = $QSLStatsBreakdownArray['QSL_Received'];
|
||||
$data['total_qsl_requested'] = $QSLStatsBreakdownArray['QSL_Requested'];
|
||||
$data['total_eqsl_sent'] = $stats['eQSL_Sent'];
|
||||
$data['total_eqsl_rcvd'] = $stats['eQSL_Received'];
|
||||
|
||||
$data['total_eqsl_sent'] = $QSLStatsBreakdownArray['eQSL_Sent'];
|
||||
$data['total_eqsl_rcvd'] = $QSLStatsBreakdownArray['eQSL_Received'];
|
||||
|
||||
$data['total_lotw_sent'] = $QSLStatsBreakdownArray['LoTW_Sent'];
|
||||
$data['total_lotw_rcvd'] = $QSLStatsBreakdownArray['LoTW_Received'];
|
||||
$data['total_lotw_sent'] = $stats['LoTW_Sent'];
|
||||
$data['total_lotw_rcvd'] = $stats['LoTW_Received'];
|
||||
|
||||
$data['results'] = $this->logbook_model->get_qsos($this->qso_per_page,$this->uri->segment(3),$logbooks_locations_array);
|
||||
|
||||
|
||||
@@ -3684,6 +3684,80 @@ class Logbook_model extends CI_Model {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Combined function to get all QSO counts (today, month, year, total) in a single query
|
||||
* This reduces 4 separate queries to 1, improving performance
|
||||
*/
|
||||
function get_qso_counts($StationLocationsArray = null, $api_key = null) {
|
||||
if ($StationLocationsArray == null) {
|
||||
$this->load->model('logbooks_model');
|
||||
if ($api_key != null) {
|
||||
$this->load->model('api_model');
|
||||
if (strpos($this->api_model->access($api_key), 'r') !== false) {
|
||||
$this->api_model->update_last_used($api_key);
|
||||
$user_id = $this->api_model->key_userid($api_key);
|
||||
$active_station_logbook = $this->logbooks_model->find_active_station_logbook_from_userid($user_id);
|
||||
$logbooks_locations_array = $this->logbooks_model->list_logbook_relationships($active_station_logbook);
|
||||
} else {
|
||||
$logbooks_locations_array = [];
|
||||
}
|
||||
} else {
|
||||
$logbooks_locations_array = $this->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
|
||||
}
|
||||
} else {
|
||||
$logbooks_locations_array = $StationLocationsArray;
|
||||
}
|
||||
|
||||
if (!$logbooks_locations_array) {
|
||||
return [
|
||||
'total' => 0,
|
||||
'today' => 0,
|
||||
'month' => 0,
|
||||
'year' => 0
|
||||
];
|
||||
}
|
||||
|
||||
// Calculate date boundaries once
|
||||
$todayStart = date('Y-m-d 00:00:00');
|
||||
$todayEnd = date('Y-m-d 23:59:59');
|
||||
$monthStart = date('Y-m-01 00:00:00');
|
||||
|
||||
$date = new DateTime('now');
|
||||
$date->modify('last day of this month');
|
||||
$monthEnd = $date->format('Y-m-d') . ' 23:59:59';
|
||||
|
||||
$yearStart = date('Y-01-01 00:00:00');
|
||||
$yearEnd = date('Y-12-31 23:59:59');
|
||||
|
||||
// Single query with conditional aggregation
|
||||
$sql = "SELECT
|
||||
COUNT(*) as total,
|
||||
SUM(CASE WHEN COL_TIME_ON >= ? AND COL_TIME_ON <= ? THEN 1 ELSE 0 END) as today,
|
||||
SUM(CASE WHEN COL_TIME_ON >= ? AND COL_TIME_ON <= ? THEN 1 ELSE 0 END) as month,
|
||||
SUM(CASE WHEN COL_TIME_ON >= ? AND COL_TIME_ON <= ? THEN 1 ELSE 0 END) as year
|
||||
FROM " . $this->config->item('table_name') . "
|
||||
WHERE station_id IN ('" . implode("','", $logbooks_locations_array) . "')";
|
||||
|
||||
$query = $this->db->query($sql, [$todayStart, $todayEnd, $monthStart, $monthEnd, $yearStart, $yearEnd]);
|
||||
|
||||
if ($query->num_rows() > 0) {
|
||||
$row = $query->row();
|
||||
return [
|
||||
'total' => (int)$row->total,
|
||||
'today' => (int)$row->today,
|
||||
'month' => (int)$row->month,
|
||||
'year' => (int)$row->year
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'total' => 0,
|
||||
'today' => 0,
|
||||
'month' => 0,
|
||||
'year' => 0
|
||||
];
|
||||
}
|
||||
|
||||
private function where_date_range($dateFrom, $dateTo) {
|
||||
if (!empty($dateFrom)) {
|
||||
$this->db->where('COL_TIME_ON >=', $dateFrom . ' 00:00:00');
|
||||
@@ -3930,30 +4004,36 @@ class Logbook_model extends CI_Model {
|
||||
$logbooks_locations_array = $StationLocationsArray;
|
||||
}
|
||||
|
||||
if (!empty($logbooks_locations_array)) {
|
||||
$this->db->select('
|
||||
COUNT(IF(COL_QSL_SENT="Y",COL_QSL_SENT,null)) as QSL_Sent,
|
||||
COUNT(IF(COL_QSL_RCVD="Y",COL_QSL_RCVD,null)) as QSL_Received,
|
||||
COUNT(IF(COL_QSL_SENT IN("Q", "R") ,COL_QSL_SENT,null)) as QSL_Requested,
|
||||
COUNT(IF(COL_EQSL_QSL_SENT="Y",COL_EQSL_QSL_SENT,null)) as eQSL_Sent,
|
||||
COUNT(IF(COL_EQSL_QSL_RCVD="Y",COL_EQSL_QSL_RCVD,null)) as eQSL_Received,
|
||||
COUNT(IF(COL_LOTW_QSL_SENT="Y",COL_LOTW_QSL_SENT,null)) as LoTW_Sent,
|
||||
COUNT(IF(COL_LOTW_QSL_RCVD="Y",COL_LOTW_QSL_RCVD,null)) as LoTW_Received,
|
||||
COUNT(IF(COL_QRZCOM_QSO_UPLOAD_STATUS="Y",COL_QRZCOM_QSO_UPLOAD_STATUS,null)) as QRZ_Sent,
|
||||
COUNT(IF(COL_QRZCOM_QSO_DOWNLOAD_STATUS="Y",COL_QRZCOM_QSO_DOWNLOAD_STATUS,null)) as QRZ_Received,
|
||||
COUNT(IF(COL_QSL_SENT="Y" and DATE(COL_QSLSDATE)=DATE(SYSDATE()),COL_QSL_SENT,null)) as QSL_Sent_today,
|
||||
COUNT(IF(COL_QSL_RCVD="Y" and DATE(COL_QSLRDATE)=DATE(SYSDATE()),COL_QSL_RCVD,null)) as QSL_Received_today,
|
||||
COUNT(IF(COL_QSL_SENT IN("Q", "R") and DATE(COL_QSLSDATE)=DATE(SYSDATE()) ,COL_QSL_SENT,null)) as QSL_Requested_today,
|
||||
COUNT(IF(COL_EQSL_QSL_SENT="Y" and DATE(COL_EQSL_QSLSDATE)=DATE(SYSDATE()),COL_EQSL_QSL_SENT,null)) as eQSL_Sent_today,
|
||||
COUNT(IF(COL_EQSL_QSL_RCVD="Y" and DATE(COL_EQSL_QSLRDATE)=DATE(SYSDATE()),COL_EQSL_QSL_RCVD,null)) as eQSL_Received_today,
|
||||
COUNT(IF(COL_LOTW_QSL_SENT="Y" and DATE(COL_LOTW_QSLSDATE)=DATE(SYSDATE()),COL_LOTW_QSL_SENT,null)) as LoTW_Sent_today,
|
||||
COUNT(IF(COL_LOTW_QSL_RCVD="Y" and DATE(COL_LOTW_QSLRDATE)=DATE(SYSDATE()),COL_LOTW_QSL_RCVD,null)) as LoTW_Received_today,
|
||||
COUNT(IF(COL_QRZCOM_QSO_UPLOAD_STATUS="Y" and DATE(COL_QRZCOM_QSO_UPLOAD_DATE)=DATE(SYSDATE()),COL_QRZCOM_QSO_UPLOAD_STATUS,null)) as QRZ_Sent_today,
|
||||
COUNT(IF(COL_QRZCOM_QSO_DOWNLOAD_STATUS="Y" and DATE(COL_QRZCOM_QSO_DOWNLOAD_DATE)=DATE(SYSDATE()),COL_QRZCOM_QSO_DOWNLOAD_STATUS,null)) as QRZ_Received_today
|
||||
');
|
||||
$this->db->where_in('station_id', $logbooks_locations_array);
|
||||
$location_list = "'" . implode("','", $logbooks_locations_array) . "'";
|
||||
|
||||
if ($query = $this->db->get($this->config->item('table_name'))) {
|
||||
if (!empty($logbooks_locations_array)) {
|
||||
$todayStart = date('Y-m-d 00:00:00');
|
||||
$tomorrowStart = date('Y-m-d 00:00:00', strtotime('+1 day'));
|
||||
$todayStartSql = $this->db->escape($todayStart);
|
||||
$tomorrowStartSql = $this->db->escape($tomorrowStart);
|
||||
$sql = 'SELECT
|
||||
SUM(CASE WHEN COL_QSL_SENT="Y" THEN 1 ELSE 0 END) as QSL_Sent,
|
||||
SUM(CASE WHEN COL_QSL_RCVD="Y" THEN 1 ELSE 0 END) as QSL_Received,
|
||||
SUM(CASE WHEN COL_QSL_SENT IN("Q", "R") THEN 1 ELSE 0 END) as QSL_Requested,
|
||||
SUM(CASE WHEN COL_EQSL_QSL_SENT="Y" THEN 1 ELSE 0 END) as eQSL_Sent,
|
||||
SUM(CASE WHEN COL_EQSL_QSL_RCVD="Y" THEN 1 ELSE 0 END) as eQSL_Received,
|
||||
SUM(CASE WHEN COL_LOTW_QSL_SENT="Y" THEN 1 ELSE 0 END) as LoTW_Sent,
|
||||
SUM(CASE WHEN COL_LOTW_QSL_RCVD="Y" THEN 1 ELSE 0 END) as LoTW_Received,
|
||||
SUM(CASE WHEN COL_QRZCOM_QSO_UPLOAD_STATUS="Y" THEN 1 ELSE 0 END) as QRZ_Sent,
|
||||
SUM(CASE WHEN COL_QRZCOM_QSO_DOWNLOAD_STATUS="Y" THEN 1 ELSE 0 END) as QRZ_Received,
|
||||
SUM(CASE WHEN COL_QSL_SENT="Y" AND COL_QSLSDATE >= ' . $todayStartSql . ' AND COL_QSLSDATE < ' . $tomorrowStartSql . ' THEN 1 ELSE 0 END) as QSL_Sent_today,
|
||||
SUM(CASE WHEN COL_QSL_RCVD="Y" AND COL_QSLRDATE >= ' . $todayStartSql . ' AND COL_QSLRDATE < ' . $tomorrowStartSql . ' THEN 1 ELSE 0 END) as QSL_Received_today,
|
||||
SUM(CASE WHEN COL_QSL_SENT IN("Q", "R") AND COL_QSLSDATE >= ' . $todayStartSql . ' AND COL_QSLSDATE < ' . $tomorrowStartSql . ' THEN 1 ELSE 0 END) as QSL_Requested_today,
|
||||
SUM(CASE WHEN COL_EQSL_QSL_SENT="Y" AND COL_EQSL_QSLSDATE >= ' . $todayStartSql . ' AND COL_EQSL_QSLSDATE < ' . $tomorrowStartSql . ' THEN 1 ELSE 0 END) as eQSL_Sent_today,
|
||||
SUM(CASE WHEN COL_EQSL_QSL_RCVD="Y" AND COL_EQSL_QSLRDATE >= ' . $todayStartSql . ' AND COL_EQSL_QSLRDATE < ' . $tomorrowStartSql . ' THEN 1 ELSE 0 END) as eQSL_Received_today,
|
||||
SUM(CASE WHEN COL_LOTW_QSL_SENT="Y" AND COL_LOTW_QSLSDATE >= ' . $todayStartSql . ' AND COL_LOTW_QSLSDATE < ' . $tomorrowStartSql . ' THEN 1 ELSE 0 END) as LoTW_Sent_today,
|
||||
SUM(CASE WHEN COL_LOTW_QSL_RCVD="Y" AND COL_LOTW_QSLRDATE >= ' . $todayStartSql . ' AND COL_LOTW_QSLRDATE < ' . $tomorrowStartSql . ' THEN 1 ELSE 0 END) as LoTW_Received_today,
|
||||
SUM(CASE WHEN COL_QRZCOM_QSO_UPLOAD_STATUS="Y" AND COL_QRZCOM_QSO_UPLOAD_DATE >= ' . $todayStartSql . ' AND COL_QRZCOM_QSO_UPLOAD_DATE < ' . $tomorrowStartSql . ' THEN 1 ELSE 0 END) as QRZ_Sent_today,
|
||||
SUM(CASE WHEN COL_QRZCOM_QSO_DOWNLOAD_STATUS="Y" AND COL_QRZCOM_QSO_DOWNLOAD_DATE >= ' . $todayStartSql . ' AND COL_QRZCOM_QSO_DOWNLOAD_DATE < ' . $tomorrowStartSql . ' THEN 1 ELSE 0 END) as QRZ_Received_today
|
||||
FROM ' . $this->config->item('table_name') . '
|
||||
WHERE station_id IN (' . $location_list . ')';
|
||||
|
||||
if ($query = $this->db->query($sql)) {
|
||||
$this->db->last_query();
|
||||
foreach ($query->result() as $row) {
|
||||
$QSLBreakdown['QSL_Sent'] = $row->QSL_Sent;
|
||||
@@ -4277,6 +4357,117 @@ class Logbook_model extends CI_Model {
|
||||
}
|
||||
}
|
||||
|
||||
/* Return combined countries breakdown + QSL stats in one query */
|
||||
function dashboard_stats_batch($StationLocationsArray = null) {
|
||||
if ($StationLocationsArray == null) {
|
||||
$this->load->model('logbooks_model');
|
||||
$logbooks_locations_array = $this->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
|
||||
} else {
|
||||
$logbooks_locations_array = $StationLocationsArray;
|
||||
}
|
||||
|
||||
if (!empty($logbooks_locations_array)) {
|
||||
$todayStart = date('Y-m-d 00:00:00');
|
||||
$tomorrowStart = date('Y-m-d 00:00:00', strtotime('+1 day'));
|
||||
$todayStartSql = $this->db->escape($todayStart);
|
||||
$tomorrowStartSql = $this->db->escape($tomorrowStart);
|
||||
|
||||
$location_list = "'" . implode("','", $logbooks_locations_array) . "'";
|
||||
|
||||
$sql = "SELECT
|
||||
-- Country stats (COUNT DISTINCT - filtered to valid DXCC only)
|
||||
COUNT(DISTINCT CASE WHEN t.COL_COUNTRY != 'Invalid' AND t.COL_DXCC > 0 THEN t.COL_DXCC END) as Countries_Worked,
|
||||
COUNT(DISTINCT CASE WHEN t.COL_QSL_RCVD = 'Y' AND t.COL_COUNTRY != 'Invalid' AND t.COL_DXCC > 0 THEN t.COL_DXCC END) as Countries_Worked_QSL,
|
||||
COUNT(DISTINCT CASE WHEN t.COL_EQSL_QSL_RCVD = 'Y' AND t.COL_COUNTRY != 'Invalid' AND t.COL_DXCC > 0 THEN t.COL_DXCC END) as Countries_Worked_EQSL,
|
||||
COUNT(DISTINCT CASE WHEN t.COL_LOTW_QSL_RCVD = 'Y' AND t.COL_COUNTRY != 'Invalid' AND t.COL_DXCC > 0 THEN t.COL_DXCC END) as Countries_Worked_LOTW,
|
||||
COUNT(DISTINCT CASE WHEN d.end IS NULL AND d.adif != 0 AND t.COL_COUNTRY != 'Invalid' AND t.COL_DXCC > 0 THEN t.COL_DXCC END) as Countries_Current,
|
||||
-- QSL stats (SUM - no filtering, all QSOs)
|
||||
SUM(CASE WHEN t.COL_QSL_SENT = 'Y' THEN 1 ELSE 0 END) as QSL_Sent,
|
||||
SUM(CASE WHEN t.COL_QSL_RCVD = 'Y' THEN 1 ELSE 0 END) as QSL_Received,
|
||||
SUM(CASE WHEN t.COL_QSL_SENT IN ('Q', 'R') THEN 1 ELSE 0 END) as QSL_Requested,
|
||||
SUM(CASE WHEN t.COL_EQSL_QSL_SENT = 'Y' THEN 1 ELSE 0 END) as eQSL_Sent,
|
||||
SUM(CASE WHEN t.COL_EQSL_QSL_RCVD = 'Y' THEN 1 ELSE 0 END) as eQSL_Received,
|
||||
SUM(CASE WHEN t.COL_LOTW_QSL_SENT = 'Y' THEN 1 ELSE 0 END) as LoTW_Sent,
|
||||
SUM(CASE WHEN t.COL_LOTW_QSL_RCVD = 'Y' THEN 1 ELSE 0 END) as LoTW_Received,
|
||||
SUM(CASE WHEN t.COL_QRZCOM_QSO_UPLOAD_STATUS = 'Y' THEN 1 ELSE 0 END) as QRZ_Sent,
|
||||
SUM(CASE WHEN t.COL_QRZCOM_QSO_DOWNLOAD_STATUS = 'Y' THEN 1 ELSE 0 END) as QRZ_Received,
|
||||
-- Today's stats (SUM - no filtering, all QSOs)
|
||||
SUM(CASE WHEN t.COL_QSL_SENT = 'Y' AND t.COL_QSLSDATE >= " . $todayStartSql . " AND t.COL_QSLSDATE < " . $tomorrowStartSql . " THEN 1 ELSE 0 END) as QSL_Sent_today,
|
||||
SUM(CASE WHEN t.COL_QSL_RCVD = 'Y' AND t.COL_QSLRDATE >= " . $todayStartSql . " AND t.COL_QSLRDATE < " . $tomorrowStartSql . " THEN 1 ELSE 0 END) as QSL_Received_today,
|
||||
SUM(CASE WHEN t.COL_QSL_SENT IN ('Q', 'R') AND t.COL_QSLSDATE >= " . $todayStartSql . " AND t.COL_QSLSDATE < " . $tomorrowStartSql . " THEN 1 ELSE 0 END) as QSL_Requested_today,
|
||||
SUM(CASE WHEN t.COL_EQSL_QSL_SENT = 'Y' AND t.COL_EQSL_QSLSDATE >= " . $todayStartSql . " AND t.COL_EQSL_QSLSDATE < " . $tomorrowStartSql . " THEN 1 ELSE 0 END) as eQSL_Sent_today,
|
||||
SUM(CASE WHEN t.COL_EQSL_QSL_RCVD = 'Y' AND t.COL_EQSL_QSLRDATE >= " . $todayStartSql . " AND t.COL_EQSL_QSLRDATE < " . $tomorrowStartSql . " THEN 1 ELSE 0 END) as eQSL_Received_today,
|
||||
SUM(CASE WHEN t.COL_LOTW_QSL_SENT = 'Y' AND t.COL_LOTW_QSLSDATE >= " . $todayStartSql . " AND t.COL_LOTW_QSLSDATE < " . $tomorrowStartSql . " THEN 1 ELSE 0 END) as LoTW_Sent_today,
|
||||
SUM(CASE WHEN t.COL_LOTW_QSL_RCVD = 'Y' AND t.COL_LOTW_QSLRDATE >= " . $todayStartSql . " AND t.COL_LOTW_QSLRDATE < " . $tomorrowStartSql . " THEN 1 ELSE 0 END) as LoTW_Received_today,
|
||||
SUM(CASE WHEN t.COL_QRZCOM_QSO_UPLOAD_STATUS = 'Y' AND t.COL_QRZCOM_QSO_UPLOAD_DATE >= " . $todayStartSql . " AND t.COL_QRZCOM_QSO_UPLOAD_DATE < " . $tomorrowStartSql . " THEN 1 ELSE 0 END) as QRZ_Sent_today,
|
||||
SUM(CASE WHEN t.COL_QRZCOM_QSO_DOWNLOAD_STATUS = 'Y' AND t.COL_QRZCOM_QSO_DOWNLOAD_DATE >= " . $todayStartSql . " AND t.COL_QRZCOM_QSO_DOWNLOAD_DATE < " . $tomorrowStartSql . " THEN 1 ELSE 0 END) as QRZ_Received_today
|
||||
FROM " . $this->config->item('table_name') . " t
|
||||
LEFT JOIN dxcc_entities d ON d.adif = t.col_dxcc
|
||||
WHERE t.station_id IN (" . $location_list . ")";
|
||||
|
||||
$query = $this->db->query($sql);
|
||||
|
||||
if ($query->num_rows() > 0) {
|
||||
$row = $query->row();
|
||||
return [
|
||||
// Country stats
|
||||
'Countries_Worked' => $row->Countries_Worked,
|
||||
'Countries_Worked_QSL' => $row->Countries_Worked_QSL,
|
||||
'Countries_Worked_EQSL' => $row->Countries_Worked_EQSL,
|
||||
'Countries_Worked_LOTW' => $row->Countries_Worked_LOTW,
|
||||
'Countries_Current' => $row->Countries_Current,
|
||||
// QSL stats
|
||||
'QSL_Sent' => $row->QSL_Sent,
|
||||
'QSL_Received' => $row->QSL_Received,
|
||||
'QSL_Requested' => $row->QSL_Requested,
|
||||
'eQSL_Sent' => $row->eQSL_Sent,
|
||||
'eQSL_Received' => $row->eQSL_Received,
|
||||
'LoTW_Sent' => $row->LoTW_Sent,
|
||||
'LoTW_Received' => $row->LoTW_Received,
|
||||
'QRZ_Sent' => $row->QRZ_Sent,
|
||||
'QRZ_Received' => $row->QRZ_Received,
|
||||
// Today's stats
|
||||
'QSL_Sent_today' => $row->QSL_Sent_today,
|
||||
'QSL_Received_today' => $row->QSL_Received_today,
|
||||
'QSL_Requested_today' => $row->QSL_Requested_today,
|
||||
'eQSL_Sent_today' => $row->eQSL_Sent_today,
|
||||
'eQSL_Received_today' => $row->eQSL_Received_today,
|
||||
'LoTW_Sent_today' => $row->LoTW_Sent_today,
|
||||
'LoTW_Received_today' => $row->LoTW_Received_today,
|
||||
'QRZ_Sent_today' => $row->QRZ_Sent_today,
|
||||
'QRZ_Received_today' => $row->QRZ_Received_today
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Return zero values if no data
|
||||
return [
|
||||
'Countries_Worked' => 0,
|
||||
'Countries_Worked_QSL' => 0,
|
||||
'Countries_Worked_EQSL' => 0,
|
||||
'Countries_Worked_LOTW' => 0,
|
||||
'Countries_Current' => 0,
|
||||
'QSL_Sent' => 0,
|
||||
'QSL_Received' => 0,
|
||||
'QSL_Requested' => 0,
|
||||
'eQSL_Sent' => 0,
|
||||
'eQSL_Received' => 0,
|
||||
'LoTW_Sent' => 0,
|
||||
'LoTW_Received' => 0,
|
||||
'QRZ_Sent' => 0,
|
||||
'QRZ_Received' => 0,
|
||||
'QSL_Sent_today' => 0,
|
||||
'QSL_Received_today' => 0,
|
||||
'QSL_Requested_today' => 0,
|
||||
'eQSL_Sent_today' => 0,
|
||||
'eQSL_Received_today' => 0,
|
||||
'LoTW_Sent_today' => 0,
|
||||
'LoTW_Received_today' => 0,
|
||||
'QRZ_Sent_today' => 0,
|
||||
'QRZ_Received_today' => 0
|
||||
];
|
||||
}
|
||||
|
||||
/* Return total number of countries confirmed with paper QSL */
|
||||
function total_countries_confirmed_paper() {
|
||||
$this->load->model('logbooks_model');
|
||||
|
||||
@@ -353,76 +353,122 @@ class VUCC extends CI_Model
|
||||
return $workedGridArray;
|
||||
}
|
||||
|
||||
private function get_vucc_combined_data($band = 'All') {
|
||||
if (!$this->logbooks_locations_array) {
|
||||
return ['gridsquare' => [], 'vucc_grids' => []];
|
||||
}
|
||||
|
||||
$results = ['gridsquare' => [], 'vucc_grids' => []];
|
||||
|
||||
$inPlaceholders = str_repeat('?,', count($this->logbooks_locations_array) - 1) . '?';
|
||||
|
||||
// Query 1: Get col_gridsquare data with worked/confirmed status
|
||||
$bindings1 = array_merge($this->logbooks_locations_array);
|
||||
$bandCondition1 = '';
|
||||
|
||||
if ($band != 'All') {
|
||||
if ($band == 'SAT') {
|
||||
$bandCondition1 = " and log.col_prop_mode = ?";
|
||||
$bindings1[] = $band;
|
||||
} else {
|
||||
$bandCondition1 = " and log.col_prop_mode != ? and log.col_band = ?";
|
||||
$bindings1[] = 'SAT';
|
||||
$bindings1[] = $band;
|
||||
}
|
||||
} else {
|
||||
$bandCondition1 = " and log.col_prop_mode != ?";
|
||||
$bindings1[] = 'SAT';
|
||||
}
|
||||
|
||||
$sql1 = "SELECT
|
||||
DISTINCT UPPER(SUBSTRING(col_gridsquare, 1, 4)) as gridsquare,
|
||||
MAX(CASE WHEN (col_qsl_rcvd='Y' OR col_lotw_qsl_rcvd='Y') THEN 1 ELSE 0 END) as confirmed
|
||||
FROM " . $this->config->item('table_name') . " log
|
||||
INNER JOIN bands b ON (b.band = log.col_band)
|
||||
WHERE log.station_id IN (" . $inPlaceholders . ")
|
||||
AND log.col_gridsquare <> ''
|
||||
AND b.bandgroup IN ('vhf','uhf','shf','sat')"
|
||||
. $bandCondition1 . "
|
||||
GROUP BY UPPER(SUBSTRING(col_gridsquare, 1, 4))";
|
||||
|
||||
$query1 = $this->db->query($sql1, $bindings1);
|
||||
if ($query1->num_rows() > 0) {
|
||||
$results['gridsquare'] = $query1->result_array();
|
||||
}
|
||||
|
||||
// Query 2: Get col_vucc_grids data with worked/confirmed status
|
||||
// Note: col_vucc_grids has NO band filter when band='All' (includes SAT)
|
||||
$bindings2 = array_merge($this->logbooks_locations_array);
|
||||
$bandCondition2 = '';
|
||||
|
||||
if ($band != 'All') {
|
||||
if ($band == 'SAT') {
|
||||
$bandCondition2 = " and col_prop_mode = ?";
|
||||
$bindings2[] = $band;
|
||||
} else {
|
||||
$bandCondition2 = " and col_prop_mode != ? and col_band = ?";
|
||||
$bindings2[] = 'SAT';
|
||||
$bindings2[] = $band;
|
||||
}
|
||||
}
|
||||
// When band='All', NO band filter is added (includes all prop_mode including SAT)
|
||||
|
||||
$sql2 = "SELECT
|
||||
DISTINCT col_vucc_grids,
|
||||
MAX(CASE WHEN (col_qsl_rcvd='Y' OR col_lotw_qsl_rcvd='Y') THEN 1 ELSE 0 END) as confirmed
|
||||
FROM " . $this->config->item('table_name') . "
|
||||
WHERE station_id IN (" . $inPlaceholders . ")
|
||||
AND col_vucc_grids <> ''"
|
||||
. $bandCondition2 . "
|
||||
GROUP BY col_vucc_grids";
|
||||
|
||||
$query2 = $this->db->query($sql2, $bindings2);
|
||||
if ($query2->num_rows() > 0) {
|
||||
$results['vucc_grids'] = $query2->result_array();
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds the array to display worked/confirmed vucc on dashboard page
|
||||
*/
|
||||
function fetchVuccSummary($band = 'All') {
|
||||
$totalGridConfirmed = array();
|
||||
$totalGridWorked = array();
|
||||
// Use associative arrays for O(1) lookups instead of O(n) in_array()
|
||||
$totalGridWorked = [];
|
||||
$totalGridConfirmed = [];
|
||||
|
||||
// Getting all the worked grids
|
||||
$col_gridsquare_worked = $this->get_vucc_summary($band, 'none');
|
||||
// Get combined data (2 queries instead of 4)
|
||||
$data = $this->get_vucc_combined_data($band);
|
||||
|
||||
$workedGridArray = array();
|
||||
if ($col_gridsquare_worked != null) {
|
||||
foreach ($col_gridsquare_worked as $workedgrid) {
|
||||
array_push($workedGridArray, $workedgrid['gridsquare']);
|
||||
if(!in_array($workedgrid['gridsquare'], $totalGridWorked)){
|
||||
array_push($totalGridWorked, $workedgrid['gridsquare']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$col_vucc_grids_worked = $this->get_vucc_summary_col_vucc($band, 'none');
|
||||
|
||||
if ($col_vucc_grids_worked != null) {
|
||||
foreach ($col_vucc_grids_worked as $gridSplit) {
|
||||
$grids = explode(",", $gridSplit['col_vucc_grids']);
|
||||
foreach($grids as $key) {
|
||||
$grid_four = strtoupper(substr(trim($key),0,4));
|
||||
|
||||
if(!in_array($grid_four, $workedGridArray)){
|
||||
array_push($workedGridArray, $grid_four);
|
||||
}
|
||||
|
||||
if(!in_array($grid_four, $totalGridWorked)){
|
||||
array_push($totalGridWorked, $grid_four);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Getting all the confirmed grids
|
||||
$col_gridsquare_confirmed = $this->get_vucc_summary($band, 'both');
|
||||
$confirmedGridArray = array();
|
||||
|
||||
if ($col_gridsquare_confirmed != null) {
|
||||
foreach ($col_gridsquare_confirmed as $confirmedgrid) {
|
||||
array_push($confirmedGridArray, $confirmedgrid['gridsquare']);
|
||||
if(!in_array($confirmedgrid['gridsquare'], $totalGridConfirmed)){
|
||||
array_push($totalGridConfirmed, $confirmedgrid['gridsquare']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$col_vucc_grids_confirmed = $this->get_vucc_summary_col_vucc($band, 'both');
|
||||
|
||||
if ($col_vucc_grids_confirmed != null) {
|
||||
foreach ($col_vucc_grids_confirmed as $gridSplit) {
|
||||
$grids = explode(",", $gridSplit['col_vucc_grids']);
|
||||
foreach($grids as $key) {
|
||||
$grid_four = strtoupper(substr(trim($key),0,4));
|
||||
|
||||
if(!in_array($grid_four, $confirmedGridArray)){
|
||||
array_push($confirmedGridArray, $grid_four);
|
||||
}
|
||||
|
||||
if(!in_array($grid_four, $totalGridConfirmed)){
|
||||
array_push($totalGridConfirmed, $grid_four);
|
||||
}
|
||||
// Process col_gridsquare data
|
||||
if (!empty($data['gridsquare'])) {
|
||||
foreach ($data['gridsquare'] as $row) {
|
||||
$grid = $row['gridsquare'];
|
||||
// Always add to worked
|
||||
$totalGridWorked[$grid] = true;
|
||||
// Add to confirmed if flagged
|
||||
if ($row['confirmed']) {
|
||||
$totalGridConfirmed[$grid] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process col_vucc_grids data
|
||||
if (!empty($data['vucc_grids'])) {
|
||||
foreach ($data['vucc_grids'] as $row) {
|
||||
$grids = explode(",", $row['col_vucc_grids']);
|
||||
foreach ($grids as $key) {
|
||||
$grid_four = strtoupper(substr(trim($key), 0, 4));
|
||||
// Always add to worked
|
||||
$totalGridWorked[$grid_four] = true;
|
||||
// Add to confirmed if flagged
|
||||
if ($row['confirmed']) {
|
||||
$totalGridConfirmed[$grid_four] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$vuccArray[$band]['worked'] = count($totalGridWorked);
|
||||
$vuccArray[$band]['confirmed'] = count($totalGridConfirmed);
|
||||
|
||||
Reference in New Issue
Block a user