77 lines
2.8 KiB
PHP
77 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Billing;
|
|
|
|
use App\Support\Settings;
|
|
use Illuminate\Support\Carbon;
|
|
|
|
/**
|
|
* What the last `stripe:sync-catalogue` run printed, and when.
|
|
*
|
|
* A settings row rather than a table, for the same reason InboundMailStatus is
|
|
* one: there is exactly one catalogue and exactly one last answer, and a table
|
|
* of one row is a table somebody has to prune.
|
|
*
|
|
* The OUTPUT is kept whole and unedited. Two of the things this command says
|
|
* are instructions rather than statuses — the refusal to touch a catalogue that
|
|
* belongs to the other Stripe account names the three places an operator has to
|
|
* clear, and the duplicate-product warning names an id only a person can
|
|
* resolve. Summarising either into "sync failed" would take away exactly the
|
|
* sentence that was worth reading, and send the operator back to the terminal
|
|
* this page exists to replace.
|
|
*/
|
|
class CatalogueSyncStatus
|
|
{
|
|
private const KEY = 'billing.catalogue_sync';
|
|
|
|
/**
|
|
* How much of the run's output is kept.
|
|
*
|
|
* Generous on purpose: a first run on a full catalogue prints a line per
|
|
* product and per price pair, and the interesting part of a long run is the
|
|
* end. Bounded all the same, because this is a settings row that gets read
|
|
* on every render of the page.
|
|
*/
|
|
private const MAX_OUTPUT = 20000;
|
|
|
|
public function record(bool $ok, bool $dryRun, string $output, string $by): void
|
|
{
|
|
Settings::set(self::KEY, [
|
|
'at' => Carbon::now()->toIso8601String(),
|
|
'ok' => $ok,
|
|
'dry_run' => $dryRun,
|
|
// Tail, not head: the summary line an operator is looking for
|
|
// ("N object(s) would be created", or the refusal) is the last
|
|
// thing printed, and a head-truncated log would cut off exactly it.
|
|
'output' => mb_strlen($output) > self::MAX_OUTPUT
|
|
? '…'.mb_substr($output, -self::MAX_OUTPUT)
|
|
: $output,
|
|
'by' => $by,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* The last run, or null if nobody has ever asked.
|
|
*
|
|
* @return array{at: Carbon, ok: bool, dry_run: bool, output: string, by: string}|null
|
|
*/
|
|
public function last(): ?array
|
|
{
|
|
$row = Settings::get(self::KEY);
|
|
|
|
if (! is_array($row) || ! isset($row['at'])) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
// Parsed back into a Carbon so the view can put it on the wall
|
|
// clock (R19) rather than printing an ISO string at somebody.
|
|
'at' => Carbon::parse((string) $row['at']),
|
|
'ok' => (bool) ($row['ok'] ?? false),
|
|
'dry_run' => (bool) ($row['dry_run'] ?? false),
|
|
'output' => (string) ($row['output'] ?? ''),
|
|
'by' => (string) ($row['by'] ?? ''),
|
|
];
|
|
}
|
|
}
|