diff --git a/application/controllers/Reg1Test.php b/application/controllers/Reg1Test.php new file mode 100644 index 000000000..4cf2b409f --- /dev/null +++ b/application/controllers/Reg1Test.php @@ -0,0 +1,214 @@ +load->model('user_model'); + if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); } + } + + public function index() { + //define Page title + $data['page_title'] = __("Export REG1TEST EDI"); + + //Load models + $this->load->model('Contesting_model'); + $this->load->model('stations'); + + //get station profile + $data['station_profile'] = $this->stations->all_of_user(); + $active_station_id = $this->stations->find_active(); + $station_profile = $this->stations->profile($active_station_id); + + //set station profile to view data + $data['active_station_info'] = $station_profile->row(); + + //provide REG1TEST JS + $footerData = []; + $footerData['scripts'] = [ + 'assets/js/sections/reg1test.js' + ]; + + //load view + $this->load->view('interface_assets/header', $data); + $this->load->view('reg1test/index'); + $this->load->view('interface_assets/footer', $footerData); + } + + public function getContests() { + + //load models + $this->load->model('Contesting_model'); + $this->load->model('stations'); + + //get cleaned station id and year + $station_id = $this->input->post('station_id', true); + $year = $this->input->post('year', true); + + //deny acccess if station is not accessible + if (!$this->stations->check_station_is_accessible($station_id)) { + $this->session->set_flashdata('error', __("You're not allowed to do that!")); + redirect('dashboard'); + return; + } + + //get logged contests for station + $result = $this->Contesting_model->get_logged_contests($station_id, $year); + + //return result as json + header('Content-Type: application/json'); + echo json_encode($result); + } + + public function getYears() { + + //load model + $this->load->model('Contesting_model'); + + //get cleaned station id + $station_id = $this->input->post('station_id', true); + + //get logged year for station id + $result = $this->Contesting_model->get_logged_years($station_id); + + //return result as json + header('Content-Type: application/json'); + echo json_encode($result); + } + + public function getContestDates() { + //load models + $this->load->model('Contesting_model'); + $this->load->model('stations'); + + //get cleaned station id + $station_id = $this->input->post('station_id', true); + + //deny access is stations is not accessible + if (!$this->stations->check_station_is_accessible($station_id)) { + $this->session->set_flashdata('error', __("You're not allowed to do that!")); + redirect('dashboard'); + return; + } + + //get cleaned year, contest id, from and to values + $year = $this->input->post('year', true); + $contestid = $this->input->post('contestid', true); + + //get contestdates from database + $result = $this->Contesting_model->get_contest_dates($station_id, $year, $contestid); + + //return result as json + header('Content-Type: application/json'); + echo json_encode($result); + } + + public function getContestBands() { + + //load models + $this->load->model('Contesting_model'); + $this->load->model('stations'); + + //get cleaned station id + $station_id = $this->input->post('station_id', true); + + //deny access is stations is not accessible + if (!$this->stations->check_station_is_accessible($station_id)) { + $this->session->set_flashdata('error', __("You're not allowed to do that!")); + redirect('dashboard'); + return; + } + + //get cleaned year, contest id, from and to values + $year = $this->input->post('year', true); + $contestid = $this->input->post('contestid', true); + $from = $this->input->post('contestdatesfrom', true); + $to = $this->input->post('contestdatesto', true); + + //get contestdates from database + $result = $this->Contesting_model->get_contest_bands($station_id, $year, $contestid, $from, $to); + + //return result as json + header('Content-Type: application/json'); + echo json_encode($result); + + } + + public function export() { + // Set memory limit to unlimited to allow heavy usage + ini_set('memory_limit', '-1'); + + //load models + $this->load->model('Contesting_model'); + $this->load->model('stations'); + $this->load->model('user_model'); + + //deny access if station is not accessible + $station_id = $this->input->post('station_id', true); + if (!$this->stations->check_station_is_accessible($station_id)) { + $this->session->set_flashdata('error', __("You're not allowed to do that!")); + redirect('dashboard'); + return; + } + + //get user input to define the export parameters + $contest_id = $this->input->post('contestid', true); + $from = $this->input->post('contestdatesfrom', true); + $to = $this->input->post('contestdatesto', true); + $band = $this->input->post('contestband', true); + + //load station + $station = $this->stations->profile($station_id); + $station = $station->row(); + + //load userinfo + $userinfo = $this->user_model->get_by_id($this->session->userdata('user_id')); + $userinfo = $userinfo->row(); + + //get qsos and set qso data for export + $data['qsos'] = $this->Contesting_model->export_custom($from, $to, $contest_id, $station_id); + + //set contest header data for export + $data['band'] = $band; + $data['qso_count'] = count($data['qsos']->result()); + $data['sentexchange'] = $this->input->post('sentexchange', true); + $data['contest_id'] = $contest_id; + $data['from'] = $from; + $data['to'] = $to; + $data['callsign'] = $station->station_callsign; + $data['gridlocator'] = $station->station_gridsquare; + $data['contestaddress1'] = $this->input->post('contestaddress1', true); + $data['contestaddress2'] = $this->input->post('contestaddress2', true); + $data['categoryoperator'] = $this->input->post('categoryoperator', true); + $data['club'] = $this->input->post('club', true); + $data['name'] = $userinfo->user_firstname . ' ' . $userinfo->user_lastname; + $data['responsible_operator'] = $this->input->post('responsible_operator', true); + $data['address1'] = $this->input->post('address1', true); + $data['address2'] = $this->input->post('address2', true); + $data['addresspostalcode'] = $this->input->post('addresspostalcode', true); + $data['addresscity'] = $this->input->post('addresscity', true); + $data['addresscountry'] = $this->input->post('addresscountry', true); + $data['operatorphone'] = $this->input->post('operatorphone', true); + $data['operators'] = $this->input->post('operators', true); + $data['txequipment'] = $this->input->post('txequipment', true); + $data['power'] = $this->input->post('power', true); + $data['rxequipment'] = $this->input->post('rxequipment', true); + $data['antenna'] = $this->input->post('antenna', true); + $data['antennaheight'] = $this->input->post('antennaheight', true); + + $data['soapbox'] = $this->input->post('soapbox', true); + + //load view for export + $this->load->view('reg1test/export', $data); + } +} diff --git a/application/libraries/Reg1testformat.php b/application/libraries/Reg1testformat.php new file mode 100644 index 000000000..f95f39783 --- /dev/null +++ b/application/libraries/Reg1testformat.php @@ -0,0 +1,132 @@ +reg1testbandstring($band) . "\r\n"; // Band in REG1TEST format + $edi_header .= "PClub=" . $club . "\r\n"; //Club + $edi_header .= "RName=" . $name. "\r\n"; //Name of responsible operator + $edi_header .= "RCall=" . $responsible_operator . "\r\n"; //Callsign of responsible operator, if different from contest callsign + $edi_header .= "RAdr1=" . $address1 . "\r\n"; //Operator Address Line 1 + $edi_header .= "RAdr2=" . $address2 . "\r\n"; //Operator Address Line 2 + $edi_header .= "RPoCo=" . $addresspostalcode . "\r\n"; //Operator Address Postal Code + $edi_header .= "RCity=" . $addresscity . "\r\n"; //Operator Address City + $edi_header .= "RCoun=" . $addresscountry . "\r\n"; //Operator Address Country + $edi_header .= "RPhon=" . $operatorphone . "\r\n"; //Operator Address Phone number + $edi_header .= "RHBBS=" . "\r\n"; //Bulletin board address of operator. Pretty safe to omit in past 2024 + $edi_header .= "MOpe1=" . $operators . "\r\n"; //Operators + $edi_header .= "MOpe2=" . "\r\n"; //Operators line 2. Leave empty. + $edi_header .= "STXEq=" . $txequipment . "\r\n"; //TX Equipment description + $edi_header .= "SPowe=" . $power . "\r\n"; //Power in Watts + $edi_header .= "SRXEq=" . $rxequipment . "\r\n"; //RX Equipment description + $edi_header .= "SAnte=" . $antenna . "\r\n"; //Antenna description + $edi_header .= "SAntH=" . $antennaheight . "\r\n"; //Antenna height above ground + $edi_header .= "CQSOs=" . "\r\n"; //Arguments describe the claimed number of valid QSOs and the band multiplier. Leave empty. + $edi_header .= "CQSOP=" . "\r\n"; //Argument describes the claimed total number of QSO-points. Leave empty. + $edi_header .= "CWWLs=" . "\r\n"; //Arguments describe the claimed number of WWLs worked, the number of bonus points claimed for each new WWL and the WWL multiplier. Leave empty. + $edi_header .= "CWWLB=" . "\r\n"; //Argument describes the claimed total number of WWL bonus points. Leave empty. + $edi_header .= "CExcs=" . "\r\n"; //Arguments describe the claimed number of Exchanges worked, the number of bonus points claimed for each new Exchange and the Exchange multiplier. Leave empty. + $edi_header .= "CExcB=" . "\r\n"; //Argument describes the claimed total number of Exchange bonus points. Leave empty. + $edi_header .= "CDXCs=" . "\r\n"; //Arguments describe the claimed number of DXCCs worked, the number of bonus points claimed for each new DXCC and the DXCC multiplier. Leave empty. + $edi_header .= "CDXCB=" . "\r\n"; //Argument describes the claimed total number of DXCC bonus points. Leave empty. + $edi_header .= "CToSc=" . "\r\n"; //Argument describes the total claimed score. Leave empty. + $edi_header .= "CODXC=" . "\r\n"; //Arguments describe the claimed ODX contact call, WWL and distance. Leave empty. + $edi_header .= "[Remarks]" . "\r\n" . $soapbox . "\r\n"; //Remarks + $edi_header .= "[QSORecords;" . $qso_count . "]" . "\r\n"; //QSO Header and QSO Count + + //return the header + return $edi_header; + + } + + public function footer() { + //return a newline as the last line for good measure + return "\r\n"; + } + + public function qso($qsodata, $qsonumber) { + + //Construct QSO detail + $edi_detail = ""; + + $edi_detail .= date('ymd', strtotime($qsodata->COL_TIME_ON)) . ';'; //Date in YYMMDD format + $edi_detail .= date('H:i', strtotime($qsodata->COL_TIME_ON)) . ';'; // Time in HHMM format + $edi_detail .= substr($qsodata->COL_CALL, 0, 14) . ';'; //Callsign, maximum 14 characters + $edi_detail .= $this->reg1testmodecode($qsodata->COL_MODE) . ';'; //Mode-Code in REG1TEST format + $edi_detail .= substr($qsodata->COL_RST_SENT, 3) . ';'; // Sent RST, max 3 characters + $edi_detail .= substr(str_pad($qsonumber, 4, '0', STR_PAD_LEFT), 0, 4) . ';';; //Sent Number of QSO with definitely 4 digits with leading zeros + $edi_detail .= substr($qsodata->COL_RST_RCVD, 3) . ';'; // Received RST, max 3 characters + $edi_detail .= substr(str_pad($qsodata->COL_STX, 4, '0', STR_PAD_LEFT), 0, 4) . ';';; //Received Number of QSO with definitely 4 digits with leading zeros + $edi_detail .= substr($qsodata->COL_SRX_STRING, 0, 6) . ';'; // Received Exchange, max 6 characters + $edi_detail .= substr($qsodata->COL_GRIDSQUARE, 0, 6) . ';'; // Gridsquare max 6 characters + $edi_detail .= '0;;;;' . "\r\n"; //Points and "new exchange flags" we know nothing about + + //return QSO detail + return $edi_detail; + + } + + public function reg1testbandstring($band){ + + //translate wavelogs bands to REG1TEST format + switch ($band) { + case '6m': + return "50 MHz"; + case "4m": + return "70 MHz"; + case "2m": + return "144 MHz"; + case "70cm": + return "432 MHz"; + case "23cm": + return "1,3 GHz"; + case "13cm"; + return "2,3 GHz"; + case "9cm": + return "3,4 GHz"; + case "6cm": + return "5,7 GHz"; + case "3cm": + return "10 GHz"; + case "1.25cm": + return "24 GHz"; + default: + return "invalid"; + } + } + + public function reg1testmodecode($mode){ + switch ($mode) { + case 'SSB': + return 1; + case 'CW': + return 2; + case 'AM': + return 5; + case 'FM': + return 6; + case 'RTTY': + return 7; + case 'SSTV': + return 8; + case 'ATV': + return 9; + default: + return 0; + } + } +} diff --git a/application/models/Contesting_model.php b/application/models/Contesting_model.php index 60358bcb7..4673f359a 100644 --- a/application/models/Contesting_model.php +++ b/application/models/Contesting_model.php @@ -234,7 +234,7 @@ class Contesting_model extends CI_Model { return; } - function export_custom($from, $to, $contest_id, $station_id) { + function export_custom($from, $to, $contest_id, $station_id, $band = null) { $this->db->select(''.$this->config->item('table_name').'.*, station_profile.*'); $this->db->from($this->config->item('table_name')); $this->db->where($this->config->item('table_name').'.station_id', $station_id); @@ -251,6 +251,11 @@ class Contesting_model extends CI_Model { $this->db->where("date(".$this->config->item('table_name').".COL_TIME_ON) <= '".$to."'"); } + // If band is set, we only load contacts for that band + if ($band != null) { + $this->db->where($this->config->item('table_name').'.COL_BAND', $band); + } + $this->db->where($this->config->item('table_name').'.COL_CONTEST_ID', $contest_id); $this->db->order_by($this->config->item('table_name').".COL_TIME_ON", "ASC"); @@ -316,4 +321,20 @@ class Contesting_model extends CI_Model { return $data->result(); } + + function get_contest_bands($station_id, $year, $contestid, $from, $to) { + + //get distinct bands for the selected timeframe + $sql = "select distinct COL_BAND band + from " . $this->config->item('table_name') . " + where date(".$this->config->item('table_name').".COL_TIME_ON) >= '".$from."' + and date(".$this->config->item('table_name').".COL_TIME_ON) <= '".$to."' + and station_id =" . $station_id . " and COL_CONTEST_ID ='" . $contestid . "'"; + + //get database result + $data = $this->db->query($sql); + + //return data + return $data->result(); + } } diff --git a/application/views/interface_assets/header.php b/application/views/interface_assets/header.php index 54e614a6a..95b2dafd3 100644 --- a/application/views/interface_assets/header.php +++ b/application/views/interface_assets/header.php @@ -393,6 +393,8 @@
  • +
  • +
  • diff --git a/application/views/reg1test/export.php b/application/views/reg1test/export.php new file mode 100644 index 000000000..0575a01ac --- /dev/null +++ b/application/views/reg1test/export.php @@ -0,0 +1,23 @@ +load->library('Reg1testformat'); + +//Set headers +header('Content-Type: text/plain; charset=utf-8'); +header('Content-Disposition: attachment; filename="'.$callsign.'-'.$contest_id.'-'.date('Ymd-Hi').'-'.$CI->reg1testformat->reg1testbandstring($band).'.edi"'); + +//get header +echo $CI->reg1testformat->header($contest_id, $from, $to, $callsign, $gridlocator, $contestaddress1, $contestaddress2, $categoryoperator, $band, $club, $name, + $responsible_operator, $address1, $address2, $addresspostalcode, $addresscity, $addresscountry, $operatorphone, $operators, + $soapbox, $qso_count, $sentexchange, $txequipment, $power, $rxequipment, $antenna, $antennaheight); + +//write QSO details while keeping track of the QSO number +$i = 1; +foreach ($qsos->result() as $row) { + echo $CI->reg1testformat->qso($row, $i); + $i++; +} + +//get footer +echo $CI->reg1testformat->footer(); diff --git a/application/views/reg1test/index.php b/application/views/reg1test/index.php new file mode 100644 index 000000000..ed91c23bc --- /dev/null +++ b/application/views/reg1test/index.php @@ -0,0 +1,142 @@ + +
    + +
    + +

    + +
    +
    + +
    +
    + + '; + + + if ($station_profile) { ?> + +
    +
    +
    + + +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    + + + +
    +
    +
    \ No newline at end of file diff --git a/assets/js/sections/reg1test.js b/assets/js/sections/reg1test.js new file mode 100644 index 000000000..70fb50831 --- /dev/null +++ b/assets/js/sections/reg1test.js @@ -0,0 +1,122 @@ +function loadYears() { + $(".contestyear").empty(); + $(".contestname").empty(); + $(".contestdates").empty(); + $(".contestbands").empty(); + $(".additionalinfo").attr("hidden", true); + $.ajax({ + url: base_url+'index.php/reg1test/getYears', + type: 'post', + data: {'station_id': $("#station_id").val()}, + success: function (data) { + if (data.length > 0) { + $(".contestyear").append('
    ' + lang_export_reg1testedi_select_year + '
    ' + + '' + + ' '); + + $.each(data, function(key, value) { + $('#year') + .append($("") + .attr("value",value.year) + .text(value.year)); + }); + } else { + $(".contestyear").append(lang_export_reg1testedi_no_contests_for_stationlocation); + } + } + }); +} + +function loadContests() { + $(".contestname").empty(); + $(".contestdates").empty(); + $(".contestbands").empty(); + $.ajax({ + url: base_url+'index.php/reg1test/getContests', + type: 'post', + data: {'year': $("#year").val(), + 'station_id': $("#station_id").val() + }, + success: function (data) { + $(".contestname").append('
    ' + lang_export_reg1testedi_select_contest + '
    ' + + '' + + ' '); + + $.each(data, function(key, value) { + $('#contestid') + .append($("") + .attr("value",value.col_contest_id) + .text(value.contestname)); + }); + } + }); +} + +function loadContestDates() { + $(".contestdates").empty(); + $(".contestbands").empty(); + $.ajax({ + url: base_url+'index.php/reg1test/getContestDates', + type: 'post', + data: {'year': $("#year").val(), + 'contestid': $("#contestid").val(), + 'station_id': $("#station_id").val()}, + success: function (data) { + $(".contestdates").append('
    ' + lang_export_reg1testedi_select_date_range + '
    ' + + '' + + '' + + ' '); + + $.each(data, function(key, value) { + $('#contestdatesfrom') + .append($("") + .attr("value", value.date) + .text(value.date)); + }); + + + $.each(data, function(key, value) { + $('#contestdatesto') + .append($("") + .attr("value", value.date) + .text(value.date)); + }); + } + }); +} + +function loadContestBands() { + $(".contestbands").empty(); + + $.ajax({ + url: base_url+'index.php/reg1test/getContestBands', + type: 'post', + data: {'year': $("#year").val(), + 'contestid': $("#contestid").val(), + 'station_id': $("#station_id").val(), + 'contestdatesfrom': $("#contestdatesfrom").val(), + 'contestdatesto': $("#contestdatesto").val() + }, + success: function (data) { + $(".contestbands").append('
    ' + lang_export_reg1testedi_select_band + '
    ' + + '' + + ' '); + + $.each(data, function(key, value) { + $('#contestband') + .append($("") + .attr("value",value.band) + .text(value.band)); + }); + } + }); +} + +function addAdditionalInfo() { + $(".additionalinfo").removeAttr("hidden"); +}