Files
compras/app/Console/Commands/ReplenishmentTick.php
T
2026-11-03 11:51:44 +02:00

56 lines
2.0 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Services\ReplenishmentHeartbeat;
use App\Services\ReplenishmentProcessLock;
use App\Services\ReplenishmentQueue;
use Illuminate\Console\Command;
class ReplenishmentTick extends Command
{
protected $signature = 'sgc:replenishment-tick {--limit= : Máximo de artigos/armazéns por execução}';
protected $description = 'Recuperar reposições pendentes e reavaliar mínimos e validade, sem aprovar compras';
public function handle(ReplenishmentQueue $queue): int
{
if (! $queue->ready()) {
$this->warn('Reposição durável não instalada nesta composição.');
return self::FAILURE;
}
$limit = $this->option('limit') ?? config('replenishment.batch_size');
if (! filter_var($limit, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1, 'max_range' => 500]])) {
$this->error('Limite entre 1 e 500.');
return self::INVALID;
}
$started = now()->toIso8601String();
$exitCode = self::FAILURE;
$lock = app(ReplenishmentProcessLock::class);
if (! $lock->acquire()) {
$this->info('Verificação periódica já em execução; aguarde a próxima passagem.');
return self::FAILURE;
}
try {
$queue->discover();
$result = $queue->drain((int) $limit);
$this->info('Reposição: '.$result['processed'].' trabalhos conferidos; '.$result['failed'].' a recuperar.');
$exitCode = $result['failed'] === 0 ? self::SUCCESS : self::FAILURE;
return $exitCode;
} finally {
try {
app(ReplenishmentHeartbeat::class)->record($started, $exitCode);
} catch (\Throwable $error) {
report($error);
$this->warn('Não foi possível actualizar o acompanhamento técnico desta execução.');
} finally {
$lock->release();
}
}
}
}