Repository navigation
Conversation
Assisted-by: Claude Code
1eed005 to
4df3b88
Compare
cav-adhoc
left a comment
There was a problem hiding this comment.
Review of the 19.0 → 20.0 migration. Python side looks fine (I checked _utc_midnight against pytz on all zones, no differences). Comments below are about the upgrade path and the Owl 3 port.
| @@ -0,0 +1,25 @@ | |||
| id,name,model_id,group_id/id,operation,domain | |||
| manage_mis_report_kpi,manage_mis_report_kpi,mis.report.kpi,account.group_account_manager,crud, | |||
There was a problem hiding this comment.
On a fresh 20.0 database with the 19.0 xmlids pre-seeded (ir.model.access / ir.rule rows in ir_model_data), installing this module fails when loading ir.access.csv:
For external id mis_builder.manage_mis_report_kpi when trying to create/update a record of model ir.access
found record of different model ir.model.access (59942)
(6 of 6 xmlids fail.) I could not run a real 19→20 upgrade, so I don't know whether the core upgrade scripts already convert those rows. Has anyone upgraded a database with this module installed?
If the rows survive, proposed fix: add mis_builder/migrations/20.0.1.0.0/pre-migration.py that drops the stale xmlids, only the ones still pointing to the legacy models, so it is a no-op if core already converted them:
def migrate(cr, version):
cr.execute(
"""
DELETE FROM ir_model_data
WHERE module = 'mis_builder'
AND model IN ('ir.model.access', 'ir.rule')
"""
)I have not run this script against a real upgrade.
There was a problem hiding this comment.
Added the pre-migration you proposed, unchanged in substance. I could not run a real 19.0 to 20.0 upgrade either, so I simulated it: install on 20.0, delete the ir.access rows, point the 24 xmlids back to ir.model.access / ir.rule and set the installed version to 19.0, then run -u mis_builder. Without the script it fails with the same "different model" error. With it the upgrade passes and the 24 xmlids are recreated as ir.access. If the core upgrade already converts them, the script does nothing.
| access_mis_report_instance_period_sum,access_mis_report_instance_period_sum,mis.report.instance.period.sum,base.group_user,r, | ||
| manage_mis_report_instance,manage_mis_report_instance,mis.report.instance,account.group_account_manager,crud, | ||
| access_mis_report_instance,access_mis_report_instance,mis.report.instance,base.group_user,r, | ||
| mis_builder_multi_company_rule,Mis Report Instance multi company,mis.report.instance,,crud,"['|', ('company_id', '=', False), ('company_id', 'in', company_ids), '|', ('company_ids', '=', False), ('company_ids', 'in', company_ids)]" |
There was a problem hiding this comment.
Same question as above, for the global rule: this xmlid currently points to an ir.rule record, and the pre-migration.py proposed in the previous comment covers it (model IN ('ir.model.access', 'ir.rule')).
Also, this is a global rule (no group) with crud; I assume that is the intended equivalent of the old rule, which applied to every operation.
There was a problem hiding this comment.
Yes. The old rule had no groups and the default perm_* all True, so a global ir.access with crud and the same domain is the equivalent. After the simulated upgrade it is the only restriction on mis.report.instance, with operation crud.
| rows='4' | ||
| placeholder="Insert note here" | ||
| t-model="state.annotationText" | ||
| t-custom-model="this.state.annotationText" |
There was a problem hiding this comment.
t-custom-model is the temporary Owl 2 bridge. The compatibility layer says to replace it with t-model + signals once the code builds:
owl3_compatibility_layer.js#L29
It works today because the layer is loaded in the bundles. Core already uses the native form, for example the emoji picker:
emoji_picker.js#L91:searchTerm = signal(..., { type: t.string() })emoji_picker.xml#L157:t-model="this.searchTerm"
Proposed fix for the dialog: replace the proxy state with a signal and bind it natively.
import {Component, signal, t, useProps} from "@odoo/owl";
...
setup() {
this.annotationText = signal(this.props.annotationText, {type: t.string()});
}<textarea ... t-model="this.annotationText" />and wherever the dialog reads this.state.annotationText, read this.annotationText() instead. The same applies to useSubEnv imported from @web/owl2/utils in mis_report_widget.esm.js: it is only a re-export of owl.useSubEnv (utils.js#L16), so it can be imported from @odoo/owl directly. I have not run this change.
There was a problem hiding this comment.
Done, following the emoji picker: annotationText = signal(this.props.annotationText, {type: t.string()}), t-model="this.annotationText", and confirm() reads this.annotationText(). useSubEnv now comes from @odoo/owl.
MiquelRForgeFlow
left a comment
There was a problem hiding this comment.
Since Odoo 20.0, Char fields named "name" are copied with a " (copy)" suffix unless the field sets copy explicitly. Copying a report failed ("KPI name (k1 (copy)) must be a valid python identifier") and copied expressions are broken.
There was a problem hiding this comment.
| name = fields.Char(required=True, copy=True) |
There was a problem hiding this comment.
Thanks, applied. mis.report keeps its copy() override, so the report name still gets " (copy)" and kpis, subkpis, queries, expressions, subreports and period labels keep their names. In 20.0 this comes from Char._get_attrs, which sets copy=mark_as_copy("name") on fields named name unless copy is given. Added your test plus a subreport copy test and a period label check.
There was a problem hiding this comment.
| name = fields.Char(required=True, copy=True) |
There was a problem hiding this comment.
| name = fields.Char(string="Expression", copy=True) |
There was a problem hiding this comment.
| name = fields.Char(required=True, copy=True) |
There was a problem hiding this comment.
| name = fields.Char(required=True, string="Label", translate=True, copy=True) |
Also in name of mis.report.subreport.
|
|
||
| def test_copy_mis_report_instance(self): | ||
| new_instance = self.report_instance.copy() | ||
| self.assertEqual(new_instance.name, f"{self.report_instance.name} (copy)") |
There was a problem hiding this comment.
| def test_copy_mis_report(self): | |
| new_report = self.report.copy() | |
| self.assertEqual(new_report.name, f"{self.report.name} (copy)") | |
| self.assertEqual( | |
| new_report.kpi_ids.mapped("name"), self.report.kpi_ids.mapped("name") | |
| ) | |
| self.assertEqual( | |
| new_report.subkpi_ids.mapped("name"), | |
| self.report.subkpi_ids.mapped("name"), | |
| ) | |
| self.assertEqual( | |
| new_report.query_ids.mapped("name"), self.report.query_ids.mapped("name") | |
| ) | |
| self.assertEqual( | |
| new_report.kpi_ids.expression_ids.mapped("name"), | |
| self.report.kpi_ids.expression_ids.mapped("name"), | |
| ) |
Assisted-by: Claude Code
Assisted-by: Claude Code
Assisted-by: Claude Code
ruff DTZ005 flags datetime.now() without tz in docs/conf.py, which makes pre-commit fail on the whole repository. Assisted-by: Claude Code
4df3b88 to
2155655
Compare
|
Thanks @cav-adhoc and @MiquelRForgeFlow. Pushed:
Tests: 100 passing on Odoo 20.0, no warnings in the log. |
|
One more comment: |
Odoo 20.0 no longer loads the Font Awesome stylesheet, so the fa classes of the refresh, print, export, settings, resize and annotation delete buttons were not drawn. They use the oi class with data-icon, as the core does; the resize button switches between fullscreen and fullscreen_exit.
|
Obrigado @cav-adhoc, ajustado: os cinco botões do widget e o botão de redimensionar (que alternava |
|
Hi @mileo, thanks a lot for the changes! 🙌 It looks like the only thing left is pre-commit: Some context on why this PR is a bit of a key one right now: So once this one is merged, #852 can follow, and then #853 ( |
Assisted-by: Claude Code
Migration from 19.0 on the existing 20.0 branch, where the module was set uninstallable.
Changes for 20.0:
ir.access.csv;pytzreplaced byzoneinfoin_utc_midnight(same result on ambiguous and missing times);<>domain operator replaced by!=;report_fileremoved from the xlsx report action;compile_codeobjandtry_reportimports updated;useProps,proxy,this.in templates);namefields of the report children setcopy=True, since 20.0 adds " (copy)" to Char fields namedname;ir.model.accessandir.rule, so the upgrade can create their.accessrecords.Depends on OCA/reporting-engine#1203 (report_xlsx) and OCA/server-ux#1341 (date_range).
Installs and passes its tests (100) on Odoo 20.0 with no warnings in the log.