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>
160 lines
7.5 KiB
PHP
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
|