Skip to content

Commit ed9a0f8

Browse files
authored
Merge pull request #3395 from codeeu/dev
Dev
2 parents 76912e8 + 04e6952 commit ed9a0f8

1 file changed

Lines changed: 74 additions & 0 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
namespace App\Console\Commands;
4+
5+
use App\Excellence;
6+
use App\Jobs\GenerateCertificateBatchJob;
7+
use Illuminate\Console\Command;
8+
9+
class CertificateRetryFailed extends Command
10+
{
11+
protected $signature = 'certificate:retry-failed
12+
{--edition=2025 : Target edition year}
13+
{--type=excellence : excellence|super-organiser}
14+
{--limit=200 : Max failed rows to reset}
15+
{--dispatch : Dispatch generation job after reset}';
16+
17+
protected $description = 'Reset failed certificate generation rows for retry in controlled batches';
18+
19+
public function handle(): int
20+
{
21+
$edition = (int) $this->option('edition');
22+
$typeOption = (string) $this->option('type');
23+
$limit = max(1, (int) $this->option('limit'));
24+
$shouldDispatch = (bool) $this->option('dispatch');
25+
26+
$type = $this->normalizeType($typeOption);
27+
if ($type === null) {
28+
$this->error("Invalid --type value: {$typeOption}. Use 'excellence' or 'super-organiser'.");
29+
return self::FAILURE;
30+
}
31+
32+
$baseQuery = Excellence::query()
33+
->where('edition', $edition)
34+
->where('type', $type)
35+
->whereNull('certificate_url')
36+
->whereNotNull('certificate_generation_error');
37+
38+
$totalFailed = (clone $baseQuery)->count();
39+
if ($totalFailed === 0) {
40+
$this->info("No failed generation rows found for edition {$edition}, type {$type}.");
41+
return self::SUCCESS;
42+
}
43+
44+
$ids = (clone $baseQuery)->orderBy('id')->limit($limit)->pluck('id')->toArray();
45+
$resetCount = 0;
46+
if (!empty($ids)) {
47+
$resetCount = Excellence::query()
48+
->whereIn('id', $ids)
49+
->update(['certificate_generation_error' => null]);
50+
}
51+
52+
$this->info("Failed rows found: {$totalFailed}");
53+
$this->info("Reset for retry: {$resetCount} (limit: {$limit})");
54+
55+
if ($shouldDispatch && $resetCount > 0) {
56+
GenerateCertificateBatchJob::dispatch($edition, $type, 0);
57+
$this->info("Generation job dispatched for edition {$edition}, type {$type}.");
58+
} else {
59+
$this->line('No job dispatched. Use --dispatch to start generation immediately.');
60+
}
61+
62+
return self::SUCCESS;
63+
}
64+
65+
private function normalizeType(string $typeOption): ?string
66+
{
67+
$slug = strtolower(trim($typeOption));
68+
return match ($slug) {
69+
'excellence' => 'Excellence',
70+
'super-organiser', 'superorganiser' => 'SuperOrganiser',
71+
default => null,
72+
};
73+
}
74+
}

0 commit comments

Comments
 (0)