Add IOTA status handling to DXCC list

Introduces batch processing of IOTA worked/confirmed status in the controller and model, and updates the DXCC list view to display IOTA badges with status and links. Enhances visibility of IOTA information for each DXCC entry.
pull/3320/head
Peter Goodhall 2025-08-14 15:36:38 +01:00
rodzic 98ef3d8d83
commit a39ef57fdd
3 zmienionych plików z 135 dodań i 1 usunięć

Wyświetl plik

@ -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'],

Wyświetl plik

@ -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
*/

Wyświetl plik

@ -51,7 +51,32 @@ foreach ($grouped as $month => $dxccs) {
// Add satellite badge if worked via satellite
if (isset($dxcc['workedViaSatellite']) && $dxcc['workedViaSatellite']) {
echo '<span class="badge bg-info">Worked via Satellite</span>';
echo ' <span class="badge bg-info">Worked via Satellite</span>';
}
// 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 = '<a href="' . $mapUrl . '" target="_blank" class="text-white text-decoration-none">' . $iotaTag . '</a>';
if (isset($dxcc['iota_status'])) {
$s = $dxcc['iota_status'];
if (!empty($s) && isset($s['worked']) && $s['worked']) {
echo ' <span class="badge bg-success">IOTA ' . $iotaAnchor . ' Worked</span>';
} else {
echo ' <span class="badge bg-danger">IOTA ' . $iotaAnchor . ' Needed</span>';
}
if (!empty($s) && isset($s['confirmed']) && $s['confirmed']) {
echo ' <span class="badge bg-primary">Confirmed</span>';
}
} else {
// No status; render a neutral badge containing the link
echo ' <span class="badge bg-secondary">' . $iotaAnchor . '</span>';
}
}
echo '</td>