Kundennachtrag 09.09.2026: Ist-Mengen je Charge in der Produktion sollen auf das Milligramm eingegeben werden können (z. B. 0,125 g). Bisher rundeten Datenbank (decimal 12,2), Bestandslogik, Anzeige und Toleranzsockel auf zwei Stellen; „0,125" wurde still zu 0,13, „0.125" nach der Punkt-Regel zu 125 g. - Migration 2026_09_09_100000: production_ingredients.quantity_used, stock_entries.ordered_quantity/received_quantity, stock_disposals.quantity → decimal(12,3); Casts decimal:3. Auf der Dev-DB (Live-Kopie) ausgeführt, 53/78/7 Zeilen unverändert. - InventoryService::QUANTITY_DECIMALS = 3; roundWawiQuantity() ersetzt alle round(…, 2) in InventoryService, ProductionService, StockDisposalController/-Request, StockEntryRepository/-Controller, RawMaterialStockController. - formatWawiQuantity($v, $min = 2): bis drei Stellen, mindestens zwei — Produktionsdetail, Einkauf Liste/Detail/Formular, Ausschuss-Liste, Chargen-Rest im Rohstoff-Detail. - Eingaberegel (reFormatWawiNumber, JS parseGerman/parseNumber): zusätzlich „0.xxx" als Dezimalzahl; „1.500" bleibt 1500. Produktions-JS: fmt() bis drei Stellen, fmtInput() schreibt gespeicherte Zahlen deutsch ins Feld (1,125 statt 1.125 = 1125). - Soll-Ist-Toleranz: Sockel 0,05 → 0,005 g; Ausschuss min 0,001. - Doku: Hinweise (Neu/geändert), Leitfaden Version 3.1 mit Abschnitt 26, Plan V7 AP-53, README (Deploy-Checkliste, Suite 378). Tests: QuantityPrecisionTest (6) — Parsing, Anzeige, Produktion 0,125 g exakt + Rest 9,875 g, Entwurf 1,125 wiederöffnen, Toleranz Kleinmengen, Ausschuss 0,005 g. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
106 lines
6 KiB
PHP
106 lines
6 KiB
PHP
@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">
|
||
−{{ $disposal->unit === 'piece' ? \App\Services\Util::formatNumber($disposal->quantity, 0) : formatWawiQuantity($disposal->quantity) }}
|
||
{{ $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
|