"custom" said nothing about what the module does. It is really about collecting
goods into baskets: the extra detailed-operation columns, the is_collected flag,
the Product Summary tab, the per-company validation restrictions and the
Basket Assembly operator view all serve that one job. Rename it accordingly.
Invert the dependency while at it. A generic warehouse addon was dragging in an
entire eCommerce application, and the whole coupling was a single field:
stock.move.line.home_delivery, related to picking_id.home_delivery. Everything
else was already duck-typed. website_sale_aplicoop now depends on this module
and injects its own consumer group columns into these views.
This removes duplicated logic rather than relocating it: stock.picking
.batch_consumer_group_id re-derived from sale_id a value aplicoop already stored
as stock.picking.consumer_group_id, and the duplicate carried no @api.depends,
so it never recomputed reliably. The batch transfers list now shows the stored
field, which is sortable and groupable.
The two aplicoop tests that probed information_schema for the res_company
batch_* columns can drop that guard: a real dependency guarantees them.
Renaming an addon is not something a migrations/ script can do, since a renamed
addon is a brand new module to Odoo and its migration scripts never run. A
pre_init_hook does it instead: it fires on install after the Python is imported
but before registry.load(), which is the window where remapping ir_model_data
makes Odoo reuse the existing tables and columns. is_collected, the summary line
table and the company settings all survive untouched.
Two details the hook has to get right:
- ir_model_constraint.module and ir_model_relation.module are integer FKs with
ON DELETE CASCADE, so they must be repointed before the old module row is
deleted or the bookkeeping goes with it.
- Deleting an ir_model_data row does not cascade to the record it points at.
Artifacts handed over to aplicoop only need the xmlid dropped, but artifacts
that disappear need the record deleted too, or the field survives as an orphan
manual field and the view as a custom view referencing it.
Verified against a restored copy of the dev database: 50 xmlids moved, 19 summary
lines and 5 collected move lines preserved, no orphans, both test suites green,
and the module installs cleanly on a database without website_sale_aplicoop.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Basket Assembly is where the reverting quantity was noticed, so it depends
on stock_move_manual_quantity now and its two lists load `picked`: the web
client only saves the fields present in the arch, and without it the
onchange that freezes a hand-typed quantity never reaches the server.
Collecting a line does the same, minus the demand. It is the operator saying
the goods are in the basket, so the quantity has to survive the reservation
engine even when it was never retyped -- but only a quantity typed by hand
says what the demand should become, and a line collected at zero would
otherwise lose its demand and be cancelled on validation.
Drops views/stock_move_line_views.xml on the way. It declared a second
record under the id stock_picking_batch_views.xml already uses, so it was
loaded first and immediately overwritten: dead weight that would have turned
into a duplicate-field view had anyone renamed it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Use regular dict instead of defaultdict to avoid empty entries
- Make summary_line_ids readonly=True to prevent UI from inserting empty lines
- Add SQL constraint CHECK(product_id IS NOT NULL) as safeguard
- Use boolean_toggle widget for is_collected field
- Fix tests to use TransactionCase and invalidate_recordset
- Add test for empty batch + add pickings + confirm flow