From 0c5c94d191897636a42bbf9d85fbb661e717e8cd Mon Sep 17 00:00:00 2001 From: Andreas <6977712+AndreasK79@users.noreply.github.com> Date: Tue, 2 May 2023 14:48:46 +0200 Subject: [PATCH 1/5] [Advanced Logbook] Added columns for QSL/LoTW/eQSL --- application/views/logbookadvanced/index.php | 5 +- assets/js/sections/logbookadvanced.js | 11 +- src/QSLManager/QSO.php | 251 +++++++++++++++++++- 3 files changed, 259 insertions(+), 8 deletions(-) diff --git a/application/views/logbookadvanced/index.php b/application/views/logbookadvanced/index.php index 7b094c59..2e94dd18 100644 --- a/application/views/logbookadvanced/index.php +++ b/application/views/logbookadvanced/index.php @@ -201,8 +201,9 @@ Refs Name QSL Via - QSL Sent - QSL Received + QSL + LoTW + eQSL QSL Msg DXCC State diff --git a/assets/js/sections/logbookadvanced.js b/assets/js/sections/logbookadvanced.js index 7a4c9747..f410b60e 100644 --- a/assets/js/sections/logbookadvanced.js +++ b/assets/js/sections/logbookadvanced.js @@ -26,8 +26,9 @@ function updateRow(qso) { cells.eq(c++).text(qso.dxRefs); cells.eq(c++).text(qso.name); cells.eq(c++).text(qso.qslVia); - cells.eq(c++).text(qso.qslSent); - cells.eq(c++).text(qso.qslReceived); + cells.eq(c++).text(qso.qsl); + cells.eq(c++).text(qso.lotw); + cells.eq(c++).text(qso.eqsl); cells.eq(c++).text(qso.qslMessage); cells.eq(c++).text(qso.dxcc); cells.eq(c++).text(qso.state); @@ -74,8 +75,9 @@ function loadQSOTable(rows) { qso.dxRefs, qso.name, qso.qslVia, - qso.qslSent, - qso.qslReceived, + qso.qsl, + qso.lotw, + qso.eqsl, qso.qslMessage, qso.dxcc+(qso.end == null ? '' : ' Deleted DXCC'), qso.state, @@ -88,6 +90,7 @@ function loadQSOTable(rows) { table.row(createdRow).node().id = 'qsoID-' + qso.qsoID; } table.draw(); + $('[data-toggle="tooltip"]').tooltip(); } function processNextCallbookItem() { diff --git a/src/QSLManager/QSO.php b/src/QSLManager/QSO.php index ee1a5bc3..6d60b11e 100644 --- a/src/QSLManager/QSO.php +++ b/src/QSLManager/QSO.php @@ -55,6 +55,10 @@ class QSO private string $QSLSentVia; private string $QSLVia; private ?DateTime $end; + /** QSL **/ + private string $qsl; + private string $lotw; + private string $eqsl; /** * @param array $data Does no validation, it's assumed to be a row from the database in array format @@ -164,6 +168,20 @@ class QSO $this->QSLSentVia = ($data['COL_QSL_SENT_VIA'] === null) ? '' : $data['COL_QSL_SENT_VIA']; $this->QSLVia = ($data['COL_QSL_VIA'] === null) ? '' : $data['COL_QSL_VIA']; + $CI =& get_instance(); + // Get Date format + if($CI->session->userdata('user_date_format')) { + // If Logged in and session exists + $custom_date_format = $CI->session->userdata('user_date_format'); + } else { + // Get Default date format from /config/cloudlog.php + $custom_date_format = $CI->config->item('qso_date_format'); + } + + $this->qsl = $this->getQslString($data, $custom_date_format); + $this->lotw = $this->getLotwString($data, $custom_date_format); + $this->eqsl = $this->getEqslString($data, $custom_date_format); + $this->cqzone = ($data['COL_CQZ'] === null) ? '' : $data['COL_CQZ']; $this->state = ($data['COL_STATE'] === null) ? '' :$data['COL_STATE']; $this->dxcc = ($data['name'] === null) ? '- NONE -' :$data['name']; @@ -174,6 +192,210 @@ class QSO $this->end = null; } } + + /** + * @return string + */ + function getQSLString($data, $custom_date_format): string + { + $CI =& get_instance(); + // Load language files + $CI->lang->load(array( + 'contesting', + 'qslcard', + 'lotw', + 'eqsl', + 'qso' + )); + + $qslstring = 'lang->line('general_word_sent'); + break; + case "Q": + $qslstring .= "class=\"qsl-yellow\" data-toggle=\"tooltip\" data-original-title=\"".$CI->lang->line('general_word_queued'); + break; + case "R": + $qslstring .= "class=\"qsl-yellow\" data-toggle=\"tooltip\" data-original-title=\"".$CI->lang->line('general_word_requested'); + break; + case "I": + $qslstring .= "class=\"qsl-grey\" data-toggle=\"tooltip\" data-original-title=\"".$CI->lang->line('general_word_invalid_ignore'); + break; + default: + $qslstring .= "class=\"qsl-red"; + break; + } + if ($data['COL_QSLSDATE'] != null) { + $timestamp = strtotime($data['COL_QSLSDATE']); + $qslstring .= " " .($timestamp != '' ? date($custom_date_format, $timestamp) : ''); + } + } else { + $qslstring .= "class=\"qsl-red"; + } + + if ($data['COL_QSL_SENT_VIA'] != "") { + switch ($data['COL_QSL_SENT_VIA']) { + case "B": + $qslstring .= " (" . $CI->lang->line('general_word_qslcard_bureau') . ")"; + break; + case "D": + $qslstring .= " (".$CI->lang->line('general_word_qslcard_direct').")"; + break; + case "M": + $qslstring .= " (".$CI->lang->line('general_word_qslcard_via').": ".($data['COL_QSL_VIA'] !="" ? $data['COL_QSL_VIA']:"n/a").")"; + break; + case "E": + $qslstring .= " (".$CI->lang->line('general_word_qslcard_electronic').")"; + break; + } + } + + $qslstring .= '">▲lang->line('general_word_received'); + break; + case "Q": + $qslstring .= "class=\"qsl-yellow\" data-toggle=\"tooltip\" data-original-title=\"".$CI->lang->line('general_word_queued'); + break; + case "R": + $qslstring .= "class=\"qsl-yellow\" data-toggle=\"tooltip\" data-original-title=\"".$CI->lang->line('general_word_requested'); + break; + case "I": + $qslstring .= "class=\"qsl-grey\" data-toggle=\"tooltip\" data-original-title=\"".$CI->lang->line('general_word_invalid_ignore'); + break; + default: + $qslstring .= "class=\"qsl-red"; + break; + } + if ($data['COL_QSLRDATE'] != null) { + $timestamp = strtotime($data['COL_QSLRDATE']); + $qslstring .= " " .($timestamp != '' ? date($custom_date_format, $timestamp) : ''); + } + } else { + $qslstring .= "class=\"qsl-red"; } + if ($data['COL_QSL_RCVD_VIA'] != "") { + switch ($data['COL_QSL_RCVD_VIA']) { + case "B": + $qslstring .= " (".$CI->lang->line('general_word_qslcard_bureau').")"; + break; + case "D": + $qslstring .= " (".$CI->lang->line('general_word_qslcard_direct').")"; + break; + case "M": + $qslstring .= " (Manager)"; + break; + case "E": + $qslstring .= " (".$CI->lang->line('general_word_qslcard_electronic').")"; + break; + } + } + $qslstring .= '">▼'; + return $qslstring; + } + + /** + * @return string + */ + function getLotwString($data, $custom_date_format): string + { + $CI =& get_instance(); + // Load language files + $CI->lang->load(array( + 'contesting', + 'qslcard', + 'lotw', + 'eqsl', + 'qso' + )); + + $lotwstring = 'lang->line('lotw_short')." ".$CI->lang->line('general_word_sent'); + if ($data['COL_LOTW_QSLSDATE'] != null) { + $timestamp = strtotime($data['COL_LOTW_QSLSDATE']); + $lotwstring .= " ". ($timestamp != '' ? date($custom_date_format, $timestamp) : ''); + } + $lotwstring .= "\" data-toggle=\"tooltip\""; + } + + $lotwstring .= ' class="lotw-' . (($data['COL_LOTW_QSL_SENT']=='Y') ? 'green' : 'red') . '">▲'; + $lotwstring .= 'lang->line('lotw_short') ." ". $CI->lang->line('general_word_received'); + + if ($data['COL_LOTW_QSLRDATE'] != null) { + $timestamp = strtotime($data['COL_LOTW_QSLRDATE']); + $lotwstring .= " ". ($timestamp != '' ? date($custom_date_format, $timestamp) : ''); + } + + $lotwstring .= "\" data-toggle=\"tooltip\""; + } + + $lotwstring .= ' class="lotw-' . (($data['COL_LOTW_QSL_RCVD']=='Y') ? 'green':'red') . '">▼'; + + return $lotwstring; + } + + /** + * @return string + */ + function getEqslString($data, $custom_date_format): string + { + $CI =& get_instance(); + // Load language files + $CI->lang->load(array( + 'contesting', + 'qslcard', + 'lotw', + 'eqsl', + 'qso' + )); + + $eqslstring = 'lang->line('eqsl_short')." ".$CI->lang->line('general_word_sent'); + + if ($data['COL_EQSL_QSLSDATE'] != null) { + $timestamp = strtotime($data['COL_EQSL_QSLSDATE']); + $eqslstring .= " ".($timestamp!=''?date($custom_date_format, $timestamp):''); + } + + $eqslstring .= "\" data-toggle=\"tooltip\""; + } + + $eqslstring .= ' class="eqsl-' . (($data['COL_EQSL_QSL_SENT'] =='Y') ? 'green':'red') . '">▲lang->line('eqsl_short')." ".$CI->lang->line('general_word_received'); + + if ($data['COL_EQSL_QSLRDATE'] != null) { + $timestamp = strtotime($data['COL_EQSL_QSLRDATE']); + $eqslstring .= " ".($timestamp!=''?date($custom_date_format, $timestamp):''); + } + $eqslstring .= "\" data-toggle=\"tooltip\""; + } + + $eqslstring .= ' class="eqsl-' . (($data['COL_EQSL_QSL_RCVD'] =='Y')?'green':'red') . '">'; + + if($data['COL_EQSL_QSL_RCVD'] =='Y') { + $eqslstring .= ''; + } else { + $eqslstring .= '▼'; + } + + $eqslstring .= ''; + + return $eqslstring; + } /** * @return string @@ -471,6 +693,30 @@ class QSO return $this->QSLSentVia; } + /** + * @return string + */ + public function getqsl(): string + { + return $this->qsl; + } + + /** + * @return string + */ + public function getlotw(): string + { + return $this->lotw; + } + + /** + * @return string + */ + public function geteqsl(): string + { + return $this->eqsl; + } + /** * @return string */ @@ -513,8 +759,9 @@ class QSO 'deRefs' => $this->getFormattedDeRefs(), 'dxRefs' => $this->getFormattedDxRefs(), 'qslVia' => $this->QSLVia, - 'qslSent' => $this->getFormattedQSLSent(), - 'qslReceived' => $this->getFormattedQSLReceived(), + 'qsl' => $this->getqsl(), + 'lotw' => $this->getlotw(), + 'eqsl' => $this->geteqsl(), 'qslMessage' => $this->getQSLMsg(), 'name' => $this->getName(), 'dxcc' => $this->getDXCC(), From 45e91c2b0ccfc5a64cfe434757d5fcf19a809b90 Mon Sep 17 00:00:00 2001 From: phl0 Date: Tue, 2 May 2023 18:20:08 +0200 Subject: [PATCH 2/5] Allow for HTML in table row --- assets/js/sections/logbookadvanced.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/js/sections/logbookadvanced.js b/assets/js/sections/logbookadvanced.js index f410b60e..c8d15d1e 100644 --- a/assets/js/sections/logbookadvanced.js +++ b/assets/js/sections/logbookadvanced.js @@ -26,9 +26,9 @@ function updateRow(qso) { cells.eq(c++).text(qso.dxRefs); cells.eq(c++).text(qso.name); cells.eq(c++).text(qso.qslVia); - cells.eq(c++).text(qso.qsl); - cells.eq(c++).text(qso.lotw); - cells.eq(c++).text(qso.eqsl); + cells.eq(c++).html(qso.qsl); + cells.eq(c++).html(qso.lotw); + cells.eq(c++).html(qso.eqsl); cells.eq(c++).text(qso.qslMessage); cells.eq(c++).text(qso.dxcc); cells.eq(c++).text(qso.state); From 4975072693abdd4c7a7a462c42f7a6aa9c929837 Mon Sep 17 00:00:00 2001 From: Andreas <6977712+AndreasK79@users.noreply.github.com> Date: Tue, 2 May 2023 18:24:07 +0200 Subject: [PATCH 3/5] [Advanced Logbook] Fixed tooltip for updated rows --- assets/js/sections/logbookadvanced.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/js/sections/logbookadvanced.js b/assets/js/sections/logbookadvanced.js index c8d15d1e..96906129 100644 --- a/assets/js/sections/logbookadvanced.js +++ b/assets/js/sections/logbookadvanced.js @@ -34,6 +34,8 @@ function updateRow(qso) { cells.eq(c++).text(qso.state); cells.eq(c++).text(qso.cqzone); cells.eq(c++).text(qso.iota); + + $('[data-toggle="tooltip"]').tooltip(); return row; } From 7b6a90634cb5d5424ce19f5158301522415b52c8 Mon Sep 17 00:00:00 2001 From: Andreas <6977712+AndreasK79@users.noreply.github.com> Date: Tue, 2 May 2023 19:04:12 +0200 Subject: [PATCH 4/5] [Advanced Logbook] Show/hide LoTW/eQSL according to username set --- application/views/logbookadvanced/index.php | 8 ++- assets/js/sections/logbookadvanced.js | 57 ++++++++++++--------- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/application/views/logbookadvanced/index.php b/application/views/logbookadvanced/index.php index 2e94dd18..db89c906 100644 --- a/application/views/logbookadvanced/index.php +++ b/application/views/logbookadvanced/index.php @@ -202,8 +202,12 @@ Name QSL Via QSL - LoTW - eQSL + session->userdata('user_lotw_name') != ""){ + echo 'LoTW'; + } ?> + session->userdata('user_eqsl_name') != ""){ + echo 'eQSL'; + } ?> QSL Msg DXCC State diff --git a/assets/js/sections/logbookadvanced.js b/assets/js/sections/logbookadvanced.js index 96906129..9f1b4a60 100644 --- a/assets/js/sections/logbookadvanced.js +++ b/assets/js/sections/logbookadvanced.js @@ -27,8 +27,12 @@ function updateRow(qso) { cells.eq(c++).text(qso.name); cells.eq(c++).text(qso.qslVia); cells.eq(c++).html(qso.qsl); - cells.eq(c++).html(qso.lotw); - cells.eq(c++).html(qso.eqsl); + if ($(".lotwconfirmation")[0]){ + cells.eq(c++).html(qso.lotw); + } + if ($(".eqslconfirmation")[0]){ + cells.eq(c++).html(qso.eqsl); + } cells.eq(c++).text(qso.qslMessage); cells.eq(c++).text(qso.dxcc); cells.eq(c++).text(qso.state); @@ -63,29 +67,32 @@ function loadQSOTable(rows) { for (i = 0; i < rows.length; i++) { let qso = rows[i]; - - var data = [ - '
', - qso.qsoDateTime, - qso.de, - ''+qso.dx+'', - qso.mode, - qso.rstS, - qso.rstR, - qso.band, - qso.deRefs, - qso.dxRefs, - qso.name, - qso.qslVia, - qso.qsl, - qso.lotw, - qso.eqsl, - qso.qslMessage, - qso.dxcc+(qso.end == null ? '' : ' Deleted DXCC'), - qso.state, - qso.cqzone, - qso.iota, - ]; + + var data = []; + data.push('
'); + data.push(qso.qsoDateTime); + data.push(qso.de); + data.push(''+qso.dx+''); + data.push(qso.mode); + data.push(qso.rstS); + data.push(qso.rstR); + data.push(qso.band); + data.push(qso.deRefs); + data.push(qso.dxRefs); + data.push(qso.name); + data.push(qso.qslVia); + data.push(qso.qsl); + if ($(".lotwconfirmation")[0]){ + data.push(qso.lotw); + } + if ($(".eqslconfirmation")[0]){ + data.push(qso.eqsl); + } + data.push(qso.qslMessage); + data.push(qso.dxcc+(qso.end == null ? '' : ' Deleted DXCC')); + data.push(qso.state); + data.push(qso.cqzone); + data.push(qso.iota); let createdRow = table.row.add(data).index(); table.rows(createdRow).nodes().to$().data('qsoID', qso.qsoID); From ddca0a4fe7411c733aaa8c317b2c44ab7db50c17 Mon Sep 17 00:00:00 2001 From: Andreas <6977712+AndreasK79@users.noreply.github.com> Date: Tue, 2 May 2023 20:53:29 +0200 Subject: [PATCH 5/5] [Advanced Logbook] Fixed sort order when exporting ADIF --- application/models/Logbookadvanced_model.php | 73 +++++++++++++++----- 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/application/models/Logbookadvanced_model.php b/application/models/Logbookadvanced_model.php index bb71bebd..6918f58e 100644 --- a/application/models/Logbookadvanced_model.php +++ b/application/models/Logbookadvanced_model.php @@ -122,25 +122,7 @@ class Logbookadvanced_model extends CI_Model { $where = "AND $where"; } - if ($sortorder != null) { - $sortorder = explode(',', $sortorder); - - switch($sortorder[0]) { - case 1: $order = 'ORDER BY qsos.COL_TIME_ON ' . $sortorder[1]; break; - case 2: $order = 'ORDER BY station_profile.station_callsign ' . $sortorder[1]; break; - case 3: $order = 'ORDER BY qsos.COL_CALL ' . $sortorder[1]; break; - case 4: $order = 'ORDER BY qsos.COL_MODE' . $sortorder[1] . ', qsos.COL_SUBMODE ' . $sortorder[1]; break; - case 7: $order = 'ORDER BY qsos.COL_BAND ' . $sortorder[1] . ', qsos.COL_SAT_NAME ' . $sortorder[1]; break; - case 15: $order = 'ORDER BY qsos.COL_COUNTRY ' . $sortorder[1]; break; - case 16: $order = 'ORDER BY qso.COL_STATE ' . $sortorder[1]; break; - case 17: $order = 'ORDER BY qsos.COL_CQZ ' . $sortorder[1]; break; - case 18: $order = 'ORDER BY qsos.COL_IOTA ' . $sortorder[1]; break; - default: $order = 'ORDER BY qsos.COL_TIME_ON desc'; break; - } - } else { - $order = 'ORDER BY qsos.COL_TIME_ON desc'; - } - + $order = $this->getSortorder($sortorder); $sql = " SELECT *, dxcc_entities.name AS station_country @@ -155,6 +137,59 @@ class Logbookadvanced_model extends CI_Model { return $this->db->query($sql, $binding); } + public function getSortOrder($sortorder) { + if ($sortorder == null) { + return 'ORDER BY qsos.COL_TIME_ON desc'; + } else { + $sortorder = explode(',', $sortorder); + + if ($this->session->userdata('user_lotw_name') != "" && $this->session->userdata('user_eqsl_name') != ""){ + switch($sortorder[0]) { + case 1: return 'ORDER BY qsos.COL_TIME_ON ' . $sortorder[1]; + case 2: return 'ORDER BY station_profile.station_callsign ' . $sortorder[1]; + case 3: return 'ORDER BY qsos.COL_CALL ' . $sortorder[1]; + case 4: return 'ORDER BY qsos.COL_MODE' . $sortorder[1] . ', qsos.COL_SUBMODE ' . $sortorder[1]; + case 7: return 'ORDER BY qsos.COL_BAND ' . $sortorder[1] . ', qsos.COL_SAT_NAME ' . $sortorder[1]; + case 16: return 'ORDER BY qsos.COL_COUNTRY ' . $sortorder[1]; + case 17: return 'ORDER BY qso.COL_STATE ' . $sortorder[1]; + case 18: return 'ORDER BY qsos.COL_CQZ ' . $sortorder[1]; + case 19: return 'ORDER BY qsos.COL_IOTA ' . $sortorder[1]; + default: return 'ORDER BY qsos.COL_TIME_ON desc'; + } + } + + else if (($this->session->userdata('user_eqsl_name') != "" && $this->session->userdata('user_lotw_name') == "") || ($this->session->userdata('user_eqsl_name') == "" && $this->session->userdata('user_lotw_name') != "")) { + switch($sortorder[0]) { + case 1: return 'ORDER BY qsos.COL_TIME_ON ' . $sortorder[1]; + case 2: return 'ORDER BY station_profile.station_callsign ' . $sortorder[1]; + case 3: return 'ORDER BY qsos.COL_CALL ' . $sortorder[1]; + case 4: return 'ORDER BY qsos.COL_MODE' . $sortorder[1] . ', qsos.COL_SUBMODE ' . $sortorder[1]; + case 7: return 'ORDER BY qsos.COL_BAND ' . $sortorder[1] . ', qsos.COL_SAT_NAME ' . $sortorder[1]; + case 15: return 'ORDER BY qsos.COL_COUNTRY ' . $sortorder[1]; + case 16: return 'ORDER BY qso.COL_STATE ' . $sortorder[1]; + case 17: return 'ORDER BY qsos.COL_CQZ ' . $sortorder[1]; + case 18: return 'ORDER BY qsos.COL_IOTA ' . $sortorder[1]; + default: return 'ORDER BY qsos.COL_TIME_ON desc'; + } + } + + else if ($this->session->userdata('user_eqsl_name') == "" && $this->session->userdata('user_lotw_name') == ""){ + switch($sortorder[0]) { + case 1: return 'ORDER BY qsos.COL_TIME_ON ' . $sortorder[1]; + case 2: return 'ORDER BY station_profile.station_callsign ' . $sortorder[1]; + case 3: return 'ORDER BY qsos.COL_CALL ' . $sortorder[1]; + case 4: return 'ORDER BY qsos.COL_MODE' . $sortorder[1] . ', qsos.COL_SUBMODE ' . $sortorder[1]; + case 7: return 'ORDER BY qsos.COL_BAND ' . $sortorder[1] . ', qsos.COL_SAT_NAME ' . $sortorder[1]; + case 14: return 'ORDER BY qsos.COL_COUNTRY ' . $sortorder[1]; + case 15: return 'ORDER BY qso.COL_STATE ' . $sortorder[1]; + case 16: return 'ORDER BY qsos.COL_CQZ ' . $sortorder[1]; + case 17: return 'ORDER BY qsos.COL_IOTA ' . $sortorder[1]; + default: return 'ORDER BY qsos.COL_TIME_ON desc'; + } + } + } + } + public function updateQsl($ids, $user_id, $method, $sent) { $this->load->model('user_model');