mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 08:29:36 +01:00
feat(tui,seed): Seed-Testdaten und Bestandsbewegung-Detail verbessern
Seed-Daten SQL-File (099-seed-testdata.sql) mit realistischem Szenario "Fleischerei & Feinkost" erstellt: 6 User, 6 Kategorien, 5 Lieferanten, 18 Artikel, 5 Kunden, 5 Lagerorte, Bestände, Rezepte, Chargen, Produktionsaufträge und Bestandsbewegungen. StockMovement-Detailseite: IDs durch lesbare Namen ersetzt (Lagerort, Artikel, Benutzer) mit ausgegrautem ID dahinter, stockBatchId entfernt.
This commit is contained in:
parent
6504d3a54e
commit
d63ac899e7
3 changed files with 617 additions and 8 deletions
|
|
@ -0,0 +1,567 @@
|
||||||
|
-- ============================================================================
|
||||||
|
-- Effigenix ERP – Seed-Testdaten: "Effigenix Fleischerei & Feinkost"
|
||||||
|
-- ============================================================================
|
||||||
|
-- Manuell einspielen: psql -d effigenix -f 099-seed-testdata.sql
|
||||||
|
-- NICHT im Liquibase-Changelog eingetragen!
|
||||||
|
--
|
||||||
|
-- Voraussetzung: Rollen, Permissions und Admin-User existieren bereits
|
||||||
|
-- (via 002-seed-roles-and-permissions, 004-seed-admin-user, etc.)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 1. USERS (6 Mitarbeiter)
|
||||||
|
-- ============================================================================
|
||||||
|
-- Passwort für alle: "test1234" (bcrypt)
|
||||||
|
-- $2a$12$LJ3m4ys3uz2YPMRvKbmrZOZHAMSKL4FBy.XLR3WnCKsMbVDfGKJVa
|
||||||
|
|
||||||
|
INSERT INTO users (id, username, email, password_hash, branch_id, status, created_at)
|
||||||
|
VALUES
|
||||||
|
('10000000-0000-0000-0000-000000000001', 'mweber', 'markus.weber@effigenix.de', '$2a$12$LJ3m4ys3uz2YPMRvKbmrZOZHAMSKL4FBy.XLR3WnCKsMbVDfGKJVa', NULL, 'ACTIVE', CURRENT_TIMESTAMP),
|
||||||
|
('10000000-0000-0000-0000-000000000002', 'sfischer', 'sabine.fischer@effigenix.de', '$2a$12$LJ3m4ys3uz2YPMRvKbmrZOZHAMSKL4FBy.XLR3WnCKsMbVDfGKJVa', NULL, 'ACTIVE', CURRENT_TIMESTAMP),
|
||||||
|
('10000000-0000-0000-0000-000000000003', 'tmueller', 'thomas.mueller@effigenix.de', '$2a$12$LJ3m4ys3uz2YPMRvKbmrZOZHAMSKL4FBy.XLR3WnCKsMbVDfGKJVa', NULL, 'ACTIVE', CURRENT_TIMESTAMP),
|
||||||
|
('10000000-0000-0000-0000-000000000004', 'kschneider','katrin.schneider@effigenix.de', '$2a$12$LJ3m4ys3uz2YPMRvKbmrZOZHAMSKL4FBy.XLR3WnCKsMbVDfGKJVa', NULL, 'ACTIVE', CURRENT_TIMESTAMP),
|
||||||
|
('10000000-0000-0000-0000-000000000005', 'pbraun', 'peter.braun@effigenix.de', '$2a$12$LJ3m4ys3uz2YPMRvKbmrZOZHAMSKL4FBy.XLR3WnCKsMbVDfGKJVa', NULL, 'ACTIVE', CURRENT_TIMESTAMP),
|
||||||
|
('10000000-0000-0000-0000-000000000006', 'lkrause', 'lisa.krause@effigenix.de', '$2a$12$LJ3m4ys3uz2YPMRvKbmrZOZHAMSKL4FBy.XLR3WnCKsMbVDfGKJVa', NULL, 'ACTIVE', CURRENT_TIMESTAMP)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Rollenzuweisungen
|
||||||
|
-- mweber = Produktionsleiter
|
||||||
|
-- sfischer = Einkaufsleiterin
|
||||||
|
-- tmueller = Lagerarbeiter
|
||||||
|
-- kschneider = Qualitätsmanagerin
|
||||||
|
-- pbraun = Verkaufsleiter
|
||||||
|
-- lkrause = Verkauf
|
||||||
|
INSERT INTO user_roles (user_id, role_id) VALUES
|
||||||
|
('10000000-0000-0000-0000-000000000001', 'c0a80121-0000-0000-0000-000000000002'), -- mweber → PRODUCTION_MANAGER
|
||||||
|
('10000000-0000-0000-0000-000000000002', 'c0a80121-0000-0000-0000-000000000006'), -- sfischer → PROCUREMENT_MANAGER
|
||||||
|
('10000000-0000-0000-0000-000000000003', 'c0a80121-0000-0000-0000-000000000007'), -- tmueller → WAREHOUSE_WORKER
|
||||||
|
('10000000-0000-0000-0000-000000000004', 'c0a80121-0000-0000-0000-000000000004'), -- kschneider → QUALITY_MANAGER
|
||||||
|
('10000000-0000-0000-0000-000000000005', 'c0a80121-0000-0000-0000-000000000008'), -- pbraun → SALES_MANAGER
|
||||||
|
('10000000-0000-0000-0000-000000000006', 'c0a80121-0000-0000-0000-000000000009') -- lkrause → SALES_STAFF
|
||||||
|
ON CONFLICT (user_id, role_id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 2. PRODUCT CATEGORIES
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
INSERT INTO product_categories (id, name, description) VALUES
|
||||||
|
('20000000-0000-0000-0000-000000000001', 'Frischfleisch', 'Frisches Schweine-, Rind- und Geflügelfleisch'),
|
||||||
|
('20000000-0000-0000-0000-000000000002', 'Wurstwaren', 'Brüh-, Koch- und Rohwurst, Schinken'),
|
||||||
|
('20000000-0000-0000-0000-000000000003', 'Gewürze & Zusätze', 'Gewürzmischungen, Pökelsalz, Naturdärme'),
|
||||||
|
('20000000-0000-0000-0000-000000000004', 'Verpackung', 'Folien, Schalen, Etiketten'),
|
||||||
|
('20000000-0000-0000-0000-000000000005', 'Feinkost', 'Salate, Aufstriche, marinierte Produkte'),
|
||||||
|
('20000000-0000-0000-0000-000000000006', 'Convenience', 'Fertiggerichte, Grillspezialitäten')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 3. SUPPLIERS (5 Lieferanten)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
INSERT INTO suppliers (id, name, phone, email, contact_person,
|
||||||
|
street, house_number, postal_code, city, country,
|
||||||
|
payment_due_days, payment_description,
|
||||||
|
quality_score, delivery_score, price_score,
|
||||||
|
status, created_at, updated_at) VALUES
|
||||||
|
('30000000-0000-0000-0000-000000000001',
|
||||||
|
'Bayerische Fleischwerke GmbH', '+49 89 12345678', 'einkauf@bay-fleisch.de', 'Hans Gruber',
|
||||||
|
'Schlachthofstr.', '12', '80339', 'München', 'DE',
|
||||||
|
30, 'Netto 30 Tage', 5, 4, 3, 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
('30000000-0000-0000-0000-000000000002',
|
||||||
|
'Gewürzkontor Franken', '+49 911 9876543', 'bestellung@gewuerzkontor.de', 'Maria Lehmann',
|
||||||
|
'Industrieweg', '7', '90411', 'Nürnberg', 'DE',
|
||||||
|
14, 'Netto 14 Tage, 2% Skonto bei 7 Tagen', 5, 5, 4, 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
('30000000-0000-0000-0000-000000000003',
|
||||||
|
'PackPro Verpackungen AG', '+49 711 5551234', 'vertrieb@packpro.de', 'Stefan Maier',
|
||||||
|
'Am Containerhafen', '3', '70327', 'Stuttgart', 'DE',
|
||||||
|
45, 'Netto 45 Tage', 4, 3, 5, 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
('30000000-0000-0000-0000-000000000004',
|
||||||
|
'Naturdarm Schmidt OHG', '+49 40 8887766', 'info@naturdarm-schmidt.de', 'Klaus Schmidt',
|
||||||
|
'Elbchaussee', '201', '22605', 'Hamburg', 'DE',
|
||||||
|
21, 'Netto 21 Tage', 5, 4, 4, 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
('30000000-0000-0000-0000-000000000005',
|
||||||
|
'Alpenrind Tirol KG', '+43 512 334455', 'verkauf@alpenrind.at', 'Franz Hofer',
|
||||||
|
'Brennerstr.', '88', '6020', 'Innsbruck', 'AT',
|
||||||
|
30, 'Netto 30 Tage', 4, 4, 3, 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Zertifikate
|
||||||
|
INSERT INTO quality_certificates (supplier_id, certificate_type, issuer, valid_from, valid_until) VALUES
|
||||||
|
('30000000-0000-0000-0000-000000000001', 'IFS Food', 'TÜV Süd', '2025-03-01', '2026-02-28'),
|
||||||
|
('30000000-0000-0000-0000-000000000001', 'Bio-Zertifikat', 'DE-ÖKO-006', '2025-01-01', '2025-12-31'),
|
||||||
|
('30000000-0000-0000-0000-000000000002', 'IFS Food', 'DQS GmbH', '2025-06-01', '2026-05-31'),
|
||||||
|
('30000000-0000-0000-0000-000000000004', 'EU-Zulassung', 'LAVES Niedersachsen', '2024-01-01', NULL),
|
||||||
|
('30000000-0000-0000-0000-000000000005', 'AMA-Gütesiegel', 'AMA Marketing', '2025-01-01', '2026-12-31'),
|
||||||
|
('30000000-0000-0000-0000-000000000005', 'Bio Austria', 'Austria Bio Garantie', '2025-04-01', '2026-03-31')
|
||||||
|
ON CONFLICT (supplier_id, certificate_type, valid_from) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 4. ARTICLES (18 Artikel)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- Frischfleisch
|
||||||
|
INSERT INTO articles (id, name, article_number, category_id, status, created_at, updated_at) VALUES
|
||||||
|
('40000000-0000-0000-0000-000000000001', 'Schweineschulter ohne Knochen', 'FF-001', '20000000-0000-0000-0000-000000000001', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000002', 'Schweinebauch frisch', 'FF-002', '20000000-0000-0000-0000-000000000001', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000003', 'Rindfleisch Oberschale', 'FF-003', '20000000-0000-0000-0000-000000000001', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000004', 'Schweineleber frisch', 'FF-004', '20000000-0000-0000-0000-000000000001', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000005', 'Speck durchwachsen', 'FF-005', '20000000-0000-0000-0000-000000000001', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
-- Wurstwaren (Endprodukte)
|
||||||
|
('40000000-0000-0000-0000-000000000006', 'Hausmacher Bratwurst', 'WW-001', '20000000-0000-0000-0000-000000000002', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000007', 'Kräuter-Leberwurst fein', 'WW-002', '20000000-0000-0000-0000-000000000002', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000008', 'Schinkenspeck geräuchert', 'WW-003', '20000000-0000-0000-0000-000000000002', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
-- Gewürze & Zusätze
|
||||||
|
('40000000-0000-0000-0000-000000000009', 'Bratwurstgewürz Classic', 'GZ-001', '20000000-0000-0000-0000-000000000003', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000010', 'Pökelsalz NPS 0,5%', 'GZ-002', '20000000-0000-0000-0000-000000000003', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000011', 'Kräutermischung Leberwurst', 'GZ-003', '20000000-0000-0000-0000-000000000003', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000012', 'Schweinedarm Kaliber 28/30', 'GZ-004', '20000000-0000-0000-0000-000000000003', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000013', 'Räucherchips Buche', 'GZ-005', '20000000-0000-0000-0000-000000000003', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
-- Verpackung
|
||||||
|
('40000000-0000-0000-0000-000000000014', 'Vakuumbeutel 20x30cm', 'VP-001', '20000000-0000-0000-0000-000000000004', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000015', 'Metzgerpapier Rolle 50cm', 'VP-002', '20000000-0000-0000-0000-000000000004', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
-- Feinkost
|
||||||
|
('40000000-0000-0000-0000-000000000016', 'Fleischsalat hausgemacht', 'FK-001', '20000000-0000-0000-0000-000000000005', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
-- Convenience
|
||||||
|
('40000000-0000-0000-0000-000000000017', 'Currywurst mit Soße', 'CV-001', '20000000-0000-0000-0000-000000000006', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
('40000000-0000-0000-0000-000000000018', 'Grillpaket Klassik', 'CV-002', '20000000-0000-0000-0000-000000000006', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Sales Units (Unit-Enum: KG, HUNDRED_GRAM, PIECE_FIXED, PIECE_VARIABLE)
|
||||||
|
-- (PriceModel-Enum: KG/HUNDRED_GRAM/PIECE_VARIABLE → WEIGHT_BASED, PIECE_FIXED → FIXED)
|
||||||
|
INSERT INTO sales_units (id, article_id, unit, price_model, price_amount, price_currency) VALUES
|
||||||
|
-- Frischfleisch: pro kg
|
||||||
|
('50000000-0000-0000-0000-000000000001', '40000000-0000-0000-0000-000000000001', 'KG', 'WEIGHT_BASED', 6.50, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000002', '40000000-0000-0000-0000-000000000002', 'KG', 'WEIGHT_BASED', 5.80, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000003', '40000000-0000-0000-0000-000000000003', 'KG', 'WEIGHT_BASED', 14.90, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000004', '40000000-0000-0000-0000-000000000004', 'KG', 'WEIGHT_BASED', 4.20, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000005', '40000000-0000-0000-0000-000000000005', 'KG', 'WEIGHT_BASED', 7.90, 'EUR'),
|
||||||
|
-- Wurstwaren
|
||||||
|
('50000000-0000-0000-0000-000000000006', '40000000-0000-0000-0000-000000000006', 'KG', 'WEIGHT_BASED', 12.90, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000007', '40000000-0000-0000-0000-000000000006', 'PIECE_FIXED', 'FIXED', 2.50, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000008', '40000000-0000-0000-0000-000000000007', 'KG', 'WEIGHT_BASED', 11.50, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000009', '40000000-0000-0000-0000-000000000008', 'KG', 'WEIGHT_BASED', 18.90, 'EUR'),
|
||||||
|
-- Gewürze
|
||||||
|
('50000000-0000-0000-0000-000000000010', '40000000-0000-0000-0000-000000000009', 'HUNDRED_GRAM', 'WEIGHT_BASED', 2.20, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000011', '40000000-0000-0000-0000-000000000010', 'KG', 'WEIGHT_BASED', 1.80, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000012', '40000000-0000-0000-0000-000000000011', 'HUNDRED_GRAM', 'WEIGHT_BASED', 2.80, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000013', '40000000-0000-0000-0000-000000000012', 'PIECE_FIXED', 'FIXED', 0.35, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000014', '40000000-0000-0000-0000-000000000013', 'KG', 'WEIGHT_BASED', 8.50, 'EUR'),
|
||||||
|
-- Verpackung
|
||||||
|
('50000000-0000-0000-0000-000000000015', '40000000-0000-0000-0000-000000000014', 'PIECE_FIXED', 'FIXED', 0.12, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000016', '40000000-0000-0000-0000-000000000015', 'PIECE_FIXED', 'FIXED', 18.50, 'EUR'),
|
||||||
|
-- Feinkost & Convenience
|
||||||
|
('50000000-0000-0000-0000-000000000017', '40000000-0000-0000-0000-000000000016', 'KG', 'WEIGHT_BASED', 9.90, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000018', '40000000-0000-0000-0000-000000000017', 'PIECE_FIXED', 'FIXED', 3.90, 'EUR'),
|
||||||
|
('50000000-0000-0000-0000-000000000019', '40000000-0000-0000-0000-000000000018', 'PIECE_FIXED', 'FIXED', 24.90, 'EUR')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Lieferantenzuordnungen
|
||||||
|
INSERT INTO article_suppliers (article_id, supplier_id) VALUES
|
||||||
|
-- Bay. Fleischwerke liefert Frischfleisch
|
||||||
|
('40000000-0000-0000-0000-000000000001', '30000000-0000-0000-0000-000000000001'),
|
||||||
|
('40000000-0000-0000-0000-000000000002', '30000000-0000-0000-0000-000000000001'),
|
||||||
|
('40000000-0000-0000-0000-000000000004', '30000000-0000-0000-0000-000000000001'),
|
||||||
|
('40000000-0000-0000-0000-000000000005', '30000000-0000-0000-0000-000000000001'),
|
||||||
|
-- Alpenrind liefert Rindfleisch + Schweineschulter
|
||||||
|
('40000000-0000-0000-0000-000000000003', '30000000-0000-0000-0000-000000000005'),
|
||||||
|
('40000000-0000-0000-0000-000000000001', '30000000-0000-0000-0000-000000000005'),
|
||||||
|
-- Gewürzkontor liefert Gewürze
|
||||||
|
('40000000-0000-0000-0000-000000000009', '30000000-0000-0000-0000-000000000002'),
|
||||||
|
('40000000-0000-0000-0000-000000000010', '30000000-0000-0000-0000-000000000002'),
|
||||||
|
('40000000-0000-0000-0000-000000000011', '30000000-0000-0000-0000-000000000002'),
|
||||||
|
('40000000-0000-0000-0000-000000000013', '30000000-0000-0000-0000-000000000002'),
|
||||||
|
-- Naturdarm Schmidt liefert Därme
|
||||||
|
('40000000-0000-0000-0000-000000000012', '30000000-0000-0000-0000-000000000004'),
|
||||||
|
-- PackPro liefert Verpackung
|
||||||
|
('40000000-0000-0000-0000-000000000014', '30000000-0000-0000-0000-000000000003'),
|
||||||
|
('40000000-0000-0000-0000-000000000015', '30000000-0000-0000-0000-000000000003')
|
||||||
|
ON CONFLICT (article_id, supplier_id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 5. CUSTOMERS (5 Kunden)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
INSERT INTO customers (id, name, type, phone, email, contact_person,
|
||||||
|
billing_street, billing_house_number, billing_postal_code, billing_city, billing_country,
|
||||||
|
payment_due_days, payment_description, status, created_at, updated_at) VALUES
|
||||||
|
('60000000-0000-0000-0000-000000000001',
|
||||||
|
'REWE Markt Obermenzing', 'B2B', '+49 89 44556677', 'filiale.obermenzing@rewe.de', 'Andrea Huber',
|
||||||
|
'Verdistr.', '55', '81247', 'München', 'DE',
|
||||||
|
30, 'Netto 30 Tage', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
('60000000-0000-0000-0000-000000000002',
|
||||||
|
'Gasthof zum goldenen Hirsch', 'B2B', '+49 89 33221100', 'kueche@goldener-hirsch.de', 'Ludwig Meier',
|
||||||
|
'Hauptstr.', '12', '82041', 'Oberhaching', 'DE',
|
||||||
|
14, 'Netto 14 Tage', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
('60000000-0000-0000-0000-000000000003',
|
||||||
|
'Kantinenbetrieb Siemens Campus', 'B2B', '+49 89 72233445', 'einkauf@siemens-kantine.de', 'Petra Zimmermann',
|
||||||
|
'Werner-von-Siemens-Str.', '1', '80333', 'München', 'DE',
|
||||||
|
45, 'Netto 45 Tage, Sammelrechnung monatlich', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
('60000000-0000-0000-0000-000000000004',
|
||||||
|
'Metzgerei Weber Stammkunde', 'B2C', '+49 171 9988776', 'familie.weber@gmx.de', NULL,
|
||||||
|
'Rosenweg', '8', '82049', 'Pullach', 'DE',
|
||||||
|
NULL, NULL, 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
('60000000-0000-0000-0000-000000000005',
|
||||||
|
'Feinkost Dallmayr', 'B2B', '+49 89 21350', 'einkauf@dallmayr.de', 'Maximilian Sedlmayr',
|
||||||
|
'Dienerstr.', '14-15', '80331', 'München', 'DE',
|
||||||
|
60, 'Netto 60 Tage, Qualitätsprüfung bei Anlieferung', 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Lieferadressen
|
||||||
|
INSERT INTO delivery_addresses (customer_id, label, street, house_number, postal_code, city, country, contact_person, delivery_notes) VALUES
|
||||||
|
('60000000-0000-0000-0000-000000000001', 'Warenannahme', 'Verdistr.', '55', '81247', 'München', 'DE', 'Hr. Kohl (Warenannahme)', 'Anlieferung Mo-Sa 6:00-10:00, Rampe 3'),
|
||||||
|
('60000000-0000-0000-0000-000000000002', 'Küche Hintereingang', 'Hauptstr.', '12a', '82041', 'Oberhaching', 'DE', 'Küchenchef Ludwig Meier', 'Kühltransport erforderlich, Hintereingang benutzen'),
|
||||||
|
('60000000-0000-0000-0000-000000000003', 'Kantine Bau 1', 'Werner-von-Siemens-Str.', '1', '80333', 'München', 'DE', 'Fr. Zimmermann', 'Zufahrt über Tor West, Ausweispflicht'),
|
||||||
|
('60000000-0000-0000-0000-000000000003', 'Kantine Bau 7', 'Otto-Hahn-Ring', '6', '81739', 'München', 'DE', 'Hr. Berger', 'Neuperlach Campus, Rampe B'),
|
||||||
|
('60000000-0000-0000-0000-000000000005', 'Delikatessenhaus', 'Dienerstr.', '14-15', '80331', 'München', 'DE', 'Fr. Sedlmayr', 'Anlieferung nur 5:00-7:00, Kühlkette dokumentieren');
|
||||||
|
|
||||||
|
-- Kundenpräferenzen (Enum: BIO, REGIONAL, TIERWOHL, HALAL, KOSHER, GLUTENFREI, LAKTOSEFREI)
|
||||||
|
INSERT INTO customer_preferences (customer_id, preference) VALUES
|
||||||
|
('60000000-0000-0000-0000-000000000001', 'BIO'),
|
||||||
|
('60000000-0000-0000-0000-000000000001', 'REGIONAL'),
|
||||||
|
('60000000-0000-0000-0000-000000000002', 'REGIONAL'),
|
||||||
|
('60000000-0000-0000-0000-000000000003', 'HALAL'),
|
||||||
|
('60000000-0000-0000-0000-000000000005', 'BIO'),
|
||||||
|
('60000000-0000-0000-0000-000000000005', 'TIERWOHL')
|
||||||
|
ON CONFLICT (customer_id, preference) DO NOTHING;
|
||||||
|
|
||||||
|
-- Rahmenvertrag REWE
|
||||||
|
INSERT INTO frame_contracts (id, customer_id, valid_from, valid_until, delivery_rhythm) VALUES
|
||||||
|
('70000000-0000-0000-0000-000000000001', '60000000-0000-0000-0000-000000000001', '2026-01-01', '2026-12-31', 'BIWEEKLY')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
INSERT INTO contract_line_items (frame_contract_id, article_id, agreed_price_amount, agreed_price_currency, agreed_quantity, unit) VALUES
|
||||||
|
('70000000-0000-0000-0000-000000000001', '40000000-0000-0000-0000-000000000006', 11.50, 'EUR', 20.0000, 'KG'),
|
||||||
|
('70000000-0000-0000-0000-000000000001', '40000000-0000-0000-0000-000000000007', 10.20, 'EUR', 10.0000, 'KG'),
|
||||||
|
('70000000-0000-0000-0000-000000000001', '40000000-0000-0000-0000-000000000008', 17.50, 'EUR', 5.0000, 'KG')
|
||||||
|
ON CONFLICT (frame_contract_id, article_id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 6. STORAGE LOCATIONS (5 Lagerorte)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
INSERT INTO storage_locations (id, name, storage_type, min_temperature, max_temperature, active) VALUES
|
||||||
|
('80000000-0000-0000-0000-000000000001', 'Kühlraum 1 (Fleisch)', 'COLD_ROOM', 0.0, 4.0, true),
|
||||||
|
('80000000-0000-0000-0000-000000000002', 'Tiefkühler', 'FREEZER', -22.0, -18.0, true),
|
||||||
|
('80000000-0000-0000-0000-000000000003', 'Trockenlager', 'DRY_STORAGE', 15.0, 25.0, true),
|
||||||
|
('80000000-0000-0000-0000-000000000004', 'Verkaufstheke', 'DISPLAY_COUNTER', 0.0, 7.0, true),
|
||||||
|
('80000000-0000-0000-0000-000000000005', 'Produktionsraum', 'PRODUCTION_AREA', 8.0, 12.0, true)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 7. STOCKS (Bestandseinträge)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
INSERT INTO stocks (id, article_id, storage_location_id, minimum_level_amount, minimum_level_unit, minimum_shelf_life_days) VALUES
|
||||||
|
-- Frischfleisch im Kühlraum
|
||||||
|
('90000000-0000-0000-0000-000000000001', '40000000-0000-0000-0000-000000000001', '80000000-0000-0000-0000-000000000001', 50.000, 'KILOGRAM', 3),
|
||||||
|
('90000000-0000-0000-0000-000000000002', '40000000-0000-0000-0000-000000000002', '80000000-0000-0000-0000-000000000001', 30.000, 'KILOGRAM', 3),
|
||||||
|
('90000000-0000-0000-0000-000000000003', '40000000-0000-0000-0000-000000000003', '80000000-0000-0000-0000-000000000001', 20.000, 'KILOGRAM', 3),
|
||||||
|
('90000000-0000-0000-0000-000000000004', '40000000-0000-0000-0000-000000000004', '80000000-0000-0000-0000-000000000001', 10.000, 'KILOGRAM', 2),
|
||||||
|
('90000000-0000-0000-0000-000000000005', '40000000-0000-0000-0000-000000000005', '80000000-0000-0000-0000-000000000001', 15.000, 'KILOGRAM', 5),
|
||||||
|
-- Gewürze im Trockenlager
|
||||||
|
('90000000-0000-0000-0000-000000000006', '40000000-0000-0000-0000-000000000009', '80000000-0000-0000-0000-000000000003', 5.000, 'KILOGRAM', 30),
|
||||||
|
('90000000-0000-0000-0000-000000000007', '40000000-0000-0000-0000-000000000010', '80000000-0000-0000-0000-000000000003', 25.000, 'KILOGRAM', 60),
|
||||||
|
('90000000-0000-0000-0000-000000000008', '40000000-0000-0000-0000-000000000011', '80000000-0000-0000-0000-000000000003', 2.000, 'KILOGRAM', 30),
|
||||||
|
-- Wurstwaren in der Theke
|
||||||
|
('90000000-0000-0000-0000-000000000009', '40000000-0000-0000-0000-000000000006', '80000000-0000-0000-0000-000000000004', 5.000, 'KILOGRAM', 2),
|
||||||
|
('90000000-0000-0000-0000-000000000010', '40000000-0000-0000-0000-000000000007', '80000000-0000-0000-0000-000000000004', 3.000, 'KILOGRAM', 3),
|
||||||
|
('90000000-0000-0000-0000-000000000011', '40000000-0000-0000-0000-000000000008', '80000000-0000-0000-0000-000000000004', 2.000, 'KILOGRAM', 7)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 8. STOCK BATCHES (Chargen im Bestand)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
INSERT INTO stock_batches (id, stock_id, batch_id, batch_type, quantity_amount, quantity_unit, expiry_date, status, received_at) VALUES
|
||||||
|
-- Schweineschulter – 2 Chargen
|
||||||
|
('A0000000-0000-0000-0000-000000000001', '90000000-0000-0000-0000-000000000001', 'BF-2026-0215-001', 'PURCHASED', 35.000000, 'KILOGRAM', '2026-02-28', 'AVAILABLE', '2026-02-15 06:00:00+01'),
|
||||||
|
('A0000000-0000-0000-0000-000000000002', '90000000-0000-0000-0000-000000000001', 'BF-2026-0220-001', 'PURCHASED', 40.000000, 'KILOGRAM', '2026-03-05', 'AVAILABLE', '2026-02-20 06:30:00+01'),
|
||||||
|
-- Schweinebauch
|
||||||
|
('A0000000-0000-0000-0000-000000000003', '90000000-0000-0000-0000-000000000002', 'BF-2026-0218-001', 'PURCHASED', 25.000000, 'KILOGRAM', '2026-03-01', 'AVAILABLE', '2026-02-18 07:00:00+01'),
|
||||||
|
-- Rindfleisch
|
||||||
|
('A0000000-0000-0000-0000-000000000004', '90000000-0000-0000-0000-000000000003', 'AR-2026-0219-001', 'PURCHASED', 22.000000, 'KILOGRAM', '2026-03-02', 'AVAILABLE', '2026-02-19 08:00:00+01'),
|
||||||
|
-- Schweineleber
|
||||||
|
('A0000000-0000-0000-0000-000000000005', '90000000-0000-0000-0000-000000000004', 'BF-2026-0222-001', 'PURCHASED', 12.000000, 'KILOGRAM', '2026-02-26', 'EXPIRING_SOON', '2026-02-22 06:00:00+01'),
|
||||||
|
-- Speck
|
||||||
|
('A0000000-0000-0000-0000-000000000006', '90000000-0000-0000-0000-000000000005', 'BF-2026-0218-002', 'PURCHASED', 18.000000, 'KILOGRAM', '2026-03-04', 'AVAILABLE', '2026-02-18 06:30:00+01'),
|
||||||
|
-- Bratwurstgewürz
|
||||||
|
('A0000000-0000-0000-0000-000000000007', '90000000-0000-0000-0000-000000000006', 'GK-2026-0101-001', 'PURCHASED', 8.000000, 'KILOGRAM', '2026-12-31', 'AVAILABLE', '2026-01-15 10:00:00+01'),
|
||||||
|
-- Pökelsalz
|
||||||
|
('A0000000-0000-0000-0000-000000000008', '90000000-0000-0000-0000-000000000007', 'GK-2026-0110-001', 'PURCHASED', 50.000000, 'KILOGRAM', '2027-06-30', 'AVAILABLE', '2026-01-20 10:00:00+01'),
|
||||||
|
-- Kräutermischung Leberwurst
|
||||||
|
('A0000000-0000-0000-0000-000000000009', '90000000-0000-0000-0000-000000000008', 'GK-2026-0115-001', 'PURCHASED', 3.500000, 'KILOGRAM', '2026-09-30', 'AVAILABLE', '2026-01-25 09:00:00+01'),
|
||||||
|
-- Bratwurst in Theke (produziert)
|
||||||
|
('A0000000-0000-0000-0000-000000000010', '90000000-0000-0000-0000-000000000009', 'BW-260223-01', 'PRODUCED', 8.500000, 'KILOGRAM', '2026-02-28', 'AVAILABLE', '2026-02-23 14:00:00+01'),
|
||||||
|
-- Leberwurst in Theke (produziert)
|
||||||
|
('A0000000-0000-0000-0000-000000000011', '90000000-0000-0000-0000-000000000010', 'LW-260222-01', 'PRODUCED', 4.200000, 'KILOGRAM', '2026-03-01', 'AVAILABLE', '2026-02-22 15:00:00+01'),
|
||||||
|
-- Schinkenspeck in Theke (produziert)
|
||||||
|
('A0000000-0000-0000-0000-000000000012', '90000000-0000-0000-0000-000000000011', 'SS-260215-01', 'PRODUCED', 3.800000, 'KILOGRAM', '2026-03-15', 'AVAILABLE', '2026-02-15 16:00:00+01')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 9. RECIPES (3 Rezepte)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
INSERT INTO recipes (id, name, version, type, description, yield_percentage, shelf_life_days,
|
||||||
|
output_quantity, output_uom, status, article_id, created_at, updated_at) VALUES
|
||||||
|
('B0000000-0000-0000-0000-000000000001',
|
||||||
|
'Hausmacher Bratwurst', 1, 'FINISHED_PRODUCT',
|
||||||
|
'Traditionelle Bratwurst nach Hausrezept. Schweineschulter und Bauch im Verhältnis 70:30, fein gewolft, mit hauseigener Gewürzmischung.',
|
||||||
|
92, 5, 10.000000, 'KILOGRAM', 'ACTIVE',
|
||||||
|
'40000000-0000-0000-0000-000000000006',
|
||||||
|
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
('B0000000-0000-0000-0000-000000000002',
|
||||||
|
'Kräuter-Leberwurst fein', 1, 'FINISHED_PRODUCT',
|
||||||
|
'Feine Leberwurst mit frischen Kräutern. Schweineleber, Schweinebauch und Zwiebeln, fein passiert.',
|
||||||
|
88, 7, 8.000000, 'KILOGRAM', 'ACTIVE',
|
||||||
|
'40000000-0000-0000-0000-000000000007',
|
||||||
|
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
|
|
||||||
|
('B0000000-0000-0000-0000-000000000003',
|
||||||
|
'Schinkenspeck geräuchert', 1, 'FINISHED_PRODUCT',
|
||||||
|
'Durchwachsener Speck, trocken gepökelt und über Buchenholz geräuchert. Reifezeit 14 Tage.',
|
||||||
|
85, 28, 5.000000, 'KILOGRAM', 'ACTIVE',
|
||||||
|
'40000000-0000-0000-0000-000000000008',
|
||||||
|
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Rezept-Zutaten: Hausmacher Bratwurst
|
||||||
|
INSERT INTO recipe_ingredients (id, recipe_id, position, article_id, quantity, uom, substitutable) VALUES
|
||||||
|
('B1000000-0000-0000-0000-000000000001', 'B0000000-0000-0000-0000-000000000001', 1, '40000000-0000-0000-0000-000000000001', 7.000000, 'KILOGRAM', false),
|
||||||
|
('B1000000-0000-0000-0000-000000000002', 'B0000000-0000-0000-0000-000000000001', 2, '40000000-0000-0000-0000-000000000002', 3.000000, 'KILOGRAM', false),
|
||||||
|
('B1000000-0000-0000-0000-000000000003', 'B0000000-0000-0000-0000-000000000001', 3, '40000000-0000-0000-0000-000000000009', 0.200000, 'KILOGRAM', false),
|
||||||
|
('B1000000-0000-0000-0000-000000000004', 'B0000000-0000-0000-0000-000000000001', 4, '40000000-0000-0000-0000-000000000010', 0.180000, 'KILOGRAM', false),
|
||||||
|
('B1000000-0000-0000-0000-000000000005', 'B0000000-0000-0000-0000-000000000001', 5, '40000000-0000-0000-0000-000000000012', 20.000000, 'PIECE', false)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Rezept-Zutaten: Kräuter-Leberwurst
|
||||||
|
INSERT INTO recipe_ingredients (id, recipe_id, position, article_id, quantity, uom, substitutable) VALUES
|
||||||
|
('B1000000-0000-0000-0000-000000000006', 'B0000000-0000-0000-0000-000000000002', 1, '40000000-0000-0000-0000-000000000004', 3.000000, 'KILOGRAM', false),
|
||||||
|
('B1000000-0000-0000-0000-000000000007', 'B0000000-0000-0000-0000-000000000002', 2, '40000000-0000-0000-0000-000000000002', 4.500000, 'KILOGRAM', false),
|
||||||
|
('B1000000-0000-0000-0000-000000000008', 'B0000000-0000-0000-0000-000000000002', 3, '40000000-0000-0000-0000-000000000011', 0.150000, 'KILOGRAM', false),
|
||||||
|
('B1000000-0000-0000-0000-000000000009', 'B0000000-0000-0000-0000-000000000002', 4, '40000000-0000-0000-0000-000000000010', 0.120000, 'KILOGRAM', false)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Rezept-Zutaten: Schinkenspeck
|
||||||
|
INSERT INTO recipe_ingredients (id, recipe_id, position, article_id, quantity, uom, substitutable) VALUES
|
||||||
|
('B1000000-0000-0000-0000-000000000010', 'B0000000-0000-0000-0000-000000000003', 1, '40000000-0000-0000-0000-000000000005', 5.500000, 'KILOGRAM', false),
|
||||||
|
('B1000000-0000-0000-0000-000000000011', 'B0000000-0000-0000-0000-000000000003', 2, '40000000-0000-0000-0000-000000000010', 0.280000, 'KILOGRAM', false),
|
||||||
|
('B1000000-0000-0000-0000-000000000012', 'B0000000-0000-0000-0000-000000000003', 3, '40000000-0000-0000-0000-000000000013', 0.500000, 'KILOGRAM', true)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Produktionsschritte: Hausmacher Bratwurst
|
||||||
|
INSERT INTO recipe_production_steps (id, recipe_id, step_number, description, duration_minutes, temperature_celsius) VALUES
|
||||||
|
('B2000000-0000-0000-0000-000000000001', 'B0000000-0000-0000-0000-000000000001', 1, 'Fleisch auf 2°C vorkühlen und in Würfel schneiden', 30, 2),
|
||||||
|
('B2000000-0000-0000-0000-000000000002', 'B0000000-0000-0000-0000-000000000001', 2, 'Durch 3mm-Scheibe wolfen', 20, NULL),
|
||||||
|
('B2000000-0000-0000-0000-000000000003', 'B0000000-0000-0000-0000-000000000001', 3, 'Gewürze und Pökelsalz einmischen, kuttern bis Brätbindung', 15, NULL),
|
||||||
|
('B2000000-0000-0000-0000-000000000004', 'B0000000-0000-0000-0000-000000000001', 4, 'In Schweinedärme abfüllen, portionieren à 100g', 45, NULL),
|
||||||
|
('B2000000-0000-0000-0000-000000000005', 'B0000000-0000-0000-0000-000000000001', 5, 'Qualitätskontrolle: Gewicht, Bindung, Aussehen', 10, NULL)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Produktionsschritte: Kräuter-Leberwurst
|
||||||
|
INSERT INTO recipe_production_steps (id, recipe_id, step_number, description, duration_minutes, temperature_celsius) VALUES
|
||||||
|
('B2000000-0000-0000-0000-000000000006', 'B0000000-0000-0000-0000-000000000002', 1, 'Schweinebauch kochen bis weich', 90, 85),
|
||||||
|
('B2000000-0000-0000-0000-000000000007', 'B0000000-0000-0000-0000-000000000002', 2, 'Leber blanchieren und entstäuben', 10, 70),
|
||||||
|
('B2000000-0000-0000-0000-000000000008', 'B0000000-0000-0000-0000-000000000002', 3, 'Alles durch feinste Scheibe wolfen, Kräuter zugeben', 20, NULL),
|
||||||
|
('B2000000-0000-0000-0000-000000000009', 'B0000000-0000-0000-0000-000000000002', 4, 'In Dosen/Gläser abfüllen', 30, NULL),
|
||||||
|
('B2000000-0000-0000-0000-000000000010', 'B0000000-0000-0000-0000-000000000002', 5, 'Pasteurisieren bei 80°C Kerntemperatur', 120, 80)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Produktionsschritte: Schinkenspeck
|
||||||
|
INSERT INTO recipe_production_steps (id, recipe_id, step_number, description, duration_minutes, temperature_celsius) VALUES
|
||||||
|
('B2000000-0000-0000-0000-000000000011', 'B0000000-0000-0000-0000-000000000003', 1, 'Speck zuschneiden und Schwarte einritzen', 20, NULL),
|
||||||
|
('B2000000-0000-0000-0000-000000000012', 'B0000000-0000-0000-0000-000000000003', 2, 'Trockenpökelung mit NPS einreiben', 15, 4),
|
||||||
|
('B2000000-0000-0000-0000-000000000013', 'B0000000-0000-0000-0000-000000000003', 3, 'Pökelzeit im Kühlraum (14 Tage, tgl. wenden)', 20160, 4),
|
||||||
|
('B2000000-0000-0000-0000-000000000014', 'B0000000-0000-0000-0000-000000000003', 4, 'Wässern und trocken tupfen', 60, NULL),
|
||||||
|
('B2000000-0000-0000-0000-000000000015', 'B0000000-0000-0000-0000-000000000003', 5, 'Kalträuchern über Buchenholz (3 Durchgänge)', 480, 25)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 10. BATCHES (2 Produktionschargen)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
INSERT INTO batch_number_sequences (production_date, last_sequence) VALUES
|
||||||
|
('2026-02-23', 1),
|
||||||
|
('2026-02-22', 1)
|
||||||
|
ON CONFLICT (production_date) DO NOTHING;
|
||||||
|
|
||||||
|
INSERT INTO batches (id, batch_number, recipe_id, status,
|
||||||
|
planned_quantity_amount, planned_quantity_unit,
|
||||||
|
production_date, best_before_date,
|
||||||
|
actual_quantity_amount, actual_quantity_unit,
|
||||||
|
waste_amount, waste_unit, remarks,
|
||||||
|
completed_at,
|
||||||
|
created_at, updated_at, version) VALUES
|
||||||
|
-- Bratwurst-Charge: abgeschlossen
|
||||||
|
('C0000000-0000-0000-0000-000000000001',
|
||||||
|
'BW-260223-01', 'B0000000-0000-0000-0000-000000000001', 'COMPLETED',
|
||||||
|
10.000000, 'KILOGRAM',
|
||||||
|
'2026-02-23', '2026-02-28',
|
||||||
|
9.200000, 'KILOGRAM',
|
||||||
|
0.800000, 'KILOGRAM', 'Leichte Abweichung bei Darmfüllung, Qualität einwandfrei',
|
||||||
|
'2026-02-23 14:00:00+01',
|
||||||
|
'2026-02-23 06:00:00+01', '2026-02-23 14:00:00+01', 3),
|
||||||
|
|
||||||
|
-- Leberwurst-Charge: in Produktion
|
||||||
|
('C0000000-0000-0000-0000-000000000002',
|
||||||
|
'LW-260222-01', 'B0000000-0000-0000-0000-000000000002', 'IN_PRODUCTION',
|
||||||
|
8.000000, 'KILOGRAM',
|
||||||
|
'2026-02-22', '2026-03-01',
|
||||||
|
NULL, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL,
|
||||||
|
'2026-02-22 06:00:00+01', '2026-02-22 10:00:00+01', 1)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Batch Consumptions (Verbrauch der Bratwurst-Charge)
|
||||||
|
INSERT INTO batch_consumptions (id, batch_id, input_batch_id, article_id, quantity_used_amount, quantity_used_unit, consumed_at) VALUES
|
||||||
|
('C1000000-0000-0000-0000-000000000001', 'C0000000-0000-0000-0000-000000000001', 'BF-2026-0215-001', '40000000-0000-0000-0000-000000000001', 7.000000, 'KILOGRAM', '2026-02-23 07:00:00+01'),
|
||||||
|
('C1000000-0000-0000-0000-000000000002', 'C0000000-0000-0000-0000-000000000001', 'BF-2026-0218-001', '40000000-0000-0000-0000-000000000002', 3.000000, 'KILOGRAM', '2026-02-23 07:00:00+01')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 11. PRODUCTION ORDERS (3 Aufträge)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
INSERT INTO production_orders (id, recipe_id, status, planned_quantity_amount, planned_quantity_unit,
|
||||||
|
planned_date, priority, notes, batch_id,
|
||||||
|
created_at, updated_at, version) VALUES
|
||||||
|
-- Bratwurst-Auftrag: abgeschlossen (mit Batch verknüpft)
|
||||||
|
('D0000000-0000-0000-0000-000000000001',
|
||||||
|
'B0000000-0000-0000-0000-000000000001', 'COMPLETED',
|
||||||
|
10.000000, 'KILOGRAM',
|
||||||
|
'2026-02-23', 'NORMAL', 'Reguläre Wochenproduktion Bratwurst',
|
||||||
|
'C0000000-0000-0000-0000-000000000001',
|
||||||
|
'2026-02-21 09:00:00+01', '2026-02-23 14:00:00+01', 4),
|
||||||
|
|
||||||
|
-- Leberwurst-Auftrag: in Produktion
|
||||||
|
('D0000000-0000-0000-0000-000000000002',
|
||||||
|
'B0000000-0000-0000-0000-000000000002', 'IN_PROGRESS',
|
||||||
|
8.000000, 'KILOGRAM',
|
||||||
|
'2026-02-22', 'HIGH', 'Eilauftrag – Bestand in Theke niedrig',
|
||||||
|
'C0000000-0000-0000-0000-000000000002',
|
||||||
|
'2026-02-21 14:00:00+01', '2026-02-22 10:00:00+01', 2),
|
||||||
|
|
||||||
|
-- Schinkenspeck-Auftrag: freigegeben (noch kein Batch)
|
||||||
|
('D0000000-0000-0000-0000-000000000003',
|
||||||
|
'B0000000-0000-0000-0000-000000000003', 'RELEASED',
|
||||||
|
5.000000, 'KILOGRAM',
|
||||||
|
'2026-02-26', 'NORMAL', 'Nachschub für Dallmayr-Bestellung',
|
||||||
|
NULL,
|
||||||
|
'2026-02-24 08:00:00+01', '2026-02-25 09:00:00+01', 1)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 12. STOCK MOVEMENTS (Bestandsbewegungen)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
INSERT INTO stock_movements (id, stock_id, article_id, stock_batch_id, batch_id, batch_type,
|
||||||
|
movement_type, direction, quantity_amount, quantity_unit,
|
||||||
|
reason, reference_document_id,
|
||||||
|
performed_by, performed_at) VALUES
|
||||||
|
-- Wareneingänge Frischfleisch
|
||||||
|
('E0000000-0000-0000-0000-000000000001',
|
||||||
|
'90000000-0000-0000-0000-000000000001', '40000000-0000-0000-0000-000000000001',
|
||||||
|
'A0000000-0000-0000-0000-000000000001', 'BF-2026-0215-001', 'PURCHASED',
|
||||||
|
'GOODS_RECEIPT', 'IN', 35.000000, 'KILOGRAM',
|
||||||
|
'Wareneingang Bay. Fleischwerke, Lieferschein LS-2026-0455', 'LS-2026-0455',
|
||||||
|
'10000000-0000-0000-0000-000000000003', '2026-02-15 06:15:00+01'),
|
||||||
|
|
||||||
|
('E0000000-0000-0000-0000-000000000002',
|
||||||
|
'90000000-0000-0000-0000-000000000001', '40000000-0000-0000-0000-000000000001',
|
||||||
|
'A0000000-0000-0000-0000-000000000002', 'BF-2026-0220-001', 'PURCHASED',
|
||||||
|
'GOODS_RECEIPT', 'IN', 40.000000, 'KILOGRAM',
|
||||||
|
'Wareneingang Bay. Fleischwerke, Lieferschein LS-2026-0512', 'LS-2026-0512',
|
||||||
|
'10000000-0000-0000-0000-000000000003', '2026-02-20 06:45:00+01'),
|
||||||
|
|
||||||
|
('E0000000-0000-0000-0000-000000000003',
|
||||||
|
'90000000-0000-0000-0000-000000000002', '40000000-0000-0000-0000-000000000002',
|
||||||
|
'A0000000-0000-0000-0000-000000000003', 'BF-2026-0218-001', 'PURCHASED',
|
||||||
|
'GOODS_RECEIPT', 'IN', 25.000000, 'KILOGRAM',
|
||||||
|
'Wareneingang Bay. Fleischwerke', 'LS-2026-0489',
|
||||||
|
'10000000-0000-0000-0000-000000000003', '2026-02-18 07:15:00+01'),
|
||||||
|
|
||||||
|
('E0000000-0000-0000-0000-000000000004',
|
||||||
|
'90000000-0000-0000-0000-000000000003', '40000000-0000-0000-0000-000000000003',
|
||||||
|
'A0000000-0000-0000-0000-000000000004', 'AR-2026-0219-001', 'PURCHASED',
|
||||||
|
'GOODS_RECEIPT', 'IN', 22.000000, 'KILOGRAM',
|
||||||
|
'Wareneingang Alpenrind Tirol', 'LS-AT-2026-0088',
|
||||||
|
'10000000-0000-0000-0000-000000000003', '2026-02-19 08:30:00+01'),
|
||||||
|
|
||||||
|
-- Produktionsverbrauch Bratwurst (Schweineschulter)
|
||||||
|
('E0000000-0000-0000-0000-000000000005',
|
||||||
|
'90000000-0000-0000-0000-000000000001', '40000000-0000-0000-0000-000000000001',
|
||||||
|
'A0000000-0000-0000-0000-000000000001', 'BF-2026-0215-001', 'PURCHASED',
|
||||||
|
'PRODUCTION_CONSUMPTION', 'OUT', 7.000000, 'KILOGRAM',
|
||||||
|
'Verbrauch für Charge BW-260223-01', 'BW-260223-01',
|
||||||
|
'10000000-0000-0000-0000-000000000001', '2026-02-23 07:00:00+01'),
|
||||||
|
|
||||||
|
-- Produktionsverbrauch Bratwurst (Schweinebauch)
|
||||||
|
('E0000000-0000-0000-0000-000000000006',
|
||||||
|
'90000000-0000-0000-0000-000000000002', '40000000-0000-0000-0000-000000000002',
|
||||||
|
'A0000000-0000-0000-0000-000000000003', 'BF-2026-0218-001', 'PURCHASED',
|
||||||
|
'PRODUCTION_CONSUMPTION', 'OUT', 3.000000, 'KILOGRAM',
|
||||||
|
'Verbrauch für Charge BW-260223-01', 'BW-260223-01',
|
||||||
|
'10000000-0000-0000-0000-000000000001', '2026-02-23 07:00:00+01'),
|
||||||
|
|
||||||
|
-- Produktionsoutput Bratwurst
|
||||||
|
('E0000000-0000-0000-0000-000000000007',
|
||||||
|
'90000000-0000-0000-0000-000000000009', '40000000-0000-0000-0000-000000000006',
|
||||||
|
'A0000000-0000-0000-0000-000000000010', 'BW-260223-01', 'PRODUCED',
|
||||||
|
'PRODUCTION_OUTPUT', 'IN', 9.200000, 'KILOGRAM',
|
||||||
|
'Produktion Hausmacher Bratwurst, Charge BW-260223-01', 'BW-260223-01',
|
||||||
|
'10000000-0000-0000-0000-000000000001', '2026-02-23 14:00:00+01'),
|
||||||
|
|
||||||
|
-- Verkauf Bratwurst aus Theke
|
||||||
|
('E0000000-0000-0000-0000-000000000008',
|
||||||
|
'90000000-0000-0000-0000-000000000009', '40000000-0000-0000-0000-000000000006',
|
||||||
|
'A0000000-0000-0000-0000-000000000010', 'BW-260223-01', 'PRODUCED',
|
||||||
|
'SALE', 'OUT', 0.700000, 'KILOGRAM',
|
||||||
|
'Thekenverkauf', NULL,
|
||||||
|
'10000000-0000-0000-0000-000000000006', '2026-02-23 16:30:00+01'),
|
||||||
|
|
||||||
|
-- Wareneingang Gewürze
|
||||||
|
('E0000000-0000-0000-0000-000000000009',
|
||||||
|
'90000000-0000-0000-0000-000000000006', '40000000-0000-0000-0000-000000000009',
|
||||||
|
'A0000000-0000-0000-0000-000000000007', 'GK-2026-0101-001', 'PURCHASED',
|
||||||
|
'GOODS_RECEIPT', 'IN', 8.000000, 'KILOGRAM',
|
||||||
|
'Wareneingang Gewürzkontor', 'LS-GK-2026-0012',
|
||||||
|
'10000000-0000-0000-0000-000000000003', '2026-01-15 10:30:00+01'),
|
||||||
|
|
||||||
|
-- Schwund/Abschreibung Leber (kurzes MHD)
|
||||||
|
('E0000000-0000-0000-0000-000000000010',
|
||||||
|
'90000000-0000-0000-0000-000000000004', '40000000-0000-0000-0000-000000000004',
|
||||||
|
'A0000000-0000-0000-0000-000000000005', 'BF-2026-0222-001', 'PURCHASED',
|
||||||
|
'WASTE', 'OUT', 0.500000, 'KILOGRAM',
|
||||||
|
'Randstücke nicht verwertbar, MHD-kritisch', NULL,
|
||||||
|
'10000000-0000-0000-0000-000000000004', '2026-02-24 08:00:00+01')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Box, Text, useInput } from 'ink';
|
import { Box, Text, useInput } from 'ink';
|
||||||
import { useNavigation } from '../../state/navigation-context.js';
|
import { useNavigation } from '../../state/navigation-context.js';
|
||||||
import { useStockMovements } from '../../hooks/useStockMovements.js';
|
import { useStockMovements } from '../../hooks/useStockMovements.js';
|
||||||
import { LoadingSpinner } from '../shared/LoadingSpinner.js';
|
import { LoadingSpinner } from '../shared/LoadingSpinner.js';
|
||||||
import { ErrorDisplay } from '../shared/ErrorDisplay.js';
|
import { ErrorDisplay } from '../shared/ErrorDisplay.js';
|
||||||
import { MOVEMENT_TYPE_LABELS, MOVEMENT_DIRECTION_LABELS } from '@effigenix/api-client';
|
import { MOVEMENT_TYPE_LABELS, MOVEMENT_DIRECTION_LABELS, STORAGE_TYPE_LABELS } from '@effigenix/api-client';
|
||||||
import type { MovementType, MovementDirection } from '@effigenix/api-client';
|
import type { MovementType, MovementDirection, StorageType } from '@effigenix/api-client';
|
||||||
|
import { client } from '../../utils/api-client.js';
|
||||||
|
|
||||||
const DIRECTION_COLORS: Record<string, string> = {
|
const DIRECTION_COLORS: Record<string, string> = {
|
||||||
IN: 'green',
|
IN: 'green',
|
||||||
|
|
@ -16,12 +17,51 @@ export function StockMovementDetailScreen() {
|
||||||
const { params, back } = useNavigation();
|
const { params, back } = useNavigation();
|
||||||
const { movement, loading, error, fetchMovement, clearError } = useStockMovements();
|
const { movement, loading, error, fetchMovement, clearError } = useStockMovements();
|
||||||
|
|
||||||
|
const [storageLabel, setStorageLabel] = useState<string | null>(null);
|
||||||
|
const [articleLabel, setArticleLabel] = useState<string | null>(null);
|
||||||
|
const [userLabel, setUserLabel] = useState<string | null>(null);
|
||||||
|
|
||||||
const movementId = params.movementId ?? '';
|
const movementId = params.movementId ?? '';
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (movementId) void fetchMovement(movementId);
|
if (movementId) void fetchMovement(movementId);
|
||||||
}, [fetchMovement, movementId]);
|
}, [fetchMovement, movementId]);
|
||||||
|
|
||||||
|
// Resolve Storage Location via Stock → StorageLocation
|
||||||
|
useEffect(() => {
|
||||||
|
if (!movement?.stockId) return;
|
||||||
|
void (async () => {
|
||||||
|
try {
|
||||||
|
const stock = await client.stocks.getById(movement.stockId);
|
||||||
|
const loc = await client.storageLocations.getById(stock.storageLocationId);
|
||||||
|
const typeLabel = STORAGE_TYPE_LABELS[loc.storageType as StorageType] ?? loc.storageType;
|
||||||
|
setStorageLabel(`${loc.name} (${typeLabel})`);
|
||||||
|
} catch { setStorageLabel(null); }
|
||||||
|
})();
|
||||||
|
}, [movement?.stockId]);
|
||||||
|
|
||||||
|
// Resolve Article name + number
|
||||||
|
useEffect(() => {
|
||||||
|
if (!movement?.articleId) return;
|
||||||
|
void (async () => {
|
||||||
|
try {
|
||||||
|
const article = await client.articles.getById(movement.articleId);
|
||||||
|
setArticleLabel(`${article.name} (${article.articleNumber})`);
|
||||||
|
} catch { setArticleLabel(null); }
|
||||||
|
})();
|
||||||
|
}, [movement?.articleId]);
|
||||||
|
|
||||||
|
// Resolve User
|
||||||
|
useEffect(() => {
|
||||||
|
if (!movement?.performedBy) return;
|
||||||
|
void (async () => {
|
||||||
|
try {
|
||||||
|
const user = await client.users.getById(movement.performedBy);
|
||||||
|
setUserLabel(user.username);
|
||||||
|
} catch { setUserLabel(null); }
|
||||||
|
})();
|
||||||
|
}, [movement?.performedBy]);
|
||||||
|
|
||||||
useInput((_input, key) => {
|
useInput((_input, key) => {
|
||||||
if (key.backspace || key.escape) back();
|
if (key.backspace || key.escape) back();
|
||||||
});
|
});
|
||||||
|
|
@ -58,9 +98,8 @@ export function StockMovementDetailScreen() {
|
||||||
<Box><Text color="gray">Typ: </Text><Text>{typeLabel}</Text></Box>
|
<Box><Text color="gray">Typ: </Text><Text>{typeLabel}</Text></Box>
|
||||||
<Box><Text color="gray">Richtung: </Text><Text color={dirColor}>{dirLabel}</Text></Box>
|
<Box><Text color="gray">Richtung: </Text><Text color={dirColor}>{dirLabel}</Text></Box>
|
||||||
<Box><Text color="gray">Menge: </Text><Text>{movement.quantityAmount} {movement.quantityUnit}</Text></Box>
|
<Box><Text color="gray">Menge: </Text><Text>{movement.quantityAmount} {movement.quantityUnit}</Text></Box>
|
||||||
<Box><Text color="gray">Stock-ID: </Text><Text>{movement.stockId}</Text></Box>
|
<Box><Text color="gray">Lagerort: </Text><Text>{storageLabel ?? '...'}</Text><Text dimColor> {movement.stockId}</Text></Box>
|
||||||
<Box><Text color="gray">Artikel-ID: </Text><Text>{movement.articleId}</Text></Box>
|
<Box><Text color="gray">Artikel: </Text><Text>{articleLabel ?? '...'}</Text><Text dimColor> {movement.articleId}</Text></Box>
|
||||||
<Box><Text color="gray">Chargen-Batch: </Text><Text>{movement.stockBatchId}</Text></Box>
|
|
||||||
<Box><Text color="gray">Chargen-Nr.: </Text><Text>{movement.batchId}</Text></Box>
|
<Box><Text color="gray">Chargen-Nr.: </Text><Text>{movement.batchId}</Text></Box>
|
||||||
<Box><Text color="gray">Chargen-Typ: </Text><Text>{movement.batchType}</Text></Box>
|
<Box><Text color="gray">Chargen-Typ: </Text><Text>{movement.batchType}</Text></Box>
|
||||||
{movement.reason && (
|
{movement.reason && (
|
||||||
|
|
@ -69,7 +108,7 @@ export function StockMovementDetailScreen() {
|
||||||
{movement.referenceDocumentId && (
|
{movement.referenceDocumentId && (
|
||||||
<Box><Text color="gray">Referenz-Dok.: </Text><Text>{movement.referenceDocumentId}</Text></Box>
|
<Box><Text color="gray">Referenz-Dok.: </Text><Text>{movement.referenceDocumentId}</Text></Box>
|
||||||
)}
|
)}
|
||||||
<Box><Text color="gray">Durchgeführt von:</Text><Text> {movement.performedBy}</Text></Box>
|
<Box><Text color="gray">Durchgeführt von:</Text><Text> {userLabel ?? '...'}</Text><Text dimColor> {movement.performedBy}</Text></Box>
|
||||||
<Box><Text color="gray">Zeitpunkt: </Text><Text>{dateStr}</Text></Box>
|
<Box><Text color="gray">Zeitpunkt: </Text><Text>{dateStr}</Text></Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|
|
||||||
5
makefile
5
makefile
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
.PHONY: frontend-dev backend/run generate/openapi bugsink
|
.PHONY: frontend-dev backend/run generate/openapi bugsink seed-testdata
|
||||||
|
|
||||||
frontend/run:
|
frontend/run:
|
||||||
cd frontend/apps/cli && node --env-file=../../../.env --import tsx src/index.tsx
|
cd frontend/apps/cli && node --env-file=../../../.env --import tsx src/index.tsx
|
||||||
|
|
@ -10,6 +10,9 @@ backend/run:
|
||||||
generate/openapi:
|
generate/openapi:
|
||||||
./scripts/generate-openapi.sh
|
./scripts/generate-openapi.sh
|
||||||
|
|
||||||
|
seed-testdata:
|
||||||
|
PGPASSWORD=effigenix nix shell nixpkgs#postgresql --command psql -f backend/src/main/resources/db/changelog/changes/099-seed-testdata.sql -h localhost -p 5432 -U effigenix -d effigenix
|
||||||
|
|
||||||
bugsink:
|
bugsink:
|
||||||
@. ./.env 2>/dev/null || true; \
|
@. ./.env 2>/dev/null || true; \
|
||||||
docker start bugsink 2>/dev/null || \
|
docker start bugsink 2>/dev/null || \
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue