Warenwirtschaft: einheitliches UI-Design (AP-19)
- Zentrale, wiederverwendbare Design-Partial wawi-ui.blade.php (gescoptes Inline-CSS, kein Build noetig) - Bausteine: Seitenkopf, Kennzahlen-Kacheln, Karten, Toolbar/Suche, aufgeraeumte Tabellen, Status-Pills, Datenblatt-Definitionsliste, Name-Zelle mit fester Icon-Spalte, Leer-Zustaende - Umgestellt: alle Uebersicht-/Listen- und Detailseiten unter admin/inventory - Responsive: Detail-Datenblaetter brechen unter 768px gestapelt um (Label oben, Wert linksbuendig); Icon-Spalte verhindert Versatz bei Zeilenumbruch - Entwicklungsplan um AP-19 + UI-Konvention ergaenzt Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
3ee2d756e9
commit
a8f6fef38e
21 changed files with 1609 additions and 955 deletions
|
|
@ -508,7 +508,7 @@ Pro `shopping_order_item` Produkt laden:
|
||||||
|
|
||||||
## 6. Empfohlene Sofort-Reihenfolge (nächste Schritte)
|
## 6. Empfohlene Sofort-Reihenfolge (nächste Schritte)
|
||||||
|
|
||||||
✅ **Erledigt:** AP-00, AP-01, AP-04 (+ AP-04.1), AP-05, AP-06 (+ Nachtrag), AP-07 (+ AP-07.1), AP-08, AP-09 (+ AP-09.1), AP-02 (Sets via Pivot), AP-03 („Nicht vorrätig"), AP-10 (Rohstoffbestand), AP-11 (Produktbestand + Historie), AP-12 (Ausgang / Ausschuss), AP-18 (Platzhalter, laufend zu pflegen).
|
✅ **Erledigt:** AP-00, AP-01, AP-04 (+ AP-04.1), AP-05, AP-06 (+ Nachtrag), AP-07 (+ AP-07.1), AP-08, AP-09 (+ AP-09.1), AP-02 (Sets via Pivot), AP-03 („Nicht vorrätig"), AP-10 (Rohstoffbestand), AP-11 (Produktbestand + Historie), AP-12 (Ausgang / Ausschuss), AP-18 (Platzhalter, laufend zu pflegen), AP-19 (UI-Vereinheitlichung Warenwirtschaft).
|
||||||
|
|
||||||
**➡️ Hier geht es weiter:**
|
**➡️ Hier geht es weiter:**
|
||||||
1. **AP-13** (Shop-Anbindung: Bestandsabzug beim Versand inkl. Sets) – **Entwicklungskonzept liegt vor** (siehe AP-13 in §4). Kernbefund: Bestellungen liegen bereits im System (`shopping_orders`/`shopping_order_items`, Mapping über `products.wp_number`), Versandstatus wird zentral in `SalesController@store` gesetzt → Abzug kann ohne neue Tabelle auf der AP-11-Infrastruktur aufsetzen. **Vorab nur noch zu bestätigen:** Szenario A (Versand wird im Backend gebucht – empfohlen, kein neuer Woo-Eingriff) vs. Szenario B (WooCommerce meldet Versand per Webhook/REST-Pull zurück) sowie die Varianten-/Hauptprodukt-Detailfrage. Danach Folge-APs (AP-14–AP-17).
|
1. **AP-13** (Shop-Anbindung: Bestandsabzug beim Versand inkl. Sets) – **Entwicklungskonzept liegt vor** (siehe AP-13 in §4). Kernbefund: Bestellungen liegen bereits im System (`shopping_orders`/`shopping_order_items`, Mapping über `products.wp_number`), Versandstatus wird zentral in `SalesController@store` gesetzt → Abzug kann ohne neue Tabelle auf der AP-11-Infrastruktur aufsetzen. **Vorab nur noch zu bestätigen:** Szenario A (Versand wird im Backend gebucht – empfohlen, kein neuer Woo-Eingriff) vs. Szenario B (WooCommerce meldet Versand per Webhook/REST-Pull zurück) sowie die Varianten-/Hauptprodukt-Detailfrage. Danach Folge-APs (AP-14–AP-17).
|
||||||
|
|
@ -516,9 +516,26 @@ Pro `shopping_order_item` Produkt laden:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### AP-19 — UI-Vereinheitlichung Warenwirtschaft (Darstellung)
|
||||||
|
|
||||||
|
> **Status:** Erledigt (03.06.2026). Rein gestalterisch, keine fachliche Logik geändert.
|
||||||
|
|
||||||
|
Ein einheitliches, modernes Erscheinungsbild für alle Warenwirtschafts-Seiten. Zentrale, wiederverwendbare Design-Partial **`resources/views/admin/inventory/partials/wawi-ui.blade.php`** (per `@once` eingebundenes, auf `.wawi-page` gescoptes Inline-CSS – **kein** SCSS-Build/`npm run` nötig).
|
||||||
|
|
||||||
|
**Bausteine:** Seitenkopf (`wawi-page-head`, Titel + Untertitel + Aktionsbereich), Kennzahlen-Kacheln (`wawi-stats`/`wawi-stat`, teils klickbar als Filter), Karten (`wawi-card` + `wawi-card__header`/`__footer`), Toolbar mit Such-Feld (`wawi-toolbar`/`wawi-search`), aufgeräumte Tabellen (`wawi-table` mit Uppercase-Köpfen, Hover, schmaler Status-Akzentleiste links), Status-Pills (`wawi-pill--ok/--warning/--danger`), Datenblatt-Definitionsliste (`wawi-deflist`/`wawi-deflist__item`), Name-Zelle mit fester Icon-Spalte (`wawi-name-cell`), einheitlicher Leer-Zustand (`wawi-empty`).
|
||||||
|
|
||||||
|
**Responsive:** Detail-Datenblätter brechen unter 768 px auf einspaltig um – Label klein oben, Wert linksbündig darunter. Die Name-Zelle hält das Icon in eigener Spalte, damit umgebrochener Text nicht unter das Icon rutscht.
|
||||||
|
|
||||||
|
**Umgestellt:** alle Übersicht-/Listen- und Detailseiten unter `admin/inventory` (Produktbestand + Historie, Rohstoffbestand inkl. Detail, Ausgang/Ausschuss, Einkauf & Wareneingang inkl. Detail, Produktion inkl. Detail, Hinweise, Produktentwicklung, Einstellungen sowie die Stammdaten-Listen Lieferanten, Lieferanten-Kategorien, Verpackungsmaterial/-artikel, Materialqualität, Lagerorte).
|
||||||
|
|
||||||
|
**Offen (bewusst):** Die reinen **Formularseiten** (Anlegen/Bearbeiten) nutzen noch den alten `h4`-Kopf; Angleichung an `wawi-page-head` als Folgeaufgabe vorgemerkt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 7. Pflege dieses Dokuments
|
## 7. Pflege dieses Dokuments
|
||||||
|
|
||||||
- Jedes abgeschlossene AP hier mit Datum + Kurzbeschreibung + Test-Status protokollieren (analog Umsetzungsprotokoll in `entwicklungsplan.md`).
|
- Jedes abgeschlossene AP hier mit Datum + Kurzbeschreibung + Test-Status protokollieren (analog Umsetzungsprotokoll in `entwicklungsplan.md`).
|
||||||
- Bei DB-Änderungen: Migration-Dateinamen referenzieren; bei Modellen Casts in `casts()`-Methode pflegen (L11-Konvention).
|
- Bei DB-Änderungen: Migration-Dateinamen referenzieren; bei Modellen Casts in `casts()`-Methode pflegen (L11-Konvention).
|
||||||
- Vor jedem Commit: `vendor/bin/pint --dirty` und betroffene Tests (`php artisan test --filter=...`).
|
- Vor jedem Commit: `vendor/bin/pint --dirty` und betroffene Tests (`php artisan test --filter=...`).
|
||||||
- **UI-Konvention Datumsfelder:** Datumsfelder in Formularen immer als `<input type="text" class="form-control datepicker-base" value="dd.mm.yyyy">` (kein natives `type="date"`). Der Datepicker wird global über `public/js/custom.js` auf `.datepicker-base` gebunden (Format `dd.mm.yyyy`, deutsche Locale). Modellwerte mit `->format('d.m.Y')` ausgeben; Backend parst `d.m.Y` über `Carbon::parse` bzw. die `date`-Validierungsregel.
|
- **UI-Konvention Datumsfelder:** Datumsfelder in Formularen immer als `<input type="text" class="form-control datepicker-base" value="dd.mm.yyyy">` (kein natives `type="date"`). Der Datepicker wird global über `public/js/custom.js` auf `.datepicker-base` gebunden (Format `dd.mm.yyyy`, deutsche Locale). Modellwerte mit `->format('d.m.Y')` ausgeben; Backend parst `d.m.Y` über `Carbon::parse` bzw. die `date`-Validierungsregel.
|
||||||
|
- **UI-Konvention Warenwirtschaft (AP-19):** Neue Seiten unter `admin/inventory` verwenden das Design-System aus `resources/views/admin/inventory/partials/wawi-ui.blade.php` (`@include('admin.inventory.partials.wawi-ui')` + Inhalt in `<div class="wawi-page">`). Bausteine: `wawi-page-head`, `wawi-stats`/`wawi-stat`, `wawi-card`, `wawi-toolbar`/`wawi-search`, `wawi-table`, `wawi-pill`, `wawi-deflist`, `wawi-name-cell`, `wawi-empty`. Status immer über `wawi-pill` (ok/warning/danger) statt Bootstrap-`badge-pill`.
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,23 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
|
|
||||||
<div class="card mb-4">
|
<div class="wawi-page">
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
<div class="wawi-page-head">
|
||||||
|
<div>
|
||||||
|
<h1 class="wawi-page-head__title">{{ __('Einstellungen') }}</h1>
|
||||||
|
<p class="wawi-page-head__subtitle">{{ __('Umsatzsteuersätze und Lieferzeit-Vorlagen') }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="wawi-card__header">
|
||||||
<span>{{ __('Umsatzsteuersätze') }}</span>
|
<span>{{ __('Umsatzsteuersätze') }}</span>
|
||||||
<a href="{{ route('admin.inventory.tax-rates.create') }}"
|
<a href="{{ route('admin.inventory.tax-rates.create') }}" class="btn btn-sm btn-primary">{{ __('Neu anlegen') }}</a>
|
||||||
class="btn btn-sm btn-primary">{{ __('Neu anlegen') }}</a>
|
</div>
|
||||||
</h6>
|
<div class="table-responsive">
|
||||||
<div class="card-datatable table-responsive">
|
<table class="table wawi-table">
|
||||||
<table class="table table-striped table-bordered wawi-table mb-0">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="max-width: 60px;"> </th>
|
<th style="max-width: 60px;"> </th>
|
||||||
|
|
@ -33,9 +40,9 @@
|
||||||
<td>{{ number_format($taxRate->percent, 2, ',', '.') }} %</td>
|
<td>{{ number_format($taxRate->percent, 2, ',', '.') }} %</td>
|
||||||
<td>
|
<td>
|
||||||
@if ($taxRate->active)
|
@if ($taxRate->active)
|
||||||
<span class="badge badge-pill badge-success"><i class="fa fa-check"></i></span>
|
<span class="wawi-pill wawi-pill--ok">{{ __('Aktiv') }}</span>
|
||||||
@else
|
@else
|
||||||
<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>
|
<span class="wawi-pill wawi-pill--danger">{{ __('Inaktiv') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -50,8 +57,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="5" class="text-center text-muted">
|
<td colspan="5"><div class="wawi-empty">{{ __('Noch keine Umsatzsteuersätze angelegt.') }}</div></td>
|
||||||
{{ __('Noch keine Umsatzsteuersätze angelegt.') }}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
@ -59,14 +65,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="wawi-card">
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
<div class="wawi-card__header">
|
||||||
<span>{{ __('Lieferzeit-Vorlagen') }}</span>
|
<span>{{ __('Lieferzeit-Vorlagen') }}</span>
|
||||||
<a href="{{ route('admin.inventory.delivery-times.create') }}"
|
<a href="{{ route('admin.inventory.delivery-times.create') }}" class="btn btn-sm btn-primary">{{ __('Neu anlegen') }}</a>
|
||||||
class="btn btn-sm btn-primary">{{ __('Neu anlegen') }}</a>
|
</div>
|
||||||
</h6>
|
<div class="table-responsive">
|
||||||
<div class="card-datatable table-responsive">
|
<table class="table wawi-table">
|
||||||
<table class="table table-striped table-bordered wawi-table mb-0">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="max-width: 60px;"> </th>
|
<th style="max-width: 60px;"> </th>
|
||||||
|
|
@ -89,9 +94,9 @@
|
||||||
<td>{{ $deliveryTime->days !== null ? $deliveryTime->days : '–' }}</td>
|
<td>{{ $deliveryTime->days !== null ? $deliveryTime->days : '–' }}</td>
|
||||||
<td>
|
<td>
|
||||||
@if ($deliveryTime->active)
|
@if ($deliveryTime->active)
|
||||||
<span class="badge badge-pill badge-success"><i class="fa fa-check"></i></span>
|
<span class="wawi-pill wawi-pill--ok">{{ __('Aktiv') }}</span>
|
||||||
@else
|
@else
|
||||||
<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>
|
<span class="wawi-pill wawi-pill--danger">{{ __('Inaktiv') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -107,12 +112,12 @@
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="5" class="text-center text-muted">
|
<td colspan="5"><div class="wawi-empty">{{ __('Noch keine Lieferzeit-Vorlagen angelegt.') }}</div></td>
|
||||||
{{ __('Noch keine Lieferzeit-Vorlagen angelegt.') }}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
<div class="wawi-page">
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
<div class="wawi-page-head">
|
||||||
<span>{{ __('Lagerorte') }}</span>
|
<div>
|
||||||
<a href="{{ route('admin.inventory.locations.create') }}" class="btn btn-sm btn-primary">{{ __('Neu anlegen') }}</a>
|
<h1 class="wawi-page-head__title">{{ __('Lagerorte') }}</h1>
|
||||||
</h6>
|
</div>
|
||||||
<div class="card-datatable table-responsive">
|
<div class="wawi-page-head__actions">
|
||||||
<table class="datatables-style table table-striped table-bordered wawi-table">
|
<a href="{{ route('admin.inventory.locations.create') }}" class="btn btn-sm btn-primary">
|
||||||
|
<span class="fas fa-plus mr-1"></span>{{ __('Neu anlegen') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="card-datatable table-responsive p-2">
|
||||||
|
<table class="datatables-style table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="max-width: 60px;"> </th>
|
<th style="max-width: 60px;"> </th>
|
||||||
|
|
@ -28,9 +35,9 @@
|
||||||
<td>{{ $value->name }}</td>
|
<td>{{ $value->name }}</td>
|
||||||
<td data-sort="{{ $value->active ? 1 : 0 }}">
|
<td data-sort="{{ $value->active ? 1 : 0 }}">
|
||||||
@if($value->active)
|
@if($value->active)
|
||||||
<span class="badge badge-pill badge-success"><i class="fa fa-check"></i></span>
|
<span class="wawi-pill wawi-pill--ok">{{ __('Aktiv') }}</span>
|
||||||
@else
|
@else
|
||||||
<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>
|
<span class="wawi-pill wawi-pill--danger">{{ __('Inaktiv') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -47,6 +54,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
<div class="wawi-page">
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
<div class="wawi-page-head">
|
||||||
<span>{{ __('Rohstoffqualität') }}</span>
|
<div>
|
||||||
<a href="{{ route('admin.inventory.material-qualities.create') }}" class="btn btn-sm btn-primary">{{ __('Neu anlegen') }}</a>
|
<h1 class="wawi-page-head__title">{{ __('Rohstoffqualität') }}</h1>
|
||||||
</h6>
|
</div>
|
||||||
<div class="card-datatable table-responsive">
|
<div class="wawi-page-head__actions">
|
||||||
<table class="datatables-style table table-striped table-bordered wawi-table">
|
<a href="{{ route('admin.inventory.material-qualities.create') }}" class="btn btn-sm btn-primary">
|
||||||
|
<span class="fas fa-plus mr-1"></span>{{ __('Neu anlegen') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="card-datatable table-responsive p-2">
|
||||||
|
<table class="datatables-style table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="max-width: 60px;"> </th>
|
<th style="max-width: 60px;"> </th>
|
||||||
|
|
@ -41,6 +48,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.datatables-style').dataTable({
|
$('.datatables-style').dataTable({
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<h4 class="font-weight-bold py-2 mb-2">{{ __('Hinweise') }}</h4>
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
|
<div class="wawi-page">
|
||||||
|
<div class="wawi-page-head">
|
||||||
|
<div>
|
||||||
|
<h1 class="wawi-page-head__title">{{ __('Hinweise') }}</h1>
|
||||||
|
<p class="wawi-page-head__subtitle">{{ __('Allgemeine Hinweise zur Warenwirtschaft') }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card wawi-card">
|
||||||
<div class="card-body wawi-notices">
|
<div class="card-body wawi-notices">
|
||||||
{!! $content !!}
|
{!! $content !!}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('styles')
|
@section('styles')
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
<div class="wawi-page">
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
<div class="wawi-page-head">
|
||||||
<span>{{ $pageTitle }}</span>
|
<div>
|
||||||
<a href="{{ route('admin.inventory.packaging-items.create', ['category' => $category]) }}" class="btn btn-sm btn-primary">{{ __('Neu anlegen') }}</a>
|
<h1 class="wawi-page-head__title">{{ $pageTitle }}</h1>
|
||||||
</h6>
|
</div>
|
||||||
<div class="card-datatable table-responsive">
|
<div class="wawi-page-head__actions">
|
||||||
<table class="datatables-style table table-striped table-bordered wawi-table">
|
<a href="{{ route('admin.inventory.packaging-items.create', ['category' => $category]) }}" class="btn btn-sm btn-primary">
|
||||||
|
<span class="fas fa-plus mr-1"></span>{{ __('Neu anlegen') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="card-datatable table-responsive p-2">
|
||||||
|
<table class="datatables-style table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="max-width: 60px;"> </th>
|
<th style="max-width: 60px;"> </th>
|
||||||
|
|
@ -42,9 +49,9 @@
|
||||||
</td>
|
</td>
|
||||||
<td data-sort="{{ $value->active ? 1 : 0 }}">
|
<td data-sort="{{ $value->active ? 1 : 0 }}">
|
||||||
@if($value->active)
|
@if($value->active)
|
||||||
<span class="badge badge-pill badge-success"><i class="fa fa-check"></i></span>
|
<span class="wawi-pill wawi-pill--ok">{{ __('Aktiv') }}</span>
|
||||||
@else
|
@else
|
||||||
<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>
|
<span class="wawi-pill wawi-pill--danger">{{ __('Inaktiv') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -61,6 +68,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.datatables-style').dataTable({
|
$('.datatables-style').dataTable({
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
<div class="wawi-page">
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
<div class="wawi-page-head">
|
||||||
<span>{{ __('Verpackungsmaterial') }}</span>
|
<div>
|
||||||
<a href="{{ route('admin.inventory.packaging-materials.create') }}" class="btn btn-sm btn-primary">{{ __('Neu anlegen') }}</a>
|
<h1 class="wawi-page-head__title">{{ __('Verpackungsmaterial') }}</h1>
|
||||||
</h6>
|
</div>
|
||||||
<div class="card-datatable table-responsive">
|
<div class="wawi-page-head__actions">
|
||||||
<table class="datatables-style table table-striped table-bordered wawi-table">
|
<a href="{{ route('admin.inventory.packaging-materials.create') }}" class="btn btn-sm btn-primary">
|
||||||
|
<span class="fas fa-plus mr-1"></span>{{ __('Neu anlegen') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="card-datatable table-responsive p-2">
|
||||||
|
<table class="datatables-style table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="max-width: 60px;"> </th>
|
<th style="max-width: 60px;"> </th>
|
||||||
|
|
@ -41,6 +48,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.datatables-style').dataTable({
|
$('.datatables-style').dataTable({
|
||||||
|
|
|
||||||
283
resources/views/admin/inventory/partials/wawi-ui.blade.php
Normal file
283
resources/views/admin/inventory/partials/wawi-ui.blade.php
Normal file
|
|
@ -0,0 +1,283 @@
|
||||||
|
@once
|
||||||
|
<style>
|
||||||
|
/* =====================================================================
|
||||||
|
Warenwirtschaft – einheitliches UI (Vorschlag / Prototyp)
|
||||||
|
Alles auf ".wawi-page" gescoped, damit nichts anderes beeinflusst wird.
|
||||||
|
===================================================================== */
|
||||||
|
.wawi-page {
|
||||||
|
--wawi-accent: #6b8e5a;
|
||||||
|
--wawi-accent-soft: rgba(107, 142, 90, .12);
|
||||||
|
--wawi-radius: .625rem;
|
||||||
|
--wawi-border: rgba(24, 28, 33, .08);
|
||||||
|
--wawi-shadow: 0 1px 2px rgba(24, 28, 33, .04), 0 2px 8px rgba(24, 28, 33, .04);
|
||||||
|
--wawi-muted: #8a909d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Seitenkopf -------------------------------------------------- */
|
||||||
|
.wawi-page-head {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
.wawi-page-head__title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.375rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
.wawi-page-head__subtitle {
|
||||||
|
margin: .35rem 0 0;
|
||||||
|
color: var(--wawi-muted);
|
||||||
|
font-size: .875rem;
|
||||||
|
}
|
||||||
|
.wawi-page-head__actions {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Kennzahlen-Kacheln ------------------------------------------ */
|
||||||
|
.wawi-stats {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
.wawi-stat {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: .9rem;
|
||||||
|
padding: 1rem 1.1rem;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid var(--wawi-border);
|
||||||
|
border-radius: var(--wawi-radius);
|
||||||
|
box-shadow: var(--wawi-shadow);
|
||||||
|
}
|
||||||
|
.wawi-stat__icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 2.75rem;
|
||||||
|
height: 2.75rem;
|
||||||
|
border-radius: .55rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
background: var(--wawi-accent-soft);
|
||||||
|
color: var(--wawi-accent);
|
||||||
|
}
|
||||||
|
.wawi-stat__body { min-width: 0; }
|
||||||
|
.wawi-stat__value {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
.wawi-stat__label {
|
||||||
|
color: var(--wawi-muted);
|
||||||
|
font-size: .8rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .03em;
|
||||||
|
}
|
||||||
|
.wawi-stat--ok .wawi-stat__icon { background: rgba(40, 199, 111, .14); color: #28c76f; }
|
||||||
|
.wawi-stat--warning .wawi-stat__icon { background: rgba(255, 171, 0, .16); color: #ff9f00; }
|
||||||
|
.wawi-stat--danger .wawi-stat__icon { background: rgba(255, 91, 92, .14); color: #ff5b5c; }
|
||||||
|
.wawi-stat.is-clickable { cursor: pointer; transition: box-shadow .15s ease, transform .15s ease; }
|
||||||
|
.wawi-stat.is-clickable:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(24,28,33,.1); }
|
||||||
|
.wawi-stat.is-active { border-color: var(--wawi-accent); box-shadow: 0 0 0 1px var(--wawi-accent); }
|
||||||
|
|
||||||
|
/* --- Karte + Toolbar --------------------------------------------- */
|
||||||
|
.wawi-card {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid var(--wawi-border);
|
||||||
|
border-radius: var(--wawi-radius);
|
||||||
|
box-shadow: var(--wawi-shadow);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.wawi-toolbar {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: .75rem;
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
border-bottom: 1px solid var(--wawi-border);
|
||||||
|
}
|
||||||
|
.wawi-search {
|
||||||
|
position: relative;
|
||||||
|
flex: 1 1 260px;
|
||||||
|
max-width: 360px;
|
||||||
|
}
|
||||||
|
.wawi-search .fas {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: .85rem;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
color: var(--wawi-muted);
|
||||||
|
font-size: .85rem;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.wawi-search .form-control {
|
||||||
|
padding-left: 2.25rem;
|
||||||
|
border-radius: 2rem;
|
||||||
|
}
|
||||||
|
.wawi-toolbar__spacer { flex: 1 1 auto; }
|
||||||
|
.wawi-card__header {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: .5rem;
|
||||||
|
padding: .9rem 1.25rem;
|
||||||
|
border-bottom: 1px solid var(--wawi-border);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.wawi-card__footer {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: .5rem;
|
||||||
|
padding: .85rem 1.25rem;
|
||||||
|
border-top: 1px solid var(--wawi-border);
|
||||||
|
background: rgba(24, 28, 33, .015);
|
||||||
|
}
|
||||||
|
.wawi-card + .wawi-card { margin-top: 1.25rem; }
|
||||||
|
|
||||||
|
/* --- Tabelle ----------------------------------------------------- */
|
||||||
|
.wawi-page .wawi-table { margin-bottom: 0; }
|
||||||
|
.wawi-page .wawi-table thead th {
|
||||||
|
border-top: 0;
|
||||||
|
border-bottom: 1px solid var(--wawi-border);
|
||||||
|
background: rgba(24, 28, 33, .02);
|
||||||
|
color: var(--wawi-muted);
|
||||||
|
font-size: .72rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .04em;
|
||||||
|
padding-top: .8rem;
|
||||||
|
padding-bottom: .8rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.wawi-page .wawi-table tbody td {
|
||||||
|
vertical-align: middle;
|
||||||
|
padding-top: .7rem;
|
||||||
|
padding-bottom: .7rem;
|
||||||
|
border-top: 1px solid var(--wawi-border);
|
||||||
|
}
|
||||||
|
.wawi-page .wawi-table tbody tr { transition: background-color .12s ease; }
|
||||||
|
.wawi-page .wawi-table tbody tr:hover { background-color: rgba(24, 28, 33, .025); }
|
||||||
|
/* Status nur über schmale Akzent-Leiste links statt komplettem Zeilen-Rot */
|
||||||
|
.wawi-page .wawi-table tbody tr.is-warning td:first-child { box-shadow: inset .25rem 0 0 #ff9f00; }
|
||||||
|
.wawi-page .wawi-table tbody tr.is-danger td:first-child { box-shadow: inset .25rem 0 0 #ff5b5c; }
|
||||||
|
|
||||||
|
.wawi-thumb {
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
border-radius: .5rem;
|
||||||
|
object-fit: cover;
|
||||||
|
background: rgba(24, 28, 33, .03);
|
||||||
|
border: 1px solid var(--wawi-border);
|
||||||
|
}
|
||||||
|
.wawi-thumb--empty {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--wawi-muted);
|
||||||
|
}
|
||||||
|
.wawi-item-name { font-weight: 600; }
|
||||||
|
.wawi-item-sub { color: var(--wawi-muted); font-size: .8rem; }
|
||||||
|
/* Name-Zelle mit fester Icon-Spalte, damit umgebrochener Text nicht unter das Icon rutscht */
|
||||||
|
.wawi-name-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: .5rem;
|
||||||
|
}
|
||||||
|
.wawi-name-cell__icon {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-top: .15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Status-Pills ------------------------------------------------ */
|
||||||
|
.wawi-pill {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: .35rem;
|
||||||
|
padding: .2rem .6rem;
|
||||||
|
border-radius: 2rem;
|
||||||
|
font-size: .75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
.wawi-pill::before {
|
||||||
|
content: "";
|
||||||
|
width: .5rem;
|
||||||
|
height: .5rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: currentColor;
|
||||||
|
}
|
||||||
|
.wawi-pill--ok { background: rgba(40, 199, 111, .14); color: #1f9d57; }
|
||||||
|
.wawi-pill--warning { background: rgba(255, 171, 0, .16); color: #c77d00; }
|
||||||
|
.wawi-pill--danger { background: rgba(255, 91, 92, .14); color: #d63031; }
|
||||||
|
|
||||||
|
/* --- Aktionen ---------------------------------------------------- */
|
||||||
|
.wawi-actions {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: .35rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.wawi-actions .btn { margin: 0; }
|
||||||
|
|
||||||
|
/* --- Datenblatt / Definitionsliste ------------------------------- */
|
||||||
|
.wawi-deflist {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 0 2.5rem;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.wawi-deflist__item {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: .7rem 0;
|
||||||
|
border-bottom: 1px solid var(--wawi-border);
|
||||||
|
}
|
||||||
|
.wawi-deflist__label {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
color: var(--wawi-muted);
|
||||||
|
font-size: .8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .03em;
|
||||||
|
}
|
||||||
|
.wawi-deflist__value {
|
||||||
|
text-align: right;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.wawi-deflist__value .text-muted { font-weight: 400; }
|
||||||
|
/* Volle Breite erzwingen (z. B. Notizen) */
|
||||||
|
.wawi-deflist__item--wide { grid-column: 1 / -1; }
|
||||||
|
@media (max-width: 767.98px) {
|
||||||
|
.wawi-deflist { grid-template-columns: minmax(0, 1fr); }
|
||||||
|
.wawi-deflist__item {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: .15rem;
|
||||||
|
padding: .55rem 0;
|
||||||
|
}
|
||||||
|
.wawi-deflist__label { font-size: .72rem; }
|
||||||
|
.wawi-deflist__value { text-align: left; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Leerer Zustand ---------------------------------------------- */
|
||||||
|
.wawi-empty {
|
||||||
|
padding: 3rem 1rem;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--wawi-muted);
|
||||||
|
}
|
||||||
|
.wawi-empty .fas { font-size: 1.75rem; opacity: .5; margin-bottom: .5rem; }
|
||||||
|
</style>
|
||||||
|
@endonce
|
||||||
|
|
@ -1,9 +1,16 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<h4 class="font-weight-bold py-2 mb-2">{{ __('Produktentwicklung') }}</h4>
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
|
<div class="wawi-page">
|
||||||
|
<div class="wawi-page-head">
|
||||||
|
<div>
|
||||||
|
<h1 class="wawi-page-head__title">{{ __('Produktentwicklung') }}</h1>
|
||||||
|
<p class="wawi-page-head__subtitle">{{ __('Bereich in Vorbereitung') }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card wawi-card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="alert alert-info mb-0">
|
<div class="alert alert-info mb-0">
|
||||||
<h6 class="alert-heading font-weight-bold">{{ __('Briefing ausstehend') }}</h6>
|
<h6 class="alert-heading font-weight-bold">{{ __('Briefing ausstehend') }}</h6>
|
||||||
|
|
@ -16,4 +23,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -6,53 +6,67 @@
|
||||||
5 => __('Mai'), 6 => __('Juni'), 7 => __('Juli'), 8 => __('August'),
|
5 => __('Mai'), 6 => __('Juni'), 7 => __('Juli'), 8 => __('August'),
|
||||||
9 => __('September'), 10 => __('Oktober'), 11 => __('November'), 12 => __('Dezember'),
|
9 => __('September'), 10 => __('Oktober'), 11 => __('November'), 12 => __('Dezember'),
|
||||||
];
|
];
|
||||||
|
$hasFilter = $filters['product_id'] || $filters['direction'] || $filters['reason'] || $filters['month'] || $filters['year'];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
|
||||||
<h6 class="card-header">{{ __('Produktbestand Historie') }}</h6>
|
<div class="wawi-page">
|
||||||
<div class="card-body pb-0">
|
<div class="wawi-page-head">
|
||||||
<form method="get" action="{{ route('admin.inventory.product-stock.history') }}">
|
<div>
|
||||||
|
<h1 class="wawi-page-head__title">{{ __('Produktbestand Historie') }}</h1>
|
||||||
|
<p class="wawi-page-head__subtitle">{{ __('Alle Bestandsbewegungen (Eingang / Ausgang)') }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-page-head__actions">
|
||||||
|
<a href="{{ route('admin.inventory.product-stock.index') }}" class="btn btn-outline-secondary btn-sm">
|
||||||
|
<span class="fas fa-arrow-left mr-1"></span>{{ __('Zum Bestand') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="wawi-toolbar" style="align-items:flex-end;">
|
||||||
|
<form method="get" action="{{ route('admin.inventory.product-stock.history') }}" class="mb-0 w-100">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group col-md-3">
|
<div class="form-group col-md-3 mb-2">
|
||||||
<label class="small text-muted">{{ __('Produkt') }}</label>
|
<label class="small text-muted mb-1">{{ __('Produkt') }}</label>
|
||||||
<select name="product_id" class="form-control" onchange="this.form.submit()">
|
<select name="product_id" class="form-control form-control-sm" onchange="this.form.submit()">
|
||||||
<option value="">{{ __('Filter aus') }}</option>
|
<option value="">{{ __('Filter aus') }}</option>
|
||||||
@foreach ($products as $p)
|
@foreach ($products as $p)
|
||||||
<option value="{{ $p->id }}" @selected($filters['product_id'] === $p->id)>{{ $p->name }}</option>
|
<option value="{{ $p->id }}" @selected($filters['product_id'] === $p->id)>{{ $p->name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-2">
|
<div class="form-group col-md-2 mb-2">
|
||||||
<label class="small text-muted">{{ __('Eingang / Ausgang') }}</label>
|
<label class="small text-muted mb-1">{{ __('Eingang / Ausgang') }}</label>
|
||||||
<select name="direction" class="form-control" onchange="this.form.submit()">
|
<select name="direction" class="form-control form-control-sm" onchange="this.form.submit()">
|
||||||
<option value="">{{ __('Filter aus') }}</option>
|
<option value="">{{ __('Filter aus') }}</option>
|
||||||
<option value="in" @selected($filters['direction'] === 'in')>{{ __('Eingang') }}</option>
|
<option value="in" @selected($filters['direction'] === 'in')>{{ __('Eingang') }}</option>
|
||||||
<option value="out" @selected($filters['direction'] === 'out')>{{ __('Ausgang') }}</option>
|
<option value="out" @selected($filters['direction'] === 'out')>{{ __('Ausgang') }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-3">
|
<div class="form-group col-md-3 mb-2">
|
||||||
<label class="small text-muted">{{ __('Grund') }}</label>
|
<label class="small text-muted mb-1">{{ __('Grund') }}</label>
|
||||||
<select name="reason" class="form-control" onchange="this.form.submit()">
|
<select name="reason" class="form-control form-control-sm" onchange="this.form.submit()">
|
||||||
<option value="">{{ __('Filter aus') }}</option>
|
<option value="">{{ __('Filter aus') }}</option>
|
||||||
@foreach ($reasonOptions as $reason)
|
@foreach ($reasonOptions as $reason)
|
||||||
<option value="{{ $reason }}" @selected($filters['reason'] === $reason)>{{ $reason }}</option>
|
<option value="{{ $reason }}" @selected($filters['reason'] === $reason)>{{ $reason }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-2">
|
<div class="form-group col-md-2 mb-2">
|
||||||
<label class="small text-muted">{{ __('Monat') }}</label>
|
<label class="small text-muted mb-1">{{ __('Monat') }}</label>
|
||||||
<select name="month" class="form-control" onchange="this.form.submit()">
|
<select name="month" class="form-control form-control-sm" onchange="this.form.submit()">
|
||||||
<option value="">{{ __('Alle') }}</option>
|
<option value="">{{ __('Alle') }}</option>
|
||||||
@foreach ($months as $num => $label)
|
@foreach ($months as $num => $label)
|
||||||
<option value="{{ $num }}" @selected($filters['month'] === $num)>{{ $label }}</option>
|
<option value="{{ $num }}" @selected($filters['month'] === $num)>{{ $label }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-2">
|
<div class="form-group col-md-2 mb-2">
|
||||||
<label class="small text-muted">{{ __('Jahr') }}</label>
|
<label class="small text-muted mb-1">{{ __('Jahr') }}</label>
|
||||||
<select name="year" class="form-control" onchange="this.form.submit()">
|
<select name="year" class="form-control form-control-sm" onchange="this.form.submit()">
|
||||||
<option value="">{{ __('Alle') }}</option>
|
<option value="">{{ __('Alle') }}</option>
|
||||||
@foreach ($years as $y)
|
@foreach ($years as $y)
|
||||||
<option value="{{ $y }}" @selected($filters['year'] === $y)>{{ $y }}</option>
|
<option value="{{ $y }}" @selected($filters['year'] === $y)>{{ $y }}</option>
|
||||||
|
|
@ -60,13 +74,14 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if ($filters['product_id'] || $filters['direction'] || $filters['reason'] || $filters['month'] || $filters['year'])
|
@if ($hasFilter)
|
||||||
<a href="{{ route('admin.inventory.product-stock.history') }}" class="btn btn-sm btn-outline-secondary mb-3">{{ __('Filter zurücksetzen') }}</a>
|
<a href="{{ route('admin.inventory.product-stock.history') }}" class="btn btn-sm btn-outline-secondary">{{ __('Filter zurücksetzen') }}</a>
|
||||||
@endif
|
@endif
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-datatable table-responsive">
|
|
||||||
<table class="table table-striped wawi-table mb-0">
|
<div class="table-responsive">
|
||||||
|
<table class="table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ __('Produkt / Material') }}</th>
|
<th>{{ __('Produkt / Material') }}</th>
|
||||||
|
|
@ -80,12 +95,12 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
@forelse ($movements as $movement)
|
@forelse ($movements as $movement)
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $movement->product?->name ?? '—' }}</td>
|
<td><span class="wawi-item-name">{{ $movement->product?->name ?? '—' }}</span></td>
|
||||||
<td>
|
<td>
|
||||||
@if ($movement->isIn())
|
@if ($movement->isIn())
|
||||||
<span class="text-success">{{ __('Eingang') }}</span>
|
<span class="wawi-pill wawi-pill--ok">{{ __('Eingang') }}</span>
|
||||||
@else
|
@else
|
||||||
<span class="text-danger">{{ __('Ausgang') }}</span>
|
<span class="wawi-pill wawi-pill--danger">{{ __('Ausgang') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">{{ \App\Services\Util::formatNumber($movement->quantity, 0) }} {{ __('Stück') }}</td>
|
<td class="text-right">{{ \App\Services\Util::formatNumber($movement->quantity, 0) }} {{ __('Stück') }}</td>
|
||||||
|
|
@ -100,11 +115,17 @@
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="text-center text-muted py-4">{{ __('Keine Bewegungen gefunden.') }}</td>
|
<td colspan="6">
|
||||||
|
<div class="wawi-empty">
|
||||||
|
<div><span class="far fa-clock"></span></div>
|
||||||
|
{{ __('Keine Bewegungen gefunden.') }}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,120 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
|
@php
|
||||||
|
$total = $rows->count();
|
||||||
|
$criticalCount = $rows->where('status', 'critical')->count();
|
||||||
|
$warningCount = $rows->where('status', 'warning')->count();
|
||||||
|
$okCount = $total - $criticalCount - $warningCount;
|
||||||
|
@endphp
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
<div class="wawi-page">
|
||||||
<div class="d-flex flex-wrap justify-content-between align-items-center">
|
<div class="wawi-page-head">
|
||||||
<h6 class="mb-0">{{ __('Produktbestand') }}</h6>
|
<div>
|
||||||
|
<h1 class="wawi-page-head__title">{{ __('Produktbestand') }}</h1>
|
||||||
|
<p class="wawi-page-head__subtitle">{{ __('Aktueller Lagerbestand aller aktiven Produkte') }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-page-head__actions">
|
||||||
|
<a href="{{ route('admin.inventory.product-stock.history') }}" class="btn btn-outline-secondary btn-sm">
|
||||||
|
<span class="far fa-clock mr-1"></span>{{ __('Historie') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wawi-stats">
|
||||||
|
<div class="wawi-stat" data-filter="all">
|
||||||
|
<div class="wawi-stat__icon"><span class="fas fa-boxes-stacked"></span></div>
|
||||||
|
<div class="wawi-stat__body">
|
||||||
|
<div class="wawi-stat__value">{{ $total }}</div>
|
||||||
|
<div class="wawi-stat__label">{{ __('Produkte') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-stat wawi-stat--ok" data-filter="all">
|
||||||
|
<div class="wawi-stat__icon"><span class="fas fa-circle-check"></span></div>
|
||||||
|
<div class="wawi-stat__body">
|
||||||
|
<div class="wawi-stat__value">{{ $okCount }}</div>
|
||||||
|
<div class="wawi-stat__label">{{ __('Bestand OK') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-stat wawi-stat--warning is-clickable" data-filter="warning">
|
||||||
|
<div class="wawi-stat__icon"><span class="fas fa-triangle-exclamation"></span></div>
|
||||||
|
<div class="wawi-stat__body">
|
||||||
|
<div class="wawi-stat__value">{{ $warningCount }}</div>
|
||||||
|
<div class="wawi-stat__label">{{ __('Niedrig') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-stat wawi-stat--danger is-clickable" data-filter="critical">
|
||||||
|
<div class="wawi-stat__icon"><span class="fas fa-circle-exclamation"></span></div>
|
||||||
|
<div class="wawi-stat__body">
|
||||||
|
<div class="wawi-stat__value">{{ $criticalCount }}</div>
|
||||||
|
<div class="wawi-stat__label">{{ __('Kritisch') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="wawi-toolbar">
|
||||||
|
<div class="wawi-search">
|
||||||
|
<span class="fas fa-search"></span>
|
||||||
|
<input type="text" id="ps-search" class="form-control" autocomplete="off"
|
||||||
|
placeholder="{{ __('Produkt suchen …') }}">
|
||||||
|
</div>
|
||||||
|
<div class="wawi-toolbar__spacer"></div>
|
||||||
<label class="form-check d-inline-flex align-items-center mb-0">
|
<label class="form-check d-inline-flex align-items-center mb-0">
|
||||||
<input type="checkbox" id="ps-only-critical" class="form-check-input mr-2">
|
<input type="checkbox" id="ps-only-critical" class="form-check-input mr-2">
|
||||||
<span>{{ __('nur kritische anzeigen') }}</span>
|
<span>{{ __('nur kritische anzeigen') }}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mt-3 mb-0 align-items-center">
|
|
||||||
<label for="ps-search" class="col-sm-1 col-form-label">{{ __('Suchen') }}</label>
|
<div class="table-responsive">
|
||||||
<div class="col-sm-5">
|
<table class="table wawi-table" id="ps-table">
|
||||||
<input type="text" id="ps-search" class="form-control" autocomplete="off">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-datatable table-responsive">
|
|
||||||
<table class="table table-striped wawi-table mb-0" id="ps-table">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width:4rem"></th>
|
<th style="width:3.5rem"></th>
|
||||||
<th>{{ __('Name') }}</th>
|
<th>{{ __('Name') }}</th>
|
||||||
<th class="text-right">{{ __('Bestand') }}</th>
|
<th class="text-right">{{ __('Bestand') }}</th>
|
||||||
<th style="width:18rem">{{ __('Aktion') }}</th>
|
<th>{{ __('Status') }}</th>
|
||||||
|
<th class="text-right" style="width:16rem">{{ __('Aktion') }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@forelse($rows as $row)
|
@forelse($rows as $row)
|
||||||
@php
|
@php
|
||||||
$product = $row['product'];
|
$product = $row['product'];
|
||||||
$rowClass = $row['status'] === 'critical' ? 'table-danger' : ($row['status'] === 'warning' ? 'table-warning' : '');
|
$rowClass = $row['status'] === 'critical' ? 'is-danger' : ($row['status'] === 'warning' ? 'is-warning' : '');
|
||||||
$stockClass = $row['status'] === 'critical' ? 'text-danger font-weight-bold' : ($row['status'] === 'warning' ? 'text-warning font-weight-bold' : '');
|
$stockClass = $row['status'] === 'critical' ? 'text-danger font-weight-bold' : ($row['status'] === 'warning' ? 'text-warning font-weight-bold' : '');
|
||||||
@endphp
|
@endphp
|
||||||
<tr class="ps-row {{ $rowClass }}" data-name="{{ Str::lower($product->name) }} {{ Str::lower($product->number ?? '') }}" data-status="{{ $row['status'] }}">
|
<tr class="ps-row {{ $rowClass }}" data-name="{{ Str::lower($product->name) }} {{ Str::lower($product->number ?? '') }}" data-status="{{ $row['status'] }}">
|
||||||
<td>
|
<td>
|
||||||
@if ($product->images->count())
|
@if ($product->images->count())
|
||||||
<img class="img-fluid" alt="" style="max-height: 42px"
|
<img class="wawi-thumb" alt=""
|
||||||
src="{{ route('product_image', [$product->images->first()->slug]) }}">
|
src="{{ route('product_image', [$product->images->first()->slug]) }}">
|
||||||
|
@else
|
||||||
|
<span class="wawi-thumb wawi-thumb--empty"><span class="far fa-image"></span></span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td>{{ $product->name }}</td>
|
|
||||||
<td class="text-right {{ $stockClass }}">{{ \App\Services\Util::formatNumber($row['stock'], 0) }} {{ __('Stück') }}</td>
|
|
||||||
<td>
|
<td>
|
||||||
|
<div class="wawi-item-name">{{ $product->name }}</div>
|
||||||
|
@if (!empty($product->number))
|
||||||
|
<div class="wawi-item-sub">{{ $product->number }}</div>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td class="text-right {{ $stockClass }}">
|
||||||
|
{{ \App\Services\Util::formatNumber($row['stock'], 0) }} <span class="text-muted">{{ __('Stück') }}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@if ($row['status'] === 'critical')
|
||||||
|
<span class="wawi-pill wawi-pill--danger">{{ __('Kritisch') }}</span>
|
||||||
|
@elseif ($row['status'] === 'warning')
|
||||||
|
<span class="wawi-pill wawi-pill--warning">{{ __('Niedrig') }}</span>
|
||||||
|
@else
|
||||||
|
<span class="wawi-pill wawi-pill--ok">{{ __('OK') }}</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<div class="wawi-actions">
|
||||||
@if (Auth::user()->isAdmin())
|
@if (Auth::user()->isAdmin())
|
||||||
<button type="button" class="btn icon-btn btn-sm btn-success js-ps-move"
|
<button type="button" class="btn icon-btn btn-sm btn-success js-ps-move"
|
||||||
data-product="{{ $product->id }}" data-name="{{ $product->name }}" data-direction="in"
|
data-product="{{ $product->id }}" data-name="{{ $product->name }}" data-direction="in"
|
||||||
|
|
@ -54,18 +124,26 @@
|
||||||
title="{{ __('Ausgang buchen') }}"><span class="fas fa-minus"></span></button>
|
title="{{ __('Ausgang buchen') }}"><span class="fas fa-minus"></span></button>
|
||||||
@endif
|
@endif
|
||||||
<a href="{{ route('admin.inventory.productions.create', ['product_id' => $product->id]) }}"
|
<a href="{{ route('admin.inventory.productions.create', ['product_id' => $product->id]) }}"
|
||||||
class="btn btn-sm btn-dark">{{ __('Produzieren') }}</a>
|
class="btn btn-sm btn-outline-secondary">
|
||||||
|
<span class="fas fa-flask mr-1"></span>{{ __('Produzieren') }}</a>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="4" class="text-center text-muted py-4">{{ __('Keine Produkte vorhanden.') }}</td>
|
<td colspan="5">
|
||||||
|
<div class="wawi-empty">
|
||||||
|
<div><span class="fas fa-boxes-stacked"></span></div>
|
||||||
|
{{ __('Keine Produkte vorhanden.') }}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
@if (Auth::user()->isAdmin())
|
@if (Auth::user()->isAdmin())
|
||||||
<div class="modal fade" id="ps-move-modal" tabindex="-1" role="dialog" aria-hidden="true">
|
<div class="modal fade" id="ps-move-modal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
|
|
@ -126,6 +204,18 @@
|
||||||
$('#ps-search').on('keyup', applyFilter);
|
$('#ps-search').on('keyup', applyFilter);
|
||||||
$('#ps-only-critical').on('change', applyFilter);
|
$('#ps-only-critical').on('change', applyFilter);
|
||||||
|
|
||||||
|
$('.wawi-stat.is-clickable').on('click', function () {
|
||||||
|
var filter = $(this).data('filter');
|
||||||
|
var $this = $(this);
|
||||||
|
var wasActive = $this.hasClass('is-active');
|
||||||
|
$('.wawi-stat').removeClass('is-active');
|
||||||
|
if (filter === 'critical' || filter === 'warning') {
|
||||||
|
$('#ps-only-critical').prop('checked', !wasActive);
|
||||||
|
if (!wasActive) { $this.addClass('is-active'); }
|
||||||
|
applyFilter();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var moveTemplate = "{{ route('admin.inventory.product-stock.movement', ['product' => '__ID__']) }}";
|
var moveTemplate = "{{ route('admin.inventory.product-stock.movement', ['product' => '__ID__']) }}";
|
||||||
$('.js-ps-move').on('click', function () {
|
$('.js-ps-move').on('click', function () {
|
||||||
var id = $(this).data('product');
|
var id = $(this).data('product');
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,24 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
<div class="wawi-page">
|
||||||
<span>{{ __('Produktionen') }}</span>
|
<div class="wawi-page-head">
|
||||||
<a href="{{ route('admin.inventory.productions.create') }}" class="btn btn-sm btn-primary">{{ __('Neue Produktion') }}</a>
|
<div>
|
||||||
</h6>
|
<h1 class="wawi-page-head__title">{{ __('Produktionen') }}</h1>
|
||||||
<div class="card-datatable table-responsive">
|
<p class="wawi-page-head__subtitle">{{ __('Erfasste Produktionschargen inkl. Rohstoff- und Verpackungsverbrauch') }}</p>
|
||||||
<table class="datatables-style table table-striped table-bordered wawi-table">
|
</div>
|
||||||
|
<div class="wawi-page-head__actions">
|
||||||
|
<a href="{{ route('admin.inventory.productions.create') }}" class="btn btn-primary btn-sm">
|
||||||
|
<span class="fas fa-plus mr-1"></span>{{ __('Neue Produktion') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="card-datatable table-responsive p-2">
|
||||||
|
<table class="datatables-style table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="max-width: 130px;"></th>
|
<th style="max-width: 130px;"></th>
|
||||||
|
|
@ -34,12 +44,12 @@
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td data-sort="{{ $row->produced_at?->timestamp ?? 0 }}">{{ $row->produced_at?->format('d.m.Y') }}</td>
|
<td data-sort="{{ $row->produced_at?->timestamp ?? 0 }}">{{ $row->produced_at?->format('d.m.Y') }}</td>
|
||||||
<td>{{ $row->product?->name ?? '—' }}</td>
|
<td><span class="wawi-item-name">{{ $row->product?->name ?? '—' }}</span></td>
|
||||||
<td>{{ $row->quantity }}</td>
|
<td>{{ $row->quantity }}</td>
|
||||||
<td>{{ $row->location?->name ?? '—' }}</td>
|
<td>{{ $row->location?->name ?? '—' }}</td>
|
||||||
<td>
|
<td>
|
||||||
@if($row->mhd_warning)
|
@if($row->mhd_warning)
|
||||||
<span class="badge badge-warning">{{ __('Ja') }}</span>
|
<span class="wawi-pill wawi-pill--warning">{{ __('Ja') }}</span>
|
||||||
@else
|
@else
|
||||||
<span class="text-muted">—</span>
|
<span class="text-muted">—</span>
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -50,6 +60,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.datatables-style').dataTable({
|
$('.datatables-style').dataTable({
|
||||||
|
|
|
||||||
|
|
@ -5,50 +5,69 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<h4 class="font-weight-bold py-2 mb-2">{{ __('Produktion') }} #{{ $model->id }}</h4>
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
|
<div class="wawi-page">
|
||||||
<div class="card mb-3">
|
<div class="wawi-page-head">
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
|
||||||
<span>{{ __('Übersicht') }}</span>
|
|
||||||
<div>
|
<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.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.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>
|
<a href="{{ route('admin.inventory.productions.index') }}" class="btn btn-sm btn-outline-secondary">{{ __('Zurück') }}</a>
|
||||||
</div>
|
</div>
|
||||||
</h6>
|
</div>
|
||||||
|
|
||||||
|
<div class="card wawi-card mb-3">
|
||||||
|
<div class="wawi-card__header">{{ __('Übersicht') }}</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<dl class="row mb-0">
|
<div class="wawi-deflist">
|
||||||
<dt class="col-sm-3">{{ __('Produkt') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->product?->name ?? '—' }}</dd>
|
<span class="wawi-deflist__label">{{ __('Produkt') }}</span>
|
||||||
<dt class="col-sm-3">{{ __('Produktionsdatum') }}</dt>
|
<span class="wawi-deflist__value">{{ $model->product?->name ?? '—' }}</span>
|
||||||
<dd class="col-sm-9">{{ $model->produced_at?->format('d.m.Y') }}</dd>
|
</div>
|
||||||
<dt class="col-sm-3">{{ __('Stückzahl') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->quantity }}</dd>
|
<span class="wawi-deflist__label">{{ __('Produktionsdatum') }}</span>
|
||||||
<dt class="col-sm-3">{{ __('Standort') }}</dt>
|
<span class="wawi-deflist__value">{{ $model->produced_at?->format('d.m.Y') }}</span>
|
||||||
<dd class="col-sm-9">{{ $model->location?->name ?? '—' }}</dd>
|
</div>
|
||||||
<dt class="col-sm-3">{{ __('Erfasst von') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->producedByUser?->getFullName(false) ?: $model->producedByUser?->email ?? '—' }}</dd>
|
<span class="wawi-deflist__label">{{ __('Stückzahl') }}</span>
|
||||||
<dt class="col-sm-3">{{ __('MHD-Hinweis') }}</dt>
|
<span class="wawi-deflist__value">{{ $model->quantity }}</span>
|
||||||
<dd class="col-sm-9">
|
</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)
|
@if($model->mhd_warning)
|
||||||
<span class="badge badge-warning">{{ __('Rohstoff-MHD kürzer als Produkt-MHD') }}</span>
|
<span class="wawi-pill wawi-pill--warning">{{ __('Rohstoff-MHD kürzer als Produkt-MHD') }}</span>
|
||||||
@else
|
@else
|
||||||
—
|
—
|
||||||
@endif
|
@endif
|
||||||
</dd>
|
</span>
|
||||||
|
</div>
|
||||||
@if($model->notes)
|
@if($model->notes)
|
||||||
<dt class="col-sm-3">{{ __('Notizen') }}</dt>
|
<div class="wawi-deflist__item wawi-deflist__item--wide">
|
||||||
<dd class="col-sm-9">{{ $model->notes }}</dd>
|
<span class="wawi-deflist__label">{{ __('Notizen') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $model->notes }}</span>
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</dl>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-3">
|
<div class="card wawi-card mb-3">
|
||||||
<h6 class="card-header">{{ __('Rohstoff-Verbrauch (Chargen)') }}</h6>
|
<div class="wawi-card__header">{{ __('Rohstoff-Verbrauch (Chargen)') }}</div>
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped mb-0">
|
<table class="table wawi-table mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ __('Inhaltsstoff') }}</th>
|
<th>{{ __('Inhaltsstoff') }}</th>
|
||||||
|
|
@ -78,11 +97,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card wawi-card">
|
||||||
<h6 class="card-header">{{ __('Verpackung (Snapshot)') }}</h6>
|
<div class="wawi-card__header">{{ __('Verpackung (Snapshot)') }}</div>
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped mb-0">
|
<table class="table wawi-table mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ __('Artikel') }}</th>
|
<th>{{ __('Artikel') }}</th>
|
||||||
|
|
@ -101,4 +120,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,79 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
|
@php
|
||||||
|
$total = $rows->count();
|
||||||
|
$criticalCount = $rows->whereIn('status', ['critical', 'critical_ordered'])->count();
|
||||||
|
$warningCount = $rows->where('status', 'warning')->count();
|
||||||
|
$okCount = $total - $criticalCount - $warningCount;
|
||||||
|
@endphp
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<style>
|
<style>
|
||||||
#rms-table tbody tr.rms-row {
|
#rms-table tbody tr.rms-row { cursor: pointer; }
|
||||||
cursor: pointer;
|
#rms-table tbody tr.rms-row:hover .fa-edit { color: var(--wawi-accent) !important; }
|
||||||
}
|
|
||||||
#rms-table tbody tr.rms-row:hover {
|
|
||||||
background-color: rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
#rms-table tbody tr.rms-row:hover .fa-edit {
|
|
||||||
color: #26b4ff !important;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
<div class="wawi-page">
|
||||||
<div class="d-flex flex-wrap justify-content-between align-items-center">
|
<div class="wawi-page-head">
|
||||||
<h6 class="mb-0">{{ __('Rohstoffbestand') }}</h6>
|
<div>
|
||||||
|
<h1 class="wawi-page-head__title">{{ __('Rohstoffbestand') }}</h1>
|
||||||
|
<p class="wawi-page-head__subtitle">{{ __('Verfügbare Rohstoffe inkl. Reichweite und Nachbestellung') }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-page-head__actions">
|
||||||
|
<a href="{{ route('admin.inventory.stock-entries.create') }}" class="btn btn-outline-secondary btn-sm">
|
||||||
|
<span class="fas fa-truck mr-1"></span>{{ __('Einkauf erfassen') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wawi-stats">
|
||||||
|
<div class="wawi-stat">
|
||||||
|
<div class="wawi-stat__icon"><span class="fas fa-flask"></span></div>
|
||||||
|
<div class="wawi-stat__body">
|
||||||
|
<div class="wawi-stat__value">{{ $total }}</div>
|
||||||
|
<div class="wawi-stat__label">{{ __('Rohstoffe') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-stat wawi-stat--ok">
|
||||||
|
<div class="wawi-stat__icon"><span class="fas fa-circle-check"></span></div>
|
||||||
|
<div class="wawi-stat__body">
|
||||||
|
<div class="wawi-stat__value">{{ $okCount }}</div>
|
||||||
|
<div class="wawi-stat__label">{{ __('Bestand OK') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-stat wawi-stat--warning is-clickable" data-filter="warning">
|
||||||
|
<div class="wawi-stat__icon"><span class="fas fa-triangle-exclamation"></span></div>
|
||||||
|
<div class="wawi-stat__body">
|
||||||
|
<div class="wawi-stat__value">{{ $warningCount }}</div>
|
||||||
|
<div class="wawi-stat__label">{{ __('Bald nachbestellen') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-stat wawi-stat--danger is-clickable" data-filter="critical">
|
||||||
|
<div class="wawi-stat__icon"><span class="fas fa-circle-exclamation"></span></div>
|
||||||
|
<div class="wawi-stat__body">
|
||||||
|
<div class="wawi-stat__value">{{ $criticalCount }}</div>
|
||||||
|
<div class="wawi-stat__label">{{ __('Kritisch') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="wawi-toolbar">
|
||||||
|
<div class="wawi-search">
|
||||||
|
<span class="fas fa-search"></span>
|
||||||
|
<input type="text" id="rms-search" class="form-control" autocomplete="off"
|
||||||
|
placeholder="{{ __('Rohstoff suchen …') }}">
|
||||||
|
</div>
|
||||||
|
<div class="wawi-toolbar__spacer"></div>
|
||||||
<label class="form-check d-inline-flex align-items-center mb-0">
|
<label class="form-check d-inline-flex align-items-center mb-0">
|
||||||
<input type="checkbox" id="rms-only-critical" class="form-check-input mr-2">
|
<input type="checkbox" id="rms-only-critical" class="form-check-input mr-2">
|
||||||
<span>{{ __('nur kritische anzeigen') }}</span>
|
<span>{{ __('nur kritische anzeigen') }}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mt-3 mb-0 align-items-center">
|
|
||||||
<label for="rms-search" class="col-sm-1 col-form-label">{{ __('Suchen') }}</label>
|
<div class="table-responsive">
|
||||||
<div class="col-sm-5">
|
<table class="table wawi-table" id="rms-table">
|
||||||
<input type="text" id="rms-search" class="form-control" autocomplete="off">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-datatable table-responsive">
|
|
||||||
<table class="table table-striped wawi-table mb-0" id="rms-table">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ __('Name') }}</th>
|
<th>{{ __('Name') }}</th>
|
||||||
|
|
@ -53,22 +96,24 @@
|
||||||
@php
|
@php
|
||||||
$ingredient = $row['ingredient'];
|
$ingredient = $row['ingredient'];
|
||||||
$rowClass = $row['status'] === 'critical'
|
$rowClass = $row['status'] === 'critical'
|
||||||
? 'table-danger'
|
? 'is-danger'
|
||||||
: (in_array($row['status'], ['warning', 'critical_ordered'], true) ? 'table-warning' : '');
|
: (in_array($row['status'], ['warning', 'critical_ordered'], true) ? 'is-warning' : '');
|
||||||
@endphp
|
@endphp
|
||||||
<tr class="rms-row {{ $rowClass }}"
|
<tr class="rms-row {{ $rowClass }}"
|
||||||
data-name="{{ Str::lower($ingredient->name) }} {{ Str::lower($ingredient->inci ?? '') }}"
|
data-name="{{ Str::lower($ingredient->name) }} {{ Str::lower($ingredient->inci ?? '') }}"
|
||||||
data-status="{{ $row['status'] }}"
|
data-status="{{ $row['status'] }}"
|
||||||
data-href="{{ route('admin.inventory.raw-material-stock.show', $ingredient) }}">
|
data-href="{{ route('admin.inventory.raw-material-stock.show', $ingredient) }}">
|
||||||
<td>
|
<td>
|
||||||
<i class="far fa-edit text-muted mr-2" title="{{ __('Bestellung öffnen') }}"></i>
|
<span class="wawi-name-cell">
|
||||||
{{ $ingredient->name }}
|
<i class="far fa-edit text-muted wawi-name-cell__icon" title="{{ __('Bestellung öffnen') }}"></i>
|
||||||
|
<span class="wawi-item-name">{{ $ingredient->name }}</span>
|
||||||
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-muted">{{ $ingredient->materialQuality?->name ?? '—' }}</td>
|
<td class="text-muted">{{ $ingredient->materialQuality?->name ?? '—' }}</td>
|
||||||
<td class="text-right {{ in_array($row['status'], ['critical', 'critical_ordered'], true) ? 'text-danger font-weight-bold' : '' }}">
|
<td class="text-right {{ in_array($row['status'], ['critical', 'critical_ordered'], true) ? 'text-danger font-weight-bold' : '' }}">
|
||||||
{{ \App\Services\Util::formatNumber($row['remaining'], 0) }} g
|
{{ \App\Services\Util::formatNumber($row['remaining'], 0) }} g
|
||||||
@if($row['status'] === 'critical_ordered')
|
@if($row['status'] === 'critical_ordered')
|
||||||
<span class="badge badge-info ml-1">{{ __('bestellt') }}</span>
|
<span class="wawi-pill wawi-pill--warning ml-1">{{ __('bestellt') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
|
|
@ -103,13 +148,19 @@
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="7" class="text-center text-muted py-4">{{ __('Keine aktiven Rohstoffe vorhanden.') }}</td>
|
<td colspan="7">
|
||||||
|
<div class="wawi-empty">
|
||||||
|
<div><span class="fas fa-flask"></span></div>
|
||||||
|
{{ __('Keine aktiven Rohstoffe vorhanden.') }}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
@ -123,7 +174,7 @@
|
||||||
var $row = $(this);
|
var $row = $(this);
|
||||||
var matchesTerm = term === '' || ($row.data('name') || '').toString().indexOf(term) !== -1;
|
var matchesTerm = term === '' || ($row.data('name') || '').toString().indexOf(term) !== -1;
|
||||||
var status = $row.data('status');
|
var status = $row.data('status');
|
||||||
var matchesCritical = !onlyCritical || (status === 'critical' || status === 'warning');
|
var matchesCritical = !onlyCritical || (status === 'critical' || status === 'critical_ordered' || status === 'warning');
|
||||||
$row.toggle(matchesTerm && matchesCritical);
|
$row.toggle(matchesTerm && matchesCritical);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -145,6 +196,15 @@
|
||||||
$('#rms-only-critical').on('change', applyFilter);
|
$('#rms-only-critical').on('change', applyFilter);
|
||||||
$('#rms-horizon').on('change', applyForecast);
|
$('#rms-horizon').on('change', applyForecast);
|
||||||
|
|
||||||
|
$('.wawi-stat.is-clickable').on('click', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var wasActive = $this.hasClass('is-active');
|
||||||
|
$('.wawi-stat').removeClass('is-active');
|
||||||
|
$('#rms-only-critical').prop('checked', !wasActive);
|
||||||
|
if (!wasActive) { $this.addClass('is-active'); }
|
||||||
|
applyFilter();
|
||||||
|
});
|
||||||
|
|
||||||
$rows.on('click', function () {
|
$rows.on('click', function () {
|
||||||
var href = $(this).data('href');
|
var href = $(this).data('href');
|
||||||
if (href) {
|
if (href) {
|
||||||
|
|
|
||||||
|
|
@ -1,78 +1,86 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@php
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
$statusPill = match ($status) {
|
||||||
|
'critical' => '<span class="wawi-pill wawi-pill--danger">' . __('Kritisch') . '</span>',
|
||||||
@php
|
'critical_ordered' => '<span class="wawi-pill wawi-pill--warning">' . __('Kritisch · bereits bestellt') . '</span>',
|
||||||
$statusBadge = match ($status) {
|
'warning' => '<span class="wawi-pill wawi-pill--warning">' . __('Bald nachbestellen') . '</span>',
|
||||||
'critical' => '<span class="badge badge-danger">' . __('Kritisch') . '</span>',
|
default => '<span class="wawi-pill wawi-pill--ok">' . __('Ausreichend') . '</span>',
|
||||||
'critical_ordered' => '<span class="badge badge-warning">' . __('Kritisch · bereits bestellt') . '</span>',
|
|
||||||
'warning' => '<span class="badge badge-warning">' . __('Bald nachbestellen') . '</span>',
|
|
||||||
default => '<span class="badge badge-success">' . __('Ausreichend') . '</span>',
|
|
||||||
};
|
};
|
||||||
@endphp
|
$stockCritical = in_array($status, ['critical', 'critical_ordered'], true);
|
||||||
|
@endphp
|
||||||
|
|
||||||
<div class="card mb-3">
|
@section('content')
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<span>{{ __('Rohstoffbestellung') }}: {{ $ingredient->name }} {!! $statusBadge !!}</span>
|
|
||||||
<a href="{{ route('admin.inventory.raw-material-stock.index') }}" class="btn btn-sm btn-outline-secondary">{{ __('Zurück') }}</a>
|
<div class="wawi-page">
|
||||||
</h6>
|
<div class="wawi-page-head">
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3 col-6 mb-2">
|
|
||||||
<div class="text-muted small">{{ __('Qualität') }}</div>
|
|
||||||
<div>{{ $ingredient->materialQuality?->name ?? '—' }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3 col-6 mb-2">
|
|
||||||
<div class="text-muted small">{{ __('Gesamtbestand') }}</div>
|
|
||||||
<div class="{{ in_array($status, ['critical', 'critical_ordered'], true) ? 'text-danger font-weight-bold' : 'font-weight-bold' }}">
|
|
||||||
{{ \App\Services\Util::formatNumber($remaining, 0) }} g
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3 col-6 mb-2">
|
|
||||||
<div class="text-muted small">{{ __('Offen bestellt') }}</div>
|
|
||||||
<div>
|
<div>
|
||||||
@if($openTotal > 0)
|
<h1 class="wawi-page-head__title">
|
||||||
{{ \App\Services\Util::formatNumber($openTotal, 0) }} g
|
{{ $ingredient->name }} {!! $statusPill !!}
|
||||||
@else
|
</h1>
|
||||||
—
|
<p class="wawi-page-head__subtitle">{{ __('Rohstoffbestellung & Bestand') }}</p>
|
||||||
@endif
|
</div>
|
||||||
|
<div class="wawi-page-head__actions">
|
||||||
|
<a href="{{ route('admin.inventory.raw-material-stock.index') }}" class="btn btn-outline-secondary btn-sm">
|
||||||
|
<span class="fas fa-arrow-left mr-1"></span>{{ __('Zurück') }}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3 col-6 mb-2">
|
|
||||||
<div class="text-muted small">{{ __('Verbrauch / Tag') }}</div>
|
<div class="wawi-stats">
|
||||||
<div>
|
<div class="wawi-stat {{ $stockCritical ? 'wawi-stat--danger' : 'wawi-stat--ok' }}">
|
||||||
@if($daily !== null && $daily > 0)
|
<div class="wawi-stat__icon"><span class="fas fa-warehouse"></span></div>
|
||||||
{{ \App\Services\Util::formatNumber($daily, 0) }} g
|
<div class="wawi-stat__body">
|
||||||
@else
|
<div class="wawi-stat__value">{{ \App\Services\Util::formatNumber($remaining, 0) }} g</div>
|
||||||
—
|
<div class="wawi-stat__label">{{ __('Gesamtbestand') }}</div>
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3 col-6 mb-2">
|
<div class="wawi-stat">
|
||||||
<div class="text-muted small">{{ __('Voraussichtlich auf Null') }}</div>
|
<div class="wawi-stat__icon"><span class="fas fa-truck"></span></div>
|
||||||
<div>
|
<div class="wawi-stat__body">
|
||||||
|
<div class="wawi-stat__value">{{ $openTotal > 0 ? \App\Services\Util::formatNumber($openTotal, 0) . ' g' : '—' }}</div>
|
||||||
|
<div class="wawi-stat__label">{{ __('Offen bestellt') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-stat">
|
||||||
|
<div class="wawi-stat__icon"><span class="fas fa-gauge-high"></span></div>
|
||||||
|
<div class="wawi-stat__body">
|
||||||
|
<div class="wawi-stat__value">{{ ($daily !== null && $daily > 0) ? \App\Services\Util::formatNumber($daily, 0) . ' g' : '—' }}</div>
|
||||||
|
<div class="wawi-stat__label">{{ __('Verbrauch / Tag') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-stat {{ ($expectedEmpty !== null && $daysUntilEmpty <= 30) ? 'wawi-stat--warning' : '' }}">
|
||||||
|
<div class="wawi-stat__icon"><span class="fas fa-hourglass-half"></span></div>
|
||||||
|
<div class="wawi-stat__body">
|
||||||
|
<div class="wawi-stat__value">{{ $expectedEmpty !== null ? $expectedEmpty->format('d.m.Y') : '—' }}</div>
|
||||||
|
<div class="wawi-stat__label">
|
||||||
|
{{ __('Voraussichtlich auf Null') }}
|
||||||
@if($expectedEmpty !== null)
|
@if($expectedEmpty !== null)
|
||||||
{{ $expectedEmpty->format('d.m.Y') }}
|
({{ $daysUntilEmpty }} {{ trans_choice('Tag|Tagen', $daysUntilEmpty) }})
|
||||||
<span class="text-muted">({{ $daysUntilEmpty }} {{ trans_choice('Tag|Tagen', $daysUntilEmpty) }})</span>
|
|
||||||
@else
|
|
||||||
—
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if($ingredient->min_stock_alert !== null)
|
|
||||||
<div class="text-muted small mt-2">
|
|
||||||
{{ __('Meldebestand') }}: {{ \App\Services\Util::formatNumber($ingredient->min_stock_alert, 0) }} g
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="wawi-card" style="margin-bottom:1.25rem;">
|
||||||
|
<div class="wawi-card__footer" style="border-top:0; background:transparent;">
|
||||||
|
<span class="text-muted small mr-3">
|
||||||
|
{{ __('Qualität') }}: <strong>{{ $ingredient->materialQuality?->name ?? '—' }}</strong>
|
||||||
|
</span>
|
||||||
|
@if($ingredient->min_stock_alert !== null)
|
||||||
|
<span class="text-muted small">
|
||||||
|
{{ __('Meldebestand') }}: <strong>{{ \App\Services\Util::formatNumber($ingredient->min_stock_alert, 0) }} g</strong>
|
||||||
|
</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-3">
|
<div class="wawi-card">
|
||||||
<h6 class="card-header">{{ __('Enthalten in') }}</h6>
|
<div class="wawi-card__header">{{ __('Enthalten in') }}</div>
|
||||||
<div class="card-datatable table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped wawi-table mb-0">
|
<table class="table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ __('Produkt') }}</th>
|
<th>{{ __('Produkt') }}</th>
|
||||||
|
|
@ -95,7 +103,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3" class="text-center text-muted py-3">{{ __('Dieser Rohstoff wird in keiner aktiven Rezeptur verwendet.') }}</td>
|
<td colspan="3"><div class="wawi-empty">{{ __('Dieser Rohstoff wird in keiner aktiven Rezeptur verwendet.') }}</div></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
@ -103,10 +111,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-3">
|
<div class="wawi-card">
|
||||||
<h6 class="card-header">{{ __('Lieferanten & Bestellung') }}</h6>
|
<div class="wawi-card__header">{{ __('Lieferanten & Bestellung') }}</div>
|
||||||
<div class="card-datatable table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped wawi-table mb-0">
|
<table class="table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ __('Lieferant') }}</th>
|
<th>{{ __('Lieferant') }}</th>
|
||||||
|
|
@ -125,12 +133,12 @@
|
||||||
@endphp
|
@endphp
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{ $supplier->name }}
|
<span class="wawi-item-name">{{ $supplier->name }}</span>
|
||||||
@if($supplier->pivot->preferred)
|
@if($supplier->pivot->preferred)
|
||||||
<span class="badge badge-success ml-1">{{ __('bevorzugt') }}</span>
|
<span class="wawi-pill wawi-pill--ok ml-1">{{ __('bevorzugt') }}</span>
|
||||||
@endif
|
@endif
|
||||||
@if($supplier->pivot->supplier_sku)
|
@if($supplier->pivot->supplier_sku)
|
||||||
<div class="text-muted small">{{ __('Art.-Nr.') }}: {{ $supplier->pivot->supplier_sku }}</div>
|
<div class="wawi-item-sub">{{ __('Art.-Nr.') }}: {{ $supplier->pivot->supplier_sku }}</div>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td>{{ $deliveryTime ?: '—' }}</td>
|
<td>{{ $deliveryTime ?: '—' }}</td>
|
||||||
|
|
@ -143,11 +151,11 @@
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
@if($supplier->order_method === 'online_shop' && $orderUrl)
|
@if($supplier->order_method === 'online_shop' && $orderUrl)
|
||||||
<a href="{{ $orderUrl }}" target="_blank" rel="noopener" class="btn btn-sm btn-dark">{{ __('Zum Shop') }}</a>
|
<a href="{{ $orderUrl }}" target="_blank" rel="noopener" class="btn btn-sm btn-outline-secondary">{{ __('Zum Shop') }}</a>
|
||||||
@elseif($orderEmail)
|
@elseif($orderEmail)
|
||||||
<a href="mailto:{{ $orderEmail }}?subject={{ rawurlencode(__('Bestellung') . ': ' . $ingredient->name) }}" class="btn btn-sm btn-dark">{{ __('Per Mail') }}</a>
|
<a href="mailto:{{ $orderEmail }}?subject={{ rawurlencode(__('Bestellung') . ': ' . $ingredient->name) }}" class="btn btn-sm btn-outline-secondary">{{ __('Per Mail') }}</a>
|
||||||
@elseif($orderUrl)
|
@elseif($orderUrl)
|
||||||
<a href="{{ $orderUrl }}" target="_blank" rel="noopener" class="btn btn-sm btn-dark">{{ __('Zum Shop') }}</a>
|
<a href="{{ $orderUrl }}" target="_blank" rel="noopener" class="btn btn-sm btn-outline-secondary">{{ __('Zum Shop') }}</a>
|
||||||
@else
|
@else
|
||||||
<span class="text-muted">—</span>
|
<span class="text-muted">—</span>
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -155,24 +163,24 @@
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="4" class="text-center text-muted py-3">{{ __('Diesem Rohstoff ist kein Lieferant zugeordnet.') }}</td>
|
<td colspan="4"><div class="wawi-empty">{{ __('Diesem Rohstoff ist kein Lieferant zugeordnet.') }}</div></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@if(Auth::user()->isAdmin())
|
@if(Auth::user()->isAdmin())
|
||||||
<div class="card-footer">
|
<div class="wawi-card__footer">
|
||||||
<a href="{{ route('admin.inventory.stock-entries.create', ['ingredient_id' => $ingredient->id]) }}" class="btn btn-sm btn-primary">{{ __('Einkauf erfassen') }}</a>
|
<a href="{{ route('admin.inventory.stock-entries.create', ['ingredient_id' => $ingredient->id]) }}" class="btn btn-sm btn-primary">{{ __('Einkauf erfassen') }}</a>
|
||||||
<a href="{{ route('admin.inventory.stock-disposals.create', ['ingredient_id' => $ingredient->id]) }}" class="btn btn-sm btn-outline-danger">{{ __('Ausschuss erfassen') }}</a>
|
<a href="{{ route('admin.inventory.stock-disposals.create', ['ingredient_id' => $ingredient->id]) }}" class="btn btn-sm btn-outline-danger">{{ __('Ausschuss erfassen') }}</a>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-3">
|
<div class="wawi-card">
|
||||||
<h6 class="card-header">{{ __('Offene Bestellungen / unterwegs') }}</h6>
|
<div class="wawi-card__header">{{ __('Offene Bestellungen / unterwegs') }}</div>
|
||||||
<div class="card-datatable table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped wawi-table mb-0">
|
<table class="table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ __('Bestellt am') }}</th>
|
<th>{{ __('Bestellt am') }}</th>
|
||||||
|
|
@ -197,23 +205,23 @@
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="5" class="text-center text-muted py-3">{{ __('Keine offenen Bestellungen.') }}</td>
|
<td colspan="5"><div class="wawi-empty">{{ __('Keine offenen Bestellungen.') }}</div></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@if($openOrders->isNotEmpty())
|
@if($openOrders->isNotEmpty())
|
||||||
<div class="card-footer text-muted small">
|
<div class="wawi-card__footer text-muted small">
|
||||||
{{ __('Offene Bestellungen zählen erst nach gebuchtem Wareneingang zum Bestand.') }}
|
{{ __('Offene Bestellungen zählen erst nach gebuchtem Wareneingang zum Bestand.') }}
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-3">
|
<div class="wawi-card">
|
||||||
<h6 class="card-header">{{ __('Verfügbare Chargen') }}</h6>
|
<div class="wawi-card__header">{{ __('Verfügbare Chargen') }}</div>
|
||||||
<div class="card-datatable table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped wawi-table mb-0">
|
<table class="table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ __('Charge') }}</th>
|
<th>{{ __('Charge') }}</th>
|
||||||
|
|
@ -234,7 +242,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="5" class="text-center text-muted py-3">{{ __('Kein Restbestand vorhanden.') }}</td>
|
<td colspan="5"><div class="wawi-empty">{{ __('Kein Restbestand vorhanden.') }}</div></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
@ -253,4 +261,5 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,20 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<h4 class="font-weight-bold py-2 mb-2">{{ __('Ausgang / Ausschuss erfassen') }}</h4>
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
<div class="wawi-page">
|
||||||
|
<div class="wawi-page-head">
|
||||||
|
<div>
|
||||||
|
<h1 class="wawi-page-head__title">{{ __('Ausgang / Ausschuss erfassen') }}</h1>
|
||||||
|
<p class="wawi-page-head__subtitle">{{ __('Bestand eines Rohstoffs oder Verpackungsartikels reduzieren') }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-page-head__actions">
|
||||||
|
<a href="{{ route('admin.inventory.stock-disposals.index') }}" class="btn btn-outline-secondary btn-sm">
|
||||||
|
<span class="fas fa-arrow-left mr-1"></span>{{ __('Zurück') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card wawi-card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p class="text-muted small">{{ __('Reduziert den Bestand des gewählten Rohstoffs bzw. Verpackungsartikels. Der Grund ist Pflicht und erscheint in der Ausgangsliste.') }}</p>
|
<p class="text-muted small">{{ __('Reduziert den Bestand des gewählten Rohstoffs bzw. Verpackungsartikels. Der Grund ist Pflicht und erscheint in der Ausgangsliste.') }}</p>
|
||||||
<form method="post" action="{{ route('admin.inventory.stock-disposals.store') }}">
|
<form method="post" action="{{ route('admin.inventory.stock-disposals.store') }}">
|
||||||
|
|
@ -116,6 +128,7 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('scripts')
|
@section('scripts')
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,35 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
|
||||||
<div class="card-header d-flex flex-wrap justify-content-between align-items-center">
|
<div class="wawi-page">
|
||||||
<h6 class="mb-0">{{ __('Ausgang / Ausschuss') }}</h6>
|
<div class="wawi-page-head">
|
||||||
<div>
|
<div>
|
||||||
<form method="get" class="d-inline-block mr-2">
|
<h1 class="wawi-page-head__title">{{ __('Ausgang / Ausschuss') }}</h1>
|
||||||
<select name="type" class="form-control form-control-sm d-inline-block" style="width:auto"
|
<p class="wawi-page-head__subtitle">{{ __('Erfasste Bestandsabgänge von Rohstoffen und Verpackung') }}</p>
|
||||||
onchange="this.form.submit()">
|
</div>
|
||||||
|
<div class="wawi-page-head__actions">
|
||||||
|
@if (Auth::user()->isAdmin())
|
||||||
|
<a href="{{ route('admin.inventory.stock-disposals.create') }}" class="btn btn-primary btn-sm">
|
||||||
|
<span class="fas fa-plus mr-1"></span>{{ __('Ausschuss erfassen') }}
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="wawi-toolbar">
|
||||||
|
<form method="get" class="mb-0">
|
||||||
|
<select name="type" class="form-control form-control-sm" style="width:auto" onchange="this.form.submit()">
|
||||||
<option value="">{{ __('Alle Arten') }}</option>
|
<option value="">{{ __('Alle Arten') }}</option>
|
||||||
<option value="ingredient" @selected($typeFilter === 'ingredient')>{{ __('Rohstoff') }}</option>
|
<option value="ingredient" @selected($typeFilter === 'ingredient')>{{ __('Rohstoff') }}</option>
|
||||||
<option value="packaging" @selected($typeFilter === 'packaging')>{{ __('Verpackung') }}</option>
|
<option value="packaging" @selected($typeFilter === 'packaging')>{{ __('Verpackung') }}</option>
|
||||||
</select>
|
</select>
|
||||||
</form>
|
</form>
|
||||||
@if (Auth::user()->isAdmin())
|
|
||||||
<a href="{{ route('admin.inventory.stock-disposals.create') }}" class="btn btn-sm btn-primary">
|
|
||||||
{{ __('Ausschuss erfassen') }}
|
|
||||||
</a>
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="table-responsive">
|
||||||
<div class="card-datatable table-responsive">
|
<table class="table wawi-table">
|
||||||
<table class="table table-striped wawi-table mb-0">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ __('Datum') }}</th>
|
<th>{{ __('Datum') }}</th>
|
||||||
|
|
@ -42,12 +49,12 @@
|
||||||
<td>{{ $disposal->disposed_at?->format('d.m.Y') }}</td>
|
<td>{{ $disposal->disposed_at?->format('d.m.Y') }}</td>
|
||||||
<td>
|
<td>
|
||||||
@if ($disposal->isIngredient())
|
@if ($disposal->isIngredient())
|
||||||
<span class="badge badge-info">{{ __('Rohstoff') }}</span>
|
<span class="wawi-pill wawi-pill--ok">{{ __('Rohstoff') }}</span>
|
||||||
@else
|
@else
|
||||||
<span class="badge badge-secondary">{{ __('Verpackung') }}</span>
|
<span class="wawi-pill" style="background:rgba(24,28,33,.06);color:#6c757d;">{{ __('Verpackung') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td>{{ $disposal->articleName() }}</td>
|
<td><span class="wawi-item-name">{{ $disposal->articleName() }}</span></td>
|
||||||
<td>
|
<td>
|
||||||
@if ($disposal->stockEntry)
|
@if ($disposal->stockEntry)
|
||||||
{{ $disposal->stockEntry->batch_number ?: '#'.$disposal->stockEntry->id }}
|
{{ $disposal->stockEntry->batch_number ?: '#'.$disposal->stockEntry->id }}
|
||||||
|
|
@ -66,11 +73,17 @@
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="9" class="text-center text-muted py-4">{{ __('Noch keine Ausgänge erfasst.') }}</td>
|
<td colspan="9">
|
||||||
|
<div class="wawi-empty">
|
||||||
|
<div><span class="fas fa-dumpster"></span></div>
|
||||||
|
{{ __('Noch keine Ausgänge erfasst.') }}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,26 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
<div class="wawi-page">
|
||||||
<span>{{ __('Wareneingang') }}</span>
|
<div class="wawi-page-head">
|
||||||
|
<div>
|
||||||
|
<h1 class="wawi-page-head__title">{{ __('Einkauf & Wareneingang') }}</h1>
|
||||||
|
<p class="wawi-page-head__subtitle">{{ __('Bestellungen und Wareneingänge von Rohstoffen und Verpackung') }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-page-head__actions">
|
||||||
@if(Auth::user()->isAdmin())
|
@if(Auth::user()->isAdmin())
|
||||||
<a href="{{ route('admin.inventory.stock-entries.create') }}" class="btn btn-sm btn-primary">{{ __('Neuer Einkauf') }}</a>
|
<a href="{{ route('admin.inventory.stock-entries.create') }}" class="btn btn-primary btn-sm">
|
||||||
|
<span class="fas fa-plus mr-1"></span>{{ __('Neuer Einkauf') }}
|
||||||
|
</a>
|
||||||
@endif
|
@endif
|
||||||
</h6>
|
</div>
|
||||||
<div class="card-datatable table-responsive">
|
</div>
|
||||||
<table class="datatables-style table table-striped table-bordered wawi-table">
|
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="card-datatable table-responsive p-2">
|
||||||
|
<table class="datatables-style table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="max-width: 90px;"></th>
|
<th style="max-width: 90px;"></th>
|
||||||
|
|
@ -43,18 +53,18 @@
|
||||||
</td>
|
</td>
|
||||||
<td data-sort="{{ $row->status === 'pending' ? 0 : 1 }}">
|
<td data-sort="{{ $row->status === 'pending' ? 0 : 1 }}">
|
||||||
@if($row->status === 'pending')
|
@if($row->status === 'pending')
|
||||||
<span class="badge badge-warning">{{ __('Offen') }}</span>
|
<span class="wawi-pill wawi-pill--warning">{{ __('Offen') }}</span>
|
||||||
@else
|
@else
|
||||||
<span class="badge badge-success">{{ __('Eingegangen') }}</span>
|
<span class="wawi-pill wawi-pill--ok">{{ __('Eingegangen') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td data-sort="{{ $row->ordered_at?->timestamp ?? 0 }}">{{ $row->ordered_at?->format('d.m.Y') }}</td>
|
<td data-sort="{{ $row->ordered_at?->timestamp ?? 0 }}">{{ $row->ordered_at?->format('d.m.Y') }}</td>
|
||||||
<td>{{ $entryTypeLabels[$row->entry_type] ?? $row->entry_type }}</td>
|
<td>{{ $entryTypeLabels[$row->entry_type] ?? $row->entry_type }}</td>
|
||||||
<td>
|
<td>
|
||||||
@if($row->entry_type === 'ingredient' && $row->ingredient)
|
@if($row->entry_type === 'ingredient' && $row->ingredient)
|
||||||
{{ $row->ingredient->name }}
|
<span class="wawi-item-name">{{ $row->ingredient->name }}</span>
|
||||||
@elseif($row->packagingItem)
|
@elseif($row->packagingItem)
|
||||||
{{ $row->packagingItem->name }}
|
<span class="wawi-item-name">{{ $row->packagingItem->name }}</span>
|
||||||
@else
|
@else
|
||||||
—
|
—
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -83,6 +93,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.datatables-style').dataTable({
|
$('.datatables-style').dataTable({
|
||||||
|
|
|
||||||
|
|
@ -5,18 +5,21 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<h4 class="font-weight-bold py-2 mb-2">{{ __('Wareneingang') }}</h4>
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
|
<div class="wawi-page">
|
||||||
<div class="card mb-3">
|
<div class="wawi-page-head">
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
<div>
|
||||||
<span>
|
<h1 class="wawi-page-head__title">
|
||||||
|
{{ __('Wareneingang') }}
|
||||||
@if($model->status === 'pending')
|
@if($model->status === 'pending')
|
||||||
<span class="badge badge-warning">{{ __('Offen') }}</span>
|
<span class="wawi-pill wawi-pill--warning">{{ __('Offen') }}</span>
|
||||||
@else
|
@else
|
||||||
<span class="badge badge-success">{{ __('Eingegangen') }}</span>
|
<span class="wawi-pill wawi-pill--ok">{{ __('Eingegangen') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</span>
|
</h1>
|
||||||
<span>
|
<p class="wawi-page-head__subtitle">{{ $entryTypeLabels[$model->entry_type] ?? $model->entry_type }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-page-head__actions">
|
||||||
<a href="{{ route('admin.inventory.stock-entries.index') }}" class="btn btn-sm btn-outline-secondary">{{ __('Zurück zur Liste') }}</a>
|
<a href="{{ route('admin.inventory.stock-entries.index') }}" class="btn btn-sm btn-outline-secondary">{{ __('Zurück zur Liste') }}</a>
|
||||||
@if(Auth::user()->isAdmin())
|
@if(Auth::user()->isAdmin())
|
||||||
<a href="{{ route('admin.inventory.stock-entries.copy', $model) }}" class="btn btn-sm btn-outline-info">{{ __('Duplizieren') }}</a>
|
<a href="{{ route('admin.inventory.stock-entries.copy', $model) }}" class="btn btn-sm btn-outline-info">{{ __('Duplizieren') }}</a>
|
||||||
|
|
@ -24,15 +27,21 @@
|
||||||
@if(Auth::user()->isAdmin() && $model->isPending())
|
@if(Auth::user()->isAdmin() && $model->isPending())
|
||||||
<a href="{{ route('admin.inventory.stock-entries.edit', $model) }}" class="btn btn-sm btn-primary">{{ __('Bearbeiten') }}</a>
|
<a href="{{ route('admin.inventory.stock-entries.edit', $model) }}" class="btn btn-sm btn-primary">{{ __('Bearbeiten') }}</a>
|
||||||
@endif
|
@endif
|
||||||
</span>
|
</div>
|
||||||
</h6>
|
</div>
|
||||||
<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>
|
<div class="card wawi-card mb-3">
|
||||||
<dd class="col-sm-9">
|
<div class="wawi-card__header">{{ __('Details') }}</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="wawi-deflist">
|
||||||
|
<div class="wawi-deflist__item">
|
||||||
|
<span class="wawi-deflist__label">{{ __('Art') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $entryTypeLabels[$model->entry_type] ?? $model->entry_type }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wawi-deflist__item">
|
||||||
|
<span class="wawi-deflist__label">{{ __('Artikel') }}</span>
|
||||||
|
<span class="wawi-deflist__value">
|
||||||
@if($model->entry_type === 'ingredient' && $model->ingredient)
|
@if($model->entry_type === 'ingredient' && $model->ingredient)
|
||||||
{{ $model->ingredient->name }}@if($model->ingredient->inci) ({{ $model->ingredient->inci }})@endif
|
{{ $model->ingredient->name }}@if($model->ingredient->inci) ({{ $model->ingredient->inci }})@endif
|
||||||
@elseif($model->packagingItem)
|
@elseif($model->packagingItem)
|
||||||
|
|
@ -43,34 +52,46 @@
|
||||||
@else
|
@else
|
||||||
—
|
—
|
||||||
@endif
|
@endif
|
||||||
</dd>
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
@if($model->entry_type === 'ingredient' && $model->quality)
|
@if($model->entry_type === 'ingredient' && $model->quality)
|
||||||
<dt class="col-sm-3">{{ __('Rohstoffqualität') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->quality->name }}</dd>
|
<span class="wawi-deflist__label">{{ __('Rohstoffqualität') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $model->quality->name }}</span>
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<dt class="col-sm-3">{{ __('Lieferant') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->supplier?->name ?? '—' }}</dd>
|
<span class="wawi-deflist__label">{{ __('Lieferant') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $model->supplier?->name ?? '—' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<dt class="col-sm-3">{{ __('Lagerort') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->location?->name ?? '—' }}</dd>
|
<span class="wawi-deflist__label">{{ __('Lagerort') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $model->location?->name ?? '—' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<dt class="col-sm-3">{{ __('Bestelldatum') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->ordered_at?->format('d.m.Y') }}</dd>
|
<span class="wawi-deflist__label">{{ __('Bestelldatum') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $model->ordered_at?->format('d.m.Y') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<dt class="col-sm-3">{{ __('Bestellte Menge') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">
|
<span class="wawi-deflist__label">{{ __('Bestellte Menge') }}</span>
|
||||||
|
<span class="wawi-deflist__value">
|
||||||
@if($model->unit === 'gram')
|
@if($model->unit === 'gram')
|
||||||
{{ \App\Services\Util::formatNumber($model->ordered_quantity) }} g
|
{{ \App\Services\Util::formatNumber($model->ordered_quantity) }} g
|
||||||
@else
|
@else
|
||||||
{{ \App\Services\Util::formatNumber($model->ordered_quantity, 0) }} {{ __('Stk.') }}
|
{{ \App\Services\Util::formatNumber($model->ordered_quantity, 0) }} {{ __('Stk.') }}
|
||||||
@endif
|
@endif
|
||||||
</dd>
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
@if(Auth::user()->isAdmin())
|
@if(Auth::user()->isAdmin())
|
||||||
<dt class="col-sm-3">{{ __('Preise (Stufe 1)') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">
|
<span class="wawi-deflist__label">{{ __('Preise (Stufe 1)') }}</span>
|
||||||
|
<span class="wawi-deflist__value">
|
||||||
@if($model->entry_type === 'ingredient')
|
@if($model->entry_type === 'ingredient')
|
||||||
@if($model->price_per_kg !== null)
|
@if($model->price_per_kg !== null)
|
||||||
{{ \App\Services\Util::formatNumber($model->price_per_kg) }} € / kg {{ __('netto') }}
|
{{ \App\Services\Util::formatNumber($model->price_per_kg) }} € / kg {{ __('netto') }}
|
||||||
|
|
@ -90,46 +111,61 @@
|
||||||
—
|
—
|
||||||
@endif
|
@endif
|
||||||
@endif
|
@endif
|
||||||
</dd>
|
</span>
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<dt class="col-sm-3">{{ __('Bestellt von') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->orderedByUser?->getFullName(false) ?: $model->orderedByUser?->email ?? '—' }}</dd>
|
<span class="wawi-deflist__label">{{ __('Bestellt von') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $model->orderedByUser?->getFullName(false) ?: $model->orderedByUser?->email ?? '—' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
@if($model->isReceived())
|
@if($model->isReceived())
|
||||||
<dt class="col-sm-3">{{ __('Eingangsdatum') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->received_at?->format('d.m.Y') }}</dd>
|
<span class="wawi-deflist__label">{{ __('Eingangsdatum') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $model->received_at?->format('d.m.Y') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<dt class="col-sm-3">{{ __('Eingegangene Menge') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">
|
<span class="wawi-deflist__label">{{ __('Eingegangene Menge') }}</span>
|
||||||
|
<span class="wawi-deflist__value">
|
||||||
@if($model->unit === 'gram')
|
@if($model->unit === 'gram')
|
||||||
{{ \App\Services\Util::formatNumber($model->received_quantity) }} g
|
{{ \App\Services\Util::formatNumber($model->received_quantity) }} g
|
||||||
@else
|
@else
|
||||||
{{ \App\Services\Util::formatNumber($model->received_quantity, 0) }} {{ __('Stk.') }}
|
{{ \App\Services\Util::formatNumber($model->received_quantity, 0) }} {{ __('Stk.') }}
|
||||||
@endif
|
@endif
|
||||||
</dd>
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
@if($model->entry_type === 'ingredient')
|
@if($model->entry_type === 'ingredient')
|
||||||
<dt class="col-sm-3">{{ __('Charge') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->batch_number ?: '—' }}</dd>
|
<span class="wawi-deflist__label">{{ __('Charge') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $model->batch_number ?: '—' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<dt class="col-sm-3">{{ __('Mindesthaltbarkeit') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->best_before?->format('d.m.Y') ?? '—' }}</dd>
|
<span class="wawi-deflist__label">{{ __('Mindesthaltbarkeit') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $model->best_before?->format('d.m.Y') ?? '—' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<dt class="col-sm-3">{{ __('Materialqualität') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->quality?->name ?? '—' }}</dd>
|
<span class="wawi-deflist__label">{{ __('Materialqualität') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $model->quality?->name ?? '—' }}</span>
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<dt class="col-sm-3">{{ __('Eingebucht von') }}</dt>
|
<div class="wawi-deflist__item">
|
||||||
<dd class="col-sm-9">{{ $model->receivedByUser?->getFullName(false) ?: $model->receivedByUser?->email ?? '—' }}</dd>
|
<span class="wawi-deflist__label">{{ __('Eingebucht von') }}</span>
|
||||||
|
<span class="wawi-deflist__value">{{ $model->receivedByUser?->getFullName(false) ?: $model->receivedByUser?->email ?? '—' }}</span>
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</dl>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if($model->isPending())
|
@if($model->isPending())
|
||||||
<div class="card">
|
<div class="card wawi-card">
|
||||||
<h6 class="card-header">{{ __('Wareneingang buchen (Stufe 2)') }}</h6>
|
<div class="wawi-card__header">{{ __('Wareneingang buchen (Stufe 2)') }}</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form method="post" action="{{ route('admin.inventory.stock-entries.receive', $model) }}">
|
<form method="post" action="{{ route('admin.inventory.stock-entries.receive', $model) }}">
|
||||||
@csrf
|
@csrf
|
||||||
|
|
@ -202,4 +238,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
<div class="wawi-page">
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
<div class="wawi-page-head">
|
||||||
<span>{{ __('Lieferanten-Kategorien') }}</span>
|
<div>
|
||||||
<a href="{{ route('admin.inventory.supplier-categories.create') }}" class="btn btn-sm btn-primary">{{ __('Neu anlegen') }}</a>
|
<h1 class="wawi-page-head__title">{{ __('Lieferanten-Kategorien') }}</h1>
|
||||||
</h6>
|
</div>
|
||||||
<div class="card-datatable table-responsive">
|
<div class="wawi-page-head__actions">
|
||||||
<table class="datatables-style table table-striped table-bordered wawi-table">
|
<a href="{{ route('admin.inventory.supplier-categories.create') }}" class="btn btn-sm btn-primary">
|
||||||
|
<span class="fas fa-plus mr-1"></span>{{ __('Neu anlegen') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="card-datatable table-responsive p-2">
|
||||||
|
<table class="datatables-style table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="max-width: 60px;"> </th>
|
<th style="max-width: 60px;"> </th>
|
||||||
|
|
@ -41,6 +48,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.datatables-style').dataTable({
|
$('.datatables-style').dataTable({
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,22 @@
|
||||||
@extends('layouts.layout-2')
|
@extends('layouts.layout-2')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@include('admin.inventory.partials.table-actions-style')
|
@include('admin.inventory.partials.wawi-ui')
|
||||||
<div class="card">
|
<div class="wawi-page">
|
||||||
<h6 class="card-header d-flex justify-content-between align-items-center">
|
<div class="wawi-page-head">
|
||||||
<span>{{ __('Lieferanten') }}</span>
|
<div>
|
||||||
<a href="{{ route('admin.inventory.suppliers.create') }}" class="btn btn-sm btn-primary">{{ __('Neu anlegen') }}</a>
|
<h1 class="wawi-page-head__title">{{ __('Lieferanten') }}</h1>
|
||||||
</h6>
|
<p class="wawi-page-head__subtitle">{{ __('Lieferanten, Kategorien und Bestellkanäle') }}</p>
|
||||||
<div class="card-datatable table-responsive">
|
</div>
|
||||||
<table class="datatables-style table table-striped table-bordered wawi-table">
|
<div class="wawi-page-head__actions">
|
||||||
|
<a href="{{ route('admin.inventory.suppliers.create') }}" class="btn btn-sm btn-primary">
|
||||||
|
<span class="fas fa-plus mr-1"></span>{{ __('Neu anlegen') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wawi-card">
|
||||||
|
<div class="card-datatable table-responsive p-2">
|
||||||
|
<table class="datatables-style table wawi-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="max-width: 60px;"> </th>
|
<th style="max-width: 60px;"> </th>
|
||||||
|
|
@ -41,9 +49,9 @@
|
||||||
</td>
|
</td>
|
||||||
<td data-sort="{{ $value->active ? 1 : 0 }}">
|
<td data-sort="{{ $value->active ? 1 : 0 }}">
|
||||||
@if($value->active)
|
@if($value->active)
|
||||||
<span class="badge badge-pill badge-success"><i class="fa fa-check"></i></span>
|
<span class="wawi-pill wawi-pill--ok">{{ __('Aktiv') }}</span>
|
||||||
@else
|
@else
|
||||||
<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span>
|
<span class="wawi-pill wawi-pill--danger">{{ __('Inaktiv') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -60,6 +68,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="modal fade" id="supplierShowModal" tabindex="-1" role="dialog" aria-hidden="true">
|
<div class="modal fade" id="supplierShowModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-lg" role="document">
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue