-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathApplyDueAmendments.php
More file actions
81 lines (72 loc) · 3.05 KB
/
Copy pathApplyDueAmendments.php
File metadata and controls
81 lines (72 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?php
namespace App\Console\Commands\stufis;
use App\Models\BudgetPlan;
use App\States\BudgetPlan\Active;
use App\States\BudgetPlan\Approved;
use App\Support\Budget\AmendmentConflictException;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Spatie\ModelStates\Exceptions\CouldNotPerformTransition;
use Throwable;
/**
* Scheduled effectiveness for Nachtragshaushaltspläne (amendments, OP#581): an approved amendment
* with an `effective_date` in the past should go live on its own, without someone manually
* clicking "aktivieren" on the day. Runs daily (see routes/console.php).
*
* Every due amendment is transitioned independently, so one amendment's conflict (e.g. a stale
* item, or its parent plan no longer being Active) doesn't block the others. Failures are logged
* and reported on stderr; the command exits non-zero when any amendment failed, so the run stays
* visible and the schedule's failure hooks can act on it — the run is safely re-triggerable, since
* only successfully-applied amendments leave Approved.
*/
class ApplyDueAmendments extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'stufis:apply-due-amendments';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Activate approved Nachtragshaushaltspläne (amendments) whose effective_date has arrived';
public function handle(): int
{
$due = BudgetPlan::query()
->whereNotNull('parent_plan_id')
->where('state', Approved::$name)
->whereNotNull('effective_date')
->whereDate('effective_date', '<=', today())
->get()
->filter(fn (BudgetPlan $amendment): bool => $amendment->parentPlan?->state instanceof Active);
if ($due->isEmpty()) {
$this->info('No due amendments to activate.');
return self::SUCCESS;
}
$failed = 0;
foreach ($due as $amendment) {
try {
$amendment->state->transitionTo(Active::class);
$this->info("Activated amendment #{$amendment->id} ({$amendment->label()}).");
} catch (AmendmentConflictException|CouldNotPerformTransition $e) {
$failed++;
$this->error("Amendment #{$amendment->id} could not be activated: {$e->getMessage()}");
Log::warning('stufis:apply-due-amendments failed for amendment', [
'amendment_id' => $amendment->id,
'message' => $e->getMessage(),
]);
} catch (Throwable $e) {
$failed++;
$this->error("Amendment #{$amendment->id} could not be activated: {$e->getMessage()}");
Log::error('stufis:apply-due-amendments unexpected failure for amendment', [
'amendment_id' => $amendment->id,
'exception' => $e,
]);
}
}
return $failed > 0 ? self::FAILURE : self::SUCCESS;
}
}