CluPilotCloud/app/Console/Commands/ArchiveUnexportedInvoices.php

64 lines
2.1 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Jobs\ArchiveInvoice;
use App\Models\Invoice;
use App\Models\ExportTarget;
use Illuminate\Console\Command;
/**
* The sweep behind the copy-on-issue.
*
* Copying at issue is right and it is not enough. An invoice issued while the
* office connection was down never reaches the archive, the queue eventually
* gives up, and nothing about the invoice tells anybody — nobody opens an
* archive to check whether last Tuesday is in it. This picks up whatever is
* still missing, however long ago it was issued.
*
* Deliberately re-queues rather than writing here: the job already knows how to
* write one, and two code paths that both write an invoice into an archive is
* one more than the number that can be kept correct.
*/
class ArchiveUnexportedInvoices extends Command
{
protected $signature = 'clupilot:archive-invoices {--limit=200}';
protected $description = 'Queue a copy of every invoice that is not on the archive yet';
public function handle(): int
{
$targets = ExportTarget::query()->where('active', true)->get();
if ($targets->isEmpty()) {
$this->line('No export target configured — nothing to do.');
return self::SUCCESS;
}
$queued = 0;
foreach ($targets as $target) {
// Per destination, because "arrived" is a fact about a pair. An
// invoice on the office NAS and not on the off-site box is exactly
// the case this exists to catch.
$pending = Invoice::query()
->whereDoesntHave('exports', fn ($q) => $q
->where('export_target_id', $target->id)
->whereNotNull('exported_at'))
->orderBy('id')
->limit((int) $this->option('limit'))
->get();
foreach ($pending as $invoice) {
ArchiveInvoice::dispatch($invoice, $target);
$queued++;
}
}
$this->line("Queued {$queued} copy/copies for {$targets->count()} destination(s).");
return self::SUCCESS;
}
}