diff --git a/application/controllers/Workabledxcc.php b/application/controllers/Workabledxcc.php index 76964818..fda5adb8 100644 --- a/application/controllers/Workabledxcc.php +++ b/application/controllers/Workabledxcc.php @@ -58,6 +58,19 @@ class Workabledxcc extends CI_Controller $uniqueEntities = array_unique(array_filter($dxccEntities)); $dxccStatus = $this->Workabledxcc_model->batchDxccWorkedStatus($uniqueEntities); + // If JSON contains iota fields, batch process IOTA status + $iotas = []; + foreach ($dataResult as $item) { + if (!empty($item['iota'])) { + $iotas[] = $item['iota']; + } + } + $uniqueIotas = array_unique($iotas); + $iotaStatus = []; + if (!empty($uniqueIotas)) { + $iotaStatus = $this->Workabledxcc_model->batchIotaWorkedStatus($uniqueIotas); + } + // Process results $requiredData = array(); foreach ($dataResult as $index => $item) { @@ -80,6 +93,8 @@ class Workabledxcc extends CI_Controller 'start_date' => $StartDate, 'end_date' => $EndDate, 'country' => $item['2'], + 'iota' => isset($item['iota']) ? $item['iota'] : null, + 'iota_status' => (isset($item['iota']) && isset($iotaStatus[$item['iota']])) ? $iotaStatus[$item['iota']] : null, 'notes' => $item['6'], 'callsign' => $item['callsign'], 'workedBefore' => $worked['workedBefore'], diff --git a/application/models/Workabledxcc_model.php b/application/models/Workabledxcc_model.php index 55f765e5..a09e54c3 100644 --- a/application/models/Workabledxcc_model.php +++ b/application/models/Workabledxcc_model.php @@ -88,6 +88,100 @@ class Workabledxcc_model extends CI_Model return $results; } + /** + * Batch check IOTA worked/confirmed status + * @param array $iotas Array of unique IOTA tags + * @return array Array indexed by IOTA tag with ['worked'=>bool,'confirmed'=>bool] + */ + public function batchIotaWorkedStatus($iotas) + { + if (empty($iotas)) { + return array(); + } + + $user_default_confirmation = $this->session->userdata('user_default_confirmation'); + $this->load->model('logbooks_model'); + $logbooks_locations_array = $this->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook')); + + if (empty($logbooks_locations_array)) { + $out = []; + foreach ($iotas as $i) { + $out[$i] = ['worked' => false, 'confirmed' => false]; + } + return $out; + } + + // Build confirmation criteria once + $confirmationCriteria = $this->buildConfirmationCriteria($user_default_confirmation); + + // Build case-insensitive WHERE conditions for COL_IOTA + $whereConditions = array(); + foreach ($iotas as $iota) { + $whereConditions[] = "UPPER(COL_IOTA) = UPPER('" . $this->db->escape_str($iota) . "')"; + } + + if (empty($whereConditions)) { + return array(); + } + + $whereClause = '(' . implode(' OR ', $whereConditions) . ')'; + + // Worked query (any mode) + $this->db->select('COL_IOTA') + ->distinct() + ->from($this->config->item('table_name')) + ->where_in('station_id', $logbooks_locations_array) + ->where($whereClause); + + $workedQuery = $this->db->get(); + log_message('debug', 'Workable DXCC IOTA worked query: ' . $this->db->last_query()); + + $workedResults = array(); + foreach ($workedQuery->result() as $row) { + foreach ($iotas as $iota) { + if (strtoupper($row->COL_IOTA) === strtoupper($iota)) { + $workedResults[$iota] = true; + break; + } + } + } + + // Confirmed query (apply confirmation criteria, exclude satellite confirmations if desired) + $confirmedResults = array(); + if ($confirmationCriteria !== '1=0') { + $this->db->select('COL_IOTA') + ->distinct() + ->from($this->config->item('table_name')) + ->where($confirmationCriteria) + ->where_in('station_id', $logbooks_locations_array) + ->where($whereClause); + + $confirmedQuery = $this->db->get(); + foreach ($confirmedQuery->result() as $row) { + foreach ($iotas as $iota) { + if (strtoupper($row->COL_IOTA) === strtoupper($iota)) { + $confirmedResults[$iota] = true; + break; + } + } + } + } + + $out = array(); + foreach ($iotas as $iota) { + $out[$iota] = [ + 'worked' => isset($workedResults[$iota]), + 'confirmed' => isset($confirmedResults[$iota]) + ]; + } + + // Debug + log_message('debug', 'Workable DXCC: IOTA worked results: ' . json_encode($workedResults)); + log_message('debug', 'Workable DXCC: IOTA confirmed results: ' . json_encode($confirmedResults)); + + return $out; + } + /** * Batch query to check which entities have been worked via satellite */ diff --git a/application/views/workabledxcc/components/dxcclist.php b/application/views/workabledxcc/components/dxcclist.php index 83e0a4d1..5eda33d2 100644 --- a/application/views/workabledxcc/components/dxcclist.php +++ b/application/views/workabledxcc/components/dxcclist.php @@ -51,7 +51,32 @@ foreach ($grouped as $month => $dxccs) { // Add satellite badge if worked via satellite if (isset($dxcc['workedViaSatellite']) && $dxcc['workedViaSatellite']) { - echo 'Worked via Satellite'; + echo ' Worked via Satellite'; + } + + // IOTA handling: show badge if JSON contained an iota field + if (isset($dxcc['iota']) && !empty($dxcc['iota'])) { + $iotaTag = $dxcc['iota']; + $mapUrl = 'https://www.iota-world.org/iotamaps/?grpref=' . $iotaTag; + // Anchor inside badge should inherit readable text colour + $iotaAnchor = '' . $iotaTag . ''; + + if (isset($dxcc['iota_status'])) { + $s = $dxcc['iota_status']; + + if (!empty($s) && isset($s['worked']) && $s['worked']) { + echo ' IOTA ' . $iotaAnchor . ' Worked'; + } else { + echo ' IOTA ' . $iotaAnchor . ' Needed'; + } + + if (!empty($s) && isset($s['confirmed']) && $s['confirmed']) { + echo ' Confirmed'; + } + } else { + // No status; render a neutral badge containing the link + echo ' ' . $iotaAnchor . ''; + } } echo '