update
This commit is contained in:
@@ -45,7 +45,7 @@ final class OrderImportRepository
|
||||
$newPaymentStatus = (int) ($orderData['payment_status'] ?? 0);
|
||||
$paymentTransition = $currentStatus === 'nieoplacone' && $newPaymentStatus === 2;
|
||||
if (!$paymentTransition) {
|
||||
$orderData['external_status_id'] = $currentStatus;
|
||||
$orderData['status_code'] = $currentStatus;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ final class OrderImportRepository
|
||||
private function getCurrentStatus(int $orderId): string
|
||||
{
|
||||
$statement = $this->pdo->prepare(
|
||||
'SELECT external_status_id FROM orders WHERE id = :id LIMIT 1'
|
||||
'SELECT status_code FROM orders WHERE id = :id LIMIT 1'
|
||||
);
|
||||
$statement->execute(['id' => $orderId]);
|
||||
$value = $statement->fetchColumn();
|
||||
@@ -120,13 +120,13 @@ final class OrderImportRepository
|
||||
$statement = $this->pdo->prepare(
|
||||
'INSERT INTO orders (
|
||||
integration_id, source, source_order_id, external_order_id, external_platform_id, external_platform_account_id,
|
||||
external_status_id, external_payment_type_id, payment_status, external_carrier_id, external_carrier_account_id,
|
||||
status_code, external_payment_type_id, payment_status, external_carrier_id, external_carrier_account_id,
|
||||
customer_login, is_invoice, is_encrypted, is_canceled_by_buyer, currency,
|
||||
total_without_tax, total_with_tax, total_paid, delivery_price, send_date_min, send_date_max, ordered_at,
|
||||
source_created_at, source_updated_at, preferences_json, payload_json, fetched_at
|
||||
) VALUES (
|
||||
:integration_id, :source, :source_order_id, :external_order_id, :external_platform_id, :external_platform_account_id,
|
||||
:external_status_id, :external_payment_type_id, :payment_status, :external_carrier_id, :external_carrier_account_id,
|
||||
:status_code, :external_payment_type_id, :payment_status, :external_carrier_id, :external_carrier_account_id,
|
||||
:customer_login, :is_invoice, :is_encrypted, :is_canceled_by_buyer, :currency,
|
||||
:total_without_tax, :total_with_tax, :total_paid, :delivery_price, :send_date_min, :send_date_max, :ordered_at,
|
||||
:source_created_at, :source_updated_at, :preferences_json, :payload_json, :fetched_at
|
||||
@@ -155,7 +155,7 @@ final class OrderImportRepository
|
||||
external_order_id = :external_order_id,
|
||||
external_platform_id = :external_platform_id,
|
||||
external_platform_account_id = :external_platform_account_id,
|
||||
external_status_id = :external_status_id,
|
||||
status_code = :status_code,
|
||||
external_payment_type_id = :external_payment_type_id,
|
||||
payment_status = :payment_status,
|
||||
external_carrier_id = :external_carrier_id,
|
||||
@@ -201,7 +201,7 @@ final class OrderImportRepository
|
||||
'external_order_id' => $orderData['external_order_id'] ?? null,
|
||||
'external_platform_id' => $orderData['external_platform_id'] ?? null,
|
||||
'external_platform_account_id' => $orderData['external_platform_account_id'] ?? null,
|
||||
'external_status_id' => $orderData['external_status_id'] ?? null,
|
||||
'status_code' => $orderData['status_code'] ?? null,
|
||||
'external_payment_type_id' => $orderData['external_payment_type_id'] ?? null,
|
||||
'payment_status' => $orderData['payment_status'] ?? null,
|
||||
'external_carrier_id' => $orderData['external_carrier_id'] ?? null,
|
||||
|
||||
@@ -71,81 +71,98 @@ final class OrdersController
|
||||
|
||||
$tableRows = array_map(fn (array $row): array => $this->toTableRow($row, $statusLabelMap, $statusColorMap), (array) ($result['items'] ?? []));
|
||||
|
||||
$tableListData = [
|
||||
'list_key' => 'orders',
|
||||
'base_path' => '/orders/list',
|
||||
'query' => $filters,
|
||||
'filters' => [
|
||||
[
|
||||
'key' => 'search',
|
||||
'label' => $this->translator->get('orders.filters.search'),
|
||||
'type' => 'text',
|
||||
'value' => $filters['search'],
|
||||
],
|
||||
[
|
||||
'key' => 'source',
|
||||
'label' => $this->translator->get('orders.filters.source'),
|
||||
'type' => 'select',
|
||||
'value' => $filters['source'],
|
||||
'options' => ['' => $this->translator->get('orders.filters.any')] + $sourceOptions,
|
||||
],
|
||||
[
|
||||
'key' => 'status',
|
||||
'label' => $this->translator->get('orders.filters.status'),
|
||||
'type' => 'select',
|
||||
'value' => $filters['status'],
|
||||
'options' => ['' => $this->translator->get('orders.filters.any')] + $statusOptions,
|
||||
],
|
||||
[
|
||||
'key' => 'payment_status',
|
||||
'label' => $this->translator->get('orders.filters.payment_status'),
|
||||
'type' => 'select',
|
||||
'value' => $filters['payment_status'],
|
||||
'options' => $this->paymentStatusFilterOptions(),
|
||||
],
|
||||
[
|
||||
'key' => 'date_from',
|
||||
'label' => $this->translator->get('orders.filters.date_from'),
|
||||
'type' => 'date',
|
||||
'value' => $filters['date_from'],
|
||||
],
|
||||
[
|
||||
'key' => 'date_to',
|
||||
'label' => $this->translator->get('orders.filters.date_to'),
|
||||
'type' => 'date',
|
||||
'value' => $filters['date_to'],
|
||||
],
|
||||
],
|
||||
'columns' => [
|
||||
['key' => 'order_ref', 'label' => $this->translator->get('orders.fields.order_ref'), 'sortable' => true, 'sort_key' => 'source_order_id', 'raw' => true],
|
||||
['key' => 'buyer', 'label' => $this->translator->get('orders.fields.buyer'), 'raw' => true],
|
||||
['key' => 'status_badges', 'label' => $this->translator->get('orders.fields.status'), 'sortable' => true, 'sort_key' => 'status_code', 'raw' => true],
|
||||
['key' => 'products', 'label' => $this->translator->get('orders.fields.products'), 'raw' => true],
|
||||
['key' => 'totals', 'label' => $this->translator->get('orders.fields.totals'), 'sortable' => true, 'sort_key' => 'total_with_tax', 'raw' => true],
|
||||
['key' => 'shipping', 'label' => $this->translator->get('orders.fields.shipping'), 'raw' => true],
|
||||
['key' => 'ordered_at', 'label' => $this->translator->get('orders.fields.ordered_at'), 'sortable' => true, 'sort_key' => 'ordered_at'],
|
||||
],
|
||||
'rows' => $tableRows,
|
||||
'pagination' => [
|
||||
'page' => (int) ($result['page'] ?? 1),
|
||||
'total_pages' => $totalPages,
|
||||
'total' => (int) ($result['total'] ?? 0),
|
||||
'per_page' => (int) ($result['per_page'] ?? 20),
|
||||
],
|
||||
'per_page_options' => [20, 50, 100],
|
||||
'selectable' => true,
|
||||
'select_name' => 'selected_ids[]',
|
||||
'select_value_key' => 'id',
|
||||
'header_actions' => [],
|
||||
'empty_message' => $this->translator->get('orders.empty'),
|
||||
'show_actions' => false,
|
||||
];
|
||||
|
||||
if ($request->header('X-Requested-With') === 'XMLHttpRequest') {
|
||||
$tableHtml = $this->template->render('components/table-list', [
|
||||
'tableList' => $tableListData,
|
||||
]);
|
||||
$panelHtml = $this->template->render('components/order-status-panel', [
|
||||
'statusPanelList' => $statusPanel,
|
||||
'statusPanelTitle' => 'Statusy',
|
||||
]);
|
||||
|
||||
return Response::json([
|
||||
'tableHtml' => $tableHtml,
|
||||
'panelHtml' => $panelHtml,
|
||||
]);
|
||||
}
|
||||
|
||||
$html = $this->template->render('orders/list', [
|
||||
'title' => $this->translator->get('orders.title'),
|
||||
'activeMenu' => 'orders',
|
||||
'activeOrders' => 'list',
|
||||
'user' => $this->auth->user(),
|
||||
'csrfToken' => Csrf::token(),
|
||||
'tableList' => [
|
||||
'list_key' => 'orders',
|
||||
'base_path' => '/orders/list',
|
||||
'query' => $filters,
|
||||
'filters' => [
|
||||
[
|
||||
'key' => 'search',
|
||||
'label' => $this->translator->get('orders.filters.search'),
|
||||
'type' => 'text',
|
||||
'value' => $filters['search'],
|
||||
],
|
||||
[
|
||||
'key' => 'source',
|
||||
'label' => $this->translator->get('orders.filters.source'),
|
||||
'type' => 'select',
|
||||
'value' => $filters['source'],
|
||||
'options' => ['' => $this->translator->get('orders.filters.any')] + $sourceOptions,
|
||||
],
|
||||
[
|
||||
'key' => 'status',
|
||||
'label' => $this->translator->get('orders.filters.status'),
|
||||
'type' => 'select',
|
||||
'value' => $filters['status'],
|
||||
'options' => ['' => $this->translator->get('orders.filters.any')] + $statusOptions,
|
||||
],
|
||||
[
|
||||
'key' => 'payment_status',
|
||||
'label' => $this->translator->get('orders.filters.payment_status'),
|
||||
'type' => 'select',
|
||||
'value' => $filters['payment_status'],
|
||||
'options' => $this->paymentStatusFilterOptions(),
|
||||
],
|
||||
[
|
||||
'key' => 'date_from',
|
||||
'label' => $this->translator->get('orders.filters.date_from'),
|
||||
'type' => 'date',
|
||||
'value' => $filters['date_from'],
|
||||
],
|
||||
[
|
||||
'key' => 'date_to',
|
||||
'label' => $this->translator->get('orders.filters.date_to'),
|
||||
'type' => 'date',
|
||||
'value' => $filters['date_to'],
|
||||
],
|
||||
],
|
||||
'columns' => [
|
||||
['key' => 'order_ref', 'label' => $this->translator->get('orders.fields.order_ref'), 'sortable' => true, 'sort_key' => 'source_order_id', 'raw' => true],
|
||||
['key' => 'buyer', 'label' => $this->translator->get('orders.fields.buyer'), 'raw' => true],
|
||||
['key' => 'status_badges', 'label' => $this->translator->get('orders.fields.status'), 'sortable' => true, 'sort_key' => 'external_status_id', 'raw' => true],
|
||||
['key' => 'products', 'label' => $this->translator->get('orders.fields.products'), 'raw' => true],
|
||||
['key' => 'totals', 'label' => $this->translator->get('orders.fields.totals'), 'sortable' => true, 'sort_key' => 'total_with_tax', 'raw' => true],
|
||||
['key' => 'shipping', 'label' => $this->translator->get('orders.fields.shipping'), 'raw' => true],
|
||||
['key' => 'ordered_at', 'label' => $this->translator->get('orders.fields.ordered_at'), 'sortable' => true, 'sort_key' => 'ordered_at'],
|
||||
],
|
||||
'rows' => $tableRows,
|
||||
'pagination' => [
|
||||
'page' => (int) ($result['page'] ?? 1),
|
||||
'total_pages' => $totalPages,
|
||||
'total' => (int) ($result['total'] ?? 0),
|
||||
'per_page' => (int) ($result['per_page'] ?? 20),
|
||||
],
|
||||
'per_page_options' => [20, 50, 100],
|
||||
'selectable' => true,
|
||||
'select_name' => 'selected_ids[]',
|
||||
'select_value_key' => 'id',
|
||||
'header_actions' => [],
|
||||
'empty_message' => $this->translator->get('orders.empty'),
|
||||
'show_actions' => false,
|
||||
],
|
||||
'tableList' => $tableListData,
|
||||
'stats' => $stats,
|
||||
'statusPanel' => $statusPanel,
|
||||
'allStatuses' => $this->buildAllStatusOptions($statusConfig),
|
||||
@@ -173,7 +190,7 @@ final class OrdersController
|
||||
$notes = is_array($details['notes'] ?? null) ? $details['notes'] : [];
|
||||
$history = is_array($details['status_history'] ?? null) ? $details['status_history'] : [];
|
||||
$activityLog = is_array($details['activity_log'] ?? null) ? $details['activity_log'] : [];
|
||||
$statusCode = (string) (($order['effective_status_id'] ?? '') !== '' ? $order['effective_status_id'] : ($order['external_status_id'] ?? ''));
|
||||
$statusCode = (string) (($order['effective_status_id'] ?? '') !== '' ? $order['effective_status_id'] : ($order['status_code'] ?? ''));
|
||||
$statusCounts = $this->orders->statusCounts();
|
||||
$statusConfig = $this->orders->statusPanelConfig();
|
||||
$statusLabelMap = $this->statusLabelMap($statusConfig);
|
||||
@@ -280,7 +297,7 @@ final class OrdersController
|
||||
|
||||
$oldDetails = $this->orders->findDetails($orderId);
|
||||
$oldOrder = is_array($oldDetails['order'] ?? null) ? $oldDetails['order'] : [];
|
||||
$oldStatus = strtolower(trim((string) ($oldOrder['external_status_id'] ?? '')));
|
||||
$oldStatus = strtolower(trim((string) ($oldOrder['status_code'] ?? '')));
|
||||
|
||||
$success = $this->orders->updateOrderStatus($orderId, $newStatus, 'user', $actorName !== '' ? $actorName : null);
|
||||
|
||||
@@ -336,7 +353,7 @@ final class OrdersController
|
||||
$buyerName = trim((string) ($row['buyer_name'] ?? ''));
|
||||
$buyerEmail = trim((string) ($row['buyer_email'] ?? ''));
|
||||
$buyerCity = trim((string) ($row['buyer_city'] ?? ''));
|
||||
$status = trim((string) (($row['effective_status_id'] ?? '') !== '' ? $row['effective_status_id'] : ($row['external_status_id'] ?? '')));
|
||||
$status = trim((string) (($row['effective_status_id'] ?? '') !== '' ? $row['effective_status_id'] : ($row['status_code'] ?? '')));
|
||||
$currency = trim((string) ($row['currency'] ?? ''));
|
||||
$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, '.', ' ') : '-';
|
||||
@@ -349,11 +366,17 @@ final class OrdersController
|
||||
$shipments = max(0, (int) ($row['shipments_count'] ?? 0));
|
||||
$documents = max(0, (int) ($row['documents_count'] ?? 0));
|
||||
$itemsPreview = is_array($row['items_preview'] ?? null) ? $row['items_preview'] : [];
|
||||
$projectsDone = max(0, (int) ($row['projects_done'] ?? 0));
|
||||
$projectsTotal = max(0, (int) ($row['projects_total'] ?? 0));
|
||||
|
||||
$previewBtn = '<button type="button" class="btn-icon js-order-preview-btn" data-order-id="' . (int) ($row['id'] ?? 0) . '" title="Podglad">'
|
||||
. '<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>'
|
||||
. '</button>';
|
||||
|
||||
return [
|
||||
'id' => (int) ($row['id'] ?? 0),
|
||||
'order_ref' => '<div class="orders-ref">'
|
||||
. '<div class="orders-ref__main"><a href="/orders/' . (int) ($row['id'] ?? 0) . '">'
|
||||
. '<div class="orders-ref__main">' . $previewBtn . '<a href="/orders/' . (int) ($row['id'] ?? 0) . '">'
|
||||
. htmlspecialchars($internalOrderNumber !== '' ? $internalOrderNumber : ('#' . (string) ($row['id'] ?? 0)), ENT_QUOTES, 'UTF-8')
|
||||
. '</a></div>'
|
||||
. '<div class="orders-ref__meta">'
|
||||
@@ -371,7 +394,7 @@ final class OrdersController
|
||||
'status_badges' => '<div class="orders-status-wrap" data-order-id="' . (int) ($row['id'] ?? 0) . '" data-current-status="' . htmlspecialchars($status, ENT_QUOTES, 'UTF-8') . '">'
|
||||
. $this->statusBadge($status, $this->statusLabel($status, $statusLabelMap), $statusColorMap[strtolower(trim($status))] ?? '')
|
||||
. '</div>',
|
||||
'products' => $this->productsHtml($itemsPreview, $itemsCount, $itemsQty),
|
||||
'products' => $this->productsHtml($itemsPreview, $itemsCount, $itemsQty, $projectsDone, $projectsTotal),
|
||||
'totals' => '<div class="orders-money">'
|
||||
. '<div class="orders-money__main">' . htmlspecialchars($totalWithTax . ' ' . $currency, ENT_QUOTES, 'UTF-8') . ($isUnpaid ? ' <span class="order-tag is-unpaid">Nieopłacone</span>' : '') . '</div>'
|
||||
. '<div class="orders-money__meta">' . ($isCod ? '<span class="order-tag is-cod">Za pobraniem</span>' : 'oplacono: ' . htmlspecialchars($totalPaid . ' ' . $currency, ENT_QUOTES, 'UTF-8')) . '</div>'
|
||||
@@ -671,7 +694,7 @@ final class OrdersController
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $itemsPreview
|
||||
*/
|
||||
private function productsHtml(array $itemsPreview, int $itemsCount, string $itemsQty): string
|
||||
private function productsHtml(array $itemsPreview, int $itemsCount, string $itemsQty, int $projectsDone = 0, int $projectsTotal = 0): string
|
||||
{
|
||||
if ($itemsPreview === []) {
|
||||
return '<div class="orders-products">'
|
||||
@@ -704,12 +727,37 @@ final class OrdersController
|
||||
if ($itemsCount > count($itemsPreview)) {
|
||||
$html .= '<div class="orders-products__more">+' . ($itemsCount - count($itemsPreview)) . ' pozycji</div>';
|
||||
}
|
||||
$html .= '<div class="orders-products__meta">' . $itemsCount . ' pozycji / ' . htmlspecialchars($itemsQty, ENT_QUOTES, 'UTF-8') . ' szt.</div>';
|
||||
$html .= '<div class="orders-products__meta">' . $itemsCount . ' pozycji / ' . htmlspecialchars($itemsQty, ENT_QUOTES, 'UTF-8') . ' szt.'
|
||||
. $this->projectBadge($projectsDone, $projectsTotal)
|
||||
. '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
private function projectBadge(int $done, int $total): string
|
||||
{
|
||||
if ($total === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($done === $total) {
|
||||
return ' <span class="project-badge project-badge--done" title="Wszystkie projekty wygenerowane (' . $done . '/' . $total . ')">'
|
||||
. '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>'
|
||||
. '</span>';
|
||||
}
|
||||
|
||||
if ($done > 0) {
|
||||
return ' <span class="project-badge project-badge--partial" title="Projekty: ' . $done . '/' . $total . '">'
|
||||
. $done . '/' . $total
|
||||
. '</span>';
|
||||
}
|
||||
|
||||
return ' <span class="project-badge project-badge--none" title="Brak wygenerowanych projektow (0/' . $total . ')">'
|
||||
. '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/></svg>'
|
||||
. '</span>';
|
||||
}
|
||||
|
||||
private function shippingHtml(string $deliveryMethod, int $shipments, int $documents): string
|
||||
{
|
||||
$deliveryMethod = trim(html_entity_decode(strip_tags($deliveryMethod), ENT_QUOTES | ENT_HTML5, 'UTF-8'));
|
||||
@@ -961,4 +1009,35 @@ final class OrdersController
|
||||
return Response::json(['results' => $results]);
|
||||
}
|
||||
|
||||
public function preview(Request $request): Response
|
||||
{
|
||||
$orderId = max(0, (int) $request->input('id', 0));
|
||||
$details = $this->orders->findDetails($orderId);
|
||||
if ($details === null) {
|
||||
return Response::html('<div class="order-preview-error">Zamowienie nie znalezione.</div>', 404);
|
||||
}
|
||||
|
||||
$order = is_array($details['order'] ?? null) ? $details['order'] : [];
|
||||
$items = is_array($details['items'] ?? null) ? $details['items'] : [];
|
||||
$addresses = is_array($details['addresses'] ?? null) ? $details['addresses'] : [];
|
||||
$notes = is_array($details['notes'] ?? null) ? $details['notes'] : [];
|
||||
|
||||
$addressByType = ['customer' => null, 'delivery' => null, 'invoice' => null];
|
||||
foreach ($addresses as $address) {
|
||||
$type = (string) ($address['address_type'] ?? '');
|
||||
if ($type !== '' && array_key_exists($type, $addressByType) && $addressByType[$type] === null) {
|
||||
$addressByType[$type] = $address;
|
||||
}
|
||||
}
|
||||
|
||||
$html = $this->template->render('orders/partials/preview-content', [
|
||||
'order' => $order,
|
||||
'items' => $items,
|
||||
'addressByType' => $addressByType,
|
||||
'notes' => $notes,
|
||||
]);
|
||||
|
||||
return Response::html($html);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ final class OrdersRepository
|
||||
$sortColumn = match ($sort) {
|
||||
'source_order_id' => 'o.source_order_id',
|
||||
'external_order_id' => 'o.external_order_id',
|
||||
'external_status_id' => 'o.external_status_id',
|
||||
'status_code' => 'o.status_code',
|
||||
'payment_status' => 'o.payment_status',
|
||||
'total_with_tax' => 'o.total_with_tax',
|
||||
'total_paid' => 'o.total_paid',
|
||||
@@ -48,7 +48,7 @@ final class OrdersRepository
|
||||
try {
|
||||
$countSql = 'SELECT COUNT(*) FROM orders o '
|
||||
. 'LEFT JOIN order_addresses a ON a.order_id = o.id AND a.address_type = "customer" '
|
||||
. 'LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.external_status_id) = asm.allegro_status_code'
|
||||
. 'LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.status_code) = asm.allegro_status_code'
|
||||
. $whereSql;
|
||||
$countStmt = $this->pdo->prepare($countSql);
|
||||
$countStmt->execute($params);
|
||||
@@ -158,7 +158,7 @@ final class OrdersRepository
|
||||
o.source,
|
||||
o.source_order_id,
|
||||
o.external_order_id,
|
||||
o.external_status_id,
|
||||
o.status_code,
|
||||
' . $effectiveStatusSql . ' AS effective_status_id,
|
||||
o.payment_status,
|
||||
o.currency,
|
||||
@@ -178,15 +178,19 @@ final class OrdersRepository
|
||||
o.external_payment_type_id,
|
||||
COALESCE(oi_agg.items_count, 0) AS items_count,
|
||||
COALESCE(oi_agg.items_qty, 0) AS items_qty,
|
||||
COALESCE(oi_agg.projects_done, 0) AS projects_done,
|
||||
COALESCE(oi_agg.projects_total, 0) AS projects_total,
|
||||
COALESCE(sh_agg.shipments_count, 0) AS shipments_count,
|
||||
COALESCE(od_agg.documents_count, 0) AS documents_count,
|
||||
ig.name AS integration_name
|
||||
FROM orders o
|
||||
LEFT JOIN order_addresses a ON a.order_id = o.id AND a.address_type = "customer"
|
||||
LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.external_status_id) = asm.allegro_status_code
|
||||
LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.status_code) = asm.allegro_status_code
|
||||
LEFT JOIN integrations ig ON ig.id = o.integration_id
|
||||
LEFT JOIN (
|
||||
SELECT order_id, COUNT(*) AS items_count, COALESCE(SUM(quantity), 0) AS items_qty
|
||||
SELECT order_id, COUNT(*) AS items_count, COALESCE(SUM(quantity), 0) AS items_qty,
|
||||
SUM(CASE WHEN project_generated = 1 THEN 1 ELSE 0 END) AS projects_done,
|
||||
COUNT(*) AS projects_total
|
||||
FROM order_items GROUP BY order_id
|
||||
) oi_agg ON oi_agg.order_id = o.id
|
||||
LEFT JOIN (
|
||||
@@ -217,7 +221,7 @@ final class OrdersRepository
|
||||
'source' => (string) ($row['source'] ?? ''),
|
||||
'source_order_id' => (string) ($row['source_order_id'] ?? ''),
|
||||
'external_order_id' => (string) ($row['external_order_id'] ?? ''),
|
||||
'external_status_id' => (string) ($row['external_status_id'] ?? ''),
|
||||
'status_code' => (string) ($row['status_code'] ?? ''),
|
||||
'effective_status_id' => (string) ($row['effective_status_id'] ?? ''),
|
||||
'payment_status' => isset($row['payment_status']) ? (int) $row['payment_status'] : null,
|
||||
'currency' => (string) ($row['currency'] ?? ''),
|
||||
@@ -240,6 +244,8 @@ final class OrdersRepository
|
||||
'documents_count' => (int) ($row['documents_count'] ?? 0),
|
||||
'integration_name' => (string) ($row['integration_name'] ?? ''),
|
||||
'items_preview' => (array) ($itemPreviewsByOrderId[$orderId] ?? []),
|
||||
'projects_done' => (int) ($row['projects_done'] ?? 0),
|
||||
'projects_total' => (int) ($row['projects_total'] ?? 0),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -253,7 +259,7 @@ final class OrdersRepository
|
||||
$rows = $this->pdo->query(
|
||||
'SELECT DISTINCT ' . $effectiveStatusSql . ' AS effective_status_id
|
||||
FROM orders o
|
||||
LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.external_status_id) = asm.allegro_status_code
|
||||
LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.status_code) = asm.allegro_status_code
|
||||
WHERE ' . $effectiveStatusSql . ' IS NOT NULL
|
||||
AND ' . $effectiveStatusSql . ' <> ""
|
||||
ORDER BY effective_status_id ASC'
|
||||
@@ -317,7 +323,7 @@ final class OrdersRepository
|
||||
SUM(CASE WHEN payment_status = 2 THEN 1 ELSE 0 END) AS paid_count,
|
||||
SUM(CASE WHEN ' . $effectiveStatusSql . ' IN ("shipped", "delivered", "returned") THEN 1 ELSE 0 END) AS shipped_count
|
||||
FROM orders o
|
||||
LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.external_status_id) = asm.allegro_status_code')->fetch(PDO::FETCH_ASSOC);
|
||||
LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.status_code) = asm.allegro_status_code')->fetch(PDO::FETCH_ASSOC);
|
||||
} catch (Throwable) {
|
||||
return [
|
||||
'all' => 0,
|
||||
@@ -351,7 +357,7 @@ final class OrdersRepository
|
||||
$rows = $this->pdo->query(
|
||||
'SELECT ' . $effectiveStatusSql . ' AS effective_status_id, COUNT(*) AS cnt
|
||||
FROM orders o
|
||||
LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.external_status_id) = asm.allegro_status_code
|
||||
LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.status_code) = asm.allegro_status_code
|
||||
GROUP BY effective_status_id'
|
||||
)->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (Throwable) {
|
||||
@@ -475,7 +481,7 @@ final class OrdersRepository
|
||||
'SELECT o.*, ' . $effectiveStatusSql . ' AS effective_status_id,
|
||||
ig.name AS integration_name
|
||||
FROM orders o
|
||||
LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.external_status_id) = asm.allegro_status_code
|
||||
LEFT JOIN allegro_order_status_mappings asm ON o.source = "allegro" AND LOWER(o.status_code) = asm.allegro_status_code
|
||||
LEFT JOIN integrations ig ON ig.id = o.integration_id
|
||||
WHERE o.id = :id
|
||||
LIMIT 1'
|
||||
@@ -670,7 +676,7 @@ final class OrdersRepository
|
||||
AND ' . $mappingAlias . '.orderpro_status_code IS NOT NULL
|
||||
AND ' . $mappingAlias . '.orderpro_status_code <> ""
|
||||
THEN ' . $mappingAlias . '.orderpro_status_code
|
||||
ELSE ' . $orderAlias . '.external_status_id
|
||||
ELSE ' . $orderAlias . '.status_code
|
||||
END';
|
||||
}
|
||||
|
||||
@@ -981,16 +987,16 @@ final class OrdersRepository
|
||||
public function updateOrderStatus(int $orderId, string $newStatusCode, string $actorType = 'user', ?string $actorName = null): bool
|
||||
{
|
||||
try {
|
||||
$stmt = $this->pdo->prepare('SELECT external_status_id FROM orders WHERE id = :id LIMIT 1');
|
||||
$stmt = $this->pdo->prepare('SELECT status_code FROM orders WHERE id = :id LIMIT 1');
|
||||
$stmt->execute(['id' => $orderId]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!is_array($row)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$oldStatus = trim((string) ($row['external_status_id'] ?? ''));
|
||||
$oldStatus = trim((string) ($row['status_code'] ?? ''));
|
||||
|
||||
$update = $this->pdo->prepare('UPDATE orders SET external_status_id = :status, updated_at = NOW() WHERE id = :id');
|
||||
$update = $this->pdo->prepare('UPDATE orders SET status_code = :status, updated_at = NOW() WHERE id = :id');
|
||||
$update->execute(['status' => $newStatusCode, 'id' => $orderId]);
|
||||
|
||||
$this->recordStatusChange(
|
||||
|
||||
Reference in New Issue
Block a user