ResolveVendorUseCase.php
Pfad: src/Application/Rechnung/ResolveVendorUseCase.php
Ext: php
Größe: 3023 Bytes
Geändert: 2026-07-16 17:24:56+02
<?php
declare(strict_types=1);
namespace Demo\Application\Rechnung;
use Demo\Domain\Rechnung\ExtractedInvoiceData;
use Demo\Domain\Rechnung\InvoiceErrorCode;
use Demo\Domain\Rechnung\InvoiceLoggerPort;
use Demo\Domain\Rechnung\LexofficePort;
final class ResolveVendorUseCase
{
public function __construct(
private readonly LexofficePort $lexoffice,
private readonly InvoiceLoggerPort $logger,
) {
}
public function execute(string $runId, ExtractedInvoiceData $data): string
{
$invoice = $data->toArray();
$name = (string) $invoice['vendorName'];
$signature = (string) $invoice['vendorAddressSignature'];
$matches = [];
foreach ($this->lexoffice->findContactByName($name) as $contact) {
if ($this->matches($contact, $name, $signature)) {
$matches[] = $contact;
}
}
if (count($matches) > 1) {
throw new InvoiceProcessException(
InvoiceErrorCode::VENDOR_MATCH,
'resolve_vendor',
'Mehrere identische Lieferantenkontakte gefunden',
0,
null,
);
}
if ($matches !== []) {
$id = $matches[0]['id'] ?? null;
if (!is_string($id) || $id === '') {
throw new InvoiceProcessException(InvoiceErrorCode::VENDOR_MATCH, 'resolve_vendor', 'Kontakt-ID fehlt', 0, null);
}
$this->logger->logStep($runId, 'resolve_vendor', 'REUSED', ['contactId' => $id]);
return $id;
}
$id = $this->lexoffice->createContact($name, $signature);
$this->logger->logStep($runId, 'resolve_vendor', 'CREATED', ['contactId' => $id]);
return $id;
}
/** @param array<string,mixed> $contact */
private function matches(array $contact, string $name, string $signature): bool
{
$roles = $contact['roles'] ?? null;
$company = $contact['company'] ?? null;
if (!is_array($roles) || !array_key_exists('vendor', $roles) || !is_array($company)) {
return false;
}
if ($this->normalize((string) ($company['name'] ?? '')) !== $this->normalize($name)) {
return false;
}
$addresses = $contact['addresses'] ?? null;
$billing = is_array($addresses) ? ($addresses['billing'] ?? null) : null;
$address = is_array($billing) && isset($billing[0]) && is_array($billing[0]) ? $billing[0] : [];
$remote = implode('|', [
(string) ($address['street'] ?? ''),
trim((string) ($address['zip'] ?? '') . ' ' . (string) ($address['city'] ?? '')),
strtoupper((string) ($address['countryCode'] ?? '')),
]);
return $this->normalize($remote) === $this->normalize($signature);
}
private function normalize(string $value): string
{
$value = mb_strtolower(trim($value), 'UTF-8');
return preg_replace('/[^\pL\pN]+/u', '', $value) ?? '';
}
}
Frühere Versionen
| Version | Zeitpunkt | Operation |
|---|---|---|
| 35 | 2026-07-16 19:55:01.886511+02 | UPDATE |