gruene-seele/resources/views/admin/inventory/productions/show.blade.php
Kevin Adametz b8180a06a1 Warenwirtschaft: AP-53 — Gramm-Mengen mit drei Nachkommastellen (Produktion, Wareneingang, Ausschuss)
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>
2026-09-09 15:54:29 +00:00

160 lines
7.5 KiB
PHP

@php
/** @var \App\Models\Production $model */
@endphp
@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">{{ __('Produktion') }} #{{ $model->id }}</h1>
<p class="wawi-page-head__subtitle">{{ $model->product?->name ?? '—' }} · {{ $model->produced_at?->format('d.m.Y') }}</p>
</div>
<div class="wawi-page-head__actions">
<a href="{{ route('admin.inventory.productions.edit', $model) }}" class="btn btn-sm btn-primary">{{ __('Bearbeiten') }}</a>
<a href="{{ route('admin.inventory.productions.copy', $model) }}" class="btn btn-sm btn-outline-primary">{{ __('Kopieren') }}</a>
<a href="{{ route('admin.inventory.productions.index') }}" class="btn btn-sm btn-outline-secondary">{{ __('Zurück') }}</a>
</div>
</div>
<div class="card wawi-card mb-3">
<div class="wawi-card__header">{{ __('Übersicht') }}</div>
<div class="card-body">
<div class="wawi-deflist">
<div class="wawi-deflist__item">
<span class="wawi-deflist__label">{{ __('Produkt') }}</span>
<span class="wawi-deflist__value">{{ $model->product?->name ?? '—' }}</span>
</div>
<div class="wawi-deflist__item">
<span class="wawi-deflist__label">{{ __('Produktionsdatum') }}</span>
<span class="wawi-deflist__value">{{ $model->produced_at?->format('d.m.Y') }}</span>
</div>
<div class="wawi-deflist__item">
<span class="wawi-deflist__label">{{ __('Geplante Stückzahl') }}</span>
<span class="wawi-deflist__value">{{ $model->quantity }} <span class="text-muted small">({{ __('Planung — bucht keinen Bestand') }})</span></span>
</div>
<div class="wawi-deflist__item">
<span class="wawi-deflist__label">{{ __('Standort') }}</span>
<span class="wawi-deflist__value">{{ $model->location?->name ?? '—' }}</span>
</div>
<div class="wawi-deflist__item">
<span class="wawi-deflist__label">{{ __('Erfasst von') }}</span>
<span class="wawi-deflist__value">{{ $model->producedByUser?->getFullName(false) ?: $model->producedByUser?->email ?? '—' }}</span>
</div>
<div class="wawi-deflist__item">
<span class="wawi-deflist__label">{{ __('MHD-Hinweis') }}</span>
<span class="wawi-deflist__value">
@if($model->mhd_warning)
<span class="wawi-pill wawi-pill--warning">{{ __('Rohstoff-MHD kürzer als Produkt-MHD') }}</span>
@else
—
@endif
</span>
</div>
@if($model->notes)
<div class="wawi-deflist__item wawi-deflist__item--wide">
<span class="wawi-deflist__label">{{ __('Notizen') }}</span>
<span class="wawi-deflist__value">{{ $model->notes }}</span>
</div>
@endif
</div>
</div>
</div>
{{-- AP-28: Produktionsergebnis — diese Zeilen buchen den Produktbestand --}}
<div class="card wawi-card mb-3">
<div class="wawi-card__header">{{ __('Produktionsergebnis') }}</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table wawi-table mb-0">
<thead>
<tr>
<th>{{ __('Produkt') }}</th>
<th>{{ __('Produzierte Stückzahl') }}</th>
<th>{{ __('Chargen-Nr.') }}</th>
</tr>
</thead>
<tbody>
@forelse($model->outputs as $output)
<tr>
<td>{{ $output->product?->name ?? '—' }}</td>
<td>{{ $output->quantity }}</td>
<td>{{ $output->batch_number ?: '—' }}</td>
</tr>
@empty
<tr>
<td colspan="3"><div class="wawi-empty">{{ __('Kein Produktionsergebnis erfasst.') }}</div></td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
<div class="card wawi-card mb-3">
<div class="wawi-card__header">{{ __('Rohstoff-Verbrauch (Chargen)') }}</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table wawi-table mb-0">
<thead>
<tr>
<th>{{ __('Inhaltsstoff') }}</th>
<th>{{ __('Charge / Wareneingang') }}</th>
<th>{{ __('Menge (g)') }}</th>
</tr>
</thead>
<tbody>
@foreach($model->productionIngredients as $line)
<tr>
<td>{{ $line->ingredient?->name ?? '—' }}</td>
<td>
@if($line->stock_entry_id === null)
{{ __('Charge') }} {{ explode(':', (string) $line->batch_key, 3)[2] ?? $line->batch_key }}
<span class="text-muted">({{ __('Entwurf — noch nicht aufgelöst') }})</span>
@else
#{{ $line->stock_entry_id }}
@endif
@if($line->stockEntry?->batch_number)
— {{ $line->stockEntry->batch_number }}
@endif
@if($line->stockEntry?->best_before)
(MHD {{ $line->stockEntry->best_before->format('d.m.Y') }})
@endif
</td>
<td>{{ formatWawiQuantity($line->quantity_used) }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
<div class="card wawi-card">
<div class="wawi-card__header">{{ __('Verpackung (Snapshot)') }}</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table wawi-table mb-0">
<thead>
<tr>
<th>{{ __('Artikel') }}</th>
<th>{{ __('Verbrauch (Stk.)') }}</th>
</tr>
</thead>
<tbody>
@foreach($model->productionPackagings as $line)
<tr>
<td>{{ $line->packagingItem?->name ?? '—' }}</td>
<td>{{ $line->quantity_used }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
@endsection