Open Source · MIT

Crate

Lagerverwaltung mit echtem FIFO: Ein Bestand ist eine Warteschlange aus Chargen, und die Kosten jeder Auslieferung sind Zeile für Zeile aufgeschlüsselt.

v1.0.0 Einstandskosten, die sich belegen lassen
Laravel 13PHP 8.5PostgreSQL 18BladeTailwind 4Vite 8
Crate

Der Durchschnittspreis lügt

Die meisten Lagerprogramme beantworten «wie viele» und zucken bei «zu welchem Preis» mit den Schultern. Sie führen einen Durchschnittspreis je Artikel, und sobald die Einkaufspreise auseinanderlaufen, passt dieser Durchschnitt still nicht mehr zur Wirklichkeit — die Marge jeder Bestellung liegt um ein paar Prozent daneben, und niemand kann sagen, warum.

Crate behält die Schichten. Ein Wareneingang legt eine Charge mit eigenem Preis an, eine Auslieferung verbraucht die Warteschlange vom alten Ende her und schreibt auf, was sie genommen hat. Öffnen Sie eine Bestellung und Sie sehen die Rechnung: vier Stück aus der Juni-Charge, eines von Ende Juni, acht aus der Juli-Charge — und daneben, was dieselbe Zeile nach gewichtetem Durchschnitt gekostet hätte.

Was drinsteckt

Echtes FIFO

Chargen werden mit Zeilensperren gelesen und in Eingangsreihenfolge verbraucht, zwei gleichzeitige Bestellungen können denselben Bestand nicht doppelt ausgeben. Eine Auslieferung über den Bestand hinaus wird nie halb gebucht — der ganze Beleg rollt zurück.

Kosten Zeile für Zeile

Jede Auslieferungszeile speichert ihre Schichten: Charge, Datum, entnommene Menge, Einkaufspreis. Daneben steht die Alternative nach gewichtetem Durchschnitt und die Differenz — man sieht genau, wie stark der Durchschnitt gelogen hätte.

Ein unveränderliches Journal

Ein gebuchter Beleg wird nie bearbeitet. Ein Fehler wird storniert, und die Stornierung gibt die Ware genau in die Chargen zurück, aus denen sie kam. Ein Wareneingang, aus dessen Charge bereits ausgeliefert wurde, lässt sich nicht stornieren.

Umlagerungen altern nicht

Eine Umlagerung erzeugt am neuen Ort dieselben Schichten mit Preis und Eingangsdatum. Sonst würde die FIFO-Warteschlange bei jedem Transport zurückgesetzt und ein halbes Jahr alter Bestand sähe frisch aus.

Inventuren mit Aussage

Die Zählliste hält die erwartete Menge beim Öffnen fest, denn das Lager arbeitet weiter, während jemand durch die Regale geht. Überschuss wird zum Durchschnittspreis eingebucht, Fehlmenge über die Warteschlange abgeschrieben — zwei Belege, nicht einer mit Vorzeichen.

Ganze Zahlen und Prüfung

Geld in Kopeken, Mengen in Tausendsteln einer Einheit — keine Floats in einem System, dessen ganze Aufgabe es ist, dass die Zahlen aufgehen. Der Befehl crate:verify rechnet die Bestände jede Nacht aus dem Journal nach.

Screenshots

Bestand: jeder Balken ist eine Warteschlange aus Chargen
Bestand: jeder Balken ist eine Warteschlange aus Chargen
Eine Bestellung zerlegt: aus welchen Chargen die Kosten kamen
Eine Bestellung zerlegt: aus welchen Chargen die Kosten kamen
Artikelkarte: Schichten je Lager und die Bewegungshistorie
Artikelkarte: Schichten je Lager und die Bewegungshistorie
Das Journal: Eingänge, Auslieferungen, Umlagerungen, Stornos
Das Journal: Eingänge, Auslieferungen, Umlagerungen, Stornos
Inventur: erwartet, gezählt, Differenz
Inventur: erwartet, gezählt, Differenz
Gewinn: Umsatz minus Kosten der abgegangenen Chargen
Gewinn: Umsatz minus Kosten der abgegangenen Chargen

Installation

git clone https://github.com/dripips/crate.git cd crate docker compose up --build

Haben Sie ein Projekt oder eine Idee?

Schreiben Sie mir, dann besprechen wir die Aufgabe.