From 69a9420c03e64fa421bd3db5f48ed777c4f4db84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Gla=CC=88ser?= Date: Mon, 15 Jun 2026 13:29:20 +0200 Subject: [PATCH] OTC-Overlay im Home --- modules/erp/lager/service.php | 31 ++++ modules/shared/auth/ui/home.php | 272 +++++++++++++++++++++++++++++++- public/assets/styles.portal.css | 56 +++++++ public/index.php | 4 +- 4 files changed, 360 insertions(+), 3 deletions(-) diff --git a/modules/erp/lager/service.php b/modules/erp/lager/service.php index dff6f56..fcfb98e 100644 --- a/modules/erp/lager/service.php +++ b/modules/erp/lager/service.php @@ -19,6 +19,37 @@ function get_default_location_ids(PDO $pdo): array ]; } +function get_otc_order_form_products(PDO $pdo): array +{ + $stmt = $pdo->query( + "SELECT + p.id, + p.name, + COALESCE(SUM(v.qty_net), 0) AS available_qty + FROM product p + INNER JOIN stock_lot sl + ON sl.product_id = p.id + AND sl.status = 'current' + INNER JOIN v_stock_lot_balance v + ON v.stock_lot_id = sl.id + WHERE p.status = 'active' + GROUP BY p.id, p.name + HAVING COALESCE(SUM(v.qty_net), 0) > 0 + ORDER BY p.name ASC, p.id ASC" + ); + + $products = []; + foreach ($stmt->fetchAll() as $row) { + $products[] = [ + 'id' => (int) $row['id'], + 'name' => (string) $row['name'], + 'available_qty' => (float) $row['available_qty'], + ]; + } + + return $products; +} + function get_current_lot_balance_for_update(PDO $pdo, int $productId): array { $stmt = $pdo->prepare( diff --git a/modules/shared/auth/ui/home.php b/modules/shared/auth/ui/home.php index 5e85dc1..b2a9a42 100644 --- a/modules/shared/auth/ui/home.php +++ b/modules/shared/auth/ui/home.php @@ -3,8 +3,25 @@ declare(strict_types=1); require_once __DIR__ . '/../service.php'; -function render_auth_home_page(array $user): void +function render_auth_home_page(array $user, array $otcProducts = []): void { + $otcProductRows = ''; + foreach ($otcProducts as $product) { + $productId = (int) ($product['id'] ?? 0); + $productName = auth_escape_html((string) ($product['name'] ?? '')); + $availableQty = (int) max(0, (int) round((float) ($product['available_qty'] ?? 0))); + $inputId = 'otc-product-' . $productId; + + $otcProductRows .= '
'; + $otcProductRows .= ''; + $otcProductRows .= ''; + $otcProductRows .= '
'; + } + + if ($otcProductRows === '') { + $otcProductRows = '

Keine verfügbaren Produkte im Lager.

'; + } + $moduleNavigation = json_encode( [ 'Übersicht' => [], @@ -16,7 +33,7 @@ function render_auth_home_page(array $user): void ); $moduleContentCards = json_encode( [ - 'Bestellungen' => '
', + 'Bestellungen' => '
', ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ); @@ -100,6 +117,82 @@ function render_auth_home_page(array $user): void echo ''; echo ''; echo ''; + echo ''; echo ''; diff --git a/public/assets/styles.portal.css b/public/assets/styles.portal.css index c1f6497..090758b 100644 --- a/public/assets/styles.portal.css +++ b/public/assets/styles.portal.css @@ -26,3 +26,59 @@ .sg-left-navigation-pattern__group-card--content { align-content: flex-start; } + +body.sg-otc-order-overlay-open { + overflow: hidden; +} + +.sg-otc-order-overlay { + position: fixed; + inset: 0; + display: none; + align-items: center; + justify-content: center; + padding: var(--spacing-large); + background: rgba(15, 23, 42, 0.58); + z-index: 1200; +} + +.sg-otc-order-overlay[data-open="true"] { + display: flex; +} + +.sg-otc-order-overlay__panel { + width: min(960px, 100%); + max-height: calc(100vh - (2 * var(--spacing-large))); + overflow: auto; +} + +.sg-otc-order-overlay__title { + margin: 0; +} + +.sg-otc-order-overlay__close { + margin-left: auto; +} + +.sg-otc-order-form__status { + margin: 0; +} + +.sg-otc-order-form__status--error { + color: var(--color-signal-red); +} + +.sg-otc-order-overlay .sg-form-sections-card__field-group { + gap: var(--spacing-small); +} + +.sg-otc-order-overlay .sg-form-sections-card__field-group > .sg-label { + display: block; +} + +.sg-otc-order-overlay .sg-form-sections-card__field-group > .sg-input-single-line, +.sg-otc-order-overlay .sg-form-sections-card__field-group > .sg-input-single-line-wrap, +.sg-otc-order-overlay .sg-form-sections-card__field-group > .sg-input-multi-line { + width: 100%; + max-width: none; +} diff --git a/public/index.php b/public/index.php index 51ba967..7138d3f 100644 --- a/public/index.php +++ b/public/index.php @@ -4,6 +4,7 @@ declare(strict_types=1); require_once __DIR__ . '/../modules/shared/auth/service.php'; require_once __DIR__ . '/../modules/shared/auth/ui/login.php'; require_once __DIR__ . '/../modules/shared/auth/ui/home.php'; +require_once __DIR__ . '/../modules/erp/lager/service.php'; $env = expand_env_values(parse_env_file(__DIR__ . '/../.env')); $pdo = connect_database($env); @@ -43,7 +44,8 @@ if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') { $currentUser = auth_current_user($pdo); if ($currentUser !== null) { - render_auth_home_page($currentUser); + $otcProducts = get_otc_order_form_products($pdo); + render_auth_home_page($currentUser, $otcProducts); exit; }