@@ -14,16 +14,18 @@ class CertificateSendWindow extends Command
1414 protected $ signature = 'certificate:send-window
1515 {--edition=2025 : Target edition year}
1616 {--type=all : excellence|super-organiser|all}
17- {--limit=500 : Max recipients to send per type in this run}
18- {--include-send-failed : Include rows that previously failed sending} ' ;
17+ {--limit=500 : Max recipients to send per type per batch}
18+ {--include-send-failed : Include rows that previously failed sending}
19+ {--once : Run only one batch per type then stop (default: run until no recipients left)} ' ;
1920
20- protected $ description = 'Send certificate emails in controlled windows (e.g. 500 at a time); use --type=all for both certs ' ;
21+ protected $ description = 'Send certificate emails in batches; runs until no recipients left ( use --once for single batch) ' ;
2122
2223 public function handle (): int
2324 {
2425 $ edition = (int ) $ this ->option ('edition ' );
2526 $ limit = max (1 , (int ) $ this ->option ('limit ' ));
2627 $ includeSendFailed = (bool ) $ this ->option ('include-send-failed ' );
28+ $ once = (bool ) $ this ->option ('once ' );
2729 $ typeInput = strtolower (trim ((string ) $ this ->option ('type ' )));
2830 $ types = $ this ->resolveTypes ($ typeInput );
2931 if ($ types === null ) {
@@ -33,22 +35,22 @@ public function handle(): int
3335
3436 $ totalQueued = 0 ;
3537 $ totalFailed = 0 ;
36- $ any = false ;
38+ $ batchCount = 0 ;
3739
3840 foreach ($ types as $ type ) {
39- $ result = $ this ->sendWindowForType ($ edition , $ type , $ limit , $ includeSendFailed );
40- $ totalQueued += $ result ['queued ' ];
41- $ totalFailed += $ result ['failed ' ];
42- if ($ result ['processed ' ] > 0 ) {
43- $ any = true ;
44- }
41+ do {
42+ $ result = $ this ->sendWindowForType ($ edition , $ type , $ limit , $ includeSendFailed );
43+ $ totalQueued += $ result ['queued ' ];
44+ $ totalFailed += $ result ['failed ' ];
45+ if ($ result ['processed ' ] > 0 ) {
46+ $ batchCount ++;
47+ }
48+ } while (! $ once && $ result ['processed ' ] > 0 );
4549 }
4650
4751 $ this ->newLine ();
48- $ this ->info ("Send window(s) complete. Total queued: {$ totalQueued }, Total failed: {$ totalFailed }. " );
49- if ($ any ) {
50- $ this ->line ('Run the same command again to process the next batch (or ensure queue worker is running: php artisan queue:work). ' );
51- }
52+ $ this ->info ("Send complete. Batches: {$ batchCount }, Total queued: {$ totalQueued }, Total failed: {$ totalFailed }. " );
53+ $ this ->line ('Ensure queue worker is running to deliver: php artisan queue:work ' );
5254 return self ::SUCCESS ;
5355 }
5456
0 commit comments