gruene-seele/resources/views/admin/ingredient/form.blade.php
Kevin Adametz fa852340ee Warenwirtschaft: AP-42 — Rohstoff-Dichte (g/ml) für ml-Erfassung im Wareneingang
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>
2026-08-28 09:05:07 +00:00

204 lines
No EOL
12 KiB
PHP
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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') }}">&times;</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') }}">&times;</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>