diff --git a/modules/shared/auth/ui/home.php b/modules/shared/auth/ui/home.php index 99352ed..1e1b235 100644 --- a/modules/shared/auth/ui/home.php +++ b/modules/shared/auth/ui/home.php @@ -300,26 +300,23 @@ function auth_format_lager_quantity(float $value): string function auth_render_lager_documents(array $documents, bool $editable, string $scope): string { - $segmentState = $editable ? ' hidden data-lager-edit-documents="' . auth_escape_html($scope) . '"' : ''; - $html = '

Dokumente

'; - if (!$editable) { - $html .= '
'; - if ($documents === []) { - $html .= '

Keine Dokumente vorhanden.

'; - } else { - foreach ($documents as $document) { - $documentId = (int) ($document['id'] ?? 0); - $filename = (string) ($document['original_filename'] ?? 'Dokument'); - $comment = trim((string) ($document['comment'] ?? '')); - $html .= '

' . auth_escape_html($filename) . ''; - if ($comment !== '') { - $html .= '
Kommentar: ' . auth_escape_html($comment) . ''; - } - $html .= '

'; + $html = '

Dokumente

'; + $html .= '
'; + if ($documents === []) { + $html .= '

Keine Dokumente vorhanden.

'; + } else { + foreach ($documents as $document) { + $documentId = (int) ($document['id'] ?? 0); + $filename = (string) ($document['original_filename'] ?? 'Dokument'); + $comment = trim((string) ($document['comment'] ?? '')); + $html .= '

' . auth_escape_html($filename) . ''; + if ($comment !== '') { + $html .= '
Kommentar: ' . auth_escape_html($comment) . ''; } + $html .= '

'; } - $html .= '
'; } + $html .= '
'; if ($editable) { $html .= '
'; foreach ($documents as $document) { @@ -355,7 +352,7 @@ function auth_render_lager_historical_lots(array $lagerProducts): string . 'MHD: ' . auth_format_lager_date($lot['expiry_date'] ?? null) . '
' . 'Hersteller: ' . auth_escape_html((string) ($lot['manufacturer_name'] ?? 'Nicht hinterlegt')) . '
' . 'Hersteller-Chargennummer: ' . auth_escape_html((string) ($lot['manufacturer_lot_number'] ?? 'Nicht hinterlegt')) . '

' - . '
' + . '

' . auth_render_lager_documents($lot['documents'] ?? [], false, 'historical-' . (int) ($lot['lot_id'] ?? 0)) . ''; } @@ -394,9 +391,8 @@ function auth_render_lager_open_lots(array $lagerProducts, string $manufacturerO . '
' . '
' . '
' - . '

' . auth_render_lager_documents($lot['documents'] ?? [], true, 'open-edit-' . $lotId) - . '' + . '

' . '' . ''; } @@ -460,6 +456,7 @@ function auth_render_lager_content(array $lagerProducts, array $lagerArtikel, ar . '
' . '
' . '
' + . auth_render_lager_documents([], true, 'current-edit') . '

Lagerbewegungen

' . '

Buchungen werden zusätzlich zur Rückverfolgbarkeit als Lagerbewegung gespeichert. Positive Werte erhöhen den Bestand, negative Werte reduzieren ihn.

' . '
' @@ -467,7 +464,6 @@ function auth_render_lager_content(array $lagerProducts, array $lagerArtikel, ar . '
' . '

' . '' - . auth_render_lager_documents([], true, 'current-edit') . '' . '
' . auth_render_lager_historical_lots($lagerProducts) . '
' . '
' @@ -878,7 +874,7 @@ function render_auth_home_page(array $user, array $otcProducts = [], array $best echo " document.addEventListener('input', (event) => { const input = event.target.closest('[data-lager-document-delete-input]'); if (!input) { return; } const button = input.closest('[data-lager-document-confirmation]')?.querySelector('[data-lager-document-delete-confirm]'); const valid = input.value === 'DELETE'; if (button) { button.disabled = !valid; button.setAttribute('aria-disabled', String(!valid)); button.classList.toggle('sg-button--process-inactive', !valid); } });"; echo " document.addEventListener('click', async (event) => { const open = event.target.closest('[data-lager-document-delete]'); if (open) { const id = open.dataset.lagerDocumentDelete; const confirmation = open.closest('[data-lager-document-edit-row]')?.querySelector('[data-lager-document-confirmation=\"' + id + '\"]'); if (confirmation) { confirmation.hidden = false; } return; } const cancel = event.target.closest('[data-lager-document-delete-cancel]'); if (cancel) { const confirmation = cancel.closest('[data-lager-document-confirmation]'); if (confirmation) { confirmation.hidden = true; } return; } const confirm = event.target.closest('[data-lager-document-delete-confirm]'); if (!confirm || confirm.disabled) { return; } const confirmation = confirm.closest('[data-lager-document-confirmation]'); const id = confirm.dataset.lagerDocumentDeleteConfirm; confirm.disabled = true; try { await postLagerChange({ action: 'delete_document', documentId: id }); window.location.reload(); } catch (error) { confirm.disabled = false; const input = confirmation?.querySelector('[data-lager-document-delete-input]'); if (input) { input.setCustomValidity(error instanceof Error ? error.message : 'Dokument konnte nicht gelöscht werden'); input.reportValidity(); } } });"; echo " document.addEventListener('click', (event) => { const editButton = event.target.closest('[data-lager-edit-open]'); if (editButton) { const drawer = getDrawer(); const editForm = drawer?.querySelector('[data-lager-edit-form]'); if (editForm) { editForm.hidden = false; } return; } const closeButton = event.target.closest('[data-lager-edit-close]'); if (closeButton) { const drawer = getDrawer(); const editForm = drawer?.querySelector('[data-lager-edit-form]'); if (editForm) { editForm.hidden = true; } } });"; - echo " const setLagerEditMode = (editing) => { const drawer = getDrawer(); const readView = drawer?.querySelector('[data-lager-read-view]'); const editForm = drawer?.querySelector('[data-lager-edit-form]'); const documents = drawer?.querySelector('[data-lager-edit-documents=\"current-edit\"]'); if (readView) { readView.hidden = editing; } if (editForm) { editForm.hidden = !editing; } if (documents) { documents.hidden = !editing; } };"; + echo " const setLagerEditMode = (editing) => { const drawer = getDrawer(); const readView = drawer?.querySelector('[data-lager-read-view]'); const editForm = drawer?.querySelector('[data-lager-edit-form]'); if (readView) { readView.hidden = editing; } if (editForm) { editForm.hidden = !editing; } };"; echo " document.addEventListener('click', (event) => { if (event.target.closest('[data-lager-edit-open]')) { setLagerEditMode(true); } if (event.target.closest('[data-lager-edit-close]')) { clearLagerMovementInputs(); setLagerEditMode(false); } });"; echo " const syncLagerReadView = () => { const drawer = getDrawer(); if (!drawer) { return; } const manufacturer = drawer.querySelector('[data-lager-manufacturer]'); const values = { '[data-lager-drawer-manufacturer-name]': manufacturer?.selectedOptions?.[0]?.textContent || 'Nicht hinterlegt', '[data-lager-drawer-manufacturer-lot-number]': drawer.querySelector('[data-lager-manufacturer-lot]')?.value || 'Nicht hinterlegt', '[data-lager-drawer-mfg-date]': drawer.querySelector('[data-lager-mfg-date]')?.value || 'Nicht hinterlegt', '[data-lager-drawer-expiry-date]': drawer.querySelector('[data-lager-expiry-date]')?.value || 'Nicht hinterlegt', '[data-lager-drawer-purchase-date]': drawer.querySelector('[data-lager-purchase-date]')?.value || 'Nicht hinterlegt' }; Object.entries(values).forEach(([selector, value]) => { const target = drawer.querySelector(selector); if (target) { target.textContent = value; } }); const trigger = contentRoot.querySelector('[data-lager-drawer-open][aria-expanded=\"true\"]'); if (trigger) { trigger.dataset.lagerDrawerManufacturerName = values['[data-lager-drawer-manufacturer-name]']; trigger.dataset.lagerDrawerManufacturerLotNumber = values['[data-lager-drawer-manufacturer-lot-number]']; trigger.dataset.lagerDrawerMfgDate = values['[data-lager-drawer-mfg-date]']; trigger.dataset.lagerDrawerExpiryDate = values['[data-lager-drawer-expiry-date]']; trigger.dataset.lagerDrawerPurchaseDate = values['[data-lager-drawer-purchase-date]']; } };"; echo " const syncLagerBalanceView = (balance) => { const drawer = getDrawer(); if (!drawer || !balance) { return; } const currentQty = drawer.querySelector('[data-lager-drawer-current-qty]'); const qtyIn = drawer.querySelector('[data-lager-drawer-qty-in]'); if (currentQty) { currentQty.textContent = String(balance.qty_net ?? 0); } if (qtyIn) { qtyIn.textContent = String(balance.qty_in ?? 0); } const trigger = contentRoot.querySelector('[data-lager-drawer-open][aria-expanded=\"true\"]'); if (trigger) { trigger.dataset.lagerDrawerCurrentQty = String(balance.qty_net ?? 0); trigger.dataset.lagerDrawerQtyIn = String(balance.qty_in ?? 0); } };"; @@ -887,7 +883,6 @@ function render_auth_home_page(array $user, array $otcProducts = [], array $best echo " document.addEventListener('click', (event) => { const trigger = event.target.closest('[data-lager-drawer-open]'); if (!trigger || trigger.dataset.lagerDrawerType !== 'Produkt' || window.matchMedia('(max-width: 767px)').matches) { return; } const drawer = getDrawer(); const productId = trigger.closest('[data-lager-row]')?.dataset.lagerId || ''; const openProduct = drawer?.querySelector('[data-lager-open-product=\"' + productId + '\"]'); drawer?.querySelectorAll('[data-lager-open-product]').forEach((product) => { product.hidden = product !== openProduct; product.querySelectorAll('[data-lager-open-edit-form]').forEach((form) => { form.hidden = true; }); product.querySelectorAll('[data-lager-open-card]').forEach((readView) => { readView.hidden = false; }); }); const newForm = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-form\"]'); const newAction = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-action\"]'); if (newForm) { newForm.hidden = true; } if (newAction) { newAction.hidden = false; } const notificationWrapper = drawer?.querySelector('[data-lager-new-lot-notification-wrapper]'); const notification = drawer?.querySelector('[data-lager-new-lot-notification]'); const shortageQty = trigger.dataset.lagerDrawerVirtualShortageQty || '0'; const hasShortage = shortageQty !== '0' && shortageQty !== '0,00'; if (notificationWrapper) { notificationWrapper.hidden = !hasShortage; } if (notification && hasShortage) { notification.textContent = 'Für dieses Produkt bestehen virtuelle Fehlbestände in Höhe von ' + shortageQty + '. Die Eingangsmenge wird nach Aktivierung der Charge zur Nachallokation verwendet.'; } const setValue = (selector, value) => { const field = drawer?.querySelector(selector); if (field) { field.value = value || ''; } }; setValue('[data-lager-new-lot-number]', trigger.dataset.lagerOpenLotNumber); setValue('[data-lager-new-manufacturer]', trigger.dataset.lagerOpenManufacturerPartyId); setValue('[data-lager-new-manufacturer-lot]', trigger.dataset.lagerOpenManufacturerLotNumber); setValue('[data-lager-new-mfg-date]', trigger.dataset.lagerOpenMfgDate); setValue('[data-lager-new-expiry-date]', trigger.dataset.lagerOpenExpiryDate); setValue('[data-lager-new-purchase-date]', trigger.dataset.lagerOpenPurchaseDate); if (drawer) { drawer.dataset.lagerOpenLotId = trigger.dataset.lagerOpenLotId || ''; drawer.dataset.lagerProductId = productId; } });"; echo " document.addEventListener('click', (event) => { const openButton = event.target.closest('[data-lager-new-lot-open]'); if (openButton) { const drawer = getDrawer(); const form = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-form\"]'); const action = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-action\"]'); if (form) { form.hidden = false; } if (action) { action.hidden = true; } return; } if (event.target.closest('[data-lager-new-lot-close]')) { const drawer = getDrawer(); const form = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-form\"]'); const action = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-action\"]'); if (form) { form.hidden = true; } if (action) { action.hidden = false; } } });"; echo " document.addEventListener('click', (event) => { const editButton = event.target.closest('[data-lager-open-edit-open]'); if (editButton) { const card = editButton.closest('[data-lager-open-card-wrapper]'); const form = card?.querySelector('[data-lager-open-edit-form]'); const readView = card?.querySelector('[data-lager-open-card]'); if (form) { form.hidden = false; } if (readView) { readView.hidden = true; } return; } const closeButton = event.target.closest('[data-lager-open-edit-close]'); if (closeButton) { const card = closeButton.closest('[data-lager-open-card-wrapper]'); const form = card?.querySelector('[data-lager-open-edit-form]'); const readView = card?.querySelector('[data-lager-open-card]'); if (form) { form.hidden = true; } if (readView) { readView.hidden = false; } } });"; - echo " document.addEventListener('click', (event) => { const editButton = event.target.closest('[data-lager-open-edit-open]'); const closeButton = event.target.closest('[data-lager-open-edit-close]'); const card = editButton?.closest('[data-lager-open-card-wrapper]') || closeButton?.closest('[data-lager-open-card-wrapper]'); if (!card) { return; } const documents = card.querySelector('[data-lager-edit-documents]'); if (documents) { documents.hidden = Boolean(closeButton); } });"; echo " document.addEventListener('input', (event) => { const input = event.target.closest('[data-lager-open-delete-confirmation-input]'); if (!input) { return; } const card = input.closest('[data-lager-open-card-wrapper]'); const submit = card?.querySelector('[data-lager-open-delete-confirmation-submit]'); const valid = input.value === 'DELETE'; if (submit) { submit.disabled = !valid; submit.setAttribute('aria-disabled', String(!valid)); submit.classList.toggle('sg-button--process-inactive', !valid); } });"; echo " document.addEventListener('click', async (event) => { const deleteButton = event.target.closest('[data-lager-open-delete]'); if (deleteButton) { const card = deleteButton.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-delete-confirmation]'); const input = card?.querySelector('[data-lager-open-delete-confirmation-input]'); const submit = card?.querySelector('[data-lager-open-delete-confirmation-submit]'); if (input) { input.value = ''; } if (submit) { submit.disabled = true; submit.setAttribute('aria-disabled', 'true'); submit.classList.add('sg-button--process-inactive'); } if (confirmation) { confirmation.hidden = false; } if (card) { card.dataset.dialogOpen = 'true'; } return; } const cancel = event.target.closest('[data-lager-open-delete-confirmation-cancel]'); if (cancel) { const card = cancel.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-delete-confirmation]'); if (confirmation) { confirmation.hidden = true; } if (card) { card.dataset.dialogOpen = 'false'; } return; } const submit = event.target.closest('[data-lager-open-delete-confirmation-submit]'); if (!submit || submit.disabled) { return; } const card = submit.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-delete-confirmation]'); const status = card?.querySelector('[data-lager-open-delete-status]'); if (status) { status.textContent = 'Löschen läuft …'; } submit.disabled = true; try { await postLagerChange({ action: 'delete_open_lot', lotId: card?.dataset.lagerOpenCardWrapper || '' }); card?.remove(); } catch (error) { if (status) { status.textContent = error instanceof Error ? error.message : 'Löschen fehlgeschlagen'; } submit.disabled = false; } });"; echo " document.addEventListener('click', (event) => { const cancel = event.target.closest('[data-lager-open-confirmation-cancel]'); if (cancel) { const card = cancel.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-confirmation-card]'); if (confirmation) { confirmation.hidden = true; } if (card) { card.dataset.dialogOpen = 'false'; } const form = card?.querySelector('[data-lager-open-edit-form-element]'); if (form) { form.dataset.confirmationAccepted = 'false'; } return; } const confirm = event.target.closest('[data-lager-open-confirmation-submit]'); if (confirm) { const card = confirm.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-confirmation-card]'); const form = card?.querySelector('[data-lager-open-edit-form-element]'); if (confirmation) { confirmation.hidden = true; } if (card) { card.dataset.dialogOpen = 'false'; } if (form) { form.dataset.confirmationAccepted = 'true'; form.requestSubmit(); } } });";