Kundenentscheid 26.08.: Rohstoffe werden in Gramm geführt, dürfen aber in ml erfasst werden; über die Dichte ergeben sich die Gramm (100 ml Propolistinktur × 0,79 = 79 g). - Neues Feld ingredients.density (g/ml, optional) inkl. Feld im INCI-Formular. - Wareneingang: Einheiten-Umschalter g/ml am Mengenfeld (nur wenn Dichte hinterlegt; Live-Hinweis mit Gramm-Umrechnung, Dichte kommt aus der Rohstoff-Suche mit). Erfassung in ml wird über die Dichte in Gramm umgerechnet und kanonisch als Gramm gespeichert — InventoryService und alle Aggregationen bleiben unverändert. purchase_unit + density_used (Snapshot) protokollieren die ml-Erfassung für Anzeige/Bearbeitung; Detailseite zeigt „790 g (= 1.000 ml)". Wareneingang-Buchung rechnet gelieferte ml ebenfalls um. - Serverseitige Validierung: ml nur mit hinterlegter Dichte. Migrationen add_density_* auf Dev-/Live-DB. 4 Tests, Suite 318 grün. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
204 lines
No EOL
12 KiB
PHP
Executable file
204 lines
No EOL
12 KiB
PHP
Executable file
|
||
<div class="card mb-2">
|
||
|
||
<h5 class="card-header">
|
||
{{ __('Inhaltsstoff') }}
|
||
|
||
</h5>
|
||
|
||
<div class="card-body">
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col">
|
||
<label class="custom-control custom-checkbox float-right">
|
||
{!! Form::checkbox('active', 1, $model->active, ['class'=>'custom-control-input']) !!}
|
||
<span class="custom-control-label">{{__('aktiv')}}</span>
|
||
</label>
|
||
<label class="form-label" for="name">{{ __('Name') }}*</label>
|
||
{{ Form::text('name', $model->name, array('placeholder'=>__('Name'), 'class'=>'form-control', 'id'=>'name', 'required')) }}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-6">
|
||
<label class="form-label" for="alt_name">{{ __('Alternativer Name') }}</label>
|
||
{{ Form::text('alt_name', $model->alt_name, array('placeholder'=>__('z. B. Phospholipon 80 H'), 'class'=>'form-control', 'id'=>'alt_name', 'maxlength'=>255)) }}
|
||
<small class="text-muted">{{ __('Handelsname auf der Packung, damit Mitarbeiter den Rohstoff finden (z. B. LECITHIN → Phospholipon 80 H).') }}</small>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col">
|
||
<label class="form-label" for="headline">{{ __('INCI') }}</label>
|
||
{{ Form::textarea('inci', $model->inci, array('placeholder'=>__('INCI'), 'class'=>'form-control', 'id'=>'inci', 'rows'=>3)) }}
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-group col">
|
||
<label class="form-label" for="headline">{{ __('Wirkung') }}</label>
|
||
{{ Form::textarea('effect', $model->effect, array('placeholder'=>__('Wirkung'), 'class'=>'form-control', 'id'=>'inci', 'rows'=>3)) }}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="material_quality_id">{{ __('Rohstoffqualität') }}</label>
|
||
<select name="material_quality_id" id="material_quality_id" class="form-control">
|
||
<option value="">{{ __('— keine Angabe —') }}</option>
|
||
@foreach(\App\Models\MaterialQuality::orderBy('pos')->orderBy('name')->get() as $quality)
|
||
<option value="{{ $quality->id }}" @selected((string)old('material_quality_id', $model->material_quality_id) === (string)$quality->id)>{{ $quality->name }}</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="tax_rate_id">{{ __('Umsatzsteuer') }}</label>
|
||
<select name="tax_rate_id" id="tax_rate_id" class="form-control">
|
||
<option value="">{{ __('— keine Angabe —') }}</option>
|
||
@foreach($taxRates as $taxRate)
|
||
<option value="{{ $taxRate->id }}" @selected((string)old('tax_rate_id', $model->tax_rate_id) === (string)$taxRate->id)>{{ $taxRate->name }} ({{ formatNumber($taxRate->percent) }} %)</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
@php
|
||
$supplierRows = collect(old(
|
||
'suppliers',
|
||
$model->exists
|
||
? $model->suppliers->map(fn ($s) => ['id' => $s->id, 'url' => $s->pivot->url])->values()->all()
|
||
: [],
|
||
))->values();
|
||
@endphp
|
||
<div class="form-group">
|
||
<label class="form-label">{{ __('Lieferanten') }}</label>
|
||
<div id="supplier-repeater">
|
||
@foreach($supplierRows as $index => $row)
|
||
<div class="form-row supplier-row mb-2">
|
||
<div class="col-sm-5">
|
||
<select name="suppliers[{{ $index }}][id]" class="form-control">
|
||
<option value="">{{ __('— Lieferant wählen —') }}</option>
|
||
@foreach($suppliers as $supplier)
|
||
<option value="{{ $supplier->id }}" @selected((string) ($row['id'] ?? '') === (string) $supplier->id)>{{ $supplier->name }}</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
<div class="col-sm-6">
|
||
<input type="text" name="suppliers[{{ $index }}][url]" class="form-control"
|
||
value="{{ $row['url'] ?? '' }}" maxlength="2048"
|
||
placeholder="{{ __('Shop-URL (leer = Bestellung per Mail)') }}">
|
||
</div>
|
||
<div class="col-sm-1 d-flex align-items-center">
|
||
<button type="button" class="btn btn-sm btn-outline-danger js-remove-supplier-row" title="{{ __('Entfernen') }}">×</button>
|
||
</div>
|
||
</div>
|
||
@endforeach
|
||
</div>
|
||
<button type="button" class="btn btn-sm btn-outline-primary" id="add-supplier-row">+ {{ __('weiteren Lieferanten anlegen') }}</button>
|
||
<small class="text-muted d-block mt-1">{{ __('Bleibt die URL leer, wird bei diesem Lieferanten per Mail bestellt.') }}</small>
|
||
</div>
|
||
|
||
<script type="text/template" id="supplier-row-template">
|
||
<div class="form-row supplier-row mb-2">
|
||
<div class="col-sm-5">
|
||
<select name="suppliers[__INDEX__][id]" class="form-control">
|
||
<option value="">{{ __('— Lieferant wählen —') }}</option>
|
||
@foreach($suppliers as $supplier)
|
||
<option value="{{ $supplier->id }}">{{ $supplier->name }}</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
<div class="col-sm-6">
|
||
<input type="text" name="suppliers[__INDEX__][url]" class="form-control" maxlength="2048"
|
||
placeholder="{{ __('Shop-URL (leer = Bestellung per Mail)') }}">
|
||
</div>
|
||
<div class="col-sm-1 d-flex align-items-center">
|
||
<button type="button" class="btn btn-sm btn-outline-danger js-remove-supplier-row" title="{{ __('Entfernen') }}">×</button>
|
||
</div>
|
||
</div>
|
||
</script>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="storage_room_id">{{ __('Lagerort: Raum') }}</label>
|
||
<select name="storage_room_id" id="storage_room_id" class="form-control">
|
||
<option value="">{{ __('— keine Angabe —') }}</option>
|
||
@foreach($storageRooms as $room)
|
||
<option value="{{ $room->id }}" @selected((string) old('storage_room_id', $model->storage_room_id) === (string) $room->id)>{{ $room->label }}</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="storage_shelf_id">{{ __('Lagerort: Regal') }}</label>
|
||
<select name="storage_shelf_id" id="storage_shelf_id" class="form-control">
|
||
<option value="">{{ __('— keine Angabe —') }}</option>
|
||
@foreach($storageShelves as $shelf)
|
||
<option value="{{ $shelf->id }}" @selected((string) old('storage_shelf_id', $model->storage_shelf_id) === (string) $shelf->id)>{{ $shelf->label }}</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="storage_slot_id">{{ __('Lagerort: Fach / Buchstabe') }}</label>
|
||
<select name="storage_slot_id" id="storage_slot_id" class="form-control">
|
||
<option value="">{{ __('— keine Angabe —') }}</option>
|
||
@foreach($storageSlots as $slot)
|
||
<option value="{{ $slot->id }}" @selected((string) old('storage_slot_id', $model->storage_slot_id) === (string) $slot->id)>{{ $slot->label }}</option>
|
||
@endforeach
|
||
</select>
|
||
<small class="text-muted">{{ __('Bausteine zentral pflegbar unter Einstellungen → Allgemein.') }}</small>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-6">
|
||
<label class="form-label" for="delivery_time">{{ __('Lieferzeit') }}</label>
|
||
<input type="text" name="delivery_time" id="delivery_time" list="ingredient_delivery_time_options"
|
||
class="form-control" value="{{ old('delivery_time', $model->delivery_time) }}"
|
||
placeholder="{{ __('z. B. 3–5 Werktage') }}">
|
||
<datalist id="ingredient_delivery_time_options">
|
||
@foreach($deliveryTimes as $deliveryTime)
|
||
<option value="{{ $deliveryTime->label }}" data-days="{{ $deliveryTime->days }}"></option>
|
||
@endforeach
|
||
</datalist>
|
||
<small class="text-muted">{{ __('Lieferzeit des Rohstoffs (hat Vorrang vor der Lieferanten-Lieferzeit).') }}</small>
|
||
</div>
|
||
<div class="form-group col-sm-2">
|
||
<label class="form-label" for="delivery_time_days">{{ __('Tage') }}</label>
|
||
<input type="number" name="delivery_time_days" id="delivery_time_days" min="0" max="65535"
|
||
class="form-control" value="{{ old('delivery_time_days', $model->delivery_time_days) }}"
|
||
placeholder="{{ __('z. B. 5') }}">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-2">
|
||
<label class="form-label" for="pos">{{ __('pos') }}</label>
|
||
{{ Form::text('pos', $model->pos, array('placeholder'=>__('pos'), 'class'=>'form-control', 'id'=>'pos')) }}
|
||
</div>
|
||
<div class="form-group col-sm-3">
|
||
<label class="form-label" for="default_factor">{{ __('Standard-Schwundfaktor') }}</label>
|
||
{{ Form::text('default_factor', $model->default_factor !== null ? formatNumber($model->default_factor) : formatNumber(1.10), array('placeholder'=>'1,10', 'class'=>'form-control', 'id'=>'default_factor')) }}
|
||
</div>
|
||
<div class="form-group col-sm-3">
|
||
<label class="form-label" for="min_stock_alert">{{ __('Meldebestand (g)') }}</label>
|
||
{{ Form::text('min_stock_alert', $model->min_stock_alert !== null ? formatNumber($model->min_stock_alert) : '', array('placeholder'=>__('optional'), 'class'=>'form-control', 'id'=>'min_stock_alert')) }}
|
||
</div>
|
||
<div class="form-group col-sm-3">
|
||
{{-- AP-42: Dichte g/ml — erlaubt die Erfassung des Wareneingangs in ml (100 ml × 0,79 = 79 g). --}}
|
||
<label class="form-label" for="density">{{ __('Dichte (g/ml)') }}</label>
|
||
{{ Form::text('density', $model->density !== null ? formatNumber($model->density) : '', array('placeholder'=>__('z. B. 0,79 – optional'), 'class'=>'form-control', 'id'=>'density')) }}
|
||
<small class="form-text text-muted">{{ __('Leer = Erfassung in Gramm.') }}</small>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col">
|
||
<label class="custom-control custom-checkbox">
|
||
{!! Form::checkbox('exclude_from_stock', 1, $model->exclude_from_stock, ['class'=>'custom-control-input', 'id'=>'exclude_from_stock']) !!}
|
||
<span class="custom-control-label">{{ __('Kein Rohstoffbestand') }}</span>
|
||
</label>
|
||
<small class="text-muted d-block">{{ __('Für Einträge ohne Bevorratung (z. B. Allergen-Angaben) — erscheint nie im Rohstoffbestand.') }}</small>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div> |