- AP-09 Produktbestand inkl. Bewegungshistorie (product_stock_movements, ProductStockService) - AP-10 Rohstoffbestand-Ansicht je Lager (RawMaterialStockController) - AP-11 Bestandsschwellen / Out-of-Stock-Handling fuer Produkte und Shop - AP-12 Ausgang/Ausschuss (stock_disposals, StockDisposalController, InventoryService) - Set-Produkte (product_set_items) inkl. Aufloesung - Produktentwicklung & Hinweise-Verwaltung (Notices) - AP-13 Entwicklungskonzept Shop-Bestandsabzug im Plan dokumentiert - Feature-Tests fuer neue Module + aktualisierter Entwicklungsplan Co-authored-by: Cursor <cursoragent@cursor.com>
205 lines
11 KiB
PHP
205 lines
11 KiB
PHP
@php
|
|
/** @var \App\Models\StockEntry $model */
|
|
@endphp
|
|
|
|
@extends('layouts.layout-2')
|
|
|
|
@section('content')
|
|
<h4 class="font-weight-bold py-2 mb-2">{{ __('Wareneingang') }}</h4>
|
|
|
|
<div class="card mb-3">
|
|
<h6 class="card-header d-flex justify-content-between align-items-center">
|
|
<span>
|
|
@if($model->status === 'pending')
|
|
<span class="badge badge-warning">{{ __('Offen') }}</span>
|
|
@else
|
|
<span class="badge badge-success">{{ __('Eingegangen') }}</span>
|
|
@endif
|
|
</span>
|
|
<span>
|
|
<a href="{{ route('admin.inventory.stock-entries.index') }}" class="btn btn-sm btn-outline-secondary">{{ __('Zurück zur Liste') }}</a>
|
|
@if(Auth::user()->isAdmin())
|
|
<a href="{{ route('admin.inventory.stock-entries.copy', $model) }}" class="btn btn-sm btn-outline-info">{{ __('Duplizieren') }}</a>
|
|
@endif
|
|
@if(Auth::user()->isAdmin() && $model->isPending())
|
|
<a href="{{ route('admin.inventory.stock-entries.edit', $model) }}" class="btn btn-sm btn-primary">{{ __('Bearbeiten') }}</a>
|
|
@endif
|
|
</span>
|
|
</h6>
|
|
<div class="card-body">
|
|
<dl class="row mb-0">
|
|
<dt class="col-sm-3">{{ __('Art') }}</dt>
|
|
<dd class="col-sm-9">{{ $entryTypeLabels[$model->entry_type] ?? $model->entry_type }}</dd>
|
|
|
|
<dt class="col-sm-3">{{ __('Artikel') }}</dt>
|
|
<dd class="col-sm-9">
|
|
@if($model->entry_type === 'ingredient' && $model->ingredient)
|
|
{{ $model->ingredient->name }}@if($model->ingredient->inci) ({{ $model->ingredient->inci }})@endif
|
|
@elseif($model->packagingItem)
|
|
{{ $model->packagingItem->name }}
|
|
@if($model->packagingItem->packagingMaterial)
|
|
<span class="text-muted">— {{ $model->packagingItem->packagingMaterial->name }}</span>
|
|
@endif
|
|
@else
|
|
—
|
|
@endif
|
|
</dd>
|
|
|
|
@if($model->entry_type === 'ingredient' && $model->quality)
|
|
<dt class="col-sm-3">{{ __('Rohstoffqualität') }}</dt>
|
|
<dd class="col-sm-9">{{ $model->quality->name }}</dd>
|
|
@endif
|
|
|
|
<dt class="col-sm-3">{{ __('Lieferant') }}</dt>
|
|
<dd class="col-sm-9">{{ $model->supplier?->name ?? '—' }}</dd>
|
|
|
|
<dt class="col-sm-3">{{ __('Lagerort') }}</dt>
|
|
<dd class="col-sm-9">{{ $model->location?->name ?? '—' }}</dd>
|
|
|
|
<dt class="col-sm-3">{{ __('Bestelldatum') }}</dt>
|
|
<dd class="col-sm-9">{{ $model->ordered_at?->format('d.m.Y') }}</dd>
|
|
|
|
<dt class="col-sm-3">{{ __('Bestellte Menge') }}</dt>
|
|
<dd class="col-sm-9">
|
|
@if($model->unit === 'gram')
|
|
{{ \App\Services\Util::formatNumber($model->ordered_quantity) }} g
|
|
@else
|
|
{{ \App\Services\Util::formatNumber($model->ordered_quantity, 0) }} {{ __('Stk.') }}
|
|
@endif
|
|
</dd>
|
|
|
|
@if(Auth::user()->isAdmin())
|
|
<dt class="col-sm-3">{{ __('Preise (Stufe 1)') }}</dt>
|
|
<dd class="col-sm-9">
|
|
@if($model->entry_type === 'ingredient')
|
|
@if($model->price_per_kg !== null)
|
|
{{ \App\Services\Util::formatNumber($model->price_per_kg) }} € / kg {{ __('netto') }}
|
|
@else
|
|
—
|
|
@endif
|
|
@if($model->price_per_kg_gross !== null)
|
|
<span class="text-muted">· {{ \App\Services\Util::formatNumber($model->price_per_kg_gross) }} € / kg {{ __('brutto') }}</span>
|
|
@endif
|
|
@if($model->tax_rate_percent !== null)
|
|
<span class="text-muted">· {{ __('USt.') }} {{ \App\Services\Util::formatNumber($model->tax_rate_percent) }} %</span>
|
|
@endif
|
|
@else
|
|
@if($model->price_total !== null)
|
|
{{ \App\Services\Util::formatNumber($model->price_total) }} € {{ __('netto') }}
|
|
@else
|
|
—
|
|
@endif
|
|
@endif
|
|
</dd>
|
|
@endif
|
|
|
|
<dt class="col-sm-3">{{ __('Bestellt von') }}</dt>
|
|
<dd class="col-sm-9">{{ $model->orderedByUser?->getFullName(false) ?: $model->orderedByUser?->email ?? '—' }}</dd>
|
|
|
|
@if($model->isReceived())
|
|
<dt class="col-sm-3">{{ __('Eingangsdatum') }}</dt>
|
|
<dd class="col-sm-9">{{ $model->received_at?->format('d.m.Y') }}</dd>
|
|
|
|
<dt class="col-sm-3">{{ __('Eingegangene Menge') }}</dt>
|
|
<dd class="col-sm-9">
|
|
@if($model->unit === 'gram')
|
|
{{ \App\Services\Util::formatNumber($model->received_quantity) }} g
|
|
@else
|
|
{{ \App\Services\Util::formatNumber($model->received_quantity, 0) }} {{ __('Stk.') }}
|
|
@endif
|
|
</dd>
|
|
|
|
@if($model->entry_type === 'ingredient')
|
|
<dt class="col-sm-3">{{ __('Charge') }}</dt>
|
|
<dd class="col-sm-9">{{ $model->batch_number ?: '—' }}</dd>
|
|
|
|
<dt class="col-sm-3">{{ __('Mindesthaltbarkeit') }}</dt>
|
|
<dd class="col-sm-9">{{ $model->best_before?->format('d.m.Y') ?? '—' }}</dd>
|
|
|
|
<dt class="col-sm-3">{{ __('Materialqualität') }}</dt>
|
|
<dd class="col-sm-9">{{ $model->quality?->name ?? '—' }}</dd>
|
|
@endif
|
|
|
|
<dt class="col-sm-3">{{ __('Eingebucht von') }}</dt>
|
|
<dd class="col-sm-9">{{ $model->receivedByUser?->getFullName(false) ?: $model->receivedByUser?->email ?? '—' }}</dd>
|
|
@endif
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
|
|
@if($model->isPending())
|
|
<div class="card">
|
|
<h6 class="card-header">{{ __('Wareneingang buchen (Stufe 2)') }}</h6>
|
|
<div class="card-body">
|
|
<form method="post" action="{{ route('admin.inventory.stock-entries.receive', $model) }}">
|
|
@csrf
|
|
@method('PUT')
|
|
|
|
<div class="form-group">
|
|
<label for="received_at">{{ __('Eingangsdatum') }} <span class="text-danger">*</span></label>
|
|
<input type="text" name="received_at" id="received_at" required autocomplete="off"
|
|
class="form-control datepicker-base @error('received_at') is-invalid @enderror"
|
|
value="{{ old('received_at', now()->format('d.m.Y')) }}">
|
|
@error('received_at')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="received_quantity">{{ __('Eingegangene Menge') }} <span class="text-danger">*</span></label>
|
|
<input type="text" name="received_quantity" id="received_quantity" required
|
|
class="form-control @error('received_quantity') is-invalid @enderror"
|
|
value="{{ old('received_quantity', \App\Services\Util::formatNumber($model->ordered_quantity)) }}">
|
|
<small class="text-muted">
|
|
@if($model->unit === 'gram')
|
|
{{ __('Angabe in Gramm') }}
|
|
@else
|
|
{{ __('Angabe in Stück') }}
|
|
@endif
|
|
</small>
|
|
@error('received_quantity')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
|
|
@if($model->entry_type === 'ingredient')
|
|
<div class="form-group">
|
|
<label for="batch_number">{{ __('Chargennummer') }} <span class="text-danger">*</span></label>
|
|
<input type="text" name="batch_number" id="batch_number" maxlength="100"
|
|
class="form-control @error('batch_number') is-invalid @enderror"
|
|
value="{{ old('batch_number') }}">
|
|
@error('batch_number')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="best_before">{{ __('Mindesthaltbarkeit') }} <span class="text-danger">*</span></label>
|
|
<input type="text" name="best_before" id="best_before" autocomplete="off"
|
|
class="form-control datepicker-base @error('best_before') is-invalid @enderror"
|
|
value="{{ old('best_before') }}">
|
|
@error('best_before')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="quality_id">{{ __('Rohstoffqualität') }} <span class="text-danger">*</span></label>
|
|
<select name="quality_id" id="quality_id" class="form-control @error('quality_id') is-invalid @enderror">
|
|
<option value="">{{ __('Bitte wählen') }}</option>
|
|
@foreach($materialQualities as $mq)
|
|
<option value="{{ $mq->id }}" @selected((string)old('quality_id', $model->quality_id) === (string)$mq->id)>{{ $mq->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
@error('quality_id')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
@endif
|
|
|
|
<button type="submit" class="btn btn-primary">{{ __('Als eingegangen buchen') }}</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
@endsection
|