From a4bfa142985d002e028db7c7423239fb0f178cf7 Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Mon, 22 Dec 2025 08:25:26 +0100 Subject: [PATCH] [Advanced Logbook] Added a dialog with parameter for duplicate search --- application/controllers/Logbookadvanced.php | 10 ++ application/models/Logbookadvanced_model.php | 95 +++++++++++++++---- .../logbookadvanced/dupesearchdialog.php | 49 ++++++++++ application/views/logbookadvanced/index.php | 7 ++ assets/js/sections/logbookadvanced.js | 44 ++++++++- 5 files changed, 185 insertions(+), 20 deletions(-) create mode 100644 application/views/logbookadvanced/dupesearchdialog.php diff --git a/application/controllers/Logbookadvanced.php b/application/controllers/Logbookadvanced.php index 4e7e9d12f..e19768668 100644 --- a/application/controllers/Logbookadvanced.php +++ b/application/controllers/Logbookadvanced.php @@ -145,6 +145,10 @@ class Logbookadvanced extends CI_Controller { 'wwff' => xss_clean($this->input->post('wwff')), 'qslimages' => xss_clean($this->input->post('qslimages')), 'dupes' => xss_clean($this->input->post('dupes')), + 'dupedate' => xss_clean($this->input->post('dupedate')), + 'dupemode' => xss_clean($this->input->post('dupemode')), + 'dupeband' => xss_clean($this->input->post('dupeband')), + 'dupesat' => xss_clean($this->input->post('dupesat')), 'operator' => xss_clean($this->input->post('operator')), 'contest' => xss_clean($this->input->post('contest')), 'invalid' => xss_clean($this->input->post('invalid')), @@ -982,4 +986,10 @@ class Logbookadvanced extends CI_Controller { $this->load->view('logbookadvanced/showUpdateResult', $data); } + function dupeSearchDialog() { + if(!clubaccess_check(9)) return; + + $this->load->view('logbookadvanced/dupesearchdialog'); + } + } diff --git a/application/models/Logbookadvanced_model.php b/application/models/Logbookadvanced_model.php index f5a7522d7..80bcb4381 100644 --- a/application/models/Logbookadvanced_model.php +++ b/application/models/Logbookadvanced_model.php @@ -3,6 +3,81 @@ use Wavelog\QSLManager\QSO; class Logbookadvanced_model extends CI_Model { + public function dupeSearchQuery($searchCriteria, $binding) { + $group_by_append = ''; + $order_by = ''; + + $order_by .= ' order by col_call'; + $id_sql = "select GROUP_CONCAT(col_primary_key separator ',') as qsoids, COL_CALL, station_callsign, min(col_time_on) Mintime, max(col_time_on) Maxtime"; + + if (isset($searchCriteria['dupemode']) && $searchCriteria['dupemode'] === 'Y') { + $id_sql .= ", COL_MODE, COL_SUBMODE"; + $group_by_append .= ", COL_MODE, COL_SUBMODE"; + } + if (isset($searchCriteria['dupeband']) && $searchCriteria['dupeband'] === 'Y') { + $id_sql .= ", COL_BAND"; + $group_by_append .= ", COL_BAND"; + } + if (isset($searchCriteria['dupesat']) && $searchCriteria['dupesat'] === 'Y') { + $id_sql .= ", COL_SAT_NAME"; + $group_by_append .= ", COL_SAT_NAME"; + } + + $id_sql .= " from " . $this->config->item('table_name') . " + join station_profile on " . $this->config->item('table_name') . ".station_id = station_profile.station_id where station_profile.user_id = ?"; + + $id_sql .= "group by COL_CALL, station_callsign"; + $id_sql .= $group_by_append; + $id_sql .= " having count(*) > 1"; + if (isset($searchCriteria['dupedate']) && $searchCriteria['dupedate'] === 'Y') { + $id_sql .= " AND TIMESTAMPDIFF(SECOND, Mintime, Maxtime) < 1800"; + $order_by .= ' , col_time_on desc'; + } + + $id_query = $this->db->query($id_sql, array($this->session->userdata('user_id'))); + $ids2fetch = ''; + foreach ($id_query->result() as $id) { + $ids2fetch .= ','.$id->qsoids; + } + $ids2fetch = ltrim($ids2fetch, ','); + if ($ids2fetch ?? '' !== '') { + $conditions[] = "qsos.COL_PRIMARY_KEY in (".$ids2fetch.")"; + } else { + $conditions[] = "1=0"; + } + + if (($searchCriteria['ids'] ?? '') !== '') { + $conditions[] = "qsos.COL_PRIMARY_KEY in (".implode(",",$searchCriteria['ids']).")"; + } + + $where = trim(implode(" AND ", $conditions)); + if ($where != "") { + $where = "AND $where"; + } + + $limit = ''; + + if ($searchCriteria['qsoresults'] != 'All') { + $limit = 'limit ' . $searchCriteria['qsoresults']; + } + + $sql = " + SELECT qsos.*, dxcc_entities.*, lotw_users.*, station_profile.*, satellite.*, dxcc_entities.name as dxccname, mydxcc.name AS station_country, exists(select 1 from qsl_images where qsoid = qsos.COL_PRIMARY_KEY) as qslcount, coalesce(contest.name, qsos.col_contest_id) as contestname + FROM " . $this->config->item('table_name') . " qsos + INNER JOIN station_profile ON qsos.station_id=station_profile.station_id + LEFT OUTER JOIN satellite ON qsos.col_prop_mode='SAT' and qsos.COL_SAT_NAME = COALESCE(NULLIF(satellite.name, ''), NULLIF(satellite.displayname, '')) + LEFT OUTER JOIN dxcc_entities ON qsos.col_dxcc = dxcc_entities.adif + left outer join dxcc_entities mydxcc on qsos.col_my_dxcc = mydxcc.adif + LEFT OUTER JOIN lotw_users ON qsos.col_call = lotw_users.callsign + LEFT OUTER JOIN contest ON qsos.col_contest_id = contest.adifname + WHERE station_profile.user_id = ? + $where + $order_by + $limit + "; + return $this->db->query($sql, $binding); + } + public function searchDb($searchCriteria) { $conditions = []; $binding = [$searchCriteria['user_id']]; @@ -13,20 +88,7 @@ class Logbookadvanced_model extends CI_Model { } if ((isset($searchCriteria['dupes'])) && ($searchCriteria['dupes'] !== '')) { - $id_sql="select GROUP_CONCAT(col_primary_key separator ',') as qsoids, COL_CALL, COL_MODE, COL_SUBMODE, station_callsign, COL_SAT_NAME, COL_BAND, min(col_time_on) Mintime, max(col_time_on) Maxtime from " . $this->config->item('table_name') . " - join station_profile on " . $this->config->item('table_name') . ".station_id = station_profile.station_id where station_profile.user_id = ? - group by col_call, col_mode, COL_SUBMODE, STATION_CALLSIGN, col_band, COL_SAT_NAME having count(*) > 1 AND TIMESTAMPDIFF(SECOND, Mintime, Maxtime) < 1500"; - $id_query = $this->db->query($id_sql, $searchCriteria['user_id']); - $ids2fetch = ''; - foreach ($id_query->result() as $id) { - $ids2fetch .= ','.$id->qsoids; - } - $ids2fetch = ltrim($ids2fetch, ','); - if ($ids2fetch ?? '' !== '') { - $conditions[] = "qsos.COL_PRIMARY_KEY in (".$ids2fetch.")"; - } else { - $conditions[] = "1=0"; - } + return $this->dupeSearchQuery($searchCriteria, $binding); } if ((isset($searchCriteria['invalid'])) && ($searchCriteria['invalid'] !== '')) { @@ -472,11 +534,6 @@ class Logbookadvanced_model extends CI_Model { $where = "AND $where"; } - $where = trim(implode(" AND ", $conditions)); - if ($where != "") { - $where = "AND $where"; - } - $limit = ''; if ($searchCriteria['qsoresults'] != 'All') { diff --git a/application/views/logbookadvanced/dupesearchdialog.php b/application/views/logbookadvanced/dupesearchdialog.php new file mode 100644 index 000000000..7549dde06 --- /dev/null +++ b/application/views/logbookadvanced/dupesearchdialog.php @@ -0,0 +1,49 @@ +
+
+
+ +
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
diff --git a/application/views/logbookadvanced/index.php b/application/views/logbookadvanced/index.php index 3e8a453c8..c7703c8ff 100644 --- a/application/views/logbookadvanced/index.php +++ b/application/views/logbookadvanced/index.php @@ -71,6 +71,9 @@ let lang_gen_advanced_logbook_distances_updated = ''; let lang_gen_advanced_logbook_confirm_fix_missing_dxcc = ''; + let lang_gen_advanced_logbook_dupe_search = ''; + let lang_gen_advanced_logbook_search = ''; + let homegrid =''; " method="post"> + + + +
diff --git a/assets/js/sections/logbookadvanced.js b/assets/js/sections/logbookadvanced.js index 8573ef84f..4d4ac7834 100644 --- a/assets/js/sections/logbookadvanced.js +++ b/assets/js/sections/logbookadvanced.js @@ -745,6 +745,10 @@ $(document).ready(function () { wwff: this.wwff.value, qslimages: this.qslimages.value, dupes: this.dupes.value, + dupedate: this.dupedate.value, + dupemode: this.dupemode.value, + dupeband: this.dupeband.value, + dupesat: this.dupesat.value, contest: this.contest.value, invalid: this.invalid.value, continent: this.continent.value, @@ -1088,7 +1092,7 @@ $(document).ready(function () { }); $('#dupeButton').click(function (event) { - dupeSearch(); + dupeSearchDialog(); }); $('#invalidButton').click(function (event) { @@ -1457,6 +1461,44 @@ $(document).ready(function () { }); }); + function dupeSearchDialog() { + $.ajax({ + url: base_url + 'index.php/logbookadvanced/dupeSearchDialog', + type: 'post', + success: function (html) { + BootstrapDialog.show({ + title: lang_gen_advanced_logbook_dupe_search, + size: BootstrapDialog.SIZE_NORMAL, + cssClass: 'options', + nl2br: false, + message: html, + buttons: [ + { + label: lang_gen_advanced_logbook_search + '
', + cssClass: 'btn btn-sm btn-primary ld-ext-right', + id: 'dupeSearchButton', + action: function (dialogItself) { + dialogItself.close(); + $('#dupedate').val($('#date_check').is(':checked') ? "Y" : "N"); + $('#dupemode').val($('#mode_check').is(':checked') ? "Y" : "N"); + $('#dupeband').val($('#band_check').is(':checked') ? "Y" : "N"); + $('#dupesat').val($('#satellite_check').is(':checked') ? "Y" : "N"); + dupeSearch(); + } + }, + { + label: lang_admin_close, + cssClass: 'btn btn-sm btn-secondary', + id: 'closeDupeDialogButton', + action: function (dialogItself) { + dialogItself.close(); + } + }], + }); + } + }); + } + function dupeSearch() { $("#dupes").val("Y"); $('#dupeButton').prop('disabled', true).addClass('running');