@@ -32,6 +32,7 @@ public function generate_report($logbooks_locations_array, $year, $month) {
3232 'new_dxcc_satellite ' => $ this ->get_new_dxcc_by_prop ($ logbooks_locations_array , $ start_date , $ end_date , $ prev_month_end , 'SAT ' ),
3333 'new_dxcc_eme ' => $ this ->get_new_dxcc_by_prop ($ logbooks_locations_array , $ start_date , $ end_date , $ prev_month_end , 'EME ' ),
3434 'new_grids ' => $ this ->get_new_gridsquares ($ logbooks_locations_array , $ start_date , $ end_date , $ prev_month_end ),
35+ 'new_grids_by_band ' => $ this ->get_new_gridsquares_by_band ($ logbooks_locations_array , $ start_date , $ end_date , $ prev_month_end ),
3536 'new_grids_satellite ' => $ this ->get_new_gridsquares_by_prop ($ logbooks_locations_array , $ start_date , $ end_date , $ prev_month_end , 'SAT ' ),
3637 'new_grids_eme ' => $ this ->get_new_gridsquares_by_prop ($ logbooks_locations_array , $ start_date , $ end_date , $ prev_month_end , 'EME ' ),
3738 'new_grids_hf ' => $ this ->get_new_gridsquares_hf ($ logbooks_locations_array , $ start_date , $ end_date , $ prev_month_end ),
@@ -432,6 +433,152 @@ private function get_new_dxcc_by_prop($locations, $start_date, $end_date, $prev_
432433 return $ new_dxcc ;
433434 }
434435
436+ /**
437+ * Get new gridsquares by band
438+ */
439+ private function get_new_gridsquares_by_band ($ locations , $ start_date , $ end_date , $ prev_month_end ) {
440+ $ new_grids_by_band = array ();
441+
442+ // Get all bands worked this month, plus propagation mode to separate SAT/EME
443+ $ this ->db ->distinct ();
444+ $ this ->db ->select ('COL_BAND, COL_PROP_MODE ' );
445+ $ this ->db ->from ($ this ->config ->item ('table_name ' ));
446+ $ this ->db ->where_in ('station_id ' , $ locations );
447+ $ this ->db ->where ('COL_TIME_ON >= ' , $ start_date );
448+ $ this ->db ->where ('COL_TIME_ON <= ' , $ end_date );
449+ $ this ->db ->where ('COL_BAND IS NOT NULL ' );
450+ $ this ->db ->where ('COL_BAND != ' , '' );
451+ $ bands_query = $ this ->db ->get ();
452+
453+ foreach ($ bands_query ->result () as $ band_row ) {
454+ $ band = $ band_row ->COL_BAND ;
455+ $ prop_mode = $ band_row ->COL_PROP_MODE ;
456+
457+ // Group SAT and EME separately, not by frequency band
458+ if ($ prop_mode == 'SAT ' ) {
459+ $ band_key = 'Satellite ' ;
460+ } elseif ($ prop_mode == 'EME ' ) {
461+ $ band_key = 'EME ' ;
462+ } else {
463+ $ band_key = $ band ;
464+ }
465+
466+ if (!isset ($ new_grids_by_band [$ band_key ])) {
467+ $ new_grids_by_band [$ band_key ] = array ();
468+ }
469+
470+ // Get all gridsquares worked on this band/prop this month
471+ $ this ->db ->select ('COL_CALL, COL_GRIDSQUARE, COL_VUCC_GRIDS, COL_TIME_ON, COL_MODE, COL_SUBMODE, COL_SAT_NAME ' );
472+ $ this ->db ->from ($ this ->config ->item ('table_name ' ));
473+ $ this ->db ->where_in ('station_id ' , $ locations );
474+ $ this ->db ->where ('COL_TIME_ON >= ' , $ start_date );
475+ $ this ->db ->where ('COL_TIME_ON <= ' , $ end_date );
476+ $ this ->db ->where ('COL_BAND ' , $ band );
477+
478+ // Filter by propagation mode
479+ if ($ prop_mode ) {
480+ $ this ->db ->where ('COL_PROP_MODE ' , $ prop_mode );
481+ } else {
482+ // For terrestrial, exclude SAT and EME
483+ $ this ->db ->where ('(COL_PROP_MODE IS NULL OR (COL_PROP_MODE != "SAT" AND COL_PROP_MODE != "EME")) ' , NULL , FALSE );
484+ }
485+
486+ $ this ->db ->order_by ('COL_TIME_ON ' , 'ASC ' );
487+
488+ $ query = $ this ->db ->get ();
489+ $ grid_data = array ();
490+
491+ foreach ($ query ->result () as $ row ) {
492+ $ mode = !empty ($ row ->COL_SUBMODE ) ? $ row ->COL_SUBMODE : $ row ->COL_MODE ;
493+
494+ // Process main gridsquare (first 4 characters only)
495+ if (!empty ($ row ->COL_GRIDSQUARE ) && strlen ($ row ->COL_GRIDSQUARE ) >= 4 ) {
496+ $ grid_4char = strtoupper (substr ($ row ->COL_GRIDSQUARE , 0 , 4 ));
497+ if (!isset ($ grid_data [$ grid_4char ])) {
498+ $ grid_data [$ grid_4char ] = array (
499+ 'callsign ' => $ row ->COL_CALL ,
500+ 'satellite ' => !empty ($ row ->COL_SAT_NAME ) ? $ row ->COL_SAT_NAME : '' ,
501+ 'mode ' => $ mode ,
502+ 'time ' => $ row ->COL_TIME_ON
503+ );
504+ }
505+ }
506+
507+ // Process VUCC grids (first 4 characters only)
508+ if (!empty ($ row ->COL_VUCC_GRIDS )) {
509+ $ vucc_grids = explode (', ' , $ row ->COL_VUCC_GRIDS );
510+ foreach ($ vucc_grids as $ grid ) {
511+ $ grid = trim ($ grid );
512+ if (strlen ($ grid ) >= 4 ) {
513+ $ grid_4char = strtoupper (substr ($ grid , 0 , 4 ));
514+ if (!isset ($ grid_data [$ grid_4char ])) {
515+ $ grid_data [$ grid_4char ] = array (
516+ 'callsign ' => $ row ->COL_CALL ,
517+ 'satellite ' => !empty ($ row ->COL_SAT_NAME ) ? $ row ->COL_SAT_NAME : '' ,
518+ 'mode ' => $ mode ,
519+ 'time ' => $ row ->COL_TIME_ON
520+ );
521+ }
522+ }
523+ }
524+ }
525+ }
526+
527+ // Check each grid to see if it was worked before on this band/prop
528+ foreach ($ grid_data as $ grid => $ data ) {
529+ // Check if this grid was worked before this month on this band/prop
530+ $ this ->db ->select ('COUNT(*) as count ' );
531+ $ this ->db ->from ($ this ->config ->item ('table_name ' ));
532+ $ this ->db ->where_in ('station_id ' , $ locations );
533+ $ this ->db ->where ('COL_BAND ' , $ band );
534+ if ($ prop_mode ) {
535+ $ this ->db ->where ('COL_PROP_MODE ' , $ prop_mode );
536+ } else {
537+ $ this ->db ->where ('(COL_PROP_MODE IS NULL OR (COL_PROP_MODE != "SAT" AND COL_PROP_MODE != "EME")) ' , NULL , FALSE );
538+ }
539+ $ this ->db ->where ('COL_TIME_ON < ' , $ start_date );
540+ $ this ->db ->group_start ();
541+ $ this ->db ->where ('UPPER(SUBSTR(COL_GRIDSQUARE, 1, 4)) = ' , $ grid );
542+ $ this ->db ->or_like ('COL_VUCC_GRIDS ' , $ grid );
543+ $ this ->db ->group_end ();
544+
545+ $ prev_query = $ this ->db ->get ();
546+ $ prev_row = $ prev_query ->row ();
547+
548+ // If not worked before on this band/prop, it's new
549+ if ($ prev_row ->count == 0 ) {
550+ // Avoid duplicates in the same band_key
551+ $ already_added = false ;
552+ foreach ($ new_grids_by_band [$ band_key ] as $ existing ) {
553+ if ($ existing ['grid ' ] == $ grid ) {
554+ $ already_added = true ;
555+ break ;
556+ }
557+ }
558+
559+ if (!$ already_added ) {
560+ $ new_grids_by_band [$ band_key ][] = array (
561+ 'grid ' => $ grid ,
562+ 'callsign ' => $ data ['callsign ' ],
563+ 'satellite ' => $ data ['satellite ' ],
564+ 'mode ' => $ data ['mode ' ]
565+ );
566+ }
567+ }
568+ }
569+ }
570+
571+ // Remove bands with no new grids
572+ $ new_grids_by_band = array_filter ($ new_grids_by_band , function ($ arr ) {
573+ return !empty ($ arr );
574+ });
575+
576+ // Sort bands in proper amateur radio order
577+ $ new_grids_by_band = $ this ->sort_bands_array ($ new_grids_by_band );
578+
579+ return $ new_grids_by_band ;
580+ }
581+
435582 /**
436583 * Get new gridsquares worked this month (first time ever) - All modes
437584 */
0 commit comments