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');