124 lines
4.2 KiB
PHP
124 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Services\Moneybird\MoneybirdClient;
|
|
use App\Services\Moneybird\MoneybirdException;
|
|
use Illuminate\Console\Command;
|
|
|
|
/**
|
|
* One-time interactive helper for wiring up the Moneybird integration.
|
|
* Never writes .env itself — it only prints the values so you can decide
|
|
* what to do with them.
|
|
*/
|
|
class MoneybirdSetup extends Command
|
|
{
|
|
protected $signature = 'moneybird:setup';
|
|
|
|
protected $description = 'Discover your Moneybird administration/tax rate/ledger account IDs and (optionally) register the webhook';
|
|
|
|
public function handle(MoneybirdClient $client): int
|
|
{
|
|
if (blank(config('services.moneybird.api_token'))) {
|
|
$this->error('Set MONEYBIRD_API_TOKEN in .env first.');
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$administrationId = config('services.moneybird.administration_id') ?: $this->discoverAdministration($client);
|
|
|
|
if ($administrationId === null) {
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$this->line("Using administration_id: <info>{$administrationId}</info>");
|
|
|
|
// Every subsequent call reads administration_id straight from
|
|
// config, so make sure it's set for the rest of this run even if
|
|
// it was only just discovered above.
|
|
config(['services.moneybird.administration_id' => $administrationId]);
|
|
|
|
$this->newLine();
|
|
$this->listTaxRatesAndLedgerAccounts($client);
|
|
|
|
$this->newLine();
|
|
if ($this->confirm('Register a webhook now, pointing at '.config('app.url').'/webhooks/moneybird ?', false)) {
|
|
$this->registerWebhook($client);
|
|
}
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
private function discoverAdministration(MoneybirdClient $client): ?string
|
|
{
|
|
try {
|
|
$administrations = $client->listAdministrations();
|
|
} catch (MoneybirdException $e) {
|
|
$this->error($e->getMessage());
|
|
|
|
return null;
|
|
}
|
|
|
|
if ($administrations === []) {
|
|
$this->error('No Moneybird administrations found for this token.');
|
|
|
|
return null;
|
|
}
|
|
|
|
if (count($administrations) === 1) {
|
|
return (string) $administrations[0]['id'];
|
|
}
|
|
|
|
$choices = collect($administrations)->mapWithKeys(fn ($admin) => [$admin['id'] => "{$admin['name']} ({$admin['id']})"]);
|
|
|
|
$selected = $this->choice('Multiple administrations found — pick one', $choices->values()->all());
|
|
|
|
return (string) $choices->search($selected);
|
|
}
|
|
|
|
private function listTaxRatesAndLedgerAccounts(MoneybirdClient $client): void
|
|
{
|
|
try {
|
|
$taxRates = $client->listTaxRates();
|
|
$ledgerAccounts = $client->listLedgerAccounts();
|
|
} catch (MoneybirdException $e) {
|
|
$this->error($e->getMessage());
|
|
|
|
return;
|
|
}
|
|
|
|
$this->info('Tax rates — pick one for MONEYBIRD_TAX_RATE_ID (optional, invoices work without it):');
|
|
$this->table(['id', 'name', 'percentage'], collect($taxRates)->map(fn ($rate) => [
|
|
$rate['id'], $rate['name'] ?? '', $rate['percentage'] ?? '',
|
|
]));
|
|
|
|
$this->info('Ledger accounts — pick one for MONEYBIRD_LEDGER_ACCOUNT_ID (optional):');
|
|
$this->table(['id', 'name'], collect($ledgerAccounts)->map(fn ($account) => [
|
|
$account['id'], $account['name'] ?? '',
|
|
]));
|
|
}
|
|
|
|
private function registerWebhook(MoneybirdClient $client): void
|
|
{
|
|
try {
|
|
$webhook = $client->createWebhook([
|
|
'url' => config('app.url').'/webhooks/moneybird',
|
|
'enabled_events' => [
|
|
'sales_invoice_created',
|
|
'sales_invoice_created_based_on_recurring',
|
|
'sales_invoice_state_changed_to_paid',
|
|
'sales_invoice_state_changed_to_late',
|
|
'sales_invoice_marked_as_uncollectible',
|
|
'recurring_sales_invoice_invoice_created',
|
|
],
|
|
]);
|
|
} catch (MoneybirdException $e) {
|
|
$this->error($e->getMessage());
|
|
|
|
return;
|
|
}
|
|
|
|
$this->info('Webhook registered. Add this to .env:');
|
|
$this->line('MONEYBIRD_WEBHOOK_TOKEN="'.$webhook['token'].'"');
|
|
}
|
|
}
|