gruene-seele/resources/views/admin/inventory/stock-disposals/index.blade.php
Kevin Adametz d34f0a77f4 Warenwirtschaft: Audit-Niedrigbefunde N-2/3/4/5/7/8/9/15
- N-2: Letzter Netto-Preis je Lieferant nur aus tatsächlichen
  Eingängen (status received).
- N-3: Verbrauchsfenster exakt (kein startOfDay-Off-by-one).
- N-4: Kritisch-Zählung vereinheitlicht — Controller liefert die
  Kachel-Zählweise (inkl. critical_ordered), tote View-Überschreibung
  entfernt; Sidenav-Badge bleibt bewusst ohne bestellte Kritische.
- N-5: Ausschuss-Liste zeigt das 500er-Limit an + "Alle anzeigen"
  (?all=1), analog OPT-3.
- N-7: parseQuantity parst Strings konsequent im deutschen Format —
  Server und UI-Ampel interpretieren "1.500" jetzt identisch.
- N-8: Produktions-Kopie übernimmt keine alten Chargen-Nummern mehr
  (Auto-Vorschlag Präfix+ttmmjj greift).
- N-9: recordProductionStock lädt Produkte withTrashed — Korrektur-
  Gegenbuchungen soft-gelöschter Output-Produkte werden nicht mehr
  übersprungen.
- N-15: Hinweise/Leitfaden-Markdown mit html_input=strip +
  allow_unsafe_links=false gerendert.

Bewusst offen (Kundenentscheid/Design): N-1 (Chargen-Gruppierung ohne
supplier_id), N-6 (reFormatNumber-Konvention app-weit), N-10 (manuelle
Bewegung darf ins Minus, Inventur-Korrekturen), N-13 (mfg_row_phase-
Fallback auf phasenlos).

Suite: 231 grün, 823 Assertions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 12:57:26 +00:00

106 lines
5.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@extends('layouts.layout-2')
@section('content')
@include('admin.inventory.partials.wawi-ui')
<div class="wawi-page">
<div class="wawi-page-head">
<div>
<h1 class="wawi-page-head__title">{{ __('Ausgang / Ausschuss') }}</h1>
<p class="wawi-page-head__subtitle">{{ __('Erfasste Bestandsabgänge von Rohstoffen und Verpackung') }}</p>
</div>
<div class="wawi-page-head__actions">
@if (Auth::user()->isAdmin())
<a href="{{ route('admin.inventory.stock-disposals.create') }}" class="btn btn-primary btn-sm">
<span class="fas fa-plus mr-1"></span>{{ __('Ausschuss erfassen') }}
</a>
@endif
</div>
</div>
<div class="wawi-card">
<div class="wawi-toolbar">
<form method="get" class="mb-0">
<select name="type" class="form-control form-control-sm" style="width:auto" onchange="this.form.submit()">
<option value="">{{ __('Alle Arten') }}</option>
<option value="ingredient" @selected($typeFilter === 'ingredient')>{{ __('Rohstoff') }}</option>
<option value="packaging" @selected($typeFilter === 'packaging')>{{ __('Verpackung') }}</option>
</select>
</form>
</div>
<div class="table-responsive">
<table class="table wawi-table">
<thead>
<tr>
<th>{{ __('Datum') }}</th>
<th>{{ __('Art') }}</th>
<th>{{ __('Artikel') }}</th>
<th>{{ __('Charge') }}</th>
<th>{{ __('Lagerort') }}</th>
<th class="text-right">{{ __('Menge') }}</th>
<th>{{ __('Grund') }}</th>
<th>{{ __('Hinweis') }}</th>
<th>{{ __('Mitarbeiter') }}</th>
<th></th>
</tr>
</thead>
<tbody>
@forelse($values as $disposal)
<tr>
<td>{{ $disposal->disposed_at?->format('d.m.Y') }}</td>
<td>
@if ($disposal->isIngredient())
<span class="wawi-pill wawi-pill--ok">{{ __('Rohstoff') }}</span>
@else
<span class="wawi-pill" style="background:rgba(24,28,33,.06);color:#6c757d;">{{ __('Verpackung') }}</span>
@endif
</td>
<td><span class="wawi-item-name">{{ $disposal->articleName() }}</span></td>
<td>
@if ($disposal->stockEntry)
{{ $disposal->stockEntry->batch_number ?: '#'.$disposal->stockEntry->id }}
@else
<span class="text-muted">—</span>
@endif
</td>
<td>{{ $disposal->location?->name ?? '—' }}</td>
<td class="text-right text-danger font-weight-bold">
−{{ \App\Services\Util::formatNumber($disposal->quantity, $disposal->unit === 'piece' ? 0 : 2) }}
{{ $disposal->unit === 'piece' ? __('Stück') : 'g' }}
</td>
<td>{{ $disposal->reason }}</td>
<td class="text-muted">{{ $disposal->note }}</td>
<td>{{ $disposal->user?->getFullName(false) ?: ($disposal->user?->email ?? '—') }}</td>
<td>
@if(Auth::user()->isAdmin())
<form action="{{ route('admin.inventory.stock-disposals.destroy', $disposal) }}" method="post" class="d-inline"
onsubmit="return confirm(@json(__('Ausschuss-Buchung wirklich löschen? Die Menge steht dem Bestand danach wieder zur Verfügung.')));">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-link text-danger p-0" title="{{ __('Löschen') }}"><i class="far fa-trash-alt"></i></button>
</form>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="10">
<div class="wawi-empty">
<div><span class="fas fa-dumpster"></span></div>
{{ __('Noch keine Ausgänge erfasst.') }}
</div>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
@if(($listLimit ?? null) !== null && $values->count() >= $listLimit)
<p class="text-muted small px-3 pb-2 mb-0">
{{ __('Es werden die neuesten :n Abgänge angezeigt.', ['n' => $listLimit]) }}
<a href="{{ route('admin.inventory.stock-disposals.index', array_filter(['all' => 1, 'type' => $typeFilter])) }}">{{ __('Alle anzeigen') }}</a>
</p>
@endif
</div>
</div>
@endsection