KI-AGENT: Lagerkonzept nach Fachentscheidungen konkretisieren
This commit is contained in:
@@ -8,7 +8,7 @@ Das Zielbild trennt drei heute teilweise vermischte Begriffe:
|
||||
|
||||
- **Artikel** (`products`) beschreiben einen wiederverwendbaren Material- oder Handelsartikel, zum Beispiel „Kabel NYM-J 3×1,5“.
|
||||
- **Bestand** beschreibt, welche Menge eines Artikels sich an welchem Lagerplatz befindet.
|
||||
- **Inventarartikel** (`inventoryitems`) sind individuell verwaltete Betriebsmittel oder Anlagegüter, zum Beispiel ein Messgerät oder Fahrzeugzubehör. Sie können eine Seriennummer und einen aktuellen Standort haben, sind aber kein mengenmäßig geführter Lagerbestand.
|
||||
- **Inventarartikel** (`inventoryitems`) sind ausschließlich individuell verwaltete Betriebsmittel oder Anlagegüter, zum Beispiel ein Messgerät oder Fahrzeugzubehör. Sie sind für die Lagerbestandsführung vollständig irrelevant.
|
||||
|
||||
Kundeninventar bleibt ebenfalls ein eigener Bereich. Ein beim Kunden verbautes oder betreutes Gerät ist nicht automatisch eigener verfügbarer Lagerbestand.
|
||||
|
||||
@@ -25,7 +25,7 @@ FEDEO bringt bereits wesentliche Bausteine mit:
|
||||
|
||||
Die vorhandene Tabelle `movements` ist jedoch noch kein belastbares Lagerbuch. Ihr fehlen unter anderem Buchungsart und -status, Gegenlager bei Umlagerungen, Belegreferenz, Stornobeziehung, Chargenmodell, Reservierungen und Schutz vor doppelter Verarbeitung. Zudem wird sie aktuell weder über eine eigene Route noch über eine Oberfläche genutzt.
|
||||
|
||||
Die Mengenfelder von Inventar und Kundeninventar sollten nicht zur Bestandsführung von Artikeln verwendet werden. Andernfalls entstehen parallele Wahrheiten zwischen Artikel, Inventar und Lagerbewegung.
|
||||
Die Mengenfelder von Inventar und Kundeninventar werden nicht zur Bestandsführung von Artikeln verwendet. Insbesondere wird `inventoryitems` weder in Bestandsberechnungen noch in Lagerbuchungen oder in die Bestandsmigration einbezogen. Andernfalls entstünden parallele Wahrheiten zwischen Artikel, Inventar und Lagerbewegung.
|
||||
|
||||
## Fachliche Leitlinien
|
||||
|
||||
@@ -34,9 +34,11 @@ Die Mengenfelder von Inventar und Kundeninventar sollten nicht zur Bestandsführ
|
||||
3. **Ein Vorgang, eine Transaktion:** Alle Positionen eines Wareneingangs oder einer Umlagerung werden vollständig oder gar nicht gebucht.
|
||||
4. **Mandantentrennung in jeder Abfrage:** Artikel, Lagerplätze, Buchungen und Referenzen müssen zum aktiven Mandanten gehören.
|
||||
5. **Nachvollziehbare Herkunft:** Jede Buchung speichert Benutzer, Zeitpunkt, Buchungsgrund und optional Projekt, Lieferant oder FEDEO-Beleg.
|
||||
6. **Reserviert ist nicht entnommen:** Reservierungen reduzieren den verfügbaren, aber nicht den physischen Bestand.
|
||||
7. **Seriennummern und Chargen sind Bewegungsdaten:** Sie gehören zu konkreten Bestandseinheiten und nicht als Liste in eine allgemeine Buchungszeile.
|
||||
8. **Bestätigen ist endgültig:** Entwürfe sind änderbar; bestätigte Buchungen sind unveränderlich.
|
||||
6. **Negativbestände sind zulässig und sichtbar:** Verkäufe dürfen einen Bestand unter null buchen, wenn die Ware bereits berechnet, aber noch nicht geliefert beziehungsweise beschafft wurde. Ein Negativbestand wird als Handlungsbedarf hervorgehoben und niemals stillschweigend ausgeblendet.
|
||||
7. **Reserviert ist nicht entnommen:** Reservierungen reduzieren den verfügbaren, aber nicht den buchmäßigen Bestand.
|
||||
8. **Seriennummern und Chargen sind Bewegungsdaten:** Sie gehören zu konkreten Bestandseinheiten und nicht als Liste in eine allgemeine Buchungszeile.
|
||||
9. **Bestätigen ist endgültig:** Entwürfe sind änderbar; bestätigte Buchungen sind unveränderlich.
|
||||
10. **Ein Verkauf wird nur einmal gebucht:** Lieferschein und Rechnung werden positions- und mengenbezogen gegeneinander abgeglichen.
|
||||
|
||||
## Fachliches Datenmodell
|
||||
|
||||
@@ -48,7 +50,7 @@ Die Mengenfelder von Inventar und Kundeninventar sollten nicht zur Bestandsführ
|
||||
| --- | --- |
|
||||
| `stockManaged` | Artikel wird im Lager geführt |
|
||||
| `trackingMode` | `none`, `lot` oder `serial` |
|
||||
| `allowNegativeStock` | negativer Bestand erlaubt; standardmäßig `false` |
|
||||
| `allowNegativeStock` | negativer Bestand erlaubt; für den festgelegten Verkaufsprozess standardmäßig `true` |
|
||||
| `minimumStock` | mandantenweiter Mindestbestand, optional |
|
||||
| `reorderPoint` | Meldebestand, optional |
|
||||
| `defaultWarehouse` | bevorzugtes Lager, optional |
|
||||
@@ -58,16 +60,23 @@ Die bestehende `unit` ist die Bestandsbasiseinheit. Mengen sollten als `numeric`
|
||||
|
||||
### Lagerstruktur
|
||||
|
||||
Die bestehenden `spaces` können als hierarchische Lagerstruktur weiterverwendet werden. Ergänzt werden sollten:
|
||||
Die bestehenden `spaces` können als hierarchische Lagerstruktur weiterverwendet werden. Lagerplatzarten werden nicht als festes Enum programmiert, sondern je Mandant in `space_types` frei gepflegt.
|
||||
|
||||
`space_types` enthält mindestens `id`, `tenant`, `name`, `code`, `description`, `stockEnabledByDefault`, `icon`, `sortOrder` und `archived`. So können Mandanten beispielsweise „Hauptlager“, „Regal“, „Fach“, „Fahrzeug“, „Baustellencontainer“ oder eigene Begriffe anlegen, ohne eine neue Softwareversion zu benötigen.
|
||||
|
||||
`spaces` wird ergänzt um:
|
||||
|
||||
| Feld | Bedeutung |
|
||||
| --- | --- |
|
||||
| `kind` | `warehouse`, `zone`, `bin`, `vehicle`, `transit`, `scrap` |
|
||||
| `spaceTypeId` | frei pflegbare Lagerplatzart |
|
||||
| `branchId` | zugehörige Niederlassung |
|
||||
| `stockEnabled` | an diesem Knoten darf Bestand liegen |
|
||||
| `barcode` | scanbare eindeutige Kennung |
|
||||
| `sortOrder` | stabile Reihenfolge in der Lageransicht |
|
||||
|
||||
Ein typischer Baum lautet beispielsweise `Hauptlager > Halle A > Regal 03 > Fach 02`. Nur Blattknoten beziehungsweise ausdrücklich aktivierte Knoten dürfen Bestand tragen. Die Kombination aus `tenant` und `space_number` sowie ein gesetzter Barcode müssen eindeutig sein. Ein Lagerplatz darf nicht sich selbst oder einen seiner Nachfolger als übergeordneten Lagerplatz erhalten.
|
||||
Jedes Lager gehört zu einer vorhandenen FEDEO-Niederlassung (`branches`). Untergeordnete Lagerplätze übernehmen diese Niederlassung; zur schnellen Filterung wird `branchId` auch auf ihnen gespeichert und beim Verschieben im Baum konsistent aktualisiert. Umlagerungen zwischen Niederlassungen sind normale, atomare Umlagerungsbuchungen und können gesondert ausgewertet werden. Für Mandanten ohne bisherige Niederlassung wird bei der Migration eine Standardniederlassung benötigt.
|
||||
|
||||
Ein typischer Baum lautet beispielsweise `Niederlassung München > Hauptlager > Halle A > Regal 03 > Fach 02`. Nur ausdrücklich aktivierte Knoten dürfen Bestand tragen. Die Kombination aus `tenant` und `space_number` sowie ein gesetzter Barcode müssen eindeutig sein. Ein Lagerplatz darf nicht sich selbst oder einen seiner Nachfolger als übergeordneten Lagerplatz erhalten. Typ, übergeordneter Platz und Niederlassung müssen stets demselben Mandanten angehören.
|
||||
|
||||
### Lagerbeleg und Buchungszeilen
|
||||
|
||||
@@ -103,6 +112,30 @@ Für die belastbare Umsetzung empfiehlt sich ein Belegkopf mit mehreren Buchungs
|
||||
|
||||
Mindestens eine Seite einer Zeile muss gesetzt sein. Ein Wareneingang besitzt nur `toSpaceId`, eine Entnahme nur `fromSpaceId`, eine Umlagerung beide Seiten. Die Buchungsart bestimmt zusätzlich, welche Kombination erlaubt ist. Dadurch lässt sich eine Umlagerung atomar abbilden, ohne zwei lose Bewegungen erzeugen zu müssen.
|
||||
|
||||
### Verknüpfung mit Rechnungen und Lieferscheinen
|
||||
|
||||
Damit Rechnung und Lieferschein nicht dieselbe Menge doppelt ausbuchen, wird zusätzlich `stock_document_allocations` eingeführt:
|
||||
|
||||
- `tenant`
|
||||
- `createdDocumentId`
|
||||
- `sourceLineId` als dauerhafte UUID der Belegposition
|
||||
- `productId`
|
||||
- `quantity`
|
||||
- `stockTransactionLineId`
|
||||
- `reversedAt`, optional
|
||||
|
||||
Jede artikelbezogene Belegposition benötigt eine stabile `sourceLineId`. Beim Ableiten eines Lieferscheins oder einer Rechnung wird diese Herkunfts-ID in die neue Position übernommen. So kann das Backend auch Teilmengen durch die gesamte Belegkette verfolgen.
|
||||
|
||||
Bei der Bestätigung eines Verkaufsbelegs wird je Position berechnet:
|
||||
|
||||
```text
|
||||
noch zu buchen = Belegmenge - bereits wirksam gebuchte Menge der Belegkette
|
||||
```
|
||||
|
||||
Ein bestätigter Lieferschein bucht seine noch offene Menge sofort aus. Eine bestätigte Rechnung bucht nur die Menge aus, die nicht bereits durch einen zugehörigen Lieferschein oder eine frühere Rechnung wirksam gebucht wurde. Das funktioniert auch bei Teil- und Sammellieferungen. Ist die Rechnung bereits zuerst gebucht worden, erzeugt der später daraus erstellte Lieferschein keine zweite Lagerentnahme.
|
||||
|
||||
Das Erzeugen, Ändern oder Speichern eines Entwurfs löst keine Buchung aus. Erst der fachliche Statuswechsel auf einen endgültigen beziehungsweise bestätigten Zustand ruft den Lagerbuchungsservice auf. Storno und Rücknahme erzeugen Gegenbuchungen und markieren die betroffenen Zuordnungen als aufgehoben.
|
||||
|
||||
### Chargen und Seriennummern
|
||||
|
||||
`stock_lots` bildet Chargen ab:
|
||||
@@ -126,12 +159,12 @@ Bei Seriennummern entspricht jede gebuchte Einheit genau einer Seriennummer. Bei
|
||||
`stock_balances` ist eine technisch gepflegte Projektion für schnelle Listen und Prüfungen:
|
||||
|
||||
- `tenant`, `productId`, `spaceId`, optional `lotId`
|
||||
- `quantityOnHand`
|
||||
- `quantityBooked`
|
||||
- `quantityReserved`
|
||||
- `averageUnitCost`
|
||||
- `updatedAt`
|
||||
|
||||
`quantityAvailable` wird als `quantityOnHand - quantityReserved` berechnet. Die eindeutige Kombination verhindert doppelte Bestandszeilen. Die Buchungszeilen bleiben die fachliche Wahrheit; `stock_balances` kann aus ihnen jederzeit neu aufgebaut und geprüft werden.
|
||||
`quantityAvailable` wird als `quantityBooked - quantityReserved` berechnet. `quantityBooked` ist der buchmäßige Sollbestand. Er kann negativ sein und zeigt dann eine bereits verkaufte, aber noch nicht vorhandene beziehungsweise gelieferte Menge. Die eindeutige Kombination verhindert doppelte Bestandszeilen. Die Buchungszeilen bleiben die fachliche Wahrheit; `stock_balances` kann aus ihnen jederzeit neu aufgebaut und geprüft werden.
|
||||
|
||||
`stock_reservations` enthält reservierte Mengen für ein Projekt, eine Aufgabe oder einen Beleg. Zustände sind `active`, `partially_fulfilled`, `fulfilled`, `cancelled` und `expired`. Eine spätere Entnahme erfüllt die Reservierung in derselben Datenbanktransaktion.
|
||||
|
||||
@@ -145,14 +178,14 @@ Beim Bestätigen eines Lagerbelegs führt das Backend in **einer Datenbanktransa
|
||||
2. Alle Artikel und Lagerplätze laden und ihre Zugehörigkeit zum Mandanten validieren.
|
||||
3. Einheiten, Trackingregeln, Mengen und Pflichtangaben prüfen.
|
||||
4. Betroffene `stock_balances` in einer stabilen Reihenfolge sperren.
|
||||
5. Verfügbarkeit prüfen; bei einer Umlagerung ist die Quellseite maßgeblich.
|
||||
5. Verfügbarkeit prüfen und bei gesperrtem Negativbestand ablehnen; bei erlaubtem Negativbestand die Unterdeckung für Warnungen und Nachbeschaffung festhalten.
|
||||
6. Beleg und Zeilen als `posted` speichern und Bestandsprojektion aktualisieren.
|
||||
7. Seriennummern, Chargen, Reservierungen und gleitenden Durchschnittspreis aktualisieren.
|
||||
8. Einen verständlichen Historieneintrag erzeugen.
|
||||
|
||||
Bestandsrelevante Endpunkte dürfen nicht über die generische CRUD-Route umgesetzt werden, weil dort die fachlichen Invarianten, Sperren und Statusübergänge nicht sicher erzwungen werden können. Dafür wird ein eigener Lagermodul-Service verwendet.
|
||||
|
||||
Parallelzugriffe müssen über Zeilensperren oder ein atomisches SQL-Update wie `quantity_on_hand >= benötigte_menge` abgesichert werden. Eine reine Prüfung im Frontend verhindert keine Überentnahme.
|
||||
Parallelzugriffe müssen über Zeilensperren oder atomische SQL-Updates abgesichert werden. Falls ein Artikel oder Vorgang keinen Negativbestand erlaubt, muss die Bestandsbedingung Teil desselben atomischen Updates sein. Eine reine Prüfung im Frontend ist auch bei grundsätzlich zulässigen Negativbeständen nicht ausreichend, weil Buchungen und Bewertung sonst verloren gehen können.
|
||||
|
||||
### Bewertung
|
||||
|
||||
@@ -166,6 +199,8 @@ neuer Durchschnitt =
|
||||
|
||||
Abgänge werden mit dem zum Buchungszeitpunkt gültigen Durchschnitt bewertet. Der Wert wird auf der Buchungszeile festgeschrieben, damit spätere Preisänderungen historische Projektkosten nicht verändern. Stornozeilen übernehmen exakt Menge und Wert der Ursprungsbuchung mit umgekehrter Wirkung.
|
||||
|
||||
Bei einem Abgang in den Negativbestand bleibt der letzte bekannte Durchschnittspreis als vorläufiger Wert erhalten. Ein späterer Zugang deckt zuerst die negative Menge. Die Differenz zwischen vorläufigem Abgangswert und tatsächlichem Zugangspreis wird als Preisabweichung protokolliert; erst eine darüber hinausgehende positive Restmenge bildet einen neuen Durchschnitt. Damit führt ein Vorzeichenwechsel nicht zu einer Division durch null oder einem wirtschaftlich unsinnigen Durchschnittspreis.
|
||||
|
||||
## Kernabläufe
|
||||
|
||||
### Wareneingang
|
||||
@@ -186,9 +221,17 @@ Quelle scannen, Artikel und Menge erfassen, Ziel scannen und bestätigen. Quella
|
||||
|
||||
Eine Entnahme reduziert Bestand und schreibt Menge sowie Wert einem Projekt zu. Rückgaben referenzieren nach Möglichkeit die ursprüngliche Entnahme. Damit können FEDEO-Projekte tatsächliche Materialkosten statt nur kalkulierter Materialpreise ausweisen.
|
||||
|
||||
### Verkauf über Lieferschein und Rechnung
|
||||
|
||||
Beim endgültigen Bestätigen eines Lieferscheins wird die noch nicht gebuchte Artikelmenge der Belegkette aus dem gewählten Lager beziehungsweise Lagerplatz entnommen. Beim endgültigen Bestätigen einer Rechnung erfolgt dieselbe Prüfung; die Rechnung bucht ausschließlich noch nicht durch zugehörige Lieferscheine abgedeckte Mengen.
|
||||
|
||||
Reicht der Bestand nicht aus, wird trotzdem gebucht und der Bestand negativ. Die Oberfläche weist die Unterdeckung unmittelbar aus. Dadurch ist sichtbar, welche bereits verkaufte Menge noch geliefert oder beschafft werden muss. Der auslösende Beleg, seine Position und die Niederlassung bleiben an der Lagerbuchung nachvollziehbar.
|
||||
|
||||
Belegpositionen ohne verknüpften lagergeführten Artikel lösen keine Lagerbuchung aus. Vor der Bestätigung zeigt FEDEO eine Vorschau mit zu buchenden, bereits gebuchten und nicht zuordenbaren Positionen. Nicht zuordenbare Positionen verhindern die Belegbestätigung nicht, erzeugen aber einen deutlichen Hinweis.
|
||||
|
||||
### Reservierung
|
||||
|
||||
Material wird für ein Projekt vorgemerkt. Der physische Bestand bleibt unverändert, der verfügbare Bestand sinkt. Beim Kommissionieren oder bei der Entnahme wird die Reservierung ganz oder teilweise erfüllt.
|
||||
Material wird für ein Projekt vorgemerkt. Der buchmäßige Bestand bleibt unverändert, der verfügbare Bestand sinkt. Beim Kommissionieren oder bei der Entnahme wird die Reservierung ganz oder teilweise erfüllt.
|
||||
|
||||
### Inventur
|
||||
|
||||
@@ -202,7 +245,7 @@ Der gezählte Wert überschreibt niemals direkt den Bestand.
|
||||
|
||||
### Storno
|
||||
|
||||
Ein bestätigter Beleg erhält eine Gegenbuchung mit Referenz auf das Original. Ein erneutes Storno desselben Belegs ist ausgeschlossen. Kann die Gegenbuchung wegen zwischenzeitlich fehlenden Bestands nicht durchgeführt werden, braucht es eine berechtigte Korrekturbuchung statt einer stillen negativen Menge.
|
||||
Ein bestätigter Beleg erhält eine Gegenbuchung mit Referenz auf das Original. Ein erneutes Storno desselben Belegs ist ausgeschlossen. Die Gegenbuchung übernimmt Menge und Wert des Originals exakt. Entsteht dadurch eine Unterdeckung, bleibt sie als negativer Bestand sichtbar und wird nicht durch eine abweichende Korrekturmenge kaschiert.
|
||||
|
||||
## API-Schnittstellen
|
||||
|
||||
@@ -266,10 +309,11 @@ Einkaufs- und Bestandswerte können damit vor operativen Lagerbenutzern verborge
|
||||
|
||||
- Ein Angebot reserviert und bucht keinen Bestand.
|
||||
- Ein Auftrag kann optional reservieren.
|
||||
- Ein Lieferschein beziehungsweise eine ausdrücklich bestätigte Materialausgabe löst die Entnahme aus.
|
||||
- Eine Rechnung bucht nicht nochmals, wenn bereits ein Lieferschein oder eine Materialausgabe gebucht wurde.
|
||||
- Ein endgültig bestätigter Lieferschein löst die Entnahme seiner noch offenen Menge aus.
|
||||
- Eine endgültig bestätigte Rechnung löst ebenfalls eine Entnahme aus, aber nur für Mengen, die in derselben Belegkette noch nicht durch Lieferscheine oder frühere Rechnungen gebucht wurden.
|
||||
- Eine Stornorechnung ist nicht automatisch ein physischer Warenrückgang; die tatsächliche Rücknahme wird gesondert gebucht.
|
||||
- Seriengeführte Ware kann bei Ausgabe optional einen Inventar- oder Kundeninventardatensatz erzeugen. Die Verbindung bleibt nachvollziehbar, die beiden Bereiche werden aber nicht zu einer Tabelle verschmolzen.
|
||||
- Das betriebliche Inventar (`inventoryitems`) bleibt vollständig unabhängig vom Lager und wird niemals automatisch aus einer Lagerbuchung erzeugt oder verändert.
|
||||
- Kundeninventar kann in einem getrennten späteren Prozess aus gelieferten Serienartikeln entstehen, beeinflusst aber keinen eigenen Lagerbestand.
|
||||
|
||||
Diese Trennung verhindert doppelte Buchungen und bildet kaufmännische sowie physische Ereignisse korrekt ab.
|
||||
|
||||
@@ -279,7 +323,10 @@ Wichtige Datenbankregeln und Indizes:
|
||||
|
||||
- Eindeutigkeit von Lagerbelegnummer und Idempotenzschlüssel je Mandant
|
||||
- Eindeutigkeit von Lagerplatznummer und Lagerplatzbarcode je Mandant
|
||||
- Eindeutigkeit der Lagerplatzart-Codes je Mandant
|
||||
- gültige Niederlassung und einheitliche Niederlassung innerhalb eines Lagerplatzbaums
|
||||
- positive Buchungsmenge und voneinander verschiedene Quell- und Zielplätze
|
||||
- höchstens eine wirksame Lagerzuordnung je Belegposition und gebuchter Teilmenge
|
||||
- Seriennummer je Mandant und Artikel eindeutig
|
||||
- Indizes auf `(tenant, productId, spaceId)`, `(tenant, bookingDate)`, Projekt- und Belegreferenzen
|
||||
- Fremdschlüssel möglichst mit `RESTRICT`; gebuchte Stammdaten werden archiviert, nicht gelöscht
|
||||
@@ -291,12 +338,14 @@ Ein periodischer Integritätsjob vergleicht `stock_balances` mit der Summe des L
|
||||
|
||||
### Stufe 1 – belastbares MVP
|
||||
|
||||
- Artikel als lagergeführt kennzeichnen
|
||||
- Lagerplätze um Typ, Bestandsfreigabe und Barcode ergänzen
|
||||
- Artikel als lagergeführt kennzeichnen und Dezimalmengen unterstützen
|
||||
- frei pflegbare Lagerplatzarten einführen
|
||||
- Lagerplätze mit Niederlassung, Bestandsfreigabe und Barcode verbinden
|
||||
- Lagerbeleg, Buchungszeilen und Bestandsprojektion einführen
|
||||
- Anfangsbestand, Wareneingang, Entnahme, Rückgabe, Umlagerung und Storno
|
||||
- automatische, gegen Doppelbuchungen geschützte Entnahme durch bestätigte Lieferscheine und Rechnungen
|
||||
- Bestandsübersicht und Lagerjournal
|
||||
- Projektbezug, negativer Bestand standardmäßig gesperrt
|
||||
- Projekt- und Niederlassungsbezug, Negativbestände mit sichtbarer Unterdeckung
|
||||
- Rollen und serverseitige Berechtigungen
|
||||
|
||||
Damit ist bereits ein produktiv nutzbares Lager mit vollständiger Nachvollziehbarkeit vorhanden.
|
||||
@@ -313,7 +362,7 @@ Damit ist bereits ein produktiv nutzbares Lager mit vollständiger Nachvollziehb
|
||||
### Stufe 3 – erweiterte Logistik
|
||||
|
||||
- Chargen, Ablaufdaten und Seriennummern
|
||||
- mehrere Lager beziehungsweise Niederlassungen und Fahrzeuglager
|
||||
- Fahrzeuglager und komplexere niederlassungsübergreifende Logistik
|
||||
- Bestellvorschläge und Einkaufsprozess
|
||||
- Kunden- oder Konsignationsbestand mit explizitem Eigentümer
|
||||
- FIFO als optionale Bewertungsmethode
|
||||
@@ -321,23 +370,23 @@ Damit ist bereits ein produktiv nutzbares Lager mit vollständiger Nachvollziehb
|
||||
|
||||
## Migration des aktuellen Datenbestands
|
||||
|
||||
Vor der Einführung wird pro Mandant ausgewertet, wie `inventoryitems.quantity`, `inventoryitems.currentSpace` und die vorhandene Tabelle `movements` tatsächlich verwendet wurden.
|
||||
Vor der Einführung wird pro Mandant ausgewertet, wie Artikel, Lagerplätze und die vorhandene Tabelle `movements` tatsächlich verwendet wurden. `inventoryitems` gilt verbindlich als reines Inventar und bleibt von der Lagermigration ausgeschlossen.
|
||||
|
||||
Empfohlenes Vorgehen:
|
||||
|
||||
1. Bestehende Artikel und Lagerplätze bereinigen und Lagerplätze eindeutig nummerieren.
|
||||
2. Inventarartikel klassifizieren: individuelles Betriebsmittel, mengenmäßiger Altbestand oder fehlerhafte Dublette.
|
||||
3. Echte Betriebsmittel im Inventar belassen; mengenmäßige Bestände einem `product` zuordnen.
|
||||
4. Zu einem gemeinsam festgelegten Stichtag je Artikel und Lagerplatz eine bestätigte Anfangsbestandsbuchung erzeugen.
|
||||
5. Historische `movements` nur übernehmen, wenn ihre Semantik und Vollständigkeit verlässlich geklärt werden können; andernfalls revisionssicher als Altbestand erhalten.
|
||||
6. Summen, Bestandswerte und Seriennummern mit einem Migrationsbericht abstimmen.
|
||||
7. Danach direkte Mengenänderungen am Inventar nicht mehr als Lagerbuchung zulassen.
|
||||
1. Bestehende Niederlassungen prüfen und bei Bedarf eine Standardniederlassung anlegen.
|
||||
2. Frei pflegbare Lagerplatzarten anlegen und vorhandene `spaces.type` zuordnen.
|
||||
3. Bestehende Lagerplätze bereinigen, einer Niederlassung zuordnen und eindeutig nummerieren.
|
||||
4. Lagergeführte Artikel bestimmen; Mengen werden ausschließlich auf Basis von `products` übernommen.
|
||||
5. Zu einem gemeinsam festgelegten Stichtag je Artikel und Lagerplatz eine bestätigte Anfangsbestandsbuchung erzeugen.
|
||||
6. Historische `movements` nur übernehmen, wenn ihre Semantik und Vollständigkeit verlässlich geklärt werden können; andernfalls revisionssicher als Altbestand erhalten.
|
||||
7. Summen und Bestandswerte mit einem Migrationsbericht abstimmen.
|
||||
|
||||
Eine automatische Eins-zu-eins-Migration von `inventoryitems` wäre riskant, weil ein Datensatz heute sowohl ein einzelnes Gerät als auch eine Menge ähnlicher Gegenstände beschreiben kann.
|
||||
Bestehende `inventoryitems` werden weder automatisch umgewandelt noch zur Ermittlung eines Anfangsbestands herangezogen.
|
||||
|
||||
## Abnahmekriterien für das MVP
|
||||
|
||||
- Zwei parallele Entnahmen können gemeinsam nie mehr als den verfügbaren Bestand ausgeben.
|
||||
- Zwei parallele Entnahmen gehen nicht verloren und ergeben exakt die Summe beider Buchungen; falls Negativbestand für einen Vorgang gesperrt ist, können sie gemeinsam nie mehr als den verfügbaren Bestand ausgeben.
|
||||
- Jede Bestandszahl lässt sich bis zu ihren bestätigten Buchungen zurückverfolgen.
|
||||
- Eine Umlagerung verändert den Gesamtbestand nicht und wird atomar gebucht.
|
||||
- Ein Storno stellt Menge und Wertwirkung der Ursprungsbuchung exakt wieder her.
|
||||
@@ -345,11 +394,14 @@ Eine automatische Eins-zu-eins-Migration von `inventoryitems` wäre riskant, wei
|
||||
- Benutzer ohne Wertberechtigung sehen weder Einkaufspreis noch Bestandswert.
|
||||
- Artikel und Lagerplätze eines anderen Mandanten können weder gelesen noch verbucht werden.
|
||||
- Dezimalmengen werden entsprechend der Artikeleinheit korrekt gebucht.
|
||||
- Teil- und Sammellieferungen werden mengenbezogen abgeglichen; Lieferschein und Rechnung buchen gemeinsam niemals mehr als die wirksame Verkaufsmenge.
|
||||
- Negative Bestände bleiben mit auslösendem Verkaufsbeleg und Niederlassung nachvollziehbar.
|
||||
- Inventarartikel verändern Lagerbestände unter keinen Umständen.
|
||||
- Aus dem Lagerjournal neu berechnete Bestände entsprechen vollständig `stock_balances`.
|
||||
- Projektentnahmen erscheinen mit dem zum Buchungszeitpunkt festgeschriebenen Materialwert am Projekt.
|
||||
|
||||
## Empfohlene erste Umsetzung
|
||||
|
||||
Als erster vertikaler Schnitt sollte **manueller Wareneingang plus Umlagerung plus Projektentnahme** umgesetzt werden. Dieser Schnitt erzwingt bereits das richtige Buchungsmodell, die Bestandsprüfung, Mandantensicherheit, Berechtigungen und eine brauchbare Oberfläche. Reservierungen, Inventur und Tracking lassen sich danach ergänzen, ohne das Fundament erneut umzubauen.
|
||||
Als erster vertikaler Schnitt sollte **manueller Wareneingang plus automatische Verkaufsentnahme durch Lieferschein und Rechnung** umgesetzt werden. Dieser Schnitt erzwingt bereits das richtige Buchungsmodell, Dezimalmengen, Negativbestände, Niederlassungszuordnung, stabile Belegpositions-IDs, Schutz vor Doppelbuchungen, Mandantensicherheit und Berechtigungen. Danach folgen Umlagerung und Projektentnahme; Reservierungen, Inventur und Tracking lassen sich anschließend ergänzen, ohne das Fundament erneut umzubauen.
|
||||
|
||||
Die vorhandene Tabelle `movements` sollte dabei nicht schrittweise zu einer universellen CRUD-Tabelle ausgebaut werden. Sauberer ist eine neue, transaktionale Struktur aus `stock_transactions`, `stock_transaction_lines` und `stock_balances`. `movements` bleibt während der Migration lesbar und kann nach einer geprüften Übernahme später außer Betrieb genommen werden.
|
||||
|
||||
Reference in New Issue
Block a user