Add Orders and Order Status repositories with pagination and management features
- Implemented OrdersRepository for handling order data with pagination, filtering, and sorting capabilities. - Added methods for retrieving order status options, quick stats, and detailed order information. - Created OrderStatusRepository for managing order status groups and statuses, including CRUD operations and sorting. - Introduced a bootstrap file for test environment setup and autoloading.
This commit is contained in:
84
resources/views/orders/list.php
Normal file
84
resources/views/orders/list.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php $statusPanelList = is_array($statusPanel ?? null) ? $statusPanel : []; ?>
|
||||
<?php $statusPanelTitle = 'Statusy'; ?>
|
||||
|
||||
<section class="order-show-layout">
|
||||
<?php require __DIR__ . '/../components/order-status-panel.php'; ?>
|
||||
|
||||
<div class="order-show-main">
|
||||
<section class="card orders-list-page">
|
||||
<div class="orders-head">
|
||||
<div>
|
||||
<h2 class="section-title"><?= $e($t('orders.title')) ?></h2>
|
||||
<p class="muted mt-12"><?= $e($t('orders.description')) ?></p>
|
||||
</div>
|
||||
<div class="orders-stats">
|
||||
<div class="orders-stat">
|
||||
<span class="orders-stat__label"><?= $e($t('orders.stats.all')) ?></span>
|
||||
<strong class="orders-stat__value"><?= $e((string) ((int) ($stats['all'] ?? 0))) ?></strong>
|
||||
</div>
|
||||
<div class="orders-stat">
|
||||
<span class="orders-stat__label"><?= $e($t('orders.stats.paid')) ?></span>
|
||||
<strong class="orders-stat__value"><?= $e((string) ((int) ($stats['paid'] ?? 0))) ?></strong>
|
||||
</div>
|
||||
<div class="orders-stat">
|
||||
<span class="orders-stat__label"><?= $e($t('orders.stats.shipped')) ?></span>
|
||||
<strong class="orders-stat__value"><?= $e((string) ((int) ($stats['shipped'] ?? 0))) ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (!empty($errorMessage)): ?>
|
||||
<div class="alert alert--warning mt-12" role="alert">
|
||||
<?= $e((string) $errorMessage) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<?php require __DIR__ . '/../components/table-list.php'; ?>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="modal-backdrop" data-orders-image-modal hidden>
|
||||
<div class="modal modal--image-preview" role="dialog" aria-modal="true" aria-label="Podglad zdjecia produktu">
|
||||
<div class="modal__header">
|
||||
<h3>Podglad zdjecia</h3>
|
||||
<button type="button" class="btn btn--secondary" data-orders-image-close>Zamknij</button>
|
||||
</div>
|
||||
<div class="modal__body">
|
||||
<img src="" alt="" class="product-image-preview__img" data-orders-image-preview>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var modal = document.querySelector('[data-orders-image-modal]');
|
||||
var preview = document.querySelector('[data-orders-image-preview]');
|
||||
if (!modal || !preview) return;
|
||||
|
||||
function closeModal() {
|
||||
modal.setAttribute('hidden', 'hidden');
|
||||
preview.setAttribute('src', '');
|
||||
}
|
||||
|
||||
document.addEventListener('click', function (event) {
|
||||
var trigger = event.target.closest('.js-order-img-open');
|
||||
if (trigger) {
|
||||
var imageUrl = trigger.getAttribute('data-image-url') || '';
|
||||
if (imageUrl === '') return;
|
||||
preview.setAttribute('src', imageUrl);
|
||||
modal.removeAttribute('hidden');
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.target.matches('[data-orders-image-close]') || event.target === modal) {
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (event) {
|
||||
if (event.key === 'Escape' && !modal.hasAttribute('hidden')) {
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
249
resources/views/orders/show.php
Normal file
249
resources/views/orders/show.php
Normal file
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
$orderRow = is_array($order ?? null) ? $order : [];
|
||||
$itemsList = is_array($items ?? null) ? $items : [];
|
||||
$addressesList = is_array($addresses ?? null) ? $addresses : [];
|
||||
$paymentsList = is_array($payments ?? null) ? $payments : [];
|
||||
$shipmentsList = is_array($shipments ?? null) ? $shipments : [];
|
||||
$documentsList = is_array($documents ?? null) ? $documents : [];
|
||||
$notesList = is_array($notes ?? null) ? $notes : [];
|
||||
$historyList = is_array($history ?? null) ? $history : [];
|
||||
$statusPanelList = is_array($statusPanel ?? null) ? $statusPanel : [];
|
||||
$statusPanelTitle = 'Statusy';
|
||||
|
||||
$addressByType = [
|
||||
'customer' => null,
|
||||
'invoice' => null,
|
||||
'delivery' => null,
|
||||
];
|
||||
foreach ($addressesList as $address) {
|
||||
$type = (string) ($address['address_type'] ?? '');
|
||||
if ($type !== '' && array_key_exists($type, $addressByType) && $addressByType[$type] === null) {
|
||||
$addressByType[$type] = $address;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<section class="order-show-layout">
|
||||
<?php require __DIR__ . '/../components/order-status-panel.php'; ?>
|
||||
|
||||
<div class="order-show-main">
|
||||
<section class="card order-details-page">
|
||||
<div class="order-details-head">
|
||||
<div>
|
||||
<a href="/orders/list" class="order-back-link">← <?= $e($t('navigation.orders_list')) ?></a>
|
||||
<h2 class="section-title mt-12"><?= $e($t('orders.details.title')) ?> #<?= $e((string) ($orderId ?? 0)) ?></h2>
|
||||
<div class="order-details-sub mt-12">
|
||||
<span><?= $e((string) ($orderRow['source_order_id'] ?? '')) ?></span>
|
||||
<span><?= $e((string) ($orderRow['external_order_id'] ?? '')) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-details-actions">
|
||||
<button type="button" class="btn btn--secondary">Strefa klienta</button>
|
||||
<button type="button" class="btn btn--secondary">Przygotuj przesylke</button>
|
||||
<button type="button" class="btn btn--secondary">Platnosc</button>
|
||||
<button type="button" class="btn btn--secondary">Drukuj</button>
|
||||
<button type="button" class="btn btn--primary">Pakuj</button>
|
||||
<button type="button" class="btn btn--secondary">Edytuj</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-details-pill mt-12"><?= $e((string) ($statusLabel ?? '-')) ?></div>
|
||||
</section>
|
||||
|
||||
<section class="card mt-16 order-details-tabs">
|
||||
<button type="button" class="order-details-tab is-active" data-order-tab-target="details"><?= $e($t('orders.details.tabs.details')) ?></button>
|
||||
<button type="button" class="order-details-tab" data-order-tab-target="history"><?= $e($t('orders.details.tabs.history')) ?> (<?= $e((string) count($historyList)) ?>)</button>
|
||||
<button type="button" class="order-details-tab" data-order-tab-target="shipments"><?= $e($t('orders.details.tabs.shipments')) ?> (<?= $e((string) count($shipmentsList)) ?>)</button>
|
||||
<button type="button" class="order-details-tab" data-order-tab-target="payments"><?= $e($t('orders.details.tabs.payments')) ?> (<?= $e((string) count($paymentsList)) ?>)</button>
|
||||
<button type="button" class="order-details-tab" data-order-tab-target="documents"><?= $e($t('orders.details.tabs.documents')) ?> (<?= $e((string) count($documentsList)) ?>)</button>
|
||||
</section>
|
||||
|
||||
<div class="order-tab-panel is-active" data-order-tab-panel="details">
|
||||
<section class="card mt-16">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.items_title')) ?> (<?= $e((string) count($itemsList)) ?>)</h3>
|
||||
<div class="table-wrap mt-12">
|
||||
<table class="table table--details">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Lp.</th>
|
||||
<th><?= $e($t('orders.details.item_name')) ?></th>
|
||||
<th>SKU/EAN</th>
|
||||
<th><?= $e($t('orders.details.item_qty')) ?></th>
|
||||
<th><?= $e($t('orders.details.item_price')) ?></th>
|
||||
<th><?= $e($t('orders.details.item_sum')) ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if ($itemsList === []): ?>
|
||||
<tr><td colspan="6" class="muted"><?= $e($t('orders.empty')) ?></td></tr>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($itemsList as $idx => $item): ?>
|
||||
<?php
|
||||
$qty = (float) ($item['quantity'] ?? 0);
|
||||
$price = $item['original_price_with_tax'] !== null ? (float) $item['original_price_with_tax'] : null;
|
||||
$sum = $price === null ? null : ($qty * $price);
|
||||
$media = trim((string) ($item['media_url'] ?? ''));
|
||||
?>
|
||||
<tr>
|
||||
<td><?= $e((string) ($idx + 1)) ?></td>
|
||||
<td>
|
||||
<div class="order-item-cell">
|
||||
<?php if ($media !== ''): ?>
|
||||
<img src="<?= $e($media) ?>" alt="" class="order-item-thumb">
|
||||
<?php else: ?>
|
||||
<span class="order-item-thumb order-item-thumb--empty"></span>
|
||||
<?php endif; ?>
|
||||
<div>
|
||||
<div class="order-item-name"><?= $e((string) ($item['original_name'] ?? '')) ?></div>
|
||||
<div class="muted"><?= $e((string) ($item['item_type'] ?? '')) ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div><?= $e((string) ($item['sku'] ?? '-')) ?></div>
|
||||
<div class="muted"><?= $e((string) ($item['ean'] ?? '-')) ?></div>
|
||||
</td>
|
||||
<td><?= $e((string) $qty) ?></td>
|
||||
<td><?= $e($price !== null ? number_format($price, 2, '.', ' ') : '-') ?></td>
|
||||
<td><?= $e($sum !== null ? number_format($sum, 2, '.', ' ') : '-') ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="mt-16 order-grid-2">
|
||||
<article class="card">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.order_info')) ?></h3>
|
||||
<dl class="order-kv mt-12">
|
||||
<dt><?= $e($t('orders.details.fields.status')) ?></dt><dd><?= $e((string) ($statusLabel ?? '-')) ?></dd>
|
||||
<dt><?= $e($t('orders.details.fields.source_order_id')) ?></dt><dd><?= $e((string) ($orderRow['source_order_id'] ?? '-')) ?></dd>
|
||||
<dt><?= $e($t('orders.details.fields.external_order_id')) ?></dt><dd><?= $e((string) ($orderRow['external_order_id'] ?? '-')) ?></dd>
|
||||
<dt><?= $e($t('orders.details.fields.ordered_at')) ?></dt><dd><?= $e((string) ($orderRow['ordered_at'] ?? '-')) ?></dd>
|
||||
<dt><?= $e($t('orders.details.fields.customer_login')) ?></dt><dd><?= $e((string) ($orderRow['customer_login'] ?? '-')) ?></dd>
|
||||
<dt><?= $e($t('orders.details.fields.currency')) ?></dt><dd><?= $e((string) ($orderRow['currency'] ?? '-')) ?></dd>
|
||||
</dl>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.payment_shipping')) ?></h3>
|
||||
<dl class="order-kv mt-12">
|
||||
<dt><?= $e($t('orders.details.fields.payment_status')) ?></dt><dd><?= $e((string) ($orderRow['payment_status'] ?? '-')) ?></dd>
|
||||
<dt><?= $e($t('orders.details.fields.total_with_tax')) ?></dt><dd><?= $e((string) ($orderRow['total_with_tax'] ?? '-')) ?></dd>
|
||||
<dt><?= $e($t('orders.details.fields.total_paid')) ?></dt><dd><?= $e((string) ($orderRow['total_paid'] ?? '-')) ?></dd>
|
||||
<dt><?= $e($t('orders.details.fields.carrier')) ?></dt><dd><?= $e((string) ($orderRow['external_carrier_id'] ?? '-')) ?></dd>
|
||||
<dt><?= $e($t('orders.details.fields.send_date')) ?></dt><dd><?= $e((string) ($orderRow['send_date_max'] ?? '-')) ?></dd>
|
||||
<dt><?= $e($t('orders.details.fields.shipments_count')) ?></dt><dd><?= $e((string) count($shipmentsList)) ?></dd>
|
||||
</dl>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="mt-16 order-grid-3">
|
||||
<?php foreach (['customer' => $t('orders.details.address_customer'), 'invoice' => $t('orders.details.address_invoice'), 'delivery' => $t('orders.details.address_delivery')] as $addrType => $addrTitle): ?>
|
||||
<?php $addr = is_array($addressByType[$addrType] ?? null) ? $addressByType[$addrType] : []; ?>
|
||||
<article class="card">
|
||||
<h3 class="section-title"><?= $e((string) $addrTitle) ?></h3>
|
||||
<div class="order-address mt-12">
|
||||
<?php if ($addr === []): ?>
|
||||
<div class="muted">-</div>
|
||||
<?php else: ?>
|
||||
<div><?= $e((string) ($addr['name'] ?? '')) ?></div>
|
||||
<div><?= $e((string) (($addr['street_name'] ?? '') . ' ' . ($addr['street_number'] ?? ''))) ?></div>
|
||||
<div><?= $e((string) (($addr['zip_code'] ?? '') . ' ' . ($addr['city'] ?? ''))) ?></div>
|
||||
<div><?= $e((string) ($addr['country'] ?? '')) ?></div>
|
||||
<div><?= $e((string) ($addr['phone'] ?? '')) ?></div>
|
||||
<div><?= $e((string) ($addr['email'] ?? '')) ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</section>
|
||||
|
||||
<section class="mt-16 order-grid-2">
|
||||
<article class="card">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.notes_title')) ?></h3>
|
||||
<div class="order-events mt-12">
|
||||
<?php if ($notesList === []): ?>
|
||||
<div class="muted">-</div>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($notesList as $note): ?>
|
||||
<div class="order-event">
|
||||
<div class="order-event__head"><?= $e((string) ($note['note_type'] ?? '')) ?> | <?= $e((string) ($note['created_at_external'] ?? '')) ?></div>
|
||||
<div class="order-event__body"><?= $e((string) ($note['comment'] ?? '')) ?></div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.history_title')) ?></h3>
|
||||
<div class="order-events mt-12">
|
||||
<?php if ($historyList === []): ?>
|
||||
<div class="muted">-</div>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($historyList as $event): ?>
|
||||
<div class="order-event">
|
||||
<div class="order-event__head"><?= $e((string) ($event['changed_at'] ?? '')) ?></div>
|
||||
<div class="order-event__body"><?= $e((string) ($event['from_status_id'] ?? '-')) ?> -> <?= $e((string) ($event['to_status_id'] ?? '-')) ?></div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="order-tab-panel" data-order-tab-panel="history">
|
||||
<section class="card mt-16">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.tabs.history')) ?></h3>
|
||||
<div class="order-empty-placeholder mt-12"></div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="order-tab-panel" data-order-tab-panel="shipments">
|
||||
<section class="card mt-16">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.tabs.shipments')) ?></h3>
|
||||
<div class="order-empty-placeholder mt-12"></div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="order-tab-panel" data-order-tab-panel="payments">
|
||||
<section class="card mt-16">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.tabs.payments')) ?></h3>
|
||||
<div class="order-empty-placeholder mt-12"></div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="order-tab-panel" data-order-tab-panel="documents">
|
||||
<section class="card mt-16">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.tabs.documents')) ?></h3>
|
||||
<div class="order-empty-placeholder mt-12"></div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var tabButtons = document.querySelectorAll('[data-order-tab-target]');
|
||||
var tabPanels = document.querySelectorAll('[data-order-tab-panel]');
|
||||
if (!tabButtons.length || !tabPanels.length) return;
|
||||
|
||||
function setActiveTab(target) {
|
||||
var key = target || 'details';
|
||||
tabButtons.forEach(function (btn) {
|
||||
btn.classList.toggle('is-active', btn.getAttribute('data-order-tab-target') === key);
|
||||
});
|
||||
tabPanels.forEach(function (panel) {
|
||||
panel.classList.toggle('is-active', panel.getAttribute('data-order-tab-panel') === key);
|
||||
});
|
||||
}
|
||||
|
||||
tabButtons.forEach(function (button) {
|
||||
button.addEventListener('click', function () {
|
||||
setActiveTab(button.getAttribute('data-order-tab-target') || 'details');
|
||||
});
|
||||
});
|
||||
|
||||
setActiveTab('details');
|
||||
})();
|
||||
</script>
|
||||
Reference in New Issue
Block a user