From 1fb485c69c3677786d1709dfbf95120b83cb762a Mon Sep 17 00:00:00 2001 From: tallcode Date: Wed, 23 Jul 2025 10:01:17 +0800 Subject: [PATCH] Add WAPC Award --- application/controllers/Awards.php | 75 ++++ application/models/Logbook_model.php | 4 + application/models/Wapc.php | 377 ++++++++++++++++++ application/views/awards/wapc/index.php | 170 ++++++++ application/views/interface_assets/footer.php | 55 +++ application/views/interface_assets/header.php | 6 + 6 files changed, 687 insertions(+) create mode 100644 application/models/Wapc.php create mode 100644 application/views/awards/wapc/index.php diff --git a/application/controllers/Awards.php b/application/controllers/Awards.php index ac3e30c5c..ee1f078b5 100644 --- a/application/controllers/Awards.php +++ b/application/controllers/Awards.php @@ -180,6 +180,81 @@ class Awards extends CI_Controller { $this->load->view('interface_assets/footer'); } + public function wapc () { + $footerData = []; + + $this->load->model('wapc'); + $this->load->model('modes'); + $this->load->model('bands'); + + $data['worked_bands'] = ['160m','80m','40m','30m','20m','17m','15m','12m','10m','6m','2m','70cm'];; + $data['modes'] = $this->modes->active(); + + if ($this->input->post('band') != NULL) { // Band is not set when page first loads. + if ($this->input->post('band') == 'All') { // Did the user specify a band? If not, use all bands + $bands = $data['worked_bands']; + } + else { + $bands[] = $this->security->xss_clean($this->input->post('band')); + } + } + else { + $bands = $data['worked_bands']; + } + + $data['bands'] = $bands; // Used for displaying selected band(s) in the table in the view + + if($this->input->method() === 'post') { + $postdata['qsl'] = $this->security->xss_clean($this->input->post('qsl')); + $postdata['lotw'] = $this->security->xss_clean($this->input->post('lotw')); + $postdata['eqsl'] = $this->security->xss_clean($this->input->post('eqsl')); + $postdata['qrz'] = $this->security->xss_clean($this->input->post('qrz')); + $postdata['clublog'] = $this->security->xss_clean($this->input->post('clublog')); + $postdata['worked'] = $this->security->xss_clean($this->input->post('worked')); + $postdata['confirmed'] = $this->security->xss_clean($this->input->post('confirmed')); + $postdata['notworked'] = $this->security->xss_clean($this->input->post('notworked')); + $postdata['includedeleted'] = $this->security->xss_clean($this->input->post('includedeleted')); + $postdata['Africa'] = $this->security->xss_clean($this->input->post('Africa')); + $postdata['Asia'] = $this->security->xss_clean($this->input->post('Asia')); + $postdata['Europe'] = $this->security->xss_clean($this->input->post('Europe')); + $postdata['NorthAmerica'] = $this->security->xss_clean($this->input->post('NorthAmerica')); + $postdata['SouthAmerica'] = $this->security->xss_clean($this->input->post('SouthAmerica')); + $postdata['Oceania'] = $this->security->xss_clean($this->input->post('Oceania')); + $postdata['Antarctica'] = $this->security->xss_clean($this->input->post('Antarctica')); + $postdata['band'] = $this->security->xss_clean($this->input->post('band')); + $postdata['mode'] = $this->security->xss_clean($this->input->post('mode')); + } + else { // Setting default values at first load of page + $postdata['qsl'] = 1; + $postdata['lotw'] = 1; + $postdata['eqsl'] = 0; + $postdata['qrz'] = 0; + $postdata['clublog'] = 0; + $postdata['worked'] = 1; + $postdata['confirmed'] = 1; + $postdata['notworked'] = 1; + $postdata['includedeleted'] = 0; + $postdata['Africa'] = 1; + $postdata['Asia'] = 1; + $postdata['Europe'] = 1; + $postdata['NorthAmerica'] = 1; + $postdata['SouthAmerica'] = 1; + $postdata['Oceania'] = 1; + $postdata['Antarctica'] = 1; + $postdata['band'] = 'All'; + $postdata['mode'] = 'All'; + } + + $data['wapc_array'] = $this->wapc->get_wapc_array($bands, $postdata); + $data['wapc_summary'] = $this->wapc->get_wapc_summary($bands, $postdata); + + // Render Page + $data['page_title'] =__( "Awards - WAPC"); + $this->load->view('interface_assets/header', $data); + $this->load->view('awards/wapc/index'); + $this->load->view('interface_assets/footer', $footerData); + } + public function waja () { $footerData = []; $footerData['scripts'] = [ diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php index bd0cda7c0..7a8defa3e 100644 --- a/application/models/Logbook_model.php +++ b/application/models/Logbook_model.php @@ -638,6 +638,10 @@ class Logbook_model extends CI_Model { $this->db->where('COL_STATE', $state); $this->db->where('COL_DXCC', '339'); break; + case 'WAPC': + $this->db->where('COL_STATE', $searchphrase); + $this->db->where('COL_DXCC', '318'); + break; case 'QSLRDATE': $this->db->where('date(COL_QSLRDATE)=date(SYSDATE())'); break; diff --git a/application/models/Wapc.php b/application/models/Wapc.php new file mode 100644 index 000000000..465080a0b --- /dev/null +++ b/application/models/Wapc.php @@ -0,0 +1,377 @@ +load->library('Genfunctions'); + $this->load->model('logbooks_model'); + $logbooks_locations_array = $this->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook')); + $this->location_list = "'".implode("','",$logbooks_locations_array)."'"; + } + + // Province Code => Name + public $cnProvinces = array( + 'BJ' => 'Beijing', + 'HL' => 'Heilongjiang', + 'LN' => 'Liaoning', + 'JL' => 'Jilin', + 'HE' => 'Hebei', + 'TJ' => 'Tianjin', + 'NM' => 'Nei Mongol', + 'SX' => 'Shanxi', + 'SH' => 'Shanghai', + 'SD' => 'Shandong', + 'JS' => 'Jiangsu', + 'ZJ' => 'Zhejiang', + 'JX' => 'Jiangxi', + 'FJ' => 'Fujian', + 'AH' => 'Anhui', + 'HA' => 'Henan', + 'HB' => 'Hubei', + 'HN' => 'Hunan', + 'GD' => 'Guangdong', + 'GX' => 'Guangxi', + 'HI' => 'Hainan', + 'SC' => 'Sichuan', + 'CQ' => 'Chongqing', + 'GZ' => 'Guizhou', + 'YN' => 'Yunnan', + 'SN' => 'Shaanxi', + 'GS' => 'Gansu', + 'NX' => 'Ningxia', + 'QH' => 'Qinghai', + 'XJ' => 'Xinjiang', + 'XZ' => 'Xizang', + 'TW' => 'Taiwan', + 'HK' => 'Hong Kong', + 'MO' => 'Macau'); + + function get_wapc_array($bands, $postdata) { + + $wapcArray = array_keys($this->cnProvinces); + + $provinces = array(); // Used for keeping track of which states that are not worked + foreach ($wapcArray as $state) { // Generating array for use in the table + $provinces[$state]['count'] = 0; // Inits each state's count + } + + $qsl = $this->genfunctions->gen_qsl_from_postdata($postdata); + + + foreach ($bands as $band) { + foreach ($wapcArray as $state) { // Generating array for use in the table + $bandWapc[$state]['Number'] = $state; + $bandWapc[$state]['Province'] = $this->cnProvinces[$state]; + $bandWapc[$state][$band] = '-'; // Sets all to dash to indicate no result + } + + if ($postdata['worked'] != NULL) { + $wapcBand = $this->getWapcWorked($this->location_list, $band, $postdata); + foreach ($wapcBand as $line) { + // B + if($line->col_dxcc == '318'){ + $bandWapc[$line->col_state][$band] = '
col_state . '","' . $band . '","All","All","'. $postdata['mode'] . '","WAPC", "")\'>W
'; + $provinces[$line->col_state]['count']++; + } + // BS7 + else if($line->col_dxcc == '506'){ + $bandWapc['HI'][$band] = '
W
'; + $provinces['HI']['count']++; + } + // VR + else if($line->col_dxcc == '321'){ + $bandWapc['HK'][$band] = '
W
'; + $provinces['HK']['count']++; + } + // XX9 + else if($line->col_dxcc == '152'){ + $bandWapc['MO'][$band] = '
W
'; + $provinces['MO']['count']++; + } + // BU-BX/BV9P + else if($line->col_dxcc == '386' || $line->col_dxcc == '505'){ + $bandWapc['TW'][$band] = '
W
'; + $provinces['TW']['count']++; + } + } + } + if ($postdata['confirmed'] != NULL) { + $wapcBand = $this->getWapcConfirmed($this->location_list, $band, $postdata); + foreach ($wapcBand as $line) { + // B + if($line->col_dxcc === '318'){ + $bandWapc[$line->col_state][$band] = '
col_state . '","' . $band . '","All","All","'. $postdata['mode'] . '","WAPC", "'.$qsl.'")\'>C
'; + $provinces[$line->col_state]['count']++; + } + // BS7 + else if($line->col_dxcc === '506'){ + $bandWapc['HI'][$band] = '
C
'; + $provinces['HI']['count']++; + } + // VR + else if($line->col_dxcc == '321'){ + $bandWapc['HK'][$band] = '
C
'; + $provinces['HK']['count']++; + } + // XX9 + else if($line->col_dxcc == '152'){ + $bandWapc['MO'][$band] = '
C
'; + $provinces['MO']['count']++; + } + // BU-BX/BV9P + else if($line->col_dxcc == '386' || $line->col_dxcc == '505'){ + $bandWapc['TW'][$band] = '
C
'; + $provinces['MO']['count']++; + } + } + } + } + + // We want to remove the worked states in the list, since we do not want to display them + if ($postdata['worked'] == NULL) { + $wapcBand = $this->getWapcWorked($this->location_list, $postdata['band'], $postdata); + foreach ($wapcBand as $line) { + unset($bandWapc[$line->col_state]); + } + } + + // We want to remove the confirmed states in the list, since we do not want to display them + if ($postdata['confirmed'] == NULL) { + $wapcBand = $this->getWapcConfirmed($this->location_list, $postdata['band'], $postdata); + foreach ($wapcBand as $line) { + unset($bandWapc[$line->col_state]); + } + } + + if ($postdata['notworked'] == NULL) { + foreach ($wapcArray as $state) { + if ($provinces[$state]['count'] == 0) { + unset($bandWapc[$state]); + }; + } + } + + if (isset($bandWapc)) { + return $bandWapc; + } else { + return 0; + } + } + + function getWapcBandConfirmed($location_list, $band, $postdata) { + $bindings=[]; + $sql = "select adif as wapc, name from dxcc_entities + join ( + select col_dxcc from ".$this->config->item('table_name')." thcv + where station_id in (" . $location_list . + ") and col_dxcc > 0"; + + $sql .= $this->genfunctions->addBandToQuery($band,$bindings); + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = ? or col_submode = ?)"; + $bindings[]=$postdata['mode']; + $bindings[]=$postdata['mode']; + } + + $sql .= $this->genfunctions->addQslToQuery($postdata); + + $sql .= " group by col_dxcc + ) x on dxcc_entities.adif = x.col_dxcc"; + + if ($postdata['includedeleted'] == NULL) { + $sql .= " and dxcc_entities.end is null"; + } + + $query = $this->db->query($sql,$bindings); + + return $query->result(); + } + + function getWapcBandWorked($location_list, $band, $postdata) { + $bindings=[]; + $sql = "select adif as wapc, name from dxcc_entities + join ( + select col_dxcc from ".$this->config->item('table_name')." thcv + where station_id in (" . $location_list . + ") and col_dxcc > 0"; + + $sql .= $this->genfunctions->addBandToQuery($band,$bindings); + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = ? or col_submode = ?)"; + $bindings[]=$postdata['mode']; + $bindings[]=$postdata['mode']; + } + + $sql .= " group by col_dxcc + ) x on dxcc_entities.adif = x.col_dxcc";; + + if ($postdata['includedeleted'] == NULL) { + $sql .= " and dxcc_entities.end is null"; + } + + $query = $this->db->query($sql,$bindings); + + return $query->result(); + } + + /* + * Function returns all worked, but not confirmed states + * $postdata contains data from the form, in this case Lotw or QSL are used + */ + function getWapcWorked($location_list, $band, $postdata) { + $bindings=[]; + $sql = "SELECT distinct col_state, col_dxcc FROM " . $this->config->item('table_name') . " thcv + where station_id in (" . $location_list . ")"; + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = ? or col_submode = ?)"; + $bindings[]=$postdata['mode']; + $bindings[]=$postdata['mode']; + } + + $sql .= $this->addStateToQuery(); + $sql .= $this->genfunctions->addBandToQuery($band,$bindings); + + $sql .= " and not exists (select 1 from ". $this->config->item('table_name') . + " where station_id in (". $location_list . ")" . + " and (col_state = thcv.col_state and col_dxcc = thcv.col_dxcc)"; + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = ? or col_submode = ?)"; + $bindings[]=$postdata['mode']; + $bindings[]=$postdata['mode']; + } + + $sql .= $this->genfunctions->addBandToQuery($band,$bindings); + $sql .= $this->genfunctions->addQslToQuery($postdata); + $sql .= $this->addStateToQuery(); + $sql .= ")"; + $query = $this->db->query($sql,$bindings); + + return $query->result(); + } + + /* + * Function returns all confirmed states on given band and on LoTW or QSL + * $postdata contains data from the form, in this case Lotw or QSL are used + */ + function getWapcConfirmed($location_list, $band, $postdata) { + $bindings=[]; + $sql = "SELECT distinct col_state, col_dxcc FROM " . $this->config->item('table_name') . " thcv + where station_id in (" . $location_list . ")"; + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = ? or col_submode = ?)"; + $bindings[]=$postdata['mode']; + $bindings[]=$postdata['mode']; + } + + $sql .= $this->addStateToQuery(); + $sql .= $this->genfunctions->addBandToQuery($band,$bindings); + $sql .= $this->genfunctions->addQslToQuery($postdata); + $query = $this->db->query($sql,$bindings); + + return $query->result(); + } + + /* + * Function gets worked and confirmed summary on each band on the active stationprofile + */ + function get_wapc_summary($bands, $postdata) { + foreach ($bands as $band) { + $worked = $this->getSummaryByBand($band, $postdata, $this->location_list); + $confirmed = $this->getSummaryByBandConfirmed($band, $postdata, $this->location_list); + $wapcSummary['worked'][$band] = $worked[0]->count; + $wapcSummary['confirmed'][$band] = $confirmed[0]->count; + } + + $workedTotal = $this->getSummaryByBand($postdata['band'], $postdata, $this->location_list); + $confirmedTotal = $this->getSummaryByBandConfirmed($postdata['band'], $postdata, $this->location_list); + + $wapcSummary['worked']['Total'] = $workedTotal[0]->count; + $wapcSummary['confirmed']['Total'] = $confirmedTotal[0]->count; + + return $wapcSummary; + } + + function getSummaryByBand($band, $postdata, $location_list) { + $bindings=[]; + $sql = "SELECT count(distinct thcv.col_state, thcv.col_dxcc) as count FROM " . $this->config->item('table_name') . " thcv"; + $sql .= " where station_id in (" . $location_list . ")"; + + if ($band == 'SAT') { + $sql .= " and (col_mode = ? or col_submode = ?)"; + $bindings[]=$postdata['mode']; + $bindings[]=$postdata['mode']; + } else if ($band == 'All') { + $this->load->model('bands'); + + $bandslots = ['160m','80m','40m','30m','20m','17m','15m','12m','10m','6m','2m','70cm']; + + $bandslots_list = "'".implode("','",$bandslots)."'"; + + $sql .= " and thcv.col_band in (" . $bandslots_list . ")"; + $sql .= " and thcv.col_prop_mode !='SAT'"; + } else { + $sql .= " and thcv.col_prop_mode !='SAT'"; + $sql .= " and thcv.col_band = ?"; + $bindings[]=$band; + } + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = ? or col_submode = ?)"; + $bindings[]=$postdata['mode']; + $bindings[]=$postdata['mode']; + } + + $sql .= $this->addStateToQuery(); + + $query = $this->db->query($sql,$bindings); + + return $query->result(); + } + + function getSummaryByBandConfirmed($band, $postdata, $location_list) { + $bindings=[]; + $sql = "SELECT count(distinct thcv.col_state, thcv.col_dxcc) as count FROM " . $this->config->item('table_name') . " thcv"; + $sql .= " where station_id in (" . $location_list . ")"; + + if ($band == 'SAT') { + $sql .= " and thcv.col_prop_mode = ?"; + $bindings[]=$band; + } else if ($band == 'All') { + $this->load->model('bands'); + $bandslots = ['160m','80m','40m','30m','20m','17m','15m','12m','10m','6m','2m','70cm']; + $bandslots_list = "'".implode("','",$bandslots)."'"; + $sql .= " and thcv.col_band in (" . $bandslots_list . ")"; + $sql .= " and thcv.col_prop_mode !='SAT'"; + } else { + $sql .= " and thcv.col_prop_mode !='SAT'"; + $sql .= " and thcv.col_band = ?"; + $bindings[]=$band; + } + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = ? or col_submode = ?)"; + $bindings[]=$postdata['mode']; + $bindings[]=$postdata['mode']; + } + + $sql .= $this->genfunctions->addQslToQuery($postdata); + $sql .= $this->addStateToQuery(); + $query = $this->db->query($sql,$bindings); + + return $query->result(); + } + + + function addStateToQuery() { + $sql = ''; + $sql .= " and ((COL_DXCC in ('318') and COL_STATE in ('".implode("','", array_keys($this->cnProvinces))."')) OR (COL_DXCC in ('321','152','386','505','506')))"; + return $sql; + } +} +?> diff --git a/application/views/awards/wapc/index.php b/application/views/awards/wapc/index.php new file mode 100644 index 000000000..f9f248efd --- /dev/null +++ b/application/views/awards/wapc/index.php @@ -0,0 +1,170 @@ +
+ +
+
+ +

+ +
+ + +
+
+ +
+
+
+
+ input->post('worked') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> > + +
+
+ input->post('confirmed') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> > + +
+
+ input->post('notworked') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> > + +
+
+
+ +
+
+
+
+ input->post('qsl') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> > + +
+
+ input->post('lotw') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> > + +
+
+ input->post('eqsl')) echo ' checked="checked"'; ?> > + +
+
+ input->post('qrz')) echo ' checked="checked"'; ?> > + +
+
+ input->post('clublog')) echo ' checked="checked"'; ?> > + +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+
+ + + + + ' . __("Code") . ' + ' . __("Province") . ''; + + foreach($bands as $band) { + echo '' . $band . ''; + } + echo ' + + '; + foreach ($wapc_array as $wapc => $value) { // Fills the table with the data + echo ''; + foreach ($value as $name => $key) { + echo '' . $key . ''; + } + echo ''; + } + echo ' +

' . __("Summary") . '

+ + + + '; + + foreach($bands as $band) { + echo ''; + } + echo ' + + + + + '; + + foreach ($wapc_summary['worked'] as $wapc) { // Fills the table with the data + echo ''; + } + + echo ' + '; + foreach ($wapc_summary['confirmed'] as $wapc) { // Fills the table with the data + echo ''; + } + + echo ' +
' . $band . '' . __("Total") . '
' . __("Total worked") . '' . $wapc . '
' . __("Total confirmed") . '' . $wapc . '
+
'; + + } + else { + echo ''; + } + ?> + diff --git a/application/views/interface_assets/footer.php b/application/views/interface_assets/footer.php index 6bb5fafa1..5b55c9360 100644 --- a/application/views/interface_assets/footer.php +++ b/application/views/interface_assets/footer.php @@ -1945,6 +1945,61 @@ $('#sats').change(function(){ +uri->segment(2) == "wapc") { ?> + + + uri->segment(2) == "waja") { ?>