feat(06-sonarqube-quality): extract long methods to fix S138 violations (06-06)
ShopproOrdersSyncService: sync() 195→44 lines via syncOneIntegration, fetchOrdersPage, processPageCandidates, importOneOrder; mapAddresses() 166→34 lines via buildCustomerAddress, buildDeliveryAddress. OrdersRepository: paginate() 183→69 lines via buildPaginateFilters, buildListSql, transformOrderRow; findDetails() 101→40 lines via loadOrderAddresses/Items/Payments/Shipments/Documents/Notes/StatusHistory. SonarQube S138 violations: 4 → 0. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -60,169 +60,203 @@ final class ShopproOrdersSyncService
|
||||
}
|
||||
|
||||
$result['checked_integrations'] = (int) $result['checked_integrations'] + 1;
|
||||
$state = $this->syncState->getState($integrationId);
|
||||
$this->syncState->markRunStarted($integrationId, new DateTimeImmutable('now'));
|
||||
|
||||
try {
|
||||
$statusMap = $this->buildStatusMap($integrationId);
|
||||
$cursorUpdatedAt = StringHelper::nullableString((string) ($state['last_synced_updated_at'] ?? ''));
|
||||
$cursorOrderId = StringHelper::nullableString((string) ($state['last_synced_source_order_id'] ?? ''));
|
||||
$startDate = $this->resolveStartDate(
|
||||
(string) ($integration['orders_fetch_start_date'] ?? ''),
|
||||
$cursorUpdatedAt
|
||||
);
|
||||
$baseUrl = trim((string) ($integration['base_url'] ?? ''));
|
||||
$apiKey = $this->integrations->getApiKeyDecrypted($integrationId);
|
||||
$timeout = max(1, min(120, (int) ($integration['timeout_seconds'] ?? 10)));
|
||||
$productImageCache = [];
|
||||
|
||||
if ($baseUrl === '' || $apiKey === null || trim($apiKey) === '') {
|
||||
throw new \RuntimeException('Brak poprawnych danych API dla integracji.');
|
||||
}
|
||||
|
||||
$latestUpdatedAt = $cursorUpdatedAt;
|
||||
$latestOrderId = $cursorOrderId;
|
||||
$shouldStop = false;
|
||||
|
||||
for ($page = 1; $page <= $maxPages; $page++) {
|
||||
$orders = $this->apiClient->fetchOrders($baseUrl, $apiKey, $timeout, $page, $pageLimit, $startDate);
|
||||
if (($orders['ok'] ?? false) !== true) {
|
||||
throw new \RuntimeException((string) ($orders['message'] ?? 'Blad pobierania listy zamowien.'));
|
||||
}
|
||||
|
||||
$items = is_array($orders['items'] ?? null) ? $orders['items'] : [];
|
||||
if ($items === []) {
|
||||
break;
|
||||
}
|
||||
|
||||
$candidates = $this->buildCandidates($items, $cursorUpdatedAt, $cursorOrderId);
|
||||
foreach ($candidates as $candidate) {
|
||||
if ((int) $result['processed'] >= $maxOrders) {
|
||||
$shouldStop = true;
|
||||
break;
|
||||
}
|
||||
|
||||
$sourceOrderId = (string) ($candidate['source_order_id'] ?? '');
|
||||
$sourceUpdatedAt = (string) ($candidate['source_updated_at'] ?? '');
|
||||
$rawOrder = is_array($candidate['payload'] ?? null) ? $candidate['payload'] : [];
|
||||
|
||||
$details = $this->apiClient->fetchOrderById($baseUrl, $apiKey, $timeout, $sourceOrderId);
|
||||
if (($details['ok'] ?? false) === true && is_array($details['order'] ?? null)) {
|
||||
$detailsOrder = (array) $details['order'];
|
||||
foreach ([
|
||||
'products',
|
||||
'summary',
|
||||
'paid',
|
||||
'transport_cost',
|
||||
'transport',
|
||||
'transport_description',
|
||||
'client_name',
|
||||
'client_surname',
|
||||
'client_email',
|
||||
'client_phone',
|
||||
'client_city',
|
||||
'client_street',
|
||||
'client_postal_code',
|
||||
] as $protectedKey) {
|
||||
if (array_key_exists($protectedKey, $rawOrder)) {
|
||||
unset($detailsOrder[$protectedKey]);
|
||||
}
|
||||
}
|
||||
$rawOrder = array_replace($rawOrder, $detailsOrder);
|
||||
}
|
||||
|
||||
try {
|
||||
$productImages = $this->resolveProductImagesForOrder(
|
||||
$baseUrl,
|
||||
(string) $apiKey,
|
||||
$timeout,
|
||||
$rawOrder,
|
||||
$productImageCache
|
||||
);
|
||||
$aggregate = $this->mapOrderAggregate(
|
||||
$integrationId,
|
||||
$rawOrder,
|
||||
$statusMap,
|
||||
$sourceOrderId,
|
||||
$sourceUpdatedAt,
|
||||
$productImages
|
||||
);
|
||||
$save = $this->orderImportRepository->upsertOrderAggregate(
|
||||
$aggregate['order'],
|
||||
$aggregate['addresses'],
|
||||
$aggregate['items'],
|
||||
$aggregate['payments'],
|
||||
$aggregate['shipments'],
|
||||
$aggregate['notes'],
|
||||
$aggregate['status_history']
|
||||
);
|
||||
$result['processed'] = (int) $result['processed'] + 1;
|
||||
if (!empty($save['created'])) {
|
||||
$result['imported_created'] = (int) $result['imported_created'] + 1;
|
||||
} else {
|
||||
$result['imported_updated'] = (int) $result['imported_updated'] + 1;
|
||||
}
|
||||
|
||||
$this->orders->recordActivity(
|
||||
(int) ($save['order_id'] ?? 0),
|
||||
'import',
|
||||
'Import zamowienia z shopPRO',
|
||||
[
|
||||
'integration_id' => $integrationId,
|
||||
'source_order_id' => $sourceOrderId,
|
||||
],
|
||||
'import',
|
||||
'shopPRO'
|
||||
);
|
||||
} catch (Throwable $exception) {
|
||||
$result['failed'] = (int) $result['failed'] + 1;
|
||||
$errors = is_array($result['errors']) ? $result['errors'] : [];
|
||||
if (count($errors) < 20) {
|
||||
$errors[] = [
|
||||
'integration_id' => $integrationId,
|
||||
'source_order_id' => $sourceOrderId,
|
||||
'error' => $exception->getMessage(),
|
||||
];
|
||||
}
|
||||
$result['errors'] = $errors;
|
||||
}
|
||||
|
||||
if ($latestUpdatedAt === null || $sourceUpdatedAt > $latestUpdatedAt) {
|
||||
$latestUpdatedAt = $sourceUpdatedAt;
|
||||
$latestOrderId = $sourceOrderId;
|
||||
} elseif ($latestUpdatedAt === $sourceUpdatedAt && ($latestOrderId === null || strcmp($sourceOrderId, $latestOrderId) > 0)) {
|
||||
$latestOrderId = $sourceOrderId;
|
||||
}
|
||||
}
|
||||
|
||||
if ($shouldStop || count($items) < $pageLimit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->syncState->markRunSuccess(
|
||||
$integrationId,
|
||||
new DateTimeImmutable('now'),
|
||||
$latestUpdatedAt,
|
||||
$latestOrderId
|
||||
);
|
||||
} catch (Throwable $exception) {
|
||||
$this->syncState->markRunFailed($integrationId, new DateTimeImmutable('now'), $exception->getMessage());
|
||||
$result['failed'] = (int) $result['failed'] + 1;
|
||||
$errors = is_array($result['errors']) ? $result['errors'] : [];
|
||||
if (count($errors) < 20) {
|
||||
$errors[] = [
|
||||
'integration_id' => $integrationId,
|
||||
'error' => $exception->getMessage(),
|
||||
];
|
||||
}
|
||||
$result['errors'] = $errors;
|
||||
}
|
||||
$this->syncOneIntegration($integration, $maxPages, $pageLimit, $maxOrders, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $integration
|
||||
* @param array<string, mixed> $result
|
||||
*/
|
||||
private function syncOneIntegration(array $integration, int $maxPages, int $pageLimit, int $maxOrders, array &$result): void
|
||||
{
|
||||
$integrationId = (int) ($integration['id'] ?? 0);
|
||||
$state = $this->syncState->getState($integrationId);
|
||||
$this->syncState->markRunStarted($integrationId, new DateTimeImmutable('now'));
|
||||
|
||||
try {
|
||||
$statusMap = $this->buildStatusMap($integrationId);
|
||||
$cursorUpdatedAt = StringHelper::nullableString((string) ($state['last_synced_updated_at'] ?? ''));
|
||||
$cursorOrderId = StringHelper::nullableString((string) ($state['last_synced_source_order_id'] ?? ''));
|
||||
$startDate = $this->resolveStartDate(
|
||||
(string) ($integration['orders_fetch_start_date'] ?? ''),
|
||||
$cursorUpdatedAt
|
||||
);
|
||||
$baseUrl = trim((string) ($integration['base_url'] ?? ''));
|
||||
$apiKey = $this->integrations->getApiKeyDecrypted($integrationId);
|
||||
$timeout = max(1, min(120, (int) ($integration['timeout_seconds'] ?? 10)));
|
||||
$productImageCache = [];
|
||||
|
||||
if ($baseUrl === '' || $apiKey === null || trim($apiKey) === '') {
|
||||
throw new \RuntimeException('Brak poprawnych danych API dla integracji.');
|
||||
}
|
||||
|
||||
$latestUpdatedAt = $cursorUpdatedAt;
|
||||
$latestOrderId = $cursorOrderId;
|
||||
$shouldStop = false;
|
||||
|
||||
for ($page = 1; $page <= $maxPages; $page++) {
|
||||
$items = $this->fetchOrdersPage($baseUrl, (string) $apiKey, $timeout, $page, $pageLimit, $startDate);
|
||||
if ($items === []) {
|
||||
break;
|
||||
}
|
||||
$candidates = $this->buildCandidates($items, $cursorUpdatedAt, $cursorOrderId);
|
||||
$this->processPageCandidates(
|
||||
$candidates, $integrationId, $baseUrl, (string) $apiKey, $timeout,
|
||||
$statusMap, $maxOrders, $result, $productImageCache, $shouldStop,
|
||||
$latestUpdatedAt, $latestOrderId
|
||||
);
|
||||
if ($shouldStop || count($items) < $pageLimit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->syncState->markRunSuccess($integrationId, new DateTimeImmutable('now'), $latestUpdatedAt, $latestOrderId);
|
||||
} catch (Throwable $exception) {
|
||||
$this->syncState->markRunFailed($integrationId, new DateTimeImmutable('now'), $exception->getMessage());
|
||||
$result['failed'] = (int) $result['failed'] + 1;
|
||||
$errors = is_array($result['errors']) ? $result['errors'] : [];
|
||||
if (count($errors) < 20) {
|
||||
$errors[] = ['integration_id' => $integrationId, 'error' => $exception->getMessage()];
|
||||
}
|
||||
$result['errors'] = $errors;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function fetchOrdersPage(string $baseUrl, string $apiKey, int $timeout, int $page, int $pageLimit, ?string $startDate): array
|
||||
{
|
||||
$orders = $this->apiClient->fetchOrders($baseUrl, $apiKey, $timeout, $page, $pageLimit, $startDate);
|
||||
if (($orders['ok'] ?? false) !== true) {
|
||||
throw new \RuntimeException((string) ($orders['message'] ?? 'Blad pobierania listy zamowien.'));
|
||||
}
|
||||
|
||||
return is_array($orders['items'] ?? null) ? $orders['items'] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $candidates
|
||||
* @param array<string, string> $statusMap
|
||||
* @param array<string, mixed> $result
|
||||
* @param array<int, string> $productImageCache
|
||||
*/
|
||||
private function processPageCandidates(
|
||||
array $candidates,
|
||||
int $integrationId,
|
||||
string $baseUrl,
|
||||
string $apiKey,
|
||||
int $timeout,
|
||||
array $statusMap,
|
||||
int $maxOrders,
|
||||
array &$result,
|
||||
array &$productImageCache,
|
||||
bool &$shouldStop,
|
||||
?string &$latestUpdatedAt,
|
||||
?string &$latestOrderId
|
||||
): void {
|
||||
foreach ($candidates as $candidate) {
|
||||
if ((int) $result['processed'] >= $maxOrders) {
|
||||
$shouldStop = true;
|
||||
break;
|
||||
}
|
||||
|
||||
$sourceOrderId = (string) ($candidate['source_order_id'] ?? '');
|
||||
$sourceUpdatedAt = (string) ($candidate['source_updated_at'] ?? '');
|
||||
$rawOrder = is_array($candidate['payload'] ?? null) ? $candidate['payload'] : [];
|
||||
|
||||
$details = $this->apiClient->fetchOrderById($baseUrl, $apiKey, $timeout, $sourceOrderId);
|
||||
if (($details['ok'] ?? false) === true && is_array($details['order'] ?? null)) {
|
||||
$detailsOrder = (array) $details['order'];
|
||||
foreach (['products', 'summary', 'paid', 'transport_cost', 'transport', 'transport_description',
|
||||
'client_name', 'client_surname', 'client_email', 'client_phone', 'client_city',
|
||||
'client_street', 'client_postal_code'] as $protectedKey) {
|
||||
if (array_key_exists($protectedKey, $rawOrder)) {
|
||||
unset($detailsOrder[$protectedKey]);
|
||||
}
|
||||
}
|
||||
$rawOrder = array_replace($rawOrder, $detailsOrder);
|
||||
}
|
||||
|
||||
$this->importOneOrder(
|
||||
$integrationId, $sourceOrderId, $sourceUpdatedAt, $rawOrder,
|
||||
$baseUrl, $apiKey, $timeout, $statusMap, $result, $productImageCache
|
||||
);
|
||||
|
||||
if ($latestUpdatedAt === null || $sourceUpdatedAt > $latestUpdatedAt) {
|
||||
$latestUpdatedAt = $sourceUpdatedAt;
|
||||
$latestOrderId = $sourceOrderId;
|
||||
} elseif ($latestUpdatedAt === $sourceUpdatedAt && ($latestOrderId === null || strcmp($sourceOrderId, $latestOrderId) > 0)) {
|
||||
$latestOrderId = $sourceOrderId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $rawOrder
|
||||
* @param array<string, string> $statusMap
|
||||
* @param array<string, mixed> $result
|
||||
* @param array<int, string> $productImageCache
|
||||
*/
|
||||
private function importOneOrder(
|
||||
int $integrationId,
|
||||
string $sourceOrderId,
|
||||
string $sourceUpdatedAt,
|
||||
array $rawOrder,
|
||||
string $baseUrl,
|
||||
string $apiKey,
|
||||
int $timeout,
|
||||
array $statusMap,
|
||||
array &$result,
|
||||
array &$productImageCache
|
||||
): void {
|
||||
try {
|
||||
$productImages = $this->resolveProductImagesForOrder(
|
||||
$baseUrl, $apiKey, $timeout, $rawOrder, $productImageCache
|
||||
);
|
||||
$aggregate = $this->mapOrderAggregate(
|
||||
$integrationId, $rawOrder, $statusMap, $sourceOrderId, $sourceUpdatedAt, $productImages
|
||||
);
|
||||
$save = $this->orderImportRepository->upsertOrderAggregate(
|
||||
$aggregate['order'],
|
||||
$aggregate['addresses'],
|
||||
$aggregate['items'],
|
||||
$aggregate['payments'],
|
||||
$aggregate['shipments'],
|
||||
$aggregate['notes'],
|
||||
$aggregate['status_history']
|
||||
);
|
||||
$result['processed'] = (int) $result['processed'] + 1;
|
||||
if (!empty($save['created'])) {
|
||||
$result['imported_created'] = (int) $result['imported_created'] + 1;
|
||||
} else {
|
||||
$result['imported_updated'] = (int) $result['imported_updated'] + 1;
|
||||
}
|
||||
$this->orders->recordActivity(
|
||||
(int) ($save['order_id'] ?? 0),
|
||||
'import',
|
||||
'Import zamowienia z shopPRO',
|
||||
['integration_id' => $integrationId, 'source_order_id' => $sourceOrderId],
|
||||
'import',
|
||||
'shopPRO'
|
||||
);
|
||||
} catch (Throwable $exception) {
|
||||
$result['failed'] = (int) $result['failed'] + 1;
|
||||
$errors = is_array($result['errors']) ? $result['errors'] : [];
|
||||
if (count($errors) < 20) {
|
||||
$errors[] = [
|
||||
'integration_id' => $integrationId,
|
||||
'source_order_id' => $sourceOrderId,
|
||||
'error' => $exception->getMessage(),
|
||||
];
|
||||
}
|
||||
$result['errors'] = $errors;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $rawIds
|
||||
* @return array<int, true>
|
||||
@@ -486,6 +520,38 @@ final class ShopproOrdersSyncService
|
||||
{
|
||||
$result = [];
|
||||
|
||||
$customerData = $this->buildCustomerAddress($payload);
|
||||
$result[] = $customerData['address'];
|
||||
|
||||
$invoiceAddress = $this->buildInvoiceAddress(
|
||||
$payload,
|
||||
$customerData['name'],
|
||||
$customerData['email'],
|
||||
$customerData['phone']
|
||||
);
|
||||
if ($invoiceAddress !== null) {
|
||||
$result[] = $invoiceAddress;
|
||||
}
|
||||
|
||||
$deliveryAddress = $this->buildDeliveryAddress(
|
||||
$payload,
|
||||
$customerData['name'],
|
||||
$customerData['email'],
|
||||
$customerData['phone']
|
||||
);
|
||||
if ($deliveryAddress !== null) {
|
||||
$result[] = $deliveryAddress;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $payload
|
||||
* @return array{address:array<string,mixed>,name:?string,email:?string,phone:?string}
|
||||
*/
|
||||
private function buildCustomerAddress(array $payload): array
|
||||
{
|
||||
$customerFirstName = StringHelper::nullableString((string) $this->readPath($payload, [
|
||||
'buyer.first_name', 'buyer.firstname', 'customer.first_name', 'customer.firstname',
|
||||
'client.first_name', 'client.firstname', 'billing_address.first_name', 'billing_address.firstname',
|
||||
@@ -499,10 +565,7 @@ final class ShopproOrdersSyncService
|
||||
$customerName = StringHelper::nullableString((string) $this->readPath($payload, [
|
||||
'buyer_name', 'buyer.name', 'customer.name', 'client.name', 'billing_address.name',
|
||||
'receiver.name', 'client', 'customer_full_name', 'client_full_name',
|
||||
]));
|
||||
if ($customerName === null) {
|
||||
$customerName = $this->composeName($customerFirstName, $customerLastName, 'Klient');
|
||||
}
|
||||
])) ?? $this->composeName($customerFirstName, $customerLastName, 'Klient');
|
||||
|
||||
$customerEmail = StringHelper::nullableString((string) $this->readPath($payload, [
|
||||
'buyer_email', 'buyer.email', 'customer.email', 'client.email', 'billing_address.email',
|
||||
@@ -514,7 +577,7 @@ final class ShopproOrdersSyncService
|
||||
'phone_number', 'client_phone_number',
|
||||
]));
|
||||
|
||||
$result[] = [
|
||||
$address = [
|
||||
'address_type' => 'customer',
|
||||
'name' => $customerName ?? 'Klient',
|
||||
'phone' => $customerPhone,
|
||||
@@ -550,11 +613,15 @@ final class ShopproOrdersSyncService
|
||||
],
|
||||
];
|
||||
|
||||
$invoiceAddress = $this->buildInvoiceAddress($payload, $customerName, $customerEmail, $customerPhone);
|
||||
if ($invoiceAddress !== null) {
|
||||
$result[] = $invoiceAddress;
|
||||
}
|
||||
return ['address' => $address, 'name' => $customerName, 'email' => $customerEmail, 'phone' => $customerPhone];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $payload
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
private function buildDeliveryAddress(array $payload, ?string $customerName, ?string $customerEmail, ?string $customerPhone): ?array
|
||||
{
|
||||
$deliveryFirstName = StringHelper::nullableString((string) $this->readPath($payload, [
|
||||
'delivery.address.first_name', 'delivery.address.firstname', 'shipping.address.first_name', 'shipping.address.firstname',
|
||||
'delivery_address.first_name', 'delivery_address.firstname', 'shipping_address.first_name', 'shipping_address.firstname',
|
||||
@@ -568,14 +635,11 @@ final class ShopproOrdersSyncService
|
||||
$deliveryName = StringHelper::nullableString((string) $this->readPath($payload, [
|
||||
'delivery.address.name', 'shipping.address.name', 'delivery_address.name', 'shipping_address.name',
|
||||
'receiver.name', 'delivery_name', 'shipping_name',
|
||||
]));
|
||||
if ($deliveryName === null) {
|
||||
$deliveryName = $this->composeName($deliveryFirstName, $deliveryLastName, null);
|
||||
}
|
||||
])) ?? $this->composeName($deliveryFirstName, $deliveryLastName, null);
|
||||
|
||||
$pickupData = $this->parsePickupPoint((string) $this->readPath($payload, ['inpost_paczkomat', 'orlen_point', 'pickup_point']));
|
||||
$deliveryAddress = [
|
||||
'name' => $deliveryName,
|
||||
$fields = [
|
||||
'name' => $deliveryName ?? StringHelper::nullableString($this->buildDeliveryMethodLabel($payload)),
|
||||
'phone' => StringHelper::nullableString((string) $this->readPath($payload, [
|
||||
'delivery.address.phone', 'shipping.address.phone', 'delivery_address.phone', 'shipping_address.phone',
|
||||
'receiver.phone', 'delivery_phone', 'shipping_phone',
|
||||
@@ -620,29 +684,24 @@ final class ShopproOrdersSyncService
|
||||
],
|
||||
];
|
||||
|
||||
if (($deliveryAddress['name'] ?? null) === null) {
|
||||
$deliveryAddress['name'] = StringHelper::nullableString($this->buildDeliveryMethodLabel($payload));
|
||||
if (!$this->hasAddressData($fields)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$hasDeliveryData = $this->hasAddressData($deliveryAddress);
|
||||
if ($hasDeliveryData) {
|
||||
$result[] = [
|
||||
'address_type' => 'delivery',
|
||||
'name' => $deliveryAddress['name'] ?? $customerName ?? 'Dostawa',
|
||||
'phone' => $deliveryAddress['phone'] ?? null,
|
||||
'email' => $deliveryAddress['email'] ?? $customerEmail,
|
||||
'street_name' => $deliveryAddress['street_name'] ?? null,
|
||||
'street_number' => $deliveryAddress['street_number'] ?? null,
|
||||
'city' => $deliveryAddress['city'] ?? null,
|
||||
'zip_code' => $deliveryAddress['zip_code'] ?? null,
|
||||
'country' => $deliveryAddress['country'] ?? null,
|
||||
'parcel_external_id' => $deliveryAddress['parcel_external_id'] ?? null,
|
||||
'parcel_name' => $deliveryAddress['parcel_name'] ?? null,
|
||||
'payload_json' => is_array($deliveryAddress['payload_json'] ?? null) ? $deliveryAddress['payload_json'] : null,
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
return [
|
||||
'address_type' => 'delivery',
|
||||
'name' => $fields['name'] ?? $customerName ?? 'Dostawa',
|
||||
'phone' => $fields['phone'] ?? null,
|
||||
'email' => $fields['email'] ?? $customerEmail,
|
||||
'street_name' => $fields['street_name'] ?? null,
|
||||
'street_number' => $fields['street_number'] ?? null,
|
||||
'city' => $fields['city'] ?? null,
|
||||
'zip_code' => $fields['zip_code'] ?? null,
|
||||
'country' => $fields['country'] ?? null,
|
||||
'parcel_external_id' => $fields['parcel_external_id'] ?? null,
|
||||
'parcel_name' => $fields['parcel_name'] ?? null,
|
||||
'payload_json' => is_array($fields['payload_json'] ?? null) ? $fields['payload_json'] : null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user