From 977e09d8ac8659c81bb0e07067be2b628a64ddf2 Mon Sep 17 00:00:00 2001 From: "bert.hausmans" Date: Sun, 5 Apr 2026 10:48:04 +0200 Subject: [PATCH] fix: show real Weeztix company trade names, not GUID-as-name Merge nested company objects, prefer trade_name over name, skip UUID-like labels; Alpine falls back to stored company_name when API label is junk. Made-with: Cursor --- app/Services/WeeztixService.php | 98 +++++++++++++++++++++++++++++++-- resources/js/app.js | 28 ++++++++-- 2 files changed, 115 insertions(+), 11 deletions(-) diff --git a/app/Services/WeeztixService.php b/app/Services/WeeztixService.php index 3c0df8e..51ae729 100644 --- a/app/Services/WeeztixService.php +++ b/app/Services/WeeztixService.php @@ -385,15 +385,17 @@ final class WeeztixService return; } - $guid = data_get($row, 'guid') ?? data_get($row, 'id'); - $name = data_get($row, 'name'); + $merged = $this->mergeCompanyRowWithNested($row); + $guid = data_get($merged, 'guid') ?? data_get($merged, 'id'); if (! is_string($guid) || $guid === '') { return; } + $name = $this->resolveCompanyNameFromRow($merged, $guid); + $this->config->update([ 'company_guid' => $guid, - 'company_name' => is_string($name) ? $name : null, + 'company_name' => $name, ]); $this->config->refresh(); } @@ -417,6 +419,20 @@ final class WeeztixService return $this->normalizeCompanyRows($companies); } + $defaultCompany = data_get($profile, 'default_company'); + if (is_array($defaultCompany)) { + $merged = $this->mergeCompanyRowWithNested($defaultCompany); + $guid = data_get($merged, 'guid') ?? data_get($merged, 'id'); + if (is_string($guid) && $guid !== '') { + return [ + [ + 'guid' => $guid, + 'name' => $this->resolveCompanyNameFromRow($merged, $guid), + ], + ]; + } + } + $defaultId = data_get($profile, 'default_company_id'); if (is_string($defaultId) && $defaultId !== '') { return [ @@ -438,20 +454,90 @@ final class WeeztixService if (! is_array($row)) { continue; } - $guid = data_get($row, 'guid') ?? data_get($row, 'id'); + $merged = $this->mergeCompanyRowWithNested($row); + $guid = data_get($merged, 'guid') + ?? data_get($merged, 'id') + ?? data_get($merged, 'company_id'); if (! is_string($guid) || $guid === '') { continue; } - $name = data_get($row, 'name'); $out[] = [ 'guid' => $guid, - 'name' => is_string($name) ? $name : null, + 'name' => $this->resolveCompanyNameFromRow($merged, $guid), ]; } return $out; } + /** + * Flatten `{ "company": { ... } }` style payloads so name fields resolve reliably. + * + * @param array $row + * @return array + */ + private function mergeCompanyRowWithNested(array $row): array + { + $nested = data_get($row, 'company'); + if (! is_array($nested)) { + return $row; + } + + return array_merge($row, $nested); + } + + /** + * Weeztix / Open Ticket payloads use varying keys; `name` is sometimes a duplicate of the GUID. + * + * @param array $row + */ + private function resolveCompanyNameFromRow(array $row, ?string $companyGuid = null): ?string + { + $candidates = [ + data_get($row, 'trade_name'), + data_get($row, 'commercial_name'), + data_get($row, 'business_name'), + data_get($row, 'legal_name'), + data_get($row, 'company_name'), + data_get($row, 'display_name'), + data_get($row, 'title'), + data_get($row, 'label'), + data_get($row, 'general.name'), + data_get($row, 'company.trade_name'), + data_get($row, 'company.legal_name'), + data_get($row, 'company.name'), + data_get($row, 'name'), + ]; + + foreach ($candidates as $value) { + if (! is_string($value)) { + continue; + } + $trimmed = trim($value); + if ($trimmed === '') { + continue; + } + if ($companyGuid !== null && strcasecmp($trimmed, $companyGuid) === 0) { + continue; + } + if ($this->stringLooksLikeUuid($trimmed)) { + continue; + } + + return $trimmed; + } + + return null; + } + + private function stringLooksLikeUuid(string $value): bool + { + return preg_match( + '/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/', + $value + ) === 1; + } + private function logFailedResponse(string $action, string $url, Response $response): void { Log::error('Weeztix API request failed', [ diff --git a/resources/js/app.js b/resources/js/app.js index 8a3abf1..779ad67 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -916,17 +916,35 @@ document.addEventListener('alpine:init', () => { this.syncCouponName(); }, - /** Prefer API/display name; avoid showing raw GUID when a label exists. */ + /** Prefer human-readable label; skip API "names" that are just the GUID / UUID. */ companyLabel(c) { if (!c || typeof c.guid !== 'string') { return ''; } - const n = c.name; - if (typeof n === 'string' && n.trim() !== '') { - return n.trim(); + const g = c.guid; + const isBadLabel = (s) => { + const t = typeof s === 'string' ? s.trim() : ''; + return ( + t === '' || + t.toLowerCase() === g.toLowerCase() || + this.stringLooksLikeUuid(t) + ); + }; + const fromApi = typeof c.name === 'string' ? c.name : ''; + if (!isBadLabel(fromApi)) { + return fromApi.trim(); + } + if (this.companyGuid === g && !isBadLabel(this.companyName)) { + return String(this.companyName).trim(); } - return c.guid; + return g; + }, + + stringLooksLikeUuid(s) { + return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/.test( + String(s), + ); }, })); });