When running production records after migrating from Tryton 7.0 to 8.0, we hit validation errors on stock.move.currency for production input moves.
Example error:
The value “Euro” for field “Currency” in record “…” of “Stock Move” is not valid according to its domain.
The confusing part is that the user does not see any currency field on the move form.
The failing moves are production input moves with:
- origin flow:
storage -> production unit_price_required = Falseunit_price = NULLcurrency = EUR
In Tryton 8.0 this is invalid, because currency now has a domain that requires NULL when unit_price_required is false.
So the move contains stored data that was accepted in older versions but is no longer valid after the upgrade.
On stock.move, the currency field is hidden when unit_price_required is false.
For storage -> production moves:
unit_price_requiredis false- the field is hidden in the UI
- but the stored value is still validated by the server
This is why the user gets a domain error for a field that is not visible.
In Tryton 7.0 , modules/production/production.py, production _move() created moves with:
move = Move(
product=product,
unit=unit,
quantity=quantity,
company=self.company,
currency=self.company.currency if self.company else None)
So input moves could be created with a currency even before checking whether a unit price was required.
At the same time, in modules/stock/move.py, the currency field had UI states but no domain enforcing NULL when unit_price_required was false.
So this inconsistent data shape was tolerated.
By 7.4, upstream changed both sides:
production._move()no longer prefilledcurrencyfor all moves and only set it whenunit_price_requiredwas true.stock.move.currencygained a domain requiringNULLwhenunit_price_requiredwas false:
domain=[
If(~Eval('unit_price_required'),
('id', '=', None),
()),
]
This means data created on 7.0 can become invalid once validated on 7.4+ and therefore also on 8.0.
This looks like a cross-version data consistency issue:
- 7.0 allowed production input moves with
currency != NULL - 8.0 rejects that same stored state
- legacy rows remain in the database after migration
- those rows fail only when they are touched or revalidated later
In our database we found many old rows with this pattern, including rows created years before the 8.0 migration.
The problematic legacy row has:
from_location.type = storage
to_location.type = production
unit_price_required = False
unit_price = NULL
currency = <company currency>
In 8.0, such a row is no longer valid.
Should Tryton provide a migration step, or at least document one, to normalize legacy stock_move rows created on older series?
For example, something like:
UPDATE stock_move m
SET currency = NULL
FROM stock_location fl, stock_location tl
WHERE fl.id = m.from_location
AND tl.id = m.to_location
AND fl.type = 'storage'
AND tl.type = 'production'
AND m.unit_price IS NULL
AND m.currency IS NOT NULL;