Rezepturen als mehrstufige Stücklisten: das geteilte Modul #3

Open
odoo wants to merge 21 commits from odoo/19.0-baker-recipe into 19.0 AGit
Owner

Die Presets tragen jetzt noupdate. Damit legt das Modul sie einmal an und
fasst sie nie wieder an -- eine Änderung daran überlebt also die
Aktualisierung, und das Schreibverbot, das sie schützen sollte, ist überflüssig
geworden. Es fällt weg, und mit ihm die Ausnahme, die ich einbauen musste,
damit das Modul überhaupt noch seine eigenen Daten laden konnte. Ein zweites
Laden geht ohne sie durch; die Ausnahme hing wirklich nur an dieser Sperre.

Gesperrt ist damit nur noch, was tatsächlich mehrfach verwendet wird. In den
Demodaten trifft das genau das eine Preset, das beide Rezepte als Anstellgut
nehmen -- die übrigen vier sind frei editierbar.

Neu ist der Löschschutz: die Stückliste einer verwendeten Zubereitung lässt
sich nicht mehr löschen. Das ist kein Komfort, sondern schliesst eine Lücke.
Löschen wäre kein Löschen: das Produkt bleibt als Zeile in jedem Rezept
stehen, das es verwendet, verliert aber seine Rezeptur -- damit ist es keine
Zubereitung mehr, sein Mehl rollt nicht mehr hoch, und die Rezepte ändern
stillschweigend ihre Zahlen. mrp schützt nur vor laufenden
Fertigungsaufträgen, was diesen Fall gar nicht berührt.

Dazu ein Test, der eine Lücke aus der liquid-Umstellung schliesst: die
Stellschraube für die Teigausbeute wurde über die Rolle gesucht. Ein Brühstück
oder Altbrot bringt Wasser mit, ohne eine Flüssigkeit zu sein, und ein Rezept
aus solchen Zutaten muss einstellbar bleiben. Der Rückfall war da, geprüft war
er nicht.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com

Die Presets tragen jetzt noupdate. Damit legt das Modul sie einmal an und fasst sie nie wieder an -- eine Änderung daran überlebt also die Aktualisierung, und das Schreibverbot, das sie schützen sollte, ist überflüssig geworden. Es fällt weg, und mit ihm die Ausnahme, die ich einbauen musste, damit das Modul überhaupt noch seine eigenen Daten laden konnte. Ein zweites Laden geht ohne sie durch; die Ausnahme hing wirklich nur an dieser Sperre. Gesperrt ist damit nur noch, was tatsächlich mehrfach verwendet wird. In den Demodaten trifft das genau das eine Preset, das beide Rezepte als Anstellgut nehmen -- die übrigen vier sind frei editierbar. Neu ist der Löschschutz: die Stückliste einer verwendeten Zubereitung lässt sich nicht mehr löschen. Das ist kein Komfort, sondern schliesst eine Lücke. Löschen wäre kein Löschen: das Produkt bleibt als Zeile in jedem Rezept stehen, das es verwendet, verliert aber seine Rezeptur -- damit ist es keine Zubereitung mehr, sein Mehl rollt nicht mehr hoch, und die Rezepte ändern stillschweigend ihre Zahlen. mrp schützt nur vor laufenden Fertigungsaufträgen, was diesen Fall gar nicht berührt. Dazu ein Test, der eine Lücke aus der liquid-Umstellung schliesst: die Stellschraube für die Teigausbeute wurde über die Rolle gesucht. Ein Brühstück oder Altbrot bringt Wasser mit, ohne eine Flüssigkeit zu sein, und ein Rezept aus solchen Zutaten muss einstellbar bleiben. Der Rückfall war da, geprüft war er nicht. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Beide Editoren -- der Baum und das Formelblatt -- bauen auf derselben
Modellschicht auf. Solange sie in einem Modul mit einem der beiden steckte, war
der andere von ihm abhängig, obwohl er nichts davon benutzt.

Hier liegt, was beiden gehört: Rollen am Produkt, Bäckerprozente, die
Rekursion über die Stufen, die drei Teigausbeuten, der Backschritt, die Sperre
geteilter Vorstufen samt Öffnen und Ableiten, dazu Ansichten, Demodaten und
Übersetzung.

Der Name ändert sich mit: aus baker_recipe_editor wird baker_recipe, weil das
Modul keinen Editor mehr enthält. Die beiden Editoren werden eigene Module und
hängen hieran.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drei Änderungswünsche.

Gesamtmehl, Gesamtsalz und "verwendet in" verschwinden aus dem Formular; Salz
in Prozent und die drei Teigausbeuten bleiben. Das Zählfeld geht ganz: es war
reine Anzeige und hätte ohne Formular keinen Abnehmer mehr. Die Methode
dahinter bleibt, die trägt die Sperre.

Der Ableiten-Knopf hing bisher an jeder Vorstufenzeile. Wird eine Vorstufe nur
einmal verwendet, gibt es nichts abzuleiten -- sie gehört bereits zu diesem
einen Rezept, und eine Änderung daran kann kein anderes erreichen.

Die Ausnahme deckt einen Fall ab, den es vorher gar nicht gab: eine
Zubereitung, die MIT DEM MODUL kommt. Die liess sich bisher bearbeiten, und
die nächste Modulaktualisierung hätte die Änderung stillschweigend
überschrieben -- dieselbe Sorte unsichtbarer Verlust wie bei der geteilten
Vorstufe, nur mit der Zeit statt mit einem fremden Rezept als Gegner. Solche
Zubereitungen sind jetzt gesperrt, und genau deshalb muss der Ableiten-Knopf
dort auch dann erscheinen, wenn sie erst einmal verwendet wird. Erkannt werden
sie am externen Bezeichner: stammt er aus einem Modul, ist es ein Preset.

"Gesperrt" heisst damit zweierlei -- mehrfach verwendet oder aus dem Modul --
und beides hat dieselbe Antwort: leite dir eine eigene Kopie ab.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
44 Terme, über "odoo-bin i18n export" erzeugt und dann gefüllt. Enthält nur
noch, was zur Grundlage gehört -- die Texte der beiden Editoren liegen bei
ihnen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Rollen sind jetzt Mehl, Flüssigkeit und Salz. Wasser ist keine eigene
Rolle mehr, sondern eine Flüssigkeit mit 100 % Wasseranteil -- Milch eine mit
ihrem eigenen.

Das ist nicht nur eine Umbenennung, es macht die theoretische Teigausbeute
erst richtig. Sie zählt die SCHÜTTFLÜSSIGKEIT, und 2000 g Milch sind 2000 g
Schüttflüssigkeit, auch wenn davon nur 1740 g Wasser sind. Vorher zählte nur,
was die Rolle "water" trug, und Milch fiel ganz heraus. Der Unterschied
zwischen theoretischer und tatsächlicher TA ist damit genau das, wofür die
beiden Zahlen da sind.

Nebenbei verschwindet ein Sonderfall: die Feuchte je Einheit brauchte bisher
einen eigenen Zweig für Wasser. Jetzt trägt jede Zutat den Anteil bei, den sie
angibt, und eine Zubereitung das, was ihre Zeilen ergeben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Fünf Mehle, Wasser, Milch und Salz als Rohstoffe, dazu fünf fertige
Zubereitungen: Roggensauerteig aus Vollkorn und aus 1150er, Weizensauerteig
aus Vollkorn, Levain liquide und Levito madre. Die Teigausbeute steht im
Namen, weil ein Bäcker danach greift -- TA 200 sind gleiche Teile Mehl und
Wasser, TA 150 die feste Führung.

Der Wasseranteil von Milch ist mit 87,5 angesetzt und aus der Zusammensetzung
gerechnet statt aus einer Nährwerttabelle abgeschrieben: 3,3 g Eiweiss,
4,8 g Kohlenhydrate, 3,5 g Fett und rund 0,7 g Mineralstoffe je 100 g ergeben
12,3 g Trockenmasse.

Die Demodaten führen ihre Mehle und ihr Wasser nicht mehr doppelt, sondern
greifen auf die Presets zu. Übrig bleibt dort, was den beiden Broten eigen
ist: Alpenroggenmehl, Tipo 0, Altbrot, Schabzigerklee.

Dabei ist ein Fehler im Preset-Schutz aufgefallen, der sich erst beim
tatsächlichen Laden zeigt: Er sperrte das MODUL aus seinen eigenen Daten aus.
Eine Aktualisierung schreibt die Presets neu, und der Wächter verbot es -- die
Datei liess sich kein zweites Mal laden. Die Sperre soll einen Menschen daran
hindern, etwas zu bearbeiten, das die nächste Aktualisierung überschreibt;
sie darf nicht die Aktualisierung selbst verhindern. Sie greift jetzt nicht,
solange Odoo Moduldaten lädt.

Nachgemessen an einer frisch aufgesetzten Datenbank: die fünf Presets kommen
mit genau der Teigausbeute heraus, die ihr Name nennt, sind gesperrt und als
Preset erkannt; die Demorezepte treffen weiterhin ihre Zahlen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Das Roggen-Anstellgut der Demodaten war Zeile für Zeile das Preset
"Rye sourdough 1150, DY 200" -- dieselben zwei Zutaten im selben Verhältnis.
Eine zweite Kopie davon zu führen ist genau die Doppelung, die dieses Modul
vermeiden soll. Die beiden Rezepte greifen jetzt darauf zu.

Das hat einen angenehmen Nebeneffekt: das Preset wird damit von zwei
Rezepturen verwendet und ist dadurch gesperrt. Die Demodaten zeigen den
Ableiten-Knopf also an echten Daten, ohne dass man dafür etwas konstruieren
müsste.

Das Weizen-Anstellgut bleibt Demodatum. 1050er Weizen bei TA 200 hat kein
Preset -- die gelieferten Weizenzubereitungen sind Vollkorn und 550er -- und
eines zu erfinden hiesse, die Preset-Liste stillschweigend zu erweitern.

Nachgemessen: die Rezepte treffen weiterhin ihre Zahlen, Neudorfer 169,58
gegen die angegebenen 170.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Presets tragen jetzt noupdate. Damit legt das Modul sie einmal an und
fasst sie nie wieder an -- eine Änderung daran überlebt also die
Aktualisierung, und das Schreibverbot, das sie schützen sollte, ist überflüssig
geworden. Es fällt weg, und mit ihm die Ausnahme, die ich einbauen musste,
damit das Modul überhaupt noch seine eigenen Daten laden konnte. Ein zweites
Laden geht ohne sie durch; die Ausnahme hing wirklich nur an dieser Sperre.

Gesperrt ist damit nur noch, was tatsächlich mehrfach verwendet wird. In den
Demodaten trifft das genau das eine Preset, das beide Rezepte als Anstellgut
nehmen -- die übrigen vier sind frei editierbar.

Neu ist der Löschschutz: die Stückliste einer verwendeten Zubereitung lässt
sich nicht mehr löschen. Das ist kein Komfort, sondern schliesst eine Lücke.
Löschen wäre kein Löschen: das Produkt bleibt als Zeile in jedem Rezept
stehen, das es verwendet, verliert aber seine Rezeptur -- damit ist es keine
Zubereitung mehr, sein Mehl rollt nicht mehr hoch, und die Rezepte ändern
stillschweigend ihre Zahlen. mrp schützt nur vor laufenden
Fertigungsaufträgen, was diesen Fall gar nicht berührt.

Dazu ein Test, der eine Lücke aus der liquid-Umstellung schliesst: die
Stellschraube für die Teigausbeute wurde über die Rolle gesucht. Ein Brühstück
oder Altbrot bringt Wasser mit, ohne eine Flüssigkeit zu sein, und ein Rezept
aus solchen Zutaten muss einstellbar bleiben. Der Rückfall war da, geprüft war
er nicht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Mehl, Wasser und Salz kauft eine Bäckerei ein, Vorstufen und Teige sind
Zwischenstufen — nichts davon gehört auf die Preisliste. Verkauft wird das,
was der Backschritt herstellt, und genau dort bleibt sale_ok unangetastet.

Beim Anlegen wird der Wert in die Werte geschrieben statt hinterher gesetzt:
eine Variante entsteht über die inherits-Mechanik der Vorlage, und ein erst
danach gesetzter Wert lässt die Variante den alten Stand melden.

Bewusst ohne Ausnahme für ein mitgegebenes sale_ok — default_get hat es zu
diesem Zeitpunkt längst eingetragen, eine Voreinstellung ist von einer
Entscheidung also nicht mehr zu unterscheiden. Wer sein Mehl doch über die
Theke verkauft, schreibt den Wert einmal; der Haken beim Ändern greift nur
bei einem echten Rollenwechsel und lässt diese Entscheidung stehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die beiden Arten von Stückliste werden getrennt angeschaut — die Rezeptur,
an der entwickelt wird, und der Backschritt, der daraus ein Brot macht. Dazu
zwei Filter und eine Gruppierung nach Rezeptart.

Die Tests lesen die Domain aus der Suchansicht und führen sie aus, statt nur
zu prüfen, ob der Filter da ist: vertauscht man die beiden Domains, bleibt
der Filter vorhanden und liefert trotzdem das Falsche.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Presets und der Flüssigkeits-Umbau haben fünfzehn Strings hinterlassen,
die nie übersetzt wurden — Mehl- und Sauerteignamen, "Flüssigkeit",
"Gesamtflüssigkeit" und die Sperrmeldung standen auf Englisch in einer sonst
deutschen Oberfläche. Die Datei ist neu aus dem Export aufgebaut, damit
nichts weiter unbemerkt zurückbleibt.

Dabei fiel auf, dass der Dateikopf noch baker_recipe_editor nannte, ein Rest
der Umbenennung. Die beiden Zeitstempel aus dem Export bleiben draußen, sonst
ändert sich die Datei bei jedem Export.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
odoo force-pushed odoo/19.0-baker-recipe from b98cc90d2e to 4dfed4b11e 2026-09-22 18:47:40 +00:00 Compare
Die Hooks liefen bisher nicht mit, deshalb kommt ihr Ergebnis in einem Zug:
ruff-format und prettier über Python und XML, das generierte README.rst.

Zwei Befunde waren echt und nicht bloß Form. pylint_odoo verlangt
self.env._ statt des importierten _; das ist seit 17.0 der Weg und der
Kern nutzt ihn selbst. Und im Readme-Fragment war eine Überschrift zu kurz
unterstrichen, woran die README-Erzeugung scheiterte.

Die Hilfetexte sind nur umbrochen, nicht umformuliert -- Python fügt die
Teile beim Übersetzen zusammen, der msgid bleibt also derselbe und die
Übersetzungen bleiben gültig.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Jeder Punkt daraus steht im Modul: die Marker an Zutat und Stückliste, die
sieben Preset-Zutaten mit Rolle und Wasseranteil, die fünf Sauerteige mit
ihrer TA, die Sperre einer mehrfach verwendeten Vorstufe, Englisch und
Deutsch. Der Punkt "presets should not be editable" ist nicht offen, sondern
abgelöst: noupdate statt Schreibverbot, dafür Löschschutz solange in
Verwendung.

Eine abgearbeitete Liste wird gelöscht und nicht als Erledigt-Datei
weitergeschleppt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Versäuerungsgrad ist das versäuerte Mehl geteilt durch das Gesamtmehl.
Entscheidend ist, was als versäuert zählt: ein Brühstück oder ein Hefevorteig
bindet ebenso Mehl und ist kein Sauerteig. Deshalb eine ausdrückliche
Kennzeichnung an der Zubereitung statt einer Ableitung aus "ist eine
Vorstufe".

Unterhalb einer markierten Stufe wird nicht weiter gefragt: ihr ganzer
Mehlgehalt ist versäuert, das Anstellgut eingeschlossen. Das entspricht der
Sache und spart die Rekursion.

Die fünf Presets und die Sauerteige der Demorezepte sind markiert, das
Brühstück nicht. Frisch installiert ergibt das 41,9 % für das Berliner
Roggenmischbrot und 33,6 % für das Neudorfer -- beides im branchenüblichen
Bereich für Roggen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
odoo force-pushed odoo/19.0-baker-recipe from 6d25906700 to 1b5c901fc3 2026-09-22 19:28:46 +00:00 Compare
Die Statustabelle endete dort, wo das Modul zum ersten Mal lief. Seither sind
vier Dinge dazugekommen -- noupdate statt Schreibverbot mit Löschschutz, der
Verkaufsausschluss für Teige und Rezeptzutaten, die getrennte Suche und die
Versäuerung. Jeweils mit dem Grund, nicht nur mit dem Was.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Beide Oberflächen brauchen dieselbe Bewegung -- eine Kopie der Zubereitung,
die genau einem Rezept gehört und deshalb wieder änderbar ist, während das
geteilte Original unberührt bleibt. Sie steht jetzt an der Stückliste, die
Zeilenaktion ruft sie nur noch auf.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sie beschreibt die Zubereitung, nicht eine ihrer Rezepturen. Am Produkt
überlebt sie ohne Rezeptur, steht dort, wo ein Bäcker sie sucht, und eine
abgezweigte Kopie trägt sie von selbst mit -- vorher hing sie an der
Stückliste und war damit an eine Rezeptur gebunden.

Die Stückliste liest sie von dort; alle bestehenden Zugriffe bleiben, wie
sie waren.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der hochgerechnete Mehlwert sagt wie viel, nicht wovon. Wer die Mehle eines
Rezepts auflisten will, braucht die Produkte -- und die kennt nur der Graph:
für den, der sie verwendet, ist eine Zubereitung eine einzige Zeile.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Umzug des Feldes lässt eine bestehende Datenbank sonst still ohne
Markierungen zurück, und mit ihnen ohne die Versäuerung jedes darauf
gebauten Rezepts. Die Presets kommen auch nicht von selbst wieder: sie sind
noupdate und werden bei einer Aktualisierung nicht neu eingespielt.

Vor der Modellaktualisierung, weil die alte Spalte danach nicht mehr gelesen
werden kann. Nachgestellt an einer Datenbank im alten Zustand: neun
Markierungen übernommen, die Versäuerung des Berliner Roggenmischbrots steht
wieder bei 41,92 %.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Eine Zubereitung, die auf etwas Saurem aufbaut, IST ein Sauerteig -- das
muss niemand bestätigen. Markiert wird nur, was die Säure trägt: ein
Anstellgut oder eine als solche gehaltene Zubereitung. Alles darauf Gebaute
erkennt sich daran, über beliebig viele Stufen.

Der letzte Teig ist die Ausnahme: er enthält einen Sauerteig, und das ist
etwas anderes, als einer zu sein. Erkennbar ist er daran, dass ihn keine
weitere Rezeptur als Zutat führt -- eine Frage nach rückwärts, also gefragt
und nicht gehalten.

Die Demorezepte tragen deshalb keine Markierung mehr; frisch installiert
werden ihre Sauerteige erkannt, und die Versäuerung des Berliner
Roggenmischbrots steht unverändert bei 41,92 %.

Dazu der Versäuerungswert am Produkt: eine Zubereitung ist für den, der sie
verwendet, eine einzige Zeile, und was sie mitbringt, soll lesbar sein, ohne
ihre Rezeptur erneut abzulaufen. Er wird bei jeder Änderung der Rezeptur
fortgeschrieben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Beide sind Zubereitungen, und sie werden verschieden gebraucht: ein
Anstellgut wird geführt und geht als Zutat in eine Stufe ein, eine Vorstufe
wird für ein Rezept angesetzt und ist eine eigene Stufe. Ohne diesen
Unterschied kann das Formelblatt nicht entscheiden, was beim Einlesen zur
Stufe wird und was Zutat bleibt.

Mit der Sauerkeit hat das nichts zu tun: die trägt das Anstellgut, und ein
Sauerteig wird daran erkannt. Ein Hefevorteig ist eine Vorstufe ohne Säure,
ein Weizenanstellgut ein Anstellgut mit.

Die fünf Presets und das Demo-Anstellgut sind entsprechend markiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin +refs/pull/3/head:odoo/19.0-baker-recipe
git switch odoo/19.0-baker-recipe

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch 19.0
git merge --no-ff odoo/19.0-baker-recipe
git switch odoo/19.0-baker-recipe
git rebase 19.0
git switch 19.0
git merge --ff-only odoo/19.0-baker-recipe
git switch odoo/19.0-baker-recipe
git rebase 19.0
git switch 19.0
git merge --no-ff odoo/19.0-baker-recipe
git switch 19.0
git merge --squash odoo/19.0-baker-recipe
git switch 19.0
git merge --ff-only odoo/19.0-baker-recipe
git switch 19.0
git merge odoo/19.0-baker-recipe
git push origin 19.0
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
odoo/odooapps!3
No description provided.