# SpiceManagementSystem Warenwirtschafts-Panel für Gewürzmischungen — verwaltet Rohstoffe, Rezepte, Produkte, Chargen und Shopify-Sync. Built with [Laravel](https://laravel.com) + [Filament](https://filamentphp.com), deployed via Docker. --- ## Lokale Entwicklung **Voraussetzungen:** PHP 8.4, Composer, Node.js, MariaDB ```bash composer install npm install && npm run build cp .env.example .env php artisan key:generate php artisan migrate php artisan serve ``` Die App läuft dann auf `http://localhost:8000`. --- ## Produktion (Docker) Der Deploy läuft automatisch via Gitea Actions bei jedem Push auf `main`: 1. Dateien per SCP auf den VPS kopieren 2. `docker compose up -d --build` — baut das Image neu und startet die Container 3. `php artisan migrate --force` — läuft automatisch im Container ### Artisan-Befehle auf dem Server Da die App in Docker mit PHP 8.4 läuft, müssen alle artisan-Befehle **im Container** ausgeführt werden: ```bash cd ~/app && docker compose exec app php artisan ``` --- ## Shopify-Import ### Erstimport (Produkte + Lagerbestand + Beschreibung) ```bash cd ~/app && docker compose exec app php artisan shopify:import ``` Optionen: - `--dry-run` — zeigt nur an was importiert würde, speichert nichts ### Produktbilder herunterladen ```bash cd ~/app && docker compose exec app php artisan shopify:images ``` Optionen: - `--force` — lädt Bilder auch für Produkte neu, die bereits welche haben ### Lagerbestand + Preise synchronisieren ```bash cd ~/app && docker compose exec app php artisan shopify:sync ``` --- ## Chargen (LOT) & Rohstoff-Abzug Beim Anlegen einer Charge wird der Rohstoffbestand automatisch abgezogen: ``` Charge: 50 Einheiten × 100g Standbodenbeutel = 5000g → Kurkuma (60%): 3000g vom Lager abgezogen → Pfeffer (30%): 1500g vom Lager abgezogen → Ingwer (10%): 500g vom Lager abgezogen ``` - Beim **Bearbeiten** einer Charge wird der Abzug neu berechnet - Beim **Löschen** werden die Mengen zurückgebucht - Chargen können direkt auf der Produktseite angelegt werden --- ## Rezept-Versionierung Rezepte sind versioniert und einem Produkt zugeordnet: - Jedes Rezept hat eine Versionsnummer (v1, v2, …) - Beim Anlegen eines neuen Rezepts über das Produktformular wird die Version automatisch hochgezählt - Ältere Versionen bleiben erhalten (z.B. für Chargen-Rückverfolgung) --- ## Cronjob Auf dem Server einrichten, damit der Laravel-Scheduler läuft: ``` * * * * * cd ~/app && docker compose exec -T app php artisan schedule:run >> /dev/null 2>&1 ``` --- ## Datenbankstruktur ``` Table spices { id int [pk] name varchar(255) quantity decimal(10,2) -- immer in Gramm unit varchar } Table recipes { id int [pk] product_id int [ref: > products.id, nullable] version int -- auto-increment pro Produkt name varchar(255) description text } Table recipes_spices { recipe_id int [ref: > recipes.id] spice_id int [ref: > spices.id] amount_in_percent decimal(4,2) } Table packings { id int [pk] name varchar(255) size decimal(10,2) -- Gramm pro Einheit } Table products { id int [pk] title text images json description text recipes_id int [ref: > recipes.id] } Table products_sizes { id int [pk] product_id int [ref: > products.id] packing_id int [ref: > packings.id] sku varchar shopify_variant_id varchar gtin varchar price float } Table products_inventory { id int [pk] product_id int [ref: > products.id] size_id int [ref: > products_sizes.id] out_at timestamp } Table batches { id int [pk] lot_number varchar [unique] product_id int [ref: > products.id] size_id int [ref: > products_sizes.id] recipe_id int [ref: > recipes.id] units_produced int quantity_g decimal(10,2) -- berechnet: units × packing.size produced_at date expires_at date } Table batch_origins { id int [pk] batch_id int [ref: > batches.id] spice_id int [ref: > spices.id] supplier_id int [ref: > suppliers.id, nullable] origin_country varchar farmer varchar notes text } ``` --- ## Vision & Todo **Fokus: Warenwirtschaft (Lager, Rohstoffe, Produkte)** - [x] DB-Schema mit Produkthistorie - [x] Rezepte mit Versionierung - [x] Produktgrößen, Preise, SKU, GTIN mit Barcode-Vorschau - [x] Inventar (eindeutige Items mit Ausgangs-Flag) - [x] Chargen (LOT) mit automatischem Rohstoff-Abzug - [x] Warenausgang (Produktverkauf) - [x] Shopify-Import (Produkte, Varianten, Lagerbestand, Bilder, Beschreibung, Preise) - [x] Continuous Deployment via Gitea Actions + Docker - [x] Frontend (Sidebar, Navigation, Barcode-Preview, Bild-Grid) - [ ] Dashboard (Füllstände, Lager, Sales-Zeitspanne)