Files
ladill-qr-plus/app/Console/Commands/ImportQrPlusCommand.php
T
isaaccladandCursor cd6571f199
Deploy Ladill QR Plus / deploy (push) Failing after 1s
Extract Ladill QR Plus as standalone app at qr.ladill.com.
Utility QR types only (URL, WiFi, link list, business, app download) with
SSO, Billing API integration, public /q resolver, and qr-plus:import for
platform migration. vCard and commerce types stay on the platform.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 21:31:24 +00:00

162 lines
5.0 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\QrCode;
use App\Models\QrScanEvent;
use App\Models\QrTransaction;
use App\Models\QrWallet;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class ImportQrPlusCommand extends Command
{
protected $signature = 'qr-plus:import
{file : Path to qr-plus-export.json from the platform}
{--commit : Actually write changes}';
protected $description = 'Import QR Plus codes from the platform export';
/** @var array<int,int> platform qr_code id → local id */
private array $codeMap = [];
public function handle(): int
{
$commit = (bool) $this->option('commit');
if (! $commit) {
$this->warn('DRY RUN — no changes will be written. Re-run with --commit to apply.');
}
$path = $this->argument('file');
if (! is_file($path)) {
$this->error("File not found: {$path}");
return self::FAILURE;
}
$payload = json_decode((string) file_get_contents($path), true);
if (! is_array($payload)) {
$this->error('Invalid JSON export file.');
return self::FAILURE;
}
$apply = function (callable $callback) use ($commit): void {
if ($commit) {
DB::transaction($callback);
} else {
$callback();
}
};
$apply(function () use ($payload, $commit): void {
foreach ($payload['qr_wallets'] ?? [] as $row) {
$this->importWallet($row, $commit);
}
foreach ($payload['qr_codes'] ?? [] as $row) {
$this->importCode($row, $commit);
}
foreach ($payload['qr_scan_events'] ?? [] as $row) {
$this->importScanEvent($row, $commit);
}
foreach ($payload['qr_transactions'] ?? [] as $row) {
$this->importTransaction($row, $commit);
}
});
$this->info(($commit ? 'Imported' : 'Would import').' '.count($this->codeMap).' QR code(s).');
return self::SUCCESS;
}
private function resolveUser(array $row): ?User
{
$publicId = $row['owner_public_id'] ?? null;
if (! $publicId) {
return null;
}
return User::firstOrCreate(
['public_id' => $publicId],
['email' => $row['owner_email'] ?? $publicId.'@users.ladill.com', 'name' => 'Imported user'],
);
}
/** @param array<string,mixed> $row */
private function importWallet(array $row, bool $commit): void
{
$user = $this->resolveUser($row);
if (! $user) {
return;
}
$attrs = collect($row)->except(['platform_id', 'owner_public_id', 'owner_email', 'id', 'user_id'])->all();
if ($commit) {
QrWallet::updateOrCreate(['user_id' => $user->id], $attrs);
}
}
/** @param array<string,mixed> $row */
private function importCode(array $row, bool $commit): void
{
$user = $this->resolveUser($row);
if (! $user) {
return;
}
$platformId = (int) ($row['platform_id'] ?? 0);
$shortCode = (string) ($row['short_code'] ?? '');
$attrs = collect($row)->except(['platform_id', 'owner_public_id', 'owner_email', 'id', 'user_id', 'qr_document_id'])->all();
$attrs['user_id'] = $user->id;
if ($commit) {
$code = QrCode::updateOrCreate(['short_code' => $shortCode], $attrs);
$this->codeMap[$platformId] = $code->id;
} else {
$this->codeMap[$platformId] = $platformId;
}
}
/** @param array<string,mixed> $row */
private function importScanEvent(array $row, bool $commit): void
{
$platformCodeId = (int) ($row['platform_qr_code_id'] ?? 0);
$localCodeId = $this->codeMap[$platformCodeId] ?? null;
if (! $localCodeId) {
return;
}
$attrs = collect($row)->except(['platform_id', 'platform_qr_code_id', 'id', 'qr_code_id'])->all();
$attrs['qr_code_id'] = $localCodeId;
if ($commit) {
QrScanEvent::updateOrCreate(
['qr_code_id' => $localCodeId, 'created_at' => $attrs['created_at'] ?? now()],
$attrs,
);
}
}
/** @param array<string,mixed> $row */
private function importTransaction(array $row, bool $commit): void
{
$user = $this->resolveUser($row);
if (! $user) {
return;
}
$wallet = QrWallet::firstOrCreate(['user_id' => $user->id]);
$reference = (string) ($row['reference'] ?? '');
$attrs = collect($row)->except(['platform_id', 'owner_public_id', 'id', 'user_id', 'qr_wallet_id', 'qr_code_id'])->all();
$attrs['user_id'] = $user->id;
$attrs['qr_wallet_id'] = $wallet->id;
if ($commit && $reference !== '') {
QrTransaction::updateOrCreate(['reference' => $reference], $attrs);
}
}
}