update
This commit is contained in:
@@ -28,6 +28,33 @@ final class StringHelper
|
||||
}
|
||||
}
|
||||
|
||||
private const COD_PAYMENT_TYPES = [
|
||||
'CASH_ON_DELIVERY',
|
||||
'COD',
|
||||
'POBRANIE',
|
||||
'ZA POBRANIEM',
|
||||
];
|
||||
|
||||
private const COD_PAYMENT_KEYWORDS = [
|
||||
'PRZY ODBIORZE',
|
||||
'POBRANIEM',
|
||||
'POBRANIE',
|
||||
];
|
||||
|
||||
public static function isCodPayment(string $value): bool
|
||||
{
|
||||
$normalized = strtoupper(trim($value));
|
||||
if (in_array($normalized, self::COD_PAYMENT_TYPES, true)) {
|
||||
return true;
|
||||
}
|
||||
foreach (self::COD_PAYMENT_KEYWORDS as $keyword) {
|
||||
if (str_contains($normalized, $keyword)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function normalizeColorHex(string $value): string
|
||||
{
|
||||
$trimmed = trim($value);
|
||||
|
||||
@@ -38,6 +38,7 @@ use App\Modules\Settings\ShopproApiClient;
|
||||
use App\Modules\Settings\ShopproIntegrationsRepository;
|
||||
use App\Modules\Settings\ShopproOrderMapper;
|
||||
use App\Modules\Settings\ShopproOrdersSyncService;
|
||||
use App\Modules\Settings\ShopproPullStatusMappingRepository;
|
||||
use App\Modules\Settings\ShopproOrderSyncStateRepository;
|
||||
use App\Modules\Settings\ShopproPaymentStatusSyncService;
|
||||
use App\Modules\Settings\ShopproProductImageResolver;
|
||||
@@ -90,6 +91,7 @@ final class CronHandlerFactory
|
||||
$shopproApiClient = new ShopproApiClient();
|
||||
$shopproSyncStateRepo = new ShopproOrderSyncStateRepository($this->db);
|
||||
$shopproStatusMappingRepo = new ShopproStatusMappingRepository($this->db);
|
||||
$shopproPullStatusMappingRepo = new ShopproPullStatusMappingRepository($this->db);
|
||||
$shopproSyncService = new ShopproOrdersSyncService(
|
||||
$shopproIntegrationsRepo,
|
||||
$shopproSyncStateRepo,
|
||||
@@ -98,7 +100,8 @@ final class CronHandlerFactory
|
||||
$shopproStatusMappingRepo,
|
||||
$ordersRepository,
|
||||
new ShopproOrderMapper(),
|
||||
new ShopproProductImageResolver($shopproApiClient)
|
||||
new ShopproProductImageResolver($shopproApiClient),
|
||||
$shopproPullStatusMappingRepo
|
||||
);
|
||||
$shopproStatusSyncService = new ShopproStatusSyncService(
|
||||
$shopproIntegrationsRepo,
|
||||
|
||||
@@ -38,6 +38,17 @@ final class OrderImportRepository
|
||||
$sourceOrderId = trim((string) ($orderData['source_order_id'] ?? ''));
|
||||
$existingOrderId = $this->findOrderIdBySource($source, $sourceOrderId);
|
||||
$created = $existingOrderId === null;
|
||||
$paymentTransition = false;
|
||||
|
||||
if (!$created) {
|
||||
$currentStatus = $this->getCurrentStatus($existingOrderId);
|
||||
$newPaymentStatus = (int) ($orderData['payment_status'] ?? 0);
|
||||
$paymentTransition = $currentStatus === 'nieoplacone' && $newPaymentStatus === 2;
|
||||
if (!$paymentTransition) {
|
||||
$orderData['external_status_id'] = $currentStatus;
|
||||
}
|
||||
}
|
||||
|
||||
$orderId = $created
|
||||
? $this->insertOrder($orderData)
|
||||
: $this->updateOrder($existingOrderId, $orderData);
|
||||
@@ -50,6 +61,8 @@ final class OrderImportRepository
|
||||
$this->replacePayments($orderId, $payments);
|
||||
$this->replaceShipments($orderId, $shipments);
|
||||
$this->replaceStatusHistory($orderId, $statusHistory);
|
||||
} elseif ($paymentTransition) {
|
||||
$this->replacePayments($orderId, $payments);
|
||||
}
|
||||
|
||||
$this->pdo->commit();
|
||||
@@ -63,6 +76,7 @@ final class OrderImportRepository
|
||||
return [
|
||||
'order_id' => $orderId,
|
||||
'created' => $created,
|
||||
'payment_transition' => $paymentTransition,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -87,6 +101,17 @@ final class OrderImportRepository
|
||||
return $id > 0 ? $id : null;
|
||||
}
|
||||
|
||||
private function getCurrentStatus(int $orderId): string
|
||||
{
|
||||
$statement = $this->pdo->prepare(
|
||||
'SELECT external_status_id FROM orders WHERE id = :id LIMIT 1'
|
||||
);
|
||||
$statement->execute(['id' => $orderId]);
|
||||
$value = $statement->fetchColumn();
|
||||
|
||||
return strtolower(trim((string) ($value ?: '')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $orderData
|
||||
*/
|
||||
|
||||
@@ -340,7 +340,7 @@ final class OrdersController
|
||||
$totalWithTax = $row['total_with_tax'] !== null ? number_format((float) $row['total_with_tax'], 2, '.', ' ') : '-';
|
||||
$totalPaid = $row['total_paid'] !== null ? number_format((float) $row['total_paid'], 2, '.', ' ') : '-';
|
||||
$paymentType = strtoupper(trim((string) ($row['external_payment_type_id'] ?? '')));
|
||||
$isCod = $paymentType === 'CASH_ON_DELIVERY';
|
||||
$isCod = StringHelper::isCodPayment($paymentType);
|
||||
$paymentStatus = isset($row['payment_status']) ? (int) $row['payment_status'] : null;
|
||||
$isUnpaid = !$isCod && $paymentStatus === 0;
|
||||
$itemsCount = max(0, (int) ($row['items_count'] ?? 0));
|
||||
@@ -661,7 +661,7 @@ final class OrdersController
|
||||
$html .= '<div class="orders-product">'
|
||||
. $thumb
|
||||
. '<div class="orders-product__txt">'
|
||||
. '<div class="orders-product__name">' . htmlspecialchars($name !== '' ? $name : '-', ENT_QUOTES, 'UTF-8') . '</div>'
|
||||
. '<div class="orders-product__name"' . ($name !== '' ? ' title="' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '"' : '') . '>' . htmlspecialchars($name !== '' ? $name : '-', ENT_QUOTES, 'UTF-8') . '</div>'
|
||||
. '<div class="orders-product__qty">' . htmlspecialchars($qty, ENT_QUOTES, 'UTF-8') . ' szt.</div>'
|
||||
. '</div>'
|
||||
. '</div>';
|
||||
@@ -914,4 +914,17 @@ final class OrdersController
|
||||
}
|
||||
}
|
||||
|
||||
public function quickSearch(Request $request): Response
|
||||
{
|
||||
$query = trim((string) $request->input('q', ''));
|
||||
if ($query === '' || mb_strlen($query) < 2) {
|
||||
return Response::json(['results' => []]);
|
||||
}
|
||||
|
||||
$limit = min((int) $request->input('limit', 10), 20);
|
||||
$results = $this->orders->quickSearch($query, $limit);
|
||||
|
||||
return Response::json(['results' => $results]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -987,4 +987,60 @@ final class OrdersRepository
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array{id:int, order_number:string, buyer_name:string, buyer_email:string, buyer_phone:string}>
|
||||
*/
|
||||
public function quickSearch(string $query, int $limit = 10): array
|
||||
{
|
||||
$query = trim($query);
|
||||
if ($query === '' || mb_strlen($query) < 2) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$limit = max(1, min($limit, 20));
|
||||
$searchVal = '%' . $query . '%';
|
||||
|
||||
$sql = 'SELECT o.id, o.source_order_id, o.external_order_id, '
|
||||
. 'a.name AS buyer_name, a.email AS buyer_email, a.phone AS buyer_phone '
|
||||
. 'FROM orders o '
|
||||
. 'LEFT JOIN order_addresses a ON a.order_id = o.id AND a.address_type = "customer" '
|
||||
. 'WHERE (o.source_order_id LIKE :s1 OR o.external_order_id LIKE :s2 '
|
||||
. 'OR a.name LIKE :s3 OR a.email LIKE :s4 OR a.phone LIKE :s5 '
|
||||
. 'OR EXISTS (SELECT 1 FROM order_items oi WHERE oi.order_id = o.id AND oi.original_name LIKE :s6)) '
|
||||
. 'ORDER BY o.ordered_at DESC LIMIT :lim';
|
||||
|
||||
try {
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->bindValue(':s1', $searchVal);
|
||||
$stmt->bindValue(':s2', $searchVal);
|
||||
$stmt->bindValue(':s3', $searchVal);
|
||||
$stmt->bindValue(':s4', $searchVal);
|
||||
$stmt->bindValue(':s5', $searchVal);
|
||||
$stmt->bindValue(':s6', $searchVal);
|
||||
$stmt->bindValue(':lim', $limit, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$rows = $stmt->fetchAll();
|
||||
if (!is_array($rows)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return array_map(static function (array $row): array {
|
||||
$orderNumber = ((string) ($row['source_order_id'] ?? '')) !== ''
|
||||
? (string) $row['source_order_id']
|
||||
: (string) ($row['external_order_id'] ?? '');
|
||||
|
||||
return [
|
||||
'id' => (int) ($row['id'] ?? 0),
|
||||
'order_number' => $orderNumber,
|
||||
'buyer_name' => (string) ($row['buyer_name'] ?? ''),
|
||||
'buyer_email' => (string) ($row['buyer_email'] ?? ''),
|
||||
'buyer_phone' => (string) ($row['buyer_phone'] ?? ''),
|
||||
];
|
||||
}, $rows);
|
||||
} catch (Throwable) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ final class ShopproIntegrationsController
|
||||
private readonly AuthService $auth,
|
||||
private readonly ShopproIntegrationsRepository $repository,
|
||||
private readonly ShopproStatusMappingRepository $statusMappings,
|
||||
private readonly ShopproPullStatusMappingRepository $pullStatusMappings,
|
||||
private readonly OrderStatusRepository $orderStatuses,
|
||||
private readonly CronRepository $cronRepository,
|
||||
private readonly CarrierDeliveryMethodMappingRepository $deliveryMappings,
|
||||
@@ -71,6 +72,9 @@ final class ShopproIntegrationsController
|
||||
$mappingIndex = $integrationId > 0
|
||||
? $this->buildMappingIndex($integrationId)
|
||||
: [];
|
||||
$pullMappingIndex = $integrationId > 0
|
||||
? $this->buildPullMappingIndex($integrationId)
|
||||
: [];
|
||||
$shopproStatuses = $integrationId > 0
|
||||
? $this->buildExternalStatusOptions($integrationId, $discoveredStatuses)
|
||||
: [];
|
||||
@@ -98,6 +102,7 @@ final class ShopproIntegrationsController
|
||||
'statusSyncIntervalMinutes' => $this->currentStatusSyncIntervalMinutes(),
|
||||
'paymentSyncIntervalMinutes' => $this->currentPaymentSyncIntervalMinutes(),
|
||||
'mappingIndex' => $mappingIndex,
|
||||
'pullMappingIndex' => $pullMappingIndex,
|
||||
'orderproStatuses' => $this->orderStatuses->listStatuses(),
|
||||
'shopproStatuses' => $shopproStatuses,
|
||||
'deliveryMappings' => $deliveryMappings,
|
||||
@@ -273,6 +278,60 @@ final class ShopproIntegrationsController
|
||||
return Response::redirect($redirectTo);
|
||||
}
|
||||
|
||||
public function savePullStatusMappings(Request $request): Response
|
||||
{
|
||||
$integrationId = max(0, (int) $request->input('integration_id', 0));
|
||||
$redirectTo = $this->buildRedirectUrl($integrationId, 'statuses');
|
||||
|
||||
$accessError = $this->validateCsrfAndIntegrationAccess((string) $request->input('_token', ''), $integrationId, 'statuses');
|
||||
if ($accessError !== null) {
|
||||
return $accessError;
|
||||
}
|
||||
|
||||
$shopCodes = $request->input('shoppro_status_code', []);
|
||||
$shopNames = $request->input('shoppro_status_name', []);
|
||||
$orderCodes = $request->input('orderpro_status_code', []);
|
||||
if (!is_array($shopCodes) || !is_array($shopNames) || !is_array($orderCodes)) {
|
||||
Flash::set('settings_error', $this->translator->get('settings.order_statuses.pull.save_failed'));
|
||||
return Response::redirect($redirectTo);
|
||||
}
|
||||
|
||||
$allowedOrderpro = $this->resolveAllowedOrderproStatusCodes();
|
||||
$rowsCount = min(count($shopCodes), count($shopNames), count($orderCodes));
|
||||
$mappings = [];
|
||||
for ($index = 0; $index < $rowsCount; $index++) {
|
||||
$shopCode = trim((string) ($shopCodes[$index] ?? ''));
|
||||
$shopName = trim((string) ($shopNames[$index] ?? ''));
|
||||
$orderCode = strtolower(trim((string) ($orderCodes[$index] ?? '')));
|
||||
|
||||
if ($shopCode === '' || $orderCode === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($allowedOrderpro[$orderCode])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$mappings[] = [
|
||||
'shoppro_status_code' => $shopCode,
|
||||
'shoppro_status_name' => $shopName,
|
||||
'orderpro_status_code' => $orderCode,
|
||||
];
|
||||
}
|
||||
|
||||
try {
|
||||
$this->pullStatusMappings->replaceForIntegration($integrationId, $mappings);
|
||||
Flash::set('settings_success', $this->translator->get('settings.order_statuses.pull.saved'));
|
||||
} catch (Throwable $exception) {
|
||||
Flash::set(
|
||||
'settings_error',
|
||||
$this->translator->get('settings.order_statuses.pull.save_failed') . ' ' . $exception->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
return Response::redirect($redirectTo);
|
||||
}
|
||||
|
||||
public function syncStatuses(Request $request): Response
|
||||
{
|
||||
$integrationId = max(0, (int) $request->input('integration_id', 0));
|
||||
@@ -517,6 +576,28 @@ final class ShopproIntegrationsController
|
||||
return $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array{orderpro_status_code:string}>
|
||||
*/
|
||||
private function buildPullMappingIndex(int $integrationId): array
|
||||
{
|
||||
$rows = $this->pullStatusMappings->listByIntegration($integrationId);
|
||||
$index = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$shopproCode = trim((string) ($row['shoppro_status_code'] ?? ''));
|
||||
if ($shopproCode === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$index[$shopproCode] = [
|
||||
'orderpro_status_code' => strtolower(trim((string) ($row['orderpro_status_code'] ?? ''))),
|
||||
];
|
||||
}
|
||||
|
||||
return $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array{code:string,name:string}> $discoveredStatuses
|
||||
* @return array<int, array{code:string,name:string}>
|
||||
|
||||
@@ -136,7 +136,7 @@ final class ShopproOrderMapper
|
||||
'external_platform_id' => IntegrationSources::SHOPPRO,
|
||||
'external_platform_account_id' => null,
|
||||
'external_status_id' => $effectiveStatus,
|
||||
'external_payment_type_id' => StringHelper::nullableString((string) $this->readPath($payload, ['payment_method', 'payment.method', 'payments.method'])),
|
||||
'external_payment_type_id' => $this->normalizeCodPaymentType((string) $this->readPath($payload, ['payment_method', 'payment.method', 'payments.method'])),
|
||||
'payment_status' => $this->mapPaymentStatus($payload, $isPaid),
|
||||
'external_carrier_id' => StringHelper::nullableString($deliveryLabel),
|
||||
'external_carrier_account_id' => StringHelper::nullableString((string) $this->readPath($payload, [
|
||||
@@ -603,6 +603,16 @@ final class ShopproOrderMapper
|
||||
}
|
||||
}
|
||||
|
||||
$message = $this->readPath($row, ['message']);
|
||||
if ($message !== null && $message !== '' && $message !== false) {
|
||||
$text = str_replace(['<br>', '<br/>', '<br />'], "\n", (string) $message);
|
||||
$text = html_entity_decode(strip_tags($text), ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
$text = trim($text);
|
||||
if ($text !== '') {
|
||||
$parts[] = 'Wiadomość: ' . $text;
|
||||
}
|
||||
}
|
||||
|
||||
return $parts !== [] ? implode("\n", $parts) : null;
|
||||
}
|
||||
|
||||
@@ -659,7 +669,7 @@ final class ShopproOrderMapper
|
||||
*/
|
||||
private function mapNotes(array $payload): array
|
||||
{
|
||||
$comment = StringHelper::nullableString((string) $this->readPath($payload, ['notes', 'comment', 'customer_comment']));
|
||||
$comment = StringHelper::nullableString((string) $this->readPath($payload, ['notes', 'comment', 'customer_comment', 'message']));
|
||||
if ($comment === null) {
|
||||
return [];
|
||||
}
|
||||
@@ -827,6 +837,15 @@ final class ShopproOrderMapper
|
||||
return null;
|
||||
}
|
||||
|
||||
private function normalizeCodPaymentType(string $raw): ?string
|
||||
{
|
||||
$value = StringHelper::nullableString($raw);
|
||||
if ($value === null) {
|
||||
return null;
|
||||
}
|
||||
return StringHelper::isCodPayment($value) ? 'CASH_ON_DELIVERY' : $value;
|
||||
}
|
||||
|
||||
private function readSinglePath(mixed $payload, string $path): mixed
|
||||
{
|
||||
if ($path === '') {
|
||||
|
||||
@@ -19,7 +19,8 @@ final class ShopproOrdersSyncService
|
||||
private readonly ShopproStatusMappingRepository $statusMappings,
|
||||
private readonly OrdersRepository $orders,
|
||||
private readonly ShopproOrderMapper $mapper,
|
||||
private readonly ShopproProductImageResolver $imageResolver
|
||||
private readonly ShopproProductImageResolver $imageResolver,
|
||||
private readonly ?ShopproPullStatusMappingRepository $pullStatusMappings = null
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -237,15 +238,21 @@ final class ShopproOrdersSyncService
|
||||
$result['imported_updated'] = (int) $result['imported_updated'] + 1;
|
||||
}
|
||||
$wasCreated = !empty($save['created']);
|
||||
$wasPaymentTransition = !empty($save['payment_transition']);
|
||||
$savedOrderId = (int) ($save['order_id'] ?? 0);
|
||||
$summary = $wasCreated
|
||||
? 'Import zamowienia z shopPRO'
|
||||
: 'Zaktualizowano zamowienie z shopPRO (re-import)';
|
||||
if ($wasPaymentTransition) {
|
||||
$summary = 'Platnosc potwierdzona z shopPRO — zmiana statusu na w realizacji';
|
||||
} elseif ($wasCreated) {
|
||||
$summary = 'Import zamowienia z shopPRO';
|
||||
} else {
|
||||
$summary = 'Zaktualizowano zamowienie z shopPRO (re-import)';
|
||||
}
|
||||
$details = [
|
||||
'integration_id' => $integrationId,
|
||||
'source_order_id' => $sourceOrderId,
|
||||
'source_updated_at' => $sourceUpdatedAt,
|
||||
'created' => $wasCreated,
|
||||
'payment_transition' => $wasPaymentTransition,
|
||||
'trigger' => 'orders_sync',
|
||||
'trigger_label' => 'Synchronizacja zamowien',
|
||||
];
|
||||
@@ -297,9 +304,40 @@ final class ShopproOrdersSyncService
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string> shoppro_status_code => orderpro_status_code (reverse of DB direction)
|
||||
* @return array<string, string> shoppro_status_code => orderpro_status_code
|
||||
*/
|
||||
private function buildStatusMap(int $integrationId): array
|
||||
{
|
||||
if ($this->pullStatusMappings !== null) {
|
||||
return $this->buildStatusMapFromPullTable($integrationId);
|
||||
}
|
||||
|
||||
return $this->buildStatusMapFromPushTable($integrationId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function buildStatusMapFromPullTable(int $integrationId): array
|
||||
{
|
||||
$rows = $this->pullStatusMappings->listByIntegration($integrationId);
|
||||
$map = [];
|
||||
foreach ($rows as $row) {
|
||||
$shopCode = strtolower(trim((string) ($row['shoppro_status_code'] ?? '')));
|
||||
$orderCode = strtolower(trim((string) ($row['orderpro_status_code'] ?? '')));
|
||||
if ($shopCode === '' || $orderCode === '') {
|
||||
continue;
|
||||
}
|
||||
$map[$shopCode] = $orderCode;
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function buildStatusMapFromPushTable(int $integrationId): array
|
||||
{
|
||||
$rows = $this->statusMappings->listByIntegration($integrationId);
|
||||
$map = [];
|
||||
|
||||
99
src/Modules/Settings/ShopproPullStatusMappingRepository.php
Normal file
99
src/Modules/Settings/ShopproPullStatusMappingRepository.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Settings;
|
||||
|
||||
use PDO;
|
||||
|
||||
final class ShopproPullStatusMappingRepository
|
||||
{
|
||||
public function __construct(private readonly PDO $pdo)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array{shoppro_status_code:string,shoppro_status_name:string,orderpro_status_code:string}>
|
||||
*/
|
||||
public function listByIntegration(int $integrationId): array
|
||||
{
|
||||
if ($integrationId <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$statement = $this->pdo->prepare(
|
||||
'SELECT shoppro_status_code, shoppro_status_name, orderpro_status_code
|
||||
FROM order_status_pull_mappings
|
||||
WHERE integration_id = :integration_id
|
||||
ORDER BY shoppro_status_code ASC'
|
||||
);
|
||||
$statement->execute(['integration_id' => $integrationId]);
|
||||
$rows = $statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!is_array($rows)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ($rows as $row) {
|
||||
if (!is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$shopproCode = trim((string) ($row['shoppro_status_code'] ?? ''));
|
||||
if ($shopproCode === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[] = [
|
||||
'shoppro_status_code' => $shopproCode,
|
||||
'shoppro_status_name' => trim((string) ($row['shoppro_status_name'] ?? '')),
|
||||
'orderpro_status_code' => strtolower(trim((string) ($row['orderpro_status_code'] ?? ''))),
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array{shoppro_status_code:string,shoppro_status_name:string,orderpro_status_code:string}> $mappings
|
||||
*/
|
||||
public function replaceForIntegration(int $integrationId, array $mappings): void
|
||||
{
|
||||
if ($integrationId <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$deleteStatement = $this->pdo->prepare(
|
||||
'DELETE FROM order_status_pull_mappings WHERE integration_id = :integration_id'
|
||||
);
|
||||
$deleteStatement->execute(['integration_id' => $integrationId]);
|
||||
|
||||
if ($mappings === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
$insertStatement = $this->pdo->prepare(
|
||||
'INSERT INTO order_status_pull_mappings (
|
||||
integration_id, shoppro_status_code, shoppro_status_name, orderpro_status_code, created_at, updated_at
|
||||
) VALUES (
|
||||
:integration_id, :shoppro_status_code, :shoppro_status_name, :orderpro_status_code, NOW(), NOW()
|
||||
)'
|
||||
);
|
||||
|
||||
foreach ($mappings as $mapping) {
|
||||
$shopproCode = trim((string) ($mapping['shoppro_status_code'] ?? ''));
|
||||
$orderpro = strtolower(trim((string) ($mapping['orderpro_status_code'] ?? '')));
|
||||
if ($shopproCode === '' || $orderpro === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$shopproName = trim((string) ($mapping['shoppro_status_name'] ?? ''));
|
||||
$insertStatement->execute([
|
||||
'integration_id' => $integrationId,
|
||||
'shoppro_status_code' => $shopproCode,
|
||||
'shoppro_status_name' => $shopproName !== '' ? $shopproName : null,
|
||||
'orderpro_status_code' => $orderpro,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,16 +429,16 @@ final class ShipmentController
|
||||
}
|
||||
|
||||
$result = $delivery;
|
||||
$deliveryHasAddress = trim((string) ($delivery['street_name'] ?? '')) !== '';
|
||||
$deliveryName = trim((string) ($delivery['name'] ?? ''));
|
||||
$customerName = trim((string) ($customer['name'] ?? ''));
|
||||
if (($this->isPickupPointDelivery($delivery) || $deliveryName === '') && $customerName !== '') {
|
||||
if ((!$deliveryHasAddress || $this->isPickupPointDelivery($delivery) || $deliveryName === '') && $customerName !== '') {
|
||||
$result['name'] = $customerName;
|
||||
}
|
||||
if (trim((string) ($result['phone'] ?? '')) === '' && trim((string) ($customer['phone'] ?? '')) !== '') {
|
||||
$result['phone'] = $customer['phone'];
|
||||
}
|
||||
if (trim((string) ($result['email'] ?? '')) === '' && trim((string) ($customer['email'] ?? '')) !== '') {
|
||||
$result['email'] = $customer['email'];
|
||||
foreach (['phone', 'email', 'street_name', 'street_number', 'city', 'zip_code', 'country'] as $field) {
|
||||
if (trim((string) ($result[$field] ?? '')) === '' && trim((string) ($customer[$field] ?? '')) !== '') {
|
||||
$result[$field] = $customer[$field];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
Reference in New Issue
Block a user