Neue Anforderungen (docs/) interpretiert und als Entwicklungsplan V5.0 (AP-20 bis AP-28) aufgenommen; erste drei Pakete umgesetzt: AP-26 Ausschuss-Gründe konfigurierbar: - Stammdaten-Tabelle disposal_reasons + CRUD unter Einstellungen → Allgemein - StockDisposalController liest aktive DB-Gründe statt hartkodierter Liste - Seeder übernimmt die bisherigen 6 Gründe idempotent AP-25 Lieferbestand — Datum statt Tage: - "Nicht vorrätig" wird über Datepicker "Wieder lieferbar ab" gepflegt; Resttage-Hinweis zählt täglich automatisch herunter - Interne Bestellliste wieder kaufbar: Hinweis erscheint zusätzlich zu den Mengen-Buttons (VP entscheidet selbst) AP-22 Produktbestand-Erweiterungen: - Default-Sortierung nach Dringlichkeit, Status-Kopf toggelt - Alle vier Status-Kacheln als Filter klickbar - Neue Spalte "Verbrauch/Monat" (Ø Abgänge der letzten 6 Monate) - Produkt-Flag "Im Produktbestand anzeigen" (products.show_in_product_stock) Tests: 77 grün (DisposalReasonSettings 8, ProductOutOfStock 8, ProductStock 13 + Regression). Hinweise-Doku + Plan-Protokoll fortgeschrieben; nächster Schritt laut Plan: AP-21 (INCI-Erweiterungen). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1118 lines
67 KiB
PHP
Executable file
1118 lines
67 KiB
PHP
Executable file
<style>
|
||
html { scroll-behavior: smooth; }
|
||
[id^="product-section-"] { scroll-margin-top: 4.5rem; }
|
||
</style>
|
||
<nav class="navbar navbar-light bg-lighter border rounded mb-3 py-2 px-3 flex-wrap align-items-center"
|
||
id="product-form-section-nav" aria-label="{{ __('Sprungmarken Produktformular') }}">
|
||
<span class="navbar-text small font-weight-bold text-muted mr-2 mb-1">{{ __('Bereiche') }}:</span>
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1" href="#product-section-produkt">{{ __('Produkt') }}</a>
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1" href="#product-section-verfuegbarkeit">{{ __('Verfügbarkeit') }}</a>
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1" href="#product-section-set">{{ __('Set') }}</a>
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1" href="#product-section-preise">{{ __('Preise in EUR') }}</a>
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1" href="#product-section-laenderpreise">{{ __('Landesspezifische Preise') }}</a>
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1" href="#product-section-whitelabel">{{ __('White-Label') }}</a>
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1" href="#product-section-details">{{ __('Details') }}</a>
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1 js-nav-recipe" href="#product-section-rezeptur">{{ __('Inhaltsstoffe') }} / {{ __('Rezeptur') }}</a>
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1 js-nav-recipe" href="#product-section-herstellerrezeptur">{{ __('Hersteller Rezeptur') }}</a>
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1 js-nav-recipe" href="#product-section-verpackung">{{ __('Verpackung') }}</a>
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1 js-nav-recipe" href="#product-section-warenwirtschaft">{{ __('Warenwirtschaft') }}</a>
|
||
@if (Auth::user()->isSySAdmin())
|
||
<a class="btn btn-sm btn-outline-secondary mb-1 mr-1" href="#product-section-sysadmin">{{ __('SySAdmin Einstellungen') }}</a>
|
||
@endif
|
||
</nav>
|
||
|
||
<div class="card mb-2" id="product-section-produkt">
|
||
|
||
<h5 class="card-header">
|
||
{{ __('Produkt') }}
|
||
|
||
</h5>
|
||
|
||
<div class="card-body">
|
||
|
||
<div class="form-group">
|
||
<label class="custom-control custom-checkbox float-right">
|
||
{!! Form::checkbox('active', 1, $product->active, ['class' => 'custom-control-input']) !!}
|
||
<span class="custom-control-label">{{ __('aktiv') }}</span>
|
||
</label>
|
||
<label class="form-label" for="name">{{ __('Produktname / Titel') }}*</label>
|
||
{{ Form::text('name', $product->name, ['placeholder' => __('Name'), 'class' => 'form-control', 'id' => 'name', 'required']) }}
|
||
</div>
|
||
{{-- <div class="form-row">
|
||
<div class="form-group col-sm-5">
|
||
<label class="form-label" for="show_at">{{ __('Produkt anzeigen') }}</label>
|
||
{{ Form::select('show_at', \App\Services\Type::$showATs, $product->show_at, array('data-live-search'=>'false', 'class'=>'selectpicker', 'id'=>'show_at') ) }}
|
||
</div>
|
||
</div>
|
||
--}}
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-10">
|
||
<label class="form-label" for="title">{{ __('Kategorie (Mehrfachauswahl)') }}*</label>
|
||
<select class="selectpicker" name="categories[]" id="categories" data-style="btn-light"
|
||
data-live-search="false" multiple required>
|
||
{!! HTMLHelper::getCategoriesOptions($product->categories()->pluck('category_id')->toArray(), false) !!}
|
||
</select>
|
||
</div>
|
||
<div class="form-group col-sm-2">
|
||
<label class="form-label" for="pos">{{ __('Listenposition') }}</label>
|
||
{{ Form::text('pos', $product->pos, ['placeholder' => __('1, 2, 3, etc'), 'class' => 'form-control', 'id' => 'pos']) }}
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-group col-md-10">
|
||
<label class="form-label" for="show_on">{{ __('Produkt anzeigen (Mehrfachauswahl)') }}</label>
|
||
{{ Form::select('show_on[]', \App\Services\Type::$showONs, $product->show_on, ['data-live-search' => 'false', 'class' => 'selectpicker', 'id' => 'show_on', 'multiple']) }}
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label" for="copy">{{ __('Produktbeschreibung') }}</label>
|
||
{{ Form::textarea('copy', $product->copy, ['placeholder' => __('Produktbeschreibung'), 'class' => 'form-control summernote', 'id' => 'copy']) }}
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label" for="short_copy">{{ __('Kurzbeschreibung Microsite') }}</label>
|
||
{{ Form::textarea('short_copy', $product->short_copy, ['placeholder' => __('Kurzbeschreibung'), 'class' => 'form-control summernote', 'id' => 'short_copy']) }}
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-6">
|
||
<label class="custom-control custom-checkbox mt-2">
|
||
{!! Form::checkbox('shipping_addon', 1, $product->shipping_addon, ['class' => 'custom-control-input']) !!}
|
||
<span class="custom-control-label">Kompensationprodukt beim Versand für Berater</span>
|
||
</label>
|
||
<label class="custom-control custom-checkbox mt-2">
|
||
{!! Form::checkbox('max_buy', 1, $product->max_buy, ['class' => 'custom-control-input']) !!}
|
||
<span class="custom-control-label">Maximaler Kauf für einen Berater für dieses Produkt</span>
|
||
</label>
|
||
</div>
|
||
<div class="form-group col-sm-6">
|
||
<label class="form-label" for="max_buy_num">{{ __('Anzahl maximaler Kauf pro Berater') }}</label>
|
||
{{ Form::text('max_buy_num', $product->max_buy_num, ['placeholder' => __('in Stück'), 'class' => 'form-control', 'id' => 'max_buy_num']) }}
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<hr>
|
||
<button type="submit" class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-2" id="product-section-verfuegbarkeit">
|
||
<h5 class="card-header">{{ __('Verfügbarkeit') }}</h5>
|
||
<div class="card-body">
|
||
@php($outOfStockActive = $product->out_of_stock_until !== null && $product->out_of_stock_until->endOfDay()->isFuture())
|
||
<div class="form-group">
|
||
<label class="custom-control custom-checkbox">
|
||
{!! Form::checkbox('out_of_stock_active', 1, old('out_of_stock_active', $outOfStockActive), ['class' => 'custom-control-input', 'id' => 'out_of_stock_active']) !!}
|
||
<span class="custom-control-label">{{ __('Vorübergehend nicht vorrätig (mit Datum)') }}</span>
|
||
</label>
|
||
<p class="text-muted small mb-0">{{ __('Zeigt im Shop den Hinweis „In ca. X Tagen wieder da!" – die Tage zählen täglich automatisch herunter. Der Kauf bleibt weiterhin möglich.') }}</p>
|
||
</div>
|
||
<div class="form-row js-out-of-stock-date" style="display:none;">
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="out_of_stock_date">{{ __('Wieder lieferbar ab') }}</label>
|
||
{{ Form::text('out_of_stock_date', old('out_of_stock_date', optional($product->out_of_stock_until)->format('d.m.Y')), ['placeholder' => __('tt.mm.jjjj'), 'class' => 'form-control datepicker-base', 'id' => 'out_of_stock_date', 'autocomplete' => 'off']) }}
|
||
</div>
|
||
</div>
|
||
|
||
<hr>
|
||
|
||
<div class="form-group">
|
||
<label class="custom-control custom-checkbox">
|
||
{!! Form::checkbox('out_of_stock_indefinite', 1, old('out_of_stock_indefinite', $product->out_of_stock_indefinite), ['class' => 'custom-control-input', 'id' => 'out_of_stock_indefinite']) !!}
|
||
<span class="custom-control-label">{{ __('Auf unbestimmte Zeit nicht vorrätig') }}</span>
|
||
</label>
|
||
<p class="text-muted small mb-0">{{ __('Daueranzeige ohne Zeitangabe (hat Vorrang vor der Tagesangabe). Der Kauf bleibt weiterhin möglich.') }}</p>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<hr>
|
||
<button type="submit" class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-2" id="product-section-set">
|
||
<h5 class="card-header">{{ __('Set / Produktart') }}</h5>
|
||
<div class="card-body">
|
||
<div class="form-group">
|
||
<label class="custom-control custom-checkbox">
|
||
{!! Form::checkbox('is_set', 1, old('is_set', $product->is_set), ['class' => 'custom-control-input', 'id' => 'is_set']) !!}
|
||
<span class="custom-control-label">{{ __('Dieses Produkt ist ein Set (Bündel mehrerer Einzelprodukte)') }}</span>
|
||
</label>
|
||
<p class="text-muted small mb-0">{{ __('Bei aktivem Set werden Rezeptur, Verpackung und Warenwirtschaft ausgeblendet. Ein Set wird nicht produziert; beim Verkauf werden später die enthaltenen Einzelprodukte abgebucht.') }}</p>
|
||
</div>
|
||
|
||
<div class="js-set-fields" style="display:none;">
|
||
<p class="text-muted small mb-2">{{ __('Set-Bestandteile (nur Einzelprodukte). Reihenfolge per Drag & Drop ändern, danach speichern.') }}</p>
|
||
<div class="table-responsive">
|
||
<table class="table table-striped table-bordered mb-3">
|
||
<thead>
|
||
<tr>
|
||
<th style="width:2rem"></th>
|
||
<th>{{ __('Name') }}</th>
|
||
<th>{{ __('Artikelnr.') }}</th>
|
||
<th class="text-right" style="width:8rem">{{ __('Gewicht') }}</th>
|
||
<th class="text-right" style="width:10rem">{{ __('Preis VK in EUR (Brutto)') }}</th>
|
||
<th style="width:8rem">{{ __('Menge') }}</th>
|
||
<th style="width:3rem"></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="set-sortable-rows">
|
||
@foreach ($product->setItems as $component)
|
||
<tr data-set-product-id="{{ $component->id }}">
|
||
<td class="text-muted align-middle set-drag-handle" style="cursor:grab"
|
||
title="{{ __('Verschieben') }}">☰</td>
|
||
<td class="align-middle">{{ $component->name }}</td>
|
||
<td class="align-middle small text-muted">{{ $component->number ?? '—' }}</td>
|
||
<td class="align-middle text-right small text-muted">{{ $component->weight ? $component->weight . ' g' : '—' }}</td>
|
||
<td class="align-middle text-right small text-muted">{{ $component->getFormattedPrice() !== '' ? $component->getFormattedPrice() . ' €' : '—' }}</td>
|
||
<td>
|
||
<input type="hidden" name="set_component_id[]" value="{{ $component->id }}">
|
||
<input type="number" min="1" step="1" name="set_quantity[]"
|
||
class="form-control form-control-sm set-quantity"
|
||
value="{{ (int) ($component->pivot->quantity ?? 1) }}" autocomplete="off">
|
||
</td>
|
||
<td class="align-middle">
|
||
<a class="text-danger set-row-remove" href="#"
|
||
title="{{ __('Entfernen') }}"><i class="far fa-trash-alt"></i></a>
|
||
</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div class="form-group">
|
||
<button type="button" class="btn btn-default" data-toggle="modal"
|
||
data-target="#modal-set-pick">{{ __('Einzelprodukte hinzufügen') }}</button>
|
||
</div>
|
||
|
||
<div class="modal fade" id="modal-set-pick" tabindex="-1" role="dialog"
|
||
aria-labelledby="modal-set-pick-title" aria-hidden="true">
|
||
<div class="modal-dialog modal-lg" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="modal-set-pick-title">{{ __('Einzelprodukte auswählen') }}</h5>
|
||
<button type="button" class="close" data-dismiss="modal"
|
||
aria-label="{{ __('Schließen') }}">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group mb-2">
|
||
<input type="search" id="set-modal-search" class="form-control" autocomplete="off"
|
||
placeholder="{{ __('Name oder Artikelnr. filtern …') }}"
|
||
aria-label="{{ __('Name oder Artikelnr. filtern …') }}">
|
||
</div>
|
||
<p class="small text-muted mb-2 d-none" id="set-modal-no-results">{{ __('Keine Treffer.') }}
|
||
</p>
|
||
<div class="table-responsive border rounded"
|
||
style="max-height: min(60vh, 480px); overflow-y: auto;">
|
||
<table class="table table-sm table-striped mb-0">
|
||
<thead class="thead-light sticky-top">
|
||
<tr style="background-color: #f8f9fa;">
|
||
<th style="width:2.5rem"></th>
|
||
<th>{{ __('Name') }}</th>
|
||
<th>{{ __('Artikelnr.') }}</th>
|
||
<th class="text-right">{{ __('Gewicht') }}</th>
|
||
<th class="text-right">{{ __('Preis VK in EUR (Brutto)') }}</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="set-modal-tbody">
|
||
@foreach ($set_product_catalog as $sp)
|
||
<tr class="set-modal-row" data-set-product-id="{{ $sp->id }}"
|
||
data-set-search="{{ e(mb_strtolower(trim(($sp->name ?? '') . ' ' . ($sp->number ?? '')), 'UTF-8')) }}">
|
||
<td class="align-middle">
|
||
<label class="custom-control custom-checkbox mb-0">
|
||
<input type="checkbox" class="custom-control-input js-set-modal-cb"
|
||
value="{{ $sp->id }}"
|
||
@if ($product->setItems->contains('id', $sp->id)) disabled @endif>
|
||
<span class="custom-control-label"></span>
|
||
</label>
|
||
</td>
|
||
<td class="align-middle js-set-modal-name">{{ $sp->name }}</td>
|
||
<td class="align-middle small text-muted js-set-modal-number">{{ $sp->number ?? '—' }}</td>
|
||
<td class="align-middle small text-muted text-right">{{ $sp->weight ? $sp->weight . ' g' : '—' }}</td>
|
||
<td class="align-middle small text-muted text-right">{{ $sp->getFormattedPrice() !== '' ? $sp->getFormattedPrice() . ' €' : '—' }}</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-default"
|
||
data-dismiss="modal">{{ __('Abbrechen') }}</button>
|
||
<button type="button" class="btn btn-primary"
|
||
id="btn-set-modal-add">{{ __('Hinzufügen') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<hr>
|
||
<button type="submit" class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-2" id="product-section-preise">
|
||
<h5 class="card-header">
|
||
{{ __('Preise in EUR') }}
|
||
</h5>
|
||
<div class="card-body">
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="price">{{ __('Preis VK in EUR (Brutto)') }}</label>
|
||
{{ Form::text('price', $product->getFormattedPrice(), ['placeholder' => __('Preis VK in EUR (Brutto)'), 'class' => 'form-control', 'id' => 'price']) }}
|
||
|
||
</div>
|
||
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="tax">{{ __('MwSt in %') }}</label>
|
||
{{ Form::text('tax', $product->getFormattedTax(), ['placeholder' => __('MwSt in %'), 'class' => 'form-control', 'id' => 'tax']) }}
|
||
|
||
</div>
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="price_old">{{ __('Streichpreis in EUR (wenn > 0)') }}</label>
|
||
{{ Form::text('price_old', $product->getFormattedPriceOld(), ['placeholder' => __('Streichpreis'), 'class' => 'form-control', 'id' => 'price_old']) }}
|
||
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="weight">{{ __('Gewicht in g') }}</label>
|
||
{{ Form::text('weight', $product->weight, ['placeholder' => __('Gewicht in g'), 'class' => 'form-control', 'id' => 'weight']) }}
|
||
</div>
|
||
{{-- <div class="form-group col-sm-4">
|
||
<label class="form-label" for="points">{{ __('Points pro Produkt') }}</label>
|
||
{{ Form::text('points', $product->points, array('placeholder'=>__('Points pro Produkt'), 'class'=>'form-control', 'id'=>'points')) }}
|
||
</div>
|
||
--}}
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="amount">{{ __('Anzahl/Verfügbarkeit') }}</label>
|
||
{{ Form::text('amount', $product->amount, ['placeholder' => __('Anzahl/Verfügbarkeit'), 'class' => 'form-control', 'id' => 'amount']) }}
|
||
</div>
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="price_ek">{{ __('Preis EK in EUR') }}</label>
|
||
{{ Form::text('price_ek', $product->getFormattedPriceEk(), ['placeholder' => __('Preis EK in EUR'), 'class' => 'form-control', 'id' => 'price_ek']) }}
|
||
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="weight">{{ __('Keine Staffelprovision') }}</label>
|
||
|
||
<label class="custom-control custom-checkbox mt-2">
|
||
{!! Form::checkbox('single_commission', 1, $product->single_commission, ['class' => 'custom-control-input']) !!}
|
||
<span class="custom-control-label">Einzelrabatt für dieses Produkt</span>
|
||
</label>
|
||
<label class="custom-control custom-checkbox mt-2">
|
||
{!! Form::checkbox('amount_commission', 1, $product->amount_commission, ['class' => 'custom-control-input']) !!}
|
||
<span class="custom-control-label">Betrag zum Staffelumsatz addieren</span>
|
||
</label>
|
||
<label class="custom-control custom-checkbox mt-2">
|
||
{!! Form::checkbox('exclude_stats_sales', 1, $product->exclude_stats_sales, ['class' => 'custom-control-input']) !!}
|
||
<span class="custom-control-label">Produkt beim der Auswertung Absatzmengen ausschließen</span>
|
||
</label>
|
||
</div>
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="value_commission">{{ __('Einzelrabatt in %') }}</label>
|
||
{{ Form::text('value_commission', $product->getFormattedValueCommission(), ['placeholder' => __('Einzelrabatt in %'), 'class' => 'form-control', 'id' => 'value_commission']) }}
|
||
</div>
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label"
|
||
for="partner_commission">{{ __('Vertriebspartner Einzelrabatt in %') }}</label>
|
||
{{ Form::text('partner_commission', $product->getFormattedPartnerCommission(), ['placeholder' => __('Vertriebspartner Einzelrabatt in %'), 'class' => 'form-control', 'id' => 'partner_commission']) }}
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<hr>
|
||
<button type="submit" class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-2" id="product-section-laenderpreise">
|
||
<h5 class="card-header">
|
||
Landesspezifische Preise
|
||
</h5>
|
||
|
||
<div class="card-body pt-0">
|
||
@foreach ($country_for_prices as $country)
|
||
{{ Form::hidden('country_prices[]', $country->id) }}
|
||
<div class="card-header bg-light pb-0 mt-3">
|
||
<h6>{{ $country->de }}</h6>
|
||
</div>
|
||
<div class="bg-lighter p-2">
|
||
@if ($country->own_eur)
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-4 col-md-3">
|
||
<label class="form-label">Land hat eigenen EURO Preis</label>
|
||
<p></p>
|
||
</div>
|
||
<div class="form-group col-sm-4 col-md-3">
|
||
<label class="form-label" for="price">{{ __('Preis VK in EUR Brutto') }}</label>
|
||
{{ Form::text('c_price[' . $country->id . ']', formatNumber($product->getCPrice($country->id)), ['placeholder' => __('Preis VK in EUR Brutto'), 'class' => 'form-control', 'id' => 'c_price_' . $country->id]) }}
|
||
|
||
</div>
|
||
<div class="form-group col-sm-4 col-md-3">
|
||
<label class="form-label" for="tax">{{ __('MwSt in %') }}</label>
|
||
{{ Form::text('c_tax[' . $country->id . ']', formatNumber($product->getCTax($country->id)), ['placeholder' => __('MwSt in %'), 'class' => 'form-control', 'id' => 'c_tax' . $country->id]) }}
|
||
|
||
</div>
|
||
<div class="form-group col-sm-4 col-md-3">
|
||
<label class="form-label" for="price_old">{{ __('Streichpreis (wenn > 0)') }}</label>
|
||
{{ Form::text('c_price_old[' . $country->id . ']', formatNumber($product->getCPriceOld($country->id)), ['placeholder' => __('Streichpreis'), 'class' => 'form-control', 'id' => 'c_price_old' . $country->id]) }}
|
||
|
||
</div>
|
||
</div>
|
||
@endif
|
||
@if ($country->currency)
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-4 col-md-3">
|
||
<label class="form-label">Land hat eigene Währung</label>
|
||
<p>
|
||
@if ($country->currency_calc)
|
||
Preis Berechnung automatisch
|
||
@else
|
||
Preis manuell
|
||
angegeben
|
||
@endif
|
||
</p>
|
||
</div>
|
||
|
||
@if ($country->currency_calc)
|
||
{{--
|
||
NUR Anzeige vom automatisch berechneten Preis currency_faktor
|
||
Auf Basis vom price
|
||
Wenn own_eur auf basis vom own_eur price
|
||
--}}
|
||
<div class="form-group col-sm-4 col-md-3">
|
||
<label class="form-label">Preis VK in {{ $country->currency_unit }}</label>
|
||
{{ Form::text('c_currency[' . $country->id . ']', formatNumber($product->getRealPrice($country) * $country->currency_faktor), ['class' => 'form-control', 'readonly']) }}
|
||
</div>
|
||
@else
|
||
{{--
|
||
Eingabe
|
||
Währungs Namen aus currency_name
|
||
currency_faktor als Hinweis ausgeben
|
||
Auf Basis vom price
|
||
Wenn own_eur auf basis vom own_eur price
|
||
--}}
|
||
<div class="form-group col-sm-4 col-md-3">
|
||
<label class="form-label">{{ __('Preis VK in ') }} {{ $country->currency_unit }}
|
||
({{ formatNumber($product->getRealPrice($country) * $country->currency_faktor) }})</label>
|
||
{{ Form::text('c_currency[' . $country->id . ']', formatNumber($product->getCCurrency($country->id)), ['placeholder' => __('Preis VK in ') . $country->currency_unit, 'class' => 'form-control']) }}
|
||
</div>
|
||
@endif
|
||
|
||
<div class="form-group col-sm-4 col-md-2">
|
||
<label class="form-label">{{ __('Währungs Faktor') }}</label>
|
||
{{ Form::text('currency_faktor[' . $country->id . ']', formatNumber($country->currency_faktor, 4), ['class' => 'form-control', 'readonly']) }}
|
||
</div>
|
||
<div class="form-group col-sm-4 col-md-2">
|
||
<label class="form-label">{{ __('Preis VK in EUR ') }}</label>
|
||
{{ Form::text('preis_eur[' . $country->id . ']', formatNumber($product->getRealPrice($country)), ['class' => 'form-control', 'readonly']) }}
|
||
</div>
|
||
<div class="form-group col-sm-4 col-md-2">
|
||
<label class="form-label">{{ __('Währung') }}</label>
|
||
{{ Form::text('currency_unit[' . $country->id . ']', $country->currency_unit, ['class' => 'form-control', 'readonly']) }}
|
||
</div>
|
||
|
||
</div>
|
||
@endif
|
||
</div>
|
||
@endforeach
|
||
<em class="float-right text-muted small">für die Einstellung von landesspezifischen Preisen müssen diese unter
|
||
<a href="{{ route('admin_countries') }}">Länder</a> -> Land aktiviert werden.</em>
|
||
|
||
<div class="form-group">
|
||
<hr>
|
||
<button type="submit" class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-2" id="product-section-whitelabel">
|
||
<h5 class="card-header">
|
||
{{ __('White-Label') }}
|
||
</h5>
|
||
<div class="card-body">
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<label class="custom-control custom-checkbox mt-2">
|
||
{!! Form::checkbox('whitelabel', 1, $product->whitelabel, ['class' => 'custom-control-input']) !!}
|
||
<span class="custom-control-label">White-Label Produkt</span>
|
||
</label>
|
||
</div>
|
||
<div class="form-group col-md-6">
|
||
<label class="form-label" for="whitelabel_name">{{ __('White-Label Bezeichnung') }}</label>
|
||
{{ Form::text('whitelabel_name', $product->whitelabel_name, ['placeholder' => __('Bezeichnung'), 'class' => 'form-control', 'id' => 'whitelabel_name']) }}
|
||
</div>
|
||
<div class="form-group col-md-6">
|
||
<label class="form-label" for="whitelabel_variants">Mögliche Varianten (<a
|
||
href="{{ route('admin_product_attributes') }}">Anlage unter Attribute</a>)</label>
|
||
<select class="selectpicker" name="whitelabel_variants[]" id="whitelabel_variants"
|
||
data-style="btn-light" data-live-search="true" multiple>
|
||
{!! HTMLHelper::getAttributesOptions($product->attribute_variants()->pluck('attribute_id')->toArray(), false, 1) !!}
|
||
</select>
|
||
<div class="mt-2">
|
||
<em>Die nur die möglichen Varianten die ausgewählt sind, können einzelnen VP und Etiketten
|
||
zugeordnet werden.</em>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
|
||
@foreach ($product->whitelabel_images as $image)
|
||
<div class="col-md-12">
|
||
<hr>
|
||
</div>
|
||
<div class="col-md-3 col-lg-2">
|
||
<img class="img-fluid" alt="" style="max-height: 200px"
|
||
src="{{ route('product_image', [$image->slug]) }}">
|
||
</div>
|
||
<div class="col-md-9 col-lg-10">
|
||
<label class="form-label" for="image_wl_attributes_{{ $image->id }}">für
|
||
{{ __('Varianten') }}</label>
|
||
<select class="selectpicker" name="image_wl_attributes[{{ $image->id }}][]"
|
||
id="image_wl_attributes_{{ $image->id }}" data-style="btn-light" data-live-search="true"
|
||
multiple>
|
||
{!! HTMLHelper::getProductAttributesOptions($product->attribute_variants, $image->attributes, false, 1) !!}
|
||
</select>
|
||
<a href="{{ route('admin_product_image_delete', [$image->id, $product->id]) }}"
|
||
class="btn btn-sm btn-danger mt-2 mb-2"
|
||
onclick="return confirm('Etikett wirklich löschen?');">Etikett löschen</a>
|
||
</div>
|
||
@endforeach
|
||
|
||
<div class="form-group col-md-12">
|
||
<hr>
|
||
<button type="button" class="btn btn-sm btn-primary" data-toggle="modal"
|
||
data-target="#modals-upload-white-label"
|
||
data-id="new">{{ __('White Label Default Etikett hochladen') }}</button>
|
||
|
||
<button type="submit" class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-2" id="product-section-details">
|
||
<h5 class="card-header">
|
||
{{ __('Details') }}
|
||
</h5>
|
||
<div class="card-body">
|
||
<div class="form-row">
|
||
|
||
<div class="form-group col-sm-5">
|
||
<label class="form-label" for="contents">{{ __('Menge Inhalt (ml / g) als Text') }}</label>
|
||
{{ Form::text('contents', $product->contents, ['placeholder' => __('Bsp: 150 ml'), 'class' => 'form-control', 'id' => 'contents']) }}
|
||
</div>
|
||
<div class="form-group col-sm-3">
|
||
<label class="form-label" for="contents_total">{{ __('Gesamter Inhalt (ml / g) als Zahl') }}</label>
|
||
{{ Form::text('contents_total', $product->contents_total, ['placeholder' => __('Bsp: 150'), 'class' => 'form-control', 'id' => 'contents_total']) }}
|
||
</div>
|
||
<div class="form-group col-sm-2">
|
||
<label class="form-label" for="contents">{{ __('Grundpreis Einheit') }}</label>
|
||
{{ Form::select('unit', $product->unitTypes, $product->unit, ['data-live-search' => 'false', 'class' => 'selectpicker', 'id' => 'unit']) }}
|
||
</div>
|
||
<div class="form-group col-sm-2">
|
||
<label class="form-label" for="base_price">{{ __('Grundpreis') }}</label>
|
||
{{ Form::text('base_price', $product->getBasePriceFormattedFull(), ['placeholder' => __(''), 'class' => 'form-control', 'id' => 'base_price', 'readonly']) }}
|
||
|
||
</div>
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="number">{{ __('Artikelnummer') }}</label>
|
||
{{ Form::text('number', $product->number, ['placeholder' => __('number'), 'class' => 'form-control', 'id' => 'number']) }}
|
||
|
||
</div>
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="icons">{{ __('Icons') }}</label>
|
||
{{ Form::text('icons', $product->icons, ['placeholder' => __('icons'), 'class' => 'form-control', 'id' => 'icons']) }}
|
||
|
||
</div>
|
||
{{--
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="title">{{ __('Attribute') }}</label>
|
||
<select class="selectpicker" name="attributes[]" id="attributes" data-style="btn-light"
|
||
data-live-search="false" multiple>
|
||
{!! HTMLHelper::getAttributesOptions($product->attributes()->pluck('attribute_id')->toArray()) !!}
|
||
</select>
|
||
</div>
|
||
--}}
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label" for="description">{{ __('Beschreibung') }}</label>
|
||
{{ Form::textarea('description', $product->description, ['placeholder' => __('description'), 'class' => 'form-control summernote', 'id' => 'description']) }}
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label" for="usage">{{ __('Anwendung') }}</label>
|
||
{{ Form::textarea('usage', $product->usage, ['placeholder' => __('usage'), 'class' => 'form-control summernote', 'id' => 'usage']) }}
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label" for="ingredients">{{ __('Hinweise') }}</label>
|
||
{{ Form::textarea('ingredients', $product->ingredients, ['placeholder' => __('ingredients'), 'class' => 'form-control summernote', 'id' => 'ingredients']) }}
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<hr>
|
||
<button type="submit" class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-2" id="product-section-rezeptur">
|
||
<h5 class="card-header">
|
||
{{ __('Inhaltsstoffe') }} {{ __('Rezeptur') }}
|
||
</h5>
|
||
<div class="card-body">
|
||
<input type="hidden" name="product_inci_sync_sent" value="1">
|
||
|
||
<div class="form-group">
|
||
<label class="custom-control custom-checkbox">
|
||
{!! Form::checkbox('no_recipe_required', 1, old('no_recipe_required', $product->no_recipe_required), ['class' => 'custom-control-input', 'id' => 'no_recipe_required']) !!}
|
||
<span class="custom-control-label">{{ __('Dieses Produkt benötigt keine Rezeptur (Eigenprodukt, z. B. Broschüre, Etikett)') }}</span>
|
||
</label>
|
||
<p class="text-muted small mb-0">{{ __('Bei aktiver Option werden die Rezeptur-Felder ausgeblendet und in der Produktion wird keine Rezeptur abgefragt.') }}</p>
|
||
</div>
|
||
|
||
<div class="js-recipe-fields">
|
||
<p class="text-muted small mb-2">{{ __('Reihenfolge per Drag & Drop ändern, danach speichern.') }}</p>
|
||
<div class="table-responsive">
|
||
<table class="table table-striped table-bordered mb-3" id="recipe-table-product">
|
||
<thead>
|
||
<tr>
|
||
<th style="width:2rem"></th>
|
||
<th>{{ __('Name') }}</th>
|
||
<th>{{ __('Qualität') }}</th>
|
||
<th>{{ __('INCI') }}</th>
|
||
<th style="width:8rem">{{ __('Anteil (%)') }}</th>
|
||
<th style="width:6rem">{{ __('Faktor') }}</th>
|
||
<th style="width:7rem">{{ __('Effektiv') }}</th>
|
||
<th style="width:3rem"></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="ingredient-sortable-rows">
|
||
@foreach ($product->p_ingredients as $ingredient)
|
||
<tr data-ingredient-id="{{ $ingredient->id }}">
|
||
<td class="text-muted align-middle ingredient-drag-handle" style="cursor:grab"
|
||
title="{{ __('Verschieben') }}">☰</td>
|
||
<td class="align-middle">{{ $ingredient->name }}</td>
|
||
<td class="align-middle small text-muted">{{ $ingredient->materialQuality?->name ?? '—' }}</td>
|
||
<td class="align-middle">{{ $ingredient->inci }}</td>
|
||
<td>
|
||
<input type="hidden" name="pi_ingredient_id[]" value="{{ $ingredient->id }}">
|
||
<input type="text" name="pi_gram[]" class="form-control form-control-sm pi-gram"
|
||
value="{{ $ingredient->pivot->gram !== null ? formatNumber($ingredient->pivot->gram, 6) : '' }}"
|
||
autocomplete="off" step="0.000001">
|
||
</td>
|
||
<td>
|
||
<input type="text" name="pi_factor[]"
|
||
class="form-control form-control-sm pi-factor"
|
||
value="{{ formatNumber($ingredient->pivot->factor ?? ($ingredient->default_factor ?? 1.1)) }}"
|
||
autocomplete="off">
|
||
</td>
|
||
<td class="align-middle pi-effective text-right small text-muted">—</td>
|
||
<td class="align-middle">
|
||
@if ($product->id)
|
||
<a class="text-danger"
|
||
href="{{ route('admin_product_delete', [$product->id, 'ingredient', $ingredient->id]) }}"
|
||
onclick="return confirm('{{ __('Eintrag entfernen?') }}');"><i
|
||
class="far fa-trash-alt"></i></a>
|
||
@else
|
||
<a class="text-danger ingredient-row-remove" href="#"
|
||
title="{{ __('Entfernen') }}"><i class="far fa-trash-alt"></i></a>
|
||
@endif
|
||
</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
<tfoot>
|
||
<tr class="font-weight-bold" id="recipe-total-row">
|
||
<td colspan="4" class="text-right">{{ __('Gesamt:') }}</td>
|
||
<td class="text-right" id="recipe-total-percent">—</td>
|
||
<td colspan="3"></td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
<div class="form-group">
|
||
<button type="button" class="btn btn-default" data-toggle="modal"
|
||
data-target="#modal-ingredients-pick">
|
||
{{ __('Inhaltsstoffe hinzufügen') }}
|
||
</button>
|
||
<a class="btn btn-link btn-sm align-baseline"
|
||
href="{{ route('admin_product_ingredients') }}">{{ __('Inhaltsstoffe anlegen') }}</a>
|
||
</div>
|
||
|
||
<div class="modal fade" id="modal-ingredients-pick" tabindex="-1" role="dialog"
|
||
aria-labelledby="modal-ingredients-pick-title" aria-hidden="true">
|
||
<div class="modal-dialog modal-lg" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="modal-ingredients-pick-title">
|
||
{{ __('Inhaltsstoffe auswählen') }}</h5>
|
||
<button type="button" class="close" data-dismiss="modal"
|
||
aria-label="{{ __('Schließen') }}">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group mb-2">
|
||
<input type="search" id="ingredient-modal-search" class="form-control"
|
||
autocomplete="off" placeholder="{{ __('Name oder INCI filtern …') }}"
|
||
aria-label="{{ __('Name oder INCI filtern …') }}">
|
||
</div>
|
||
<p class="small text-muted mb-2 d-none" id="ingredient-modal-no-results">
|
||
{{ __('Keine Treffer.') }}</p>
|
||
<div class="table-responsive border rounded"
|
||
style="max-height: min(60vh, 480px); overflow-y: auto;">
|
||
<table class="table table-sm table-striped mb-0">
|
||
<thead class="thead-light sticky-top">
|
||
<tr style="background-color: #f8f9fa;">
|
||
<th style="width:2.5rem"></th>
|
||
<th>{{ __('Name') }}</th>
|
||
<th>{{ __('INCI') }}</th>
|
||
<th>{{ __('Qualität') }}</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="ingredient-modal-tbody">
|
||
@foreach ($ingredient_catalog as $ing)
|
||
<tr class="ingredient-modal-row" data-ingredient-id="{{ $ing->id }}"
|
||
data-ingredient-search="{{ e(mb_strtolower(trim(($ing->name ?? '') . ' ' . ($ing->inci ?? '') . ' ' . ($ing->materialQuality?->name ?? '')), 'UTF-8')) }}">
|
||
<td class="align-middle">
|
||
<label class="custom-control custom-checkbox mb-0">
|
||
<input type="checkbox"
|
||
class="custom-control-input js-ingredient-modal-cb"
|
||
value="{{ $ing->id }}"
|
||
@if ($product->p_ingredients->contains('id', $ing->id)) disabled @endif>
|
||
<span class="custom-control-label"></span>
|
||
</label>
|
||
</td>
|
||
<td
|
||
class="align-middle js-ing-modal-name {{ $product->p_ingredients->contains('id', $ing->id) ? 'text-muted' : '' }}">
|
||
{{ $ing->name }}</td>
|
||
<td
|
||
class="align-middle small js-ing-modal-inci {{ $product->p_ingredients->contains('id', $ing->id) ? 'text-muted' : '' }}">
|
||
{{ $ing->inci }}</td>
|
||
<td class="align-middle small text-muted">{{ $ing->materialQuality?->name ?? '—' }}</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-default"
|
||
data-dismiss="modal">{{ __('Abbrechen') }}</button>
|
||
<button type="button" class="btn btn-primary"
|
||
id="btn-ingredients-modal-add">{{ __('Hinzufügen') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>{{-- /.js-recipe-fields --}}
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<hr>
|
||
<button type="submit" class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-2" id="product-section-herstellerrezeptur">
|
||
<h5 class="card-header">
|
||
{{ __('Hersteller Rezeptur') }}
|
||
</h5>
|
||
<div class="card-body">
|
||
<input type="hidden" name="manufacturer_inci_sync_sent" value="1">
|
||
<div class="js-recipe-fields">
|
||
<p class="text-muted small mb-2">{{ __('Eigene Hersteller-Rezeptur (separate INCI-Liste). Reihenfolge per Drag & Drop ändern, danach speichern.') }}</p>
|
||
<div class="table-responsive">
|
||
<table class="table table-striped table-bordered mb-3" id="recipe-table-manufacturer">
|
||
<thead>
|
||
<tr>
|
||
<th style="width:2rem"></th>
|
||
<th>{{ __('Name') }}</th>
|
||
<th>{{ __('Qualität') }}</th>
|
||
<th>{{ __('INCI') }}</th>
|
||
<th style="width:8rem">{{ __('Anteil (%)') }}</th>
|
||
<th style="width:6rem">{{ __('Faktor') }}</th>
|
||
<th style="width:7rem">{{ __('Effektiv') }}</th>
|
||
<th style="width:3rem"></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="mfg-ingredient-sortable-rows">
|
||
@foreach ($product->manufacturer_ingredients as $ingredient)
|
||
<tr data-ingredient-id="{{ $ingredient->id }}">
|
||
<td class="text-muted align-middle mfg-ingredient-drag-handle" style="cursor:grab"
|
||
title="{{ __('Verschieben') }}">☰</td>
|
||
<td class="align-middle">{{ $ingredient->name }}</td>
|
||
<td class="align-middle small text-muted">{{ $ingredient->materialQuality?->name ?? '—' }}</td>
|
||
<td class="align-middle">{{ $ingredient->inci }}</td>
|
||
<td>
|
||
<input type="hidden" name="mfg_ingredient_id[]" value="{{ $ingredient->id }}">
|
||
<input type="text" name="mfg_gram[]" class="form-control form-control-sm mfg-gram"
|
||
value="{{ $ingredient->pivot->gram !== null ? formatNumber($ingredient->pivot->gram, 6) : '' }}"
|
||
autocomplete="off" step="0.000001">
|
||
</td>
|
||
<td>
|
||
<input type="text" name="mfg_factor[]"
|
||
class="form-control form-control-sm mfg-factor"
|
||
value="{{ formatNumber($ingredient->pivot->factor ?? ($ingredient->default_factor ?? 1.1)) }}"
|
||
autocomplete="off">
|
||
</td>
|
||
<td class="align-middle mfg-effective text-right small text-muted">—</td>
|
||
<td class="align-middle">
|
||
<a class="text-danger mfg-ingredient-row-remove" href="#"
|
||
title="{{ __('Entfernen') }}"><i class="far fa-trash-alt"></i></a>
|
||
</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
<tfoot>
|
||
<tr class="font-weight-bold" id="mfg-recipe-total-row">
|
||
<td colspan="4" class="text-right">{{ __('Gesamt:') }}</td>
|
||
<td class="text-right" id="mfg-recipe-total-percent">—</td>
|
||
<td colspan="3"></td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
<div class="form-group">
|
||
<button type="button" class="btn btn-default" data-toggle="modal"
|
||
data-target="#modal-mfg-ingredients-pick">
|
||
{{ __('Inhaltsstoffe hinzufügen') }}
|
||
</button>
|
||
</div>
|
||
|
||
<div class="modal fade" id="modal-mfg-ingredients-pick" tabindex="-1" role="dialog"
|
||
aria-labelledby="modal-mfg-ingredients-pick-title" aria-hidden="true">
|
||
<div class="modal-dialog modal-lg" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="modal-mfg-ingredients-pick-title">
|
||
{{ __('Inhaltsstoffe auswählen (Hersteller)') }}</h5>
|
||
<button type="button" class="close" data-dismiss="modal"
|
||
aria-label="{{ __('Schließen') }}">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group mb-2">
|
||
<input type="search" id="mfg-ingredient-modal-search" class="form-control"
|
||
autocomplete="off" placeholder="{{ __('Name oder INCI filtern …') }}">
|
||
</div>
|
||
<p class="small text-muted mb-2 d-none" id="mfg-ingredient-modal-no-results">{{ __('Keine Treffer.') }}</p>
|
||
<div class="table-responsive border rounded" style="max-height: min(60vh, 480px); overflow-y: auto;">
|
||
<table class="table table-sm table-striped mb-0">
|
||
<thead class="thead-light sticky-top">
|
||
<tr style="background-color: #f8f9fa;">
|
||
<th style="width:2.5rem"></th>
|
||
<th>{{ __('Name') }}</th>
|
||
<th>{{ __('INCI') }}</th>
|
||
<th>{{ __('Qualität') }}</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="mfg-ingredient-modal-tbody">
|
||
@foreach ($ingredient_catalog as $ing)
|
||
<tr class="mfg-ingredient-modal-row" data-ingredient-id="{{ $ing->id }}"
|
||
data-ingredient-search="{{ e(mb_strtolower(trim(($ing->name ?? '') . ' ' . ($ing->inci ?? '') . ' ' . ($ing->materialQuality?->name ?? '')), 'UTF-8')) }}">
|
||
<td class="align-middle">
|
||
<label class="custom-control custom-checkbox mb-0">
|
||
<input type="checkbox" class="custom-control-input js-mfg-ingredient-modal-cb"
|
||
value="{{ $ing->id }}"
|
||
@if ($product->manufacturer_ingredients->contains('id', $ing->id)) disabled @endif>
|
||
<span class="custom-control-label"></span>
|
||
</label>
|
||
</td>
|
||
<td class="align-middle">{{ $ing->name }}</td>
|
||
<td class="align-middle small">{{ $ing->inci }}</td>
|
||
<td class="align-middle small text-muted">{{ $ing->materialQuality?->name ?? '—' }}</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ __('Abbrechen') }}</button>
|
||
<button type="button" class="btn btn-primary" id="btn-mfg-ingredients-modal-add">{{ __('Hinzufügen') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>{{-- /.js-recipe-fields --}}
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<hr>
|
||
<button type="submit" class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-2" id="product-section-verpackung">
|
||
<h5 class="card-header">{{ __('Verpackung & Material') }}</h5>
|
||
<div class="card-body">
|
||
<p class="text-muted small mb-2">{{ __('Reihenfolge per Drag & Drop ändern, danach speichern.') }}</p>
|
||
<div class="table-responsive">
|
||
<table class="table table-striped table-bordered mb-3">
|
||
<thead>
|
||
<tr>
|
||
<th style="width:2rem"></th>
|
||
<th>{{ __('Name') }}</th>
|
||
<th>{{ __('Material') }}</th>
|
||
<th style="width:6rem">{{ __('Gewicht') }} (g)</th>
|
||
<th style="width:8rem">{{ __('Menge') }}</th>
|
||
<th style="width:3rem"></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="packaging-sortable-rows">
|
||
@foreach ($product->packagings as $pitem)
|
||
<tr data-packaging-item-id="{{ $pitem->id }}">
|
||
<td class="text-muted align-middle packaging-drag-handle" style="cursor:grab"
|
||
title="{{ __('Verschieben') }}">☰</td>
|
||
<td class="align-middle">{{ $pitem->name }}</td>
|
||
<td class="align-middle">{{ $pitem->packagingMaterial?->name ?? '—' }}</td>
|
||
<td class="align-middle text-right">
|
||
{{ $pitem->weight_grams !== null ? formatNumber($pitem->weight_grams) : '—' }}</td>
|
||
<td>
|
||
<input type="hidden" name="pp_packaging_item_id[]" value="{{ $pitem->id }}">
|
||
<input type="text" name="pp_quantity[]"
|
||
class="form-control form-control-sm pp-quantity"
|
||
value="{{ formatNumber($pitem->pivot->quantity ?? 1) }}" autocomplete="off">
|
||
</td>
|
||
<td class="align-middle">
|
||
<a class="text-danger packaging-row-remove" href="#"
|
||
title="{{ __('Entfernen') }}"><i class="far fa-trash-alt"></i></a>
|
||
</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div class="form-group">
|
||
<button type="button" class="btn btn-default" data-toggle="modal"
|
||
data-target="#modal-packaging-pick">{{ __('Verpackungsartikel hinzufügen') }}</button>
|
||
@if (Auth::user()->isAdmin())
|
||
<a class="btn btn-link btn-sm align-baseline"
|
||
href="{{ route('admin.inventory.packaging-items.index') }}">{{ __('Verpackungsartikel verwalten') }}</a>
|
||
@endif
|
||
</div>
|
||
|
||
<div class="modal fade" id="modal-packaging-pick" tabindex="-1" role="dialog"
|
||
aria-labelledby="modal-packaging-pick-title" aria-hidden="true">
|
||
<div class="modal-dialog modal-lg" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="modal-packaging-pick-title">
|
||
{{ __('Verpackungsartikel auswählen') }}</h5>
|
||
<button type="button" class="close" data-dismiss="modal"
|
||
aria-label="{{ __('Schließen') }}">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group mb-2">
|
||
<input type="search" id="packaging-modal-search" class="form-control" autocomplete="off"
|
||
placeholder="{{ __('Name oder Material filtern …') }}"
|
||
aria-label="{{ __('Name oder Material filtern …') }}">
|
||
</div>
|
||
<p class="small text-muted mb-2 d-none" id="packaging-modal-no-results">{{ __('Keine Treffer.') }}
|
||
</p>
|
||
<div class="table-responsive border rounded"
|
||
style="max-height: min(60vh, 480px); overflow-y: auto;">
|
||
<table class="table table-sm table-striped mb-0">
|
||
<thead class="thead-light sticky-top">
|
||
<tr style="background-color: #f8f9fa;">
|
||
<th style="width:2.5rem"></th>
|
||
<th>{{ __('Name') }}</th>
|
||
<th>{{ __('Material') }}</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="packaging-modal-tbody">
|
||
@foreach ($packaging_catalog as $pk)
|
||
<tr class="packaging-modal-row" data-packaging-item-id="{{ $pk->id }}"
|
||
data-packaging-search="{{ e(mb_strtolower(trim(($pk->name ?? '') . ' ' . ($pk->packagingMaterial?->name ?? '')), 'UTF-8')) }}">
|
||
<td class="align-middle">
|
||
<label class="custom-control custom-checkbox mb-0">
|
||
<input type="checkbox"
|
||
class="custom-control-input js-packaging-modal-cb"
|
||
value="{{ $pk->id }}"
|
||
@if ($product->packagings->contains('id', $pk->id)) disabled @endif>
|
||
<span class="custom-control-label"></span>
|
||
</label>
|
||
</td>
|
||
<td
|
||
class="align-middle js-pk-modal-name {{ $product->packagings->contains('id', $pk->id) ? 'text-muted' : '' }}">
|
||
{{ $pk->name }}</td>
|
||
<td
|
||
class="align-middle small js-pk-modal-mat {{ $product->packagings->contains('id', $pk->id) ? 'text-muted' : '' }}">
|
||
{{ $pk->packagingMaterial?->name ?? '—' }}</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-default"
|
||
data-dismiss="modal">{{ __('Abbrechen') }}</button>
|
||
<button type="button" class="btn btn-primary"
|
||
id="btn-packaging-modal-add">{{ __('Hinzufügen') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<hr>
|
||
<button type="submit" class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-2" id="product-section-warenwirtschaft">
|
||
<h5 class="card-header">{{ __('Warenwirtschaft') }}</h5>
|
||
<div class="card-body">
|
||
<div class="form-group">
|
||
<label class="d-block">{{ __('Haltbarkeit') }}</label>
|
||
<div class="custom-controls-stacked">
|
||
<label class="custom-control custom-radio">
|
||
<input type="radio" name="shelf_life_type" value=""
|
||
class="custom-control-input js-shelf-life-type" @checked(old('shelf_life_type', $product->shelf_life_type) === null ||
|
||
old('shelf_life_type', $product->shelf_life_type) === '')>
|
||
<span class="custom-control-label">{{ __('Keine Angabe') }}</span>
|
||
</label>
|
||
<label class="custom-control custom-radio">
|
||
<input type="radio" name="shelf_life_type" value="pao"
|
||
class="custom-control-input js-shelf-life-type" @checked(old('shelf_life_type', $product->shelf_life_type) === 'pao')>
|
||
<span class="custom-control-label">12M-Tiegel (PAO)</span>
|
||
</label>
|
||
<label class="custom-control custom-radio">
|
||
<input type="radio" name="shelf_life_type" value="fixed"
|
||
class="custom-control-input js-shelf-life-type" @checked(old('shelf_life_type', $product->shelf_life_type) === 'fixed')>
|
||
<span class="custom-control-label">{{ __('Festes MHD') }}</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="form-group" id="shelf-life-months-wrap" style="display: none;">
|
||
<label class="form-label" for="shelf_life_months">{{ __('Monate ab Herstellung') }}</label>
|
||
<select name="shelf_life_months" id="shelf_life_months" class="form-control">
|
||
@foreach ([6, 12, 18, 24, 30, 36] as $m)
|
||
<option value="{{ $m }}" @selected((int) old('shelf_life_months', $product->shelf_life_months) === $m)>{{ $m }}</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
|
||
<hr>
|
||
<div class="form-group">
|
||
<label class="custom-control custom-checkbox">
|
||
{!! Form::checkbox('show_in_product_stock', 1, old('show_in_product_stock', $product->exists ? $product->show_in_product_stock : true), ['class' => 'custom-control-input', 'id' => 'show_in_product_stock']) !!}
|
||
<span class="custom-control-label">{{ __('Im Produktbestand anzeigen') }}</span>
|
||
</label>
|
||
<p class="text-muted small mb-0">{{ __('Abwählen für Positionen ohne Lagerführung (z. B. Abrechnung Druckkosten, Logo-Etiketten).') }}</p>
|
||
</div>
|
||
|
||
<p class="text-muted small mb-2">{{ __('Produktbestand-Schwellwerte (Stück). Bei Erreichen wird das Produkt im Produktbestand farblich markiert.') }}</p>
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-6">
|
||
<label class="form-label" for="min_product_stock">{{ __('Meldebestand (gelb)') }}</label>
|
||
{{ Form::number('min_product_stock', old('min_product_stock', $product->min_product_stock), ['placeholder' => __('z. B. 20'), 'class' => 'form-control', 'id' => 'min_product_stock', 'min' => 0, 'step' => 1]) }}
|
||
</div>
|
||
<div class="form-group col-sm-6">
|
||
<label class="form-label" for="critical_product_stock">{{ __('Kritischer Bestand (rot)') }}</label>
|
||
{{ Form::number('critical_product_stock', old('critical_product_stock', $product->critical_product_stock), ['placeholder' => __('z. B. 10'), 'class' => 'form-control', 'id' => 'critical_product_stock', 'min' => 0, 'step' => 1]) }}
|
||
</div>
|
||
</div>
|
||
|
||
<hr>
|
||
<p class="text-muted small mb-2">{{ __('Optional: dieses Einzelprodukt einem Hauptprodukt zuordnen (z. B. „50 × 15 ml"). Der Produktbestand führt nur Haupt-/Einzelprodukte.') }}</p>
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-8">
|
||
<label class="form-label" for="main_product_id">{{ __('Hauptprodukt') }}</label>
|
||
<select name="main_product_id" id="main_product_id" class="form-control">
|
||
<option value="">{{ __('— kein Hauptprodukt —') }}</option>
|
||
@foreach ($set_product_catalog as $mp)
|
||
<option value="{{ $mp->id }}" @selected((int) old('main_product_id', $product->main_product_id) === (int) $mp->id)>
|
||
{{ $mp->name }}@if ($mp->number) ({{ $mp->number }})@endif
|
||
</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
<div class="form-group col-sm-4">
|
||
<label class="form-label" for="main_product_quantity">{{ __('Menge im Hauptprodukt') }}</label>
|
||
{{ Form::number('main_product_quantity', old('main_product_quantity', $product->main_product_quantity), ['placeholder' => __('z. B. 50'), 'class' => 'form-control', 'id' => 'main_product_quantity', 'min' => 1, 'step' => 1]) }}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<hr>
|
||
<button type="submit" class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@if (Auth::user()->isSySAdmin())
|
||
<div class="card mb-2" id="product-section-sysadmin">
|
||
<h5 class="card-header">
|
||
{{ __('SySAdmin Einstellungen') }}
|
||
</h5>
|
||
<div class="card-body">
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-5">
|
||
<label class="form-label" for="action">{{ __('Aktion beim Zahlungsprozess') }}</label>
|
||
{{ Form::select('action[]', $product->actions, $product->action, ['data-live-search' => 'false', 'class' => 'selectpicker', 'id' => 'action', 'multiple']) }}
|
||
</div>
|
||
<div class="form-group col-sm-5">
|
||
<label class="form-label"
|
||
for="identifier">{{ __('Anzeigeoptionen Zahlung Mitglieder-Accounts') }}</label>
|
||
{{ Form::select('identifier', $product->identifiers_types, $product->identifier, ['data-live-search' => 'false', 'class' => 'selectpicker', 'id' => 'identifier']) }}
|
||
</div>
|
||
<div class="form-group col-sm-2">
|
||
<label class="form-label" for="upgrade_to_id">{{ __('Bei Upgrade auf Produkt-ID') }}</label>
|
||
{{ Form::text('upgrade_to_id', $product->upgrade_to_id, ['placeholder' => __('Produkt-ID auf das geupdatet werden soll'), 'class' => 'form-control', 'id' => 'upgrade_to_id']) }}
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-group col-sm-5">
|
||
<label class="form-label" for="wp_number">WP Artikel Number (als Zahl ohne Leerzeichen für die
|
||
WP-API)</label>
|
||
{{ Form::text('wp_number', $product->wp_number, ['placeholder' => __('WP Number'), 'class' => 'form-control', 'id' => 'wp_number']) }}
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<hr>
|
||
<button type="submit"
|
||
class=" float-right btn btn-sm btn-submit">{{ __('save') }}</button>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@endif
|