From 2e3af7ad674dac0583e904bd94fdf01d88e15935 Mon Sep 17 00:00:00 2001
From: Don Kendall
Date: Wed, 23 Sep 2026 20:02:58 -0400
Subject: [PATCH] [20.0][OU-ADD] account: migration scripts
Assisted-by: Claude Opus 5
---
docsource/modules190-200.rst | 2 +-
.../account/20.0.1.5/noupdate_changes.xml | 129 ++++
.../account/20.0.1.5/post-migration.py | 100 ++++
.../scripts/account/20.0.1.5/pre-migration.py | 20 +
.../account/20.0.1.5/upgrade_analysis.txt | 564 ++++++++++++++++++
.../account/tests/data_account_migration.py | 44 ++
.../account/tests/test_account_migration.py | 76 +++
7 files changed, 934 insertions(+), 1 deletion(-)
create mode 100644 openupgrade_scripts/scripts/account/20.0.1.5/noupdate_changes.xml
create mode 100644 openupgrade_scripts/scripts/account/20.0.1.5/post-migration.py
create mode 100644 openupgrade_scripts/scripts/account/20.0.1.5/pre-migration.py
create mode 100644 openupgrade_scripts/scripts/account/20.0.1.5/upgrade_analysis.txt
create mode 100644 openupgrade_scripts/scripts/account/tests/data_account_migration.py
create mode 100644 openupgrade_scripts/scripts/account/tests/test_account_migration.py
diff --git a/docsource/modules190-200.rst b/docsource/modules190-200.rst
index 8da46d62bbc..7cc613ca895 100644
--- a/docsource/modules190-200.rst
+++ b/docsource/modules190-200.rst
@@ -6,7 +6,7 @@ Module coverage 19.0 -> 20.0
+---------------------------------------------------+----------------------+-------------------------------------------------+
| Module | Status + Extra Information |
+===================================================+======================+=================================================+
-| account | | |
+| account |Done | |
+---------------------------------------------------+----------------------+-------------------------------------------------+
| |del| account_add_gln | | |
+---------------------------------------------------+----------------------+-------------------------------------------------+
diff --git a/openupgrade_scripts/scripts/account/20.0.1.5/noupdate_changes.xml b/openupgrade_scripts/scripts/account/20.0.1.5/noupdate_changes.xml
new file mode 100644
index 00000000000..10dcc32f4e9
--- /dev/null
+++ b/openupgrade_scripts/scripts/account/20.0.1.5/noupdate_changes.xml
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+ {'module': 'general_settings'}
+
+
+ mail.mail_notification_layout_with_responsible_signature
+
+
+
+
+
+ Dear
+ Brandon Freeman (Azure Interior),
+ Azure Interior,
+
+ Brandon Freeman,
+
+
+ Here is your
+
+ invoice INV/2021/05/0005
+
+
+ invoice
+
+
+ (with reference: SUB003)
+
+ amounting in $ 143,750.00
+ from YourCompany.
+
+ This invoice is already paid.
+
+
+ Please remit payment at your earliest convenience.
+
+ Please use the following communication for your payment: INV/2021/05/0005
+
+ on the account
+
+ .
+
+
+
+ Do not hesitate to contact us if you have any questions.
+
--
Mitchell Admin
+
+
+
+ mail.mail_notification_layout_with_responsible_signature
+
+
+
+
+
+ Dear
+ Brandon Freeman (Azure Interior),
+ Azure Interior,
+
+ Brandon Freeman,
+
+
+ Here is your
+
+ self-billing invoice INV/2021/05/0005
+
+
+ self-billing invoice
+
+
+ (with reference: SUB003)
+
+ amounting in $ 143,750.00
+ from YourCompany.
+
+ This self-billing invoice has already been paid.
+
+
+ Do not hesitate to contact us if you have any questions.
+
--
Mitchell Admin
+
+
+
+
+
+
+ Hi,
+
+ Your email has been discarded. the e-mail address you have used only accepts new invoices:
+
- For new invoices, please ensure a PDF or electronic invoice file is attached
- To add information to a previously sent invoice, reply to your "sent" email
+ For any other question, write to .
+
+ --
+
+
+
+
+
+
+
+
+ Dear Azure Interior
+ We have processed your refund of
+ We have processed your payment of
+ Thank you for your refund of
+ Thank you for your payment of $ 10.00.
+ Please find the payment receipt BNK1-2021-05-0002 from YourCompany.
+
+ Do not hesitate to contact us if you have any questions.
+
+ Best regards,
+
--
Mitchell Admin
+
+
+
+ {{ object.company_id.name }} {{ object.payment_receipt_title }} (Ref {{ object.name or 'n/a' }})
+ mail.mail_notification_light
+
+
+
+
+
diff --git a/openupgrade_scripts/scripts/account/20.0.1.5/post-migration.py b/openupgrade_scripts/scripts/account/20.0.1.5/post-migration.py
new file mode 100644
index 00000000000..c6fd166ddef
--- /dev/null
+++ b/openupgrade_scripts/scripts/account/20.0.1.5/post-migration.py
@@ -0,0 +1,100 @@
+# Copyright 2026 Don Kendall
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from openupgradelib import openupgrade
+
+
+def _settle_in_process_payments(env):
+ """19.0's payment state had an "In Process" step that 20.0 does not.
+
+ 19.0 ran draft -> in_process -> paid; 20.0 runs draft -> paid ->
+ reconciled. The middle step is gone, and because the column already holds a
+ value the stored compute leaves it there: the payment reads as blank in the
+ interface and matches no branch of a domain over the state.
+
+ 'paid' is the honest landing point. It states only what is certainly true --
+ the payment was made -- and 20.0's own _compute_state takes it from there:
+ for a payment already in 'paid' or 'reconciled' it re-derives which of the
+ two applies from the liquidity lines' residual. Writing 'reconciled'
+ directly would assert a bank match this migration has no evidence for.
+ """
+ openupgrade.logged_query(
+ env.cr,
+ "UPDATE account_payment SET state = 'paid' WHERE state = 'in_process'",
+ )
+
+
+def _carry_a_deliberate_not_reviewed_into_the_review_queue(env):
+ """19.0's `checked` becomes 20.0's review_state, and only part of it is real.
+
+ 19.0 carried a boolean "Reviewed". It was a stored COMPUTE with the value
+ written by::
+
+ move.checked = move.state == 'posted' and (
+ move.journal_id.type == 'general' or move._is_user_able_to_review())
+
+ and `readonly=False`, so a user could tick or untick it afterwards.
+
+ 20.0 replaces it with `review_state`, a plain stored selection of no_review
+ / todo / reviewed / supervised / anomaly defaulting to 'no_review', and
+ keeps an index named after the field it replaced::
+
+ _checked_idx = models.Index(
+ "(journal_id) WHERE (review_state IN ('todo', 'anomaly'))")
+
+ which is what makes it a work queue rather than a label.
+
+ **Only the deviation is carried.** A True that merely reproduces the compute
+ records nothing a reader could not derive, and writing 'reviewed' for it
+ would assert a review of every posted invoice in the database -- 3206 of the
+ seed's 3223 moves, on the strength of a value that is really just "posted".
+ A posted move whose `checked` is FALSE is the opposite: the compute would
+ have set it True, so False is there because somebody put it there, and
+ 'todo' is what 20.0 calls that.
+
+ Nothing is written for a draft move. 19.0 left those unchecked by the same
+ formula, which says "not posted yet", not "waiting to be reviewed".
+
+ **This seed contains no such row** -- `checked` equals `state = 'posted'` on
+ all 3223 of its moves -- so the branch is unreachable here and the migration
+ test builds the row that reaches it. The count is reported either way, so a
+ database where it does fire says so in the log rather than only in the data.
+ """
+ openupgrade.logged_query(
+ env.cr,
+ """
+ UPDATE account_move
+ SET review_state = 'todo'
+ WHERE state = 'posted' AND NOT checked AND review_state = 'no_review'
+ """,
+ )
+ if env.cr.rowcount:
+ openupgrade.message(
+ env.cr,
+ "account",
+ False,
+ False,
+ "%s posted journal entr(ies) had been marked as NOT reviewed by hand "
+ "in 19.0 and are now in 20.0's review queue as 'todo'; entries that "
+ "merely carried the computed default were left on 'no_review'",
+ env.cr.rowcount,
+ )
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+ openupgrade.load_data(env, "account", "20.0.1.5/noupdate_changes.xml")
+ openupgrade.delete_record_translations(
+ env.cr,
+ "account",
+ ["email_template_edi_invoice", "email_template_edi_self_billing_invoice"],
+ ["body_html"],
+ )
+ openupgrade.delete_record_translations(
+ env.cr,
+ "account",
+ ["mail_template_data_payment_receipt"],
+ ["body_html", "subject"],
+ )
+ _settle_in_process_payments(env)
+ _carry_a_deliberate_not_reviewed_into_the_review_queue(env)
diff --git a/openupgrade_scripts/scripts/account/20.0.1.5/pre-migration.py b/openupgrade_scripts/scripts/account/20.0.1.5/pre-migration.py
new file mode 100644
index 00000000000..a1a55ad57f4
--- /dev/null
+++ b/openupgrade_scripts/scripts/account/20.0.1.5/pre-migration.py
@@ -0,0 +1,20 @@
+# Copyright 2026 Don Kendall
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from openupgradelib import openupgrade
+
+_renamed_xmlids = [
+ # the stock valuation report moved from stock_account into account
+ (
+ "stock_account.action_report_stock_valuation",
+ "account.action_report_stock_valuation",
+ ),
+]
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+ # The client action keeps its path, which is unique, so account's copy of
+ # the record has to land on the existing row instead of inserting a second
+ # one and tripping ir_act_client_path_unique.
+ openupgrade.rename_xmlids(env.cr, _renamed_xmlids)
diff --git a/openupgrade_scripts/scripts/account/20.0.1.5/upgrade_analysis.txt b/openupgrade_scripts/scripts/account/20.0.1.5/upgrade_analysis.txt
new file mode 100644
index 00000000000..af5e5efb645
--- /dev/null
+++ b/openupgrade_scripts/scripts/account/20.0.1.5/upgrade_analysis.txt
@@ -0,0 +1,564 @@
+---Models in module 'account'---
+obsolete model account.group
+new model account.stock.valuation.report (renamed from stock_account.stock.valuation.report in module stock_account) [abstract]
+new model res.currency.rate.consolidation.mixin [abstract]
+---Fields in module 'account'---
+account / account.account / _order : _order is now 'code_path, account_type, name_path' ('code, placeholder_code')
+account / account.account / account_stock_expense_id (many2one): previously in module stock_account
+account / account.account / account_stock_variation_id (many2one): previously in module stock_account
+account / account.account / parent_id (many2one) : NEW relation: account.account
+account / account.account / parent_path (char) : NEW
+account / account.account / website_message_ids (one2many): DEL relation: mail.message
+account / account.bank.statement / is_statement_posted (boolean) : NEW hasdefault: default
+account / account.bank.statement.line / invoice_outstanding_credits_debits_widget (binary): type is now 'json' ('binary')
+account / account.bank.statement.line / invoice_payments_widget (binary): type is now 'json' ('binary')
+account / account.bank.statement.line / needed_terms (binary) : type is now 'json' ('binary')
+account / account.bank.statement.line / payment_term_details (binary) : type is now 'json' ('binary')
+account / account.bank.statement.line / tax_totals (binary) : type is now 'json' ('binary')
+account / account.cash.rounding / _order : _order is now 'sequence, id' ('id')
+account / account.cash.rounding / active (boolean) : NEW hasdefault: default
+account / account.cash.rounding / company_id (many2one) : NEW relation: res.company
+account / account.cash.rounding / currency_ids (many2many) : NEW relation: res.currency
+account / account.cash.rounding / partner_category_ids (many2many): NEW relation: res.partner.category
+account / account.cash.rounding / payment_method_line_ids (many2many): NEW relation: account.payment.method.line
+account / account.cash.rounding / sequence (integer) : NEW required, hasdefault: default
+account / account.fiscal.position / account_map (binary) : type is now 'json' ('binary')
+account / account.fiscal.position / tax_map (binary) : type is now 'json' ('binary')
+account / account.group / code_prefix_end (char) : DEL
+account / account.group / code_prefix_start (char) : DEL
+account / account.group / company_id (many2one) : DEL relation: res.company, required
+account / account.group / name (char) : DEL required
+account / account.group / parent_id (many2one) : DEL relation: account.group
+account / account.journal / disable_dashboard_graph (boolean): NEW
+account / account.journal / display_invoice_template_pdf_report_id (boolean): now a function
+account / account.journal / journal_group_id (many2one) : NEW relation: account.journal.group
+account / account.journal / journal_group_ids (many2many) : DEL relation: account.journal.group
+account / account.journal / website_message_ids (one2many): DEL relation: mail.message
+account / account.journal.group / company_id (many2one) : DEL relation: res.company
+account / account.journal.group / excluded_journal_ids (many2many): DEL relation: account.journal
+account / account.journal.group / included_journal_ids (one2many): NEW relation: account.journal
+account / account.move / checked (boolean) : DEL
+account / account.move / document_tax_mode (selection) : NEW selection_keys: ['tax_excluded', 'tax_included'], hasdefault: compute
+account / account.move / import_source_attachment_id (many2one): NEW relation: ir.attachment
+account / account.move / inventory_closing (boolean) : NEW hasdefault: default
+account / account.move / invoice_outstanding_credits_debits_widget (binary): type is now 'json' ('binary')
+account / account.move / invoice_payments_widget (binary): type is now 'json' ('binary')
+account / account.move / journal_group_id (many2one) : now related
+account / account.move / journal_line_ids (one2many) : DEL relation: account.move.line
+account / account.move / narration (html) : now a function
+account / account.move / needed_terms (binary) : type is now 'json' ('binary')
+account / account.move / payment_term_details (binary) : type is now 'json' ('binary')
+account / account.move / review_state (selection) : NEW required, selection_keys: ['anomaly', 'no_review', 'reviewed', 'supervised', 'todo'], hasdefault: default
+account / account.move / tax_totals (binary) : type is now 'json' ('binary')
+account / account.move / website_message_ids (one2many): DEL relation: mail.message
+account / account.move.line / cogs_origin_id (many2one) : previously in module stock_account
+account / account.move.line / deductible_amount (float) : DEL
+account / account.move.line / deductible_percentage (float) : NEW hasdefault: default
+account / account.move.line / discount_allocation_key (binary): type is now 'json' ('binary')
+account / account.move.line / discount_allocation_needed (binary): type is now 'json' ('binary')
+account / account.move.line / epd_key (binary) : type is now 'json' ('binary')
+account / account.move.line / epd_needed (binary) : type is now 'json' ('binary')
+account / account.move.line / journal_group_id (many2one) : now related
+account / account.move.line / name (char) : type is now 'text' ('char')
+account / account.move.line / open_on (date) : NEW stored: False
+account / account.move.line / term_key (binary) : type is now 'json' ('binary')
+account / account.payment / commercial_partner_id (many2one): NEW relation: res.partner, isfunction: function, stored
+account / account.payment / return_partner_bank_id (many2one): NEW relation: res.partner.bank, hasdefault: compute
+account / account.payment / state (selection) : selection_keys added: [reconciled], removed: [in_process]
+account / account.payment / transaction_uuid (char) : NEW isfunction: function, stored
+account / account.payment / website_message_ids (one2many): DEL relation: mail.message
+account / account.reconcile.model / matching_order (selection) : NEW required, selection_keys: ['new_first', 'old_first'], hasdefault: default
+account / account.reconcile.model / payment_tolerance (float) : NEW required, hasdefault: default
+account / account.reconcile.model / payment_tolerance_type (selection): NEW required, selection_keys: ['amount', 'percentage'], hasdefault: default
+account / account.reconcile.model / rule_type (selection) : NEW selection_keys: ['matching_rule', 'reco_model'], hasdefault: default
+account / account.reconcile.model / website_message_ids (one2many): DEL relation: mail.message
+account / account.report / active (boolean) : not stored anymore
+account / account.report / active (boolean) : now a function
+account / account.report / active_fallback (boolean) : NEW hasdefault: default
+account / account.report / active_selection (selection) : NEW selection_keys: ['False', 'True']
+account / account.report / availability_condition (selection): selection_keys added: [consolidation] (most likely nothing to do)
+account / account.report / enable_snapshots (boolean) : NEW hasdefault: compute
+account / account.report / filter_analytic (boolean) : DEL
+account / account.report / filter_line_comparison (boolean): NEW hasdefault: compute
+account / account.report / groupby (char) : NEW
+account / account.report / prefix_groups_threshold (integer): DEL
+account / account.report / use_fiscal_periods (boolean) : NEW hasdefault: compute
+account / account.report / user_groupby (char) : NEW hasdefault: compute
+account / account.report.column / figure_type (selection) : selection_keys added: [many2one] (most likely nothing to do)
+account / account.report.column / report_id (many2one) : now required
+account / account.report.expression / engine (selection) : selection_keys added: [reference, text] (most likely nothing to do)
+account / account.report.expression / figure_type (selection) : selection_keys added: [many2one] (most likely nothing to do)
+account / account.report.expression / formula (char) : type is now 'text' ('char')
+account / account.report.expression / subformula (char) : type is now 'text' ('char')
+account / account.report.line / foldability (selection) : NEW selection_keys: ['always_unfolded', 'foldable', 'never_unfolded'], hasdefault: compute
+account / account.report.line / foldable (boolean) : DEL
+account / account.tax / website_message_ids (one2many): DEL relation: mail.message
+account / account.tax.group / advance_tax_payment_account_id (many2one): DEL relation: account.account
+account / account.tax.group / tax_payable_account_id (many2one): DEL relation: account.account
+account / account.tax.group / tax_receivable_account_id (many2one): DEL relation: account.account
+account / account.tax.repartition.line / tag_ids_domain (binary) : type is now 'json' ('binary')
+account / ir.module.module / account_templates (binary) : type is now 'json' ('binary')
+account / product.category / account_stock_variation_id (many2one): previously in module stock_account
+account / product.category / property_cost_method (selection): previously in module stock_account
+account / product.category / property_price_difference_account_id (many2one): previously in module stock_account
+account / product.category / property_stock_journal (many2one): previously in module stock_account
+account / product.category / property_stock_valuation_account_id (many2one): previously in module stock_account
+account / product.category / property_valuation (selection): previously in module stock_account
+account / product.product / catalog_is_in_selected_section (boolean): NEW stored: False
+account / product.product / cost_method (selection) : previously in module stock_account
+account / product.product / valuation (selection) : previously in module stock_account
+account / product.template / cost_method (selection) : previously in module stock_account
+account / product.template / valuation (selection) : previously in module stock_account
+account / res.company / account_stock_journal_id (many2one): previously in module stock_account
+account / res.company / account_stock_valuation_id (many2one): previously in module stock_account
+account / res.company / cost_method (selection) : previously in module stock_account
+account / res.company / document_sequence_editable (boolean): NEW
+account / res.company / expense_account_id (many2one) : not stored anymore
+account / res.company / expense_account_id (many2one) : now a function
+account / res.company / income_account_id (many2one) : not stored anymore
+account / res.company / income_account_id (many2one) : now a function
+account / res.company / inventory_period (selection) : previously in module stock_account
+account / res.company / inventory_valuation (selection): previously in module stock_account
+account / res.company / quick_edit_mode_enabled (boolean): NEW
+account / res.company / set_to_review_documents (boolean): NEW
+account / res.company / vat_check_vies (boolean) : previously in module base_vat
+account / res.company / vat_disabled (boolean) : NEW isfunction: function, stored
+account / res.company / website_message_ids (one2many): DEL relation: mail.message
+account / res.partner / display_invoice_template_pdf_report_id (boolean): now a function
+account / res.partner / duplicate_bank_partner_ids (many2many): not related anymore
+account / res.partner / duplicate_bank_partner_ids (many2many): now a function
+account / res.partner / qr_code_method (selection) : NEW selection_keys: function
+account / res.partner.bank / account_type (False) : NEW selection_keys: ['bank', 'clabe', 'iban'], mode: modify
+account / res.partner.bank / has_iban_warning (boolean) : DEL
+account / res.partner.bank / has_money_transfer_warning (boolean): DEL
+account / res.partner.bank / has_phishing_warnings (boolean): NEW isfunction: function, stored
+account / res.partner.bank / website_message_ids (one2many): DEL relation: mail.message
+account_add_gln / res.partner / global_location_number (char) : not stored anymore
+account_add_gln / res.partner / global_location_number (char) : now a function
+stock_account / product.category / property_cost_method (selection): selection_keys removed: [fifo]
+stock_account / product.template / cost_method (selection) : selection_keys removed: [fifo]
+stock_account / res.company / account_stock_journal_id (many2one): not stored anymore
+stock_account / res.company / account_stock_journal_id (many2one): now a function
+stock_account / res.company / account_stock_valuation_id (many2one): not stored anymore
+stock_account / res.company / account_stock_valuation_id (many2one): now a function
+stock_account / res.company / cost_method (selection) : not stored anymore
+stock_account / res.company / cost_method (selection) : now a function
+stock_account / res.company / cost_method (selection) : selection_keys removed: [fifo]
+stock_account / res.company / inventory_valuation (selection): not stored anymore
+stock_account / res.company / inventory_valuation (selection): now a function
+---XML records in module 'account'---
+account.account.tag: account.account_tag_financing (noupdate switched)
+account.account.tag: account.account_tag_investing (noupdate switched)
+account.account.tag: account.account_tag_operating (noupdate switched)
+account.payment.method: account.account_payment_method_manual_in (noupdate switched)
+account.payment.method: account.account_payment_method_manual_out (noupdate switched)
+account.payment.term: account.account_payment_term_15days (noupdate switched)
+account.payment.term: account.account_payment_term_21days (noupdate switched)
+account.payment.term: account.account_payment_term_30_days_end_month_the_10 (noupdate switched)
+account.payment.term: account.account_payment_term_30days (noupdate switched)
+account.payment.term: account.account_payment_term_30days_early_discount (noupdate switched)
+account.payment.term: account.account_payment_term_45days (noupdate switched)
+account.payment.term: account.account_payment_term_90days_on_the_10th (noupdate switched)
+account.payment.term: account.account_payment_term_advance_60days (noupdate switched)
+account.payment.term: account.account_payment_term_end_following_month (noupdate switched)
+account.payment.term: account.account_payment_term_immediate (noupdate switched)
+decimal.precision: account.decimal_payment (noupdate switched)
+digest.digest: digest.digest_digest_default (noupdate switched)
+DEL digest.tip: account.digest_tip_account_0
+NEW ir.access: account.access_account_account_manager
+NEW ir.access: account.access_account_account_tax
+NEW ir.access: account.access_account_account_user
+NEW ir.access: account.access_account_accrued_orders_wizard
+NEW ir.access: account.access_account_analytic_account
+NEW ir.access: account.access_account_analytic_accountant
+NEW ir.access: account.access_account_analytic_applicability_accountant
+NEW ir.access: account.access_account_analytic_distribution_invoice
+NEW ir.access: account.access_account_analytic_distribution_readonly
+NEW ir.access: account.access_account_analytic_plan_accountant
+NEW ir.access: account.access_account_automatic_entry_wizard
+NEW ir.access: account.access_account_autopost_bills_wizard
+NEW ir.access: account.access_account_bank_statement
+NEW ir.access: account.access_account_bank_statement_group_invoice
+NEW ir.access: account.access_account_bank_statement_group_readonly
+NEW ir.access: account.access_account_cash_rounding_readonly
+NEW ir.access: account.access_account_cash_rounding_uinvoice
+NEW ir.access: account.access_account_code_mapping
+NEW ir.access: account.access_account_code_mapping_manager
+NEW ir.access: account.access_account_financial_year_op
+NEW ir.access: account.access_account_fiscal_position
+NEW ir.access: account.access_account_fiscal_position_account
+NEW ir.access: account.access_account_fiscal_position_account_product_manager
+NEW ir.access: account.access_account_fiscal_position_product_manager
+NEW ir.access: account.access_account_full_reconcile_group_invoice
+NEW ir.access: account.access_account_full_reconcile_group_readonly
+NEW ir.access: account.access_account_incoterms_all
+NEW ir.access: account.access_account_incoterms_manager
+NEW ir.access: account.access_account_journal_group_invoice
+NEW ir.access: account.access_account_journal_group_manager
+NEW ir.access: account.access_account_journal_group_readonly
+NEW ir.access: account.access_account_journal_invoice
+NEW ir.access: account.access_account_journal_manager
+NEW ir.access: account.access_account_journal_readonly
+NEW ir.access: account.access_account_lock_exception
+NEW ir.access: account.access_account_lock_exception_manager
+NEW ir.access: account.access_account_merge_wizard_line_manager
+NEW ir.access: account.access_account_merge_wizard_manager
+NEW ir.access: account.access_account_move_reversal
+NEW ir.access: account.access_account_partial_reconcile_group_invoice
+NEW ir.access: account.access_account_partial_reconcile_readonly
+NEW ir.access: account.access_account_payment
+NEW ir.access: account.access_account_payment_method
+NEW ir.access: account.access_account_payment_method_line
+NEW ir.access: account.access_account_payment_method_line_readonly
+NEW ir.access: account.access_account_payment_method_readonly
+NEW ir.access: account.access_account_payment_readonly
+NEW ir.access: account.access_account_payment_register
+NEW ir.access: account.access_account_payment_term_line_manager
+NEW ir.access: account.access_account_payment_term_line_partner_manager
+NEW ir.access: account.access_account_payment_term_manager
+NEW ir.access: account.access_account_payment_term_partner_manager
+NEW ir.access: account.access_account_payment_term_portal
+NEW ir.access: account.access_account_reconcile_model
+NEW ir.access: account.access_account_reconcile_model_billing
+NEW ir.access: account.access_account_reconcile_model_line
+NEW ir.access: account.access_account_reconcile_model_line_billing
+NEW ir.access: account.access_account_reconcile_model_line_readonly
+NEW ir.access: account.access_account_reconcile_model_readonly
+NEW ir.access: account.access_account_report_ac_user
+NEW ir.access: account.access_account_report_column_ac_user
+NEW ir.access: account.access_account_report_column_readonly
+NEW ir.access: account.access_account_report_expression_ac_user
+NEW ir.access: account.access_account_report_expression_readonly
+NEW ir.access: account.access_account_report_external_value_ac_user
+NEW ir.access: account.access_account_report_external_value_readonly
+NEW ir.access: account.access_account_report_line_ac_user
+NEW ir.access: account.access_account_report_line_readonly
+NEW ir.access: account.access_account_report_readonly
+NEW ir.access: account.access_account_resequence
+NEW ir.access: account.access_account_root
+NEW ir.access: account.access_account_secure_entries_wizard
+NEW ir.access: account.access_account_setup_bank_manual_config
+NEW ir.access: account.access_account_tag_internal_user
+NEW ir.access: account.access_account_tax_group_internal_user
+NEW ir.access: account.access_account_tax_group_manager
+NEW ir.access: account.access_account_tax_internal_user
+NEW ir.access: account.access_account_tax_manager
+NEW ir.access: account.access_account_tax_repartition_line_manager
+NEW ir.access: account.access_account_tax_repartition_line_user
+NEW ir.access: account.access_base_document_layout_account_user
+NEW ir.access: account.access_ir_model_account_reports
+NEW ir.access: account.access_product_product_account_user
+NEW ir.access: account.access_res_currency_account_manager
+NEW ir.access: account.access_res_currency_rate_account_manager
+NEW ir.access: account.access_validate_account_move
+NEW ir.access: account.account_analytic_line_rule_billing_user
+NEW ir.access: account.account_analytic_line_rule_readonly_user
+NEW ir.access: account.account_bank_statement_comp_rule
+NEW ir.access: account.account_bank_statement_line_comp_rule
+NEW ir.access: account.account_bank_statement_line_rule_basic_user
+NEW ir.access: account.account_bank_statement_line_rule_invoice_user
+NEW ir.access: account.account_bank_statement_line_rule_readonly_user
+NEW ir.access: account.account_cash_rounding_comp_rule
+NEW ir.access: account.account_comp_rule
+NEW ir.access: account.account_fiscal_position_comp_rule
+NEW ir.access: account.account_invoice_line_rule_portal
+NEW ir.access: account.account_invoice_report_rule_invoice
+NEW ir.access: account.account_invoice_report_rule_readonly
+NEW ir.access: account.account_invoice_rule_portal
+NEW ir.access: account.account_move_comp_rule
+NEW ir.access: account.account_move_line_comp_rule
+NEW ir.access: account.account_move_line_rule_group_readonly
+NEW ir.access: account.account_move_line_see_all
+NEW ir.access: account.account_move_rule_group_readonly
+NEW ir.access: account.account_move_see_all
+NEW ir.access: account.account_move_send_batch_rule_group_invoice
+NEW ir.access: account.account_move_send_single_rule_group_invoice
+NEW ir.access: account.account_payment_comp_rule
+NEW ir.access: account.account_payment_term_comp_rule
+NEW ir.access: account.account_reconcile_model_line_template_comp_rule
+NEW ir.access: account.account_reconcile_model_template_comp_rule
+NEW ir.access: account.invoice_analysis_comp_rule
+NEW ir.access: account.ir_rule_res_partner_bank_billing_officers
+NEW ir.access: account.journal_comp_rule
+NEW ir.access: account.report_external_value_comp_rule
+NEW ir.access: account.res_partner_rule_user
+NEW ir.access: account.tax_comp_rule
+NEW ir.access: account.tax_group_comp_rule
+NEW ir.access: account.tax_rep_comp_rule
+ir.actions.act_window: account.account_send_payment_receipt_by_email_action (noupdate switched)
+ir.actions.act_window: account.account_send_payment_receipt_by_email_action_multi (noupdate switched)
+ir.actions.act_window: account.action_account_audit_trail_report (deleted domain)
+NEW ir.actions.act_window: account.action_account_cashflow_analysis
+NEW ir.actions.act_window: account.action_account_matching_rules
+ir.actions.act_window: account.action_account_moves_all (deleted domain)
+ir.actions.act_window: account.action_account_moves_all_a (deleted domain)
+ir.actions.act_window: account.action_account_moves_all_grouped_matching (deleted domain)
+ir.actions.act_window: account.action_account_moves_all_tree (deleted domain)
+ir.actions.act_window: account.action_account_moves_email_preview (deleted domain)
+ir.actions.act_window: account.action_account_moves_journal_bank_cash (deleted domain)
+ir.actions.act_window: account.action_account_moves_journal_misc (deleted domain)
+ir.actions.act_window: account.action_account_moves_journal_purchase (deleted domain)
+ir.actions.act_window: account.action_account_moves_journal_sales (deleted domain)
+ir.actions.act_window: account.action_account_moves_ledger_partner (deleted domain)
+ir.actions.act_window: account.action_account_resequence (noupdate switched)
+ir.actions.act_window: account.action_amounts_to_settle (deleted domain)
+ir.actions.act_window: account.action_bank_statement_tree (deleted domain)
+ir.actions.act_window: account.action_credit_statement_tree (deleted domain)
+ir.actions.act_window: account.action_move_in_invoice (deleted domain)
+ir.actions.act_window: account.action_move_in_invoice_type (deleted domain)
+ir.actions.act_window: account.action_move_in_refund_type (deleted domain)
+ir.actions.act_window: account.action_move_out_invoice (deleted domain)
+ir.actions.act_window: account.action_move_out_invoice_type (deleted domain)
+ir.actions.act_window: account.action_move_out_refund_type (deleted domain)
+ir.actions.act_window: account.action_move_out_refund_type_non_legacy (deleted domain)
+ir.actions.act_window: account.action_open_settings (noupdate switched)
+ir.actions.act_window: account.action_view_bank_statement_tree (deleted domain)
+ir.actions.act_window: account.res_partner_action_supplier_bills (deleted domain)
+NEW ir.actions.client: account.action_report_stock_valuation [renamed from stock_account module]
+NEW ir.actions.server: account.accountant_reset_to_draft_entries_action
+NEW ir.actions.server: account.action_mark_payment_as_reconciled
+NEW ir.actions.server: account.action_server_payment_receipt
+ir.actions.server: account.model_account_move_action_share (noupdate switched)
+DEL ir.actions.server: account.accountant_confirm_entries_action
+NEW ir.config_parameter: account.disable_dashboard_kpis
+ir.config_parameter: account.product_name_similarity_threshold (noupdate switched)
+NEW ir.cron: account.ir_cron_post_stock_valuation [renamed from stock_account module] (noupdate switched)
+DEL ir.model.access: account.access_account_account
+DEL ir.model.access: account.access_account_account_invoice
+DEL ir.model.access: account.access_account_account_manager
+DEL ir.model.access: account.access_account_account_partner_manager
+DEL ir.model.access: account.access_account_account_tax
+DEL ir.model.access: account.access_account_account_tax_readonly
+DEL ir.model.access: account.access_account_account_tax_user
+DEL ir.model.access: account.access_account_account_user
+DEL ir.model.access: account.access_account_accrued_orders_wizard
+DEL ir.model.access: account.access_account_analytic_account
+DEL ir.model.access: account.access_account_analytic_accountant
+DEL ir.model.access: account.access_account_analytic_applicability_accountant
+DEL ir.model.access: account.access_account_analytic_distribution_invoice
+DEL ir.model.access: account.access_account_analytic_distribution_readonly
+DEL ir.model.access: account.access_account_analytic_line_invoice
+DEL ir.model.access: account.access_account_analytic_line_manager
+DEL ir.model.access: account.access_account_analytic_line_readonly
+DEL ir.model.access: account.access_account_analytic_plan_accountant
+DEL ir.model.access: account.access_account_automatic_entry_wizard
+DEL ir.model.access: account.access_account_autopost_bills_wizard
+DEL ir.model.access: account.access_account_bank_statement
+DEL ir.model.access: account.access_account_bank_statement_group_invoice
+DEL ir.model.access: account.access_account_bank_statement_group_readonly
+DEL ir.model.access: account.access_account_bank_statement_line
+DEL ir.model.access: account.access_account_bank_statement_line_group_invoice
+DEL ir.model.access: account.access_account_bank_statement_line_group_readonly
+DEL ir.model.access: account.access_account_cash_rounding_readonly
+DEL ir.model.access: account.access_account_cash_rounding_uinvoice
+DEL ir.model.access: account.access_account_code_mapping
+DEL ir.model.access: account.access_account_code_mapping_manager
+DEL ir.model.access: account.access_account_financial_year_op
+DEL ir.model.access: account.access_account_fiscal_position
+DEL ir.model.access: account.access_account_fiscal_position_account
+DEL ir.model.access: account.access_account_fiscal_position_account_product_manager
+DEL ir.model.access: account.access_account_fiscal_position_product_manager
+DEL ir.model.access: account.access_account_full_reconcile
+DEL ir.model.access: account.access_account_full_reconcile_group_invoice
+DEL ir.model.access: account.access_account_full_reconcile_group_readonly
+DEL ir.model.access: account.access_account_group
+DEL ir.model.access: account.access_account_group_basic
+DEL ir.model.access: account.access_account_group_manager
+DEL ir.model.access: account.access_account_incoterms_all
+DEL ir.model.access: account.access_account_incoterms_manager
+DEL ir.model.access: account.access_account_invoice_line_portal
+DEL ir.model.access: account.access_account_invoice_portal
+DEL ir.model.access: account.access_account_invoice_report
+DEL ir.model.access: account.access_account_invoice_report_billing
+DEL ir.model.access: account.access_account_invoice_report_readonly
+DEL ir.model.access: account.access_account_journal_group_invoice
+DEL ir.model.access: account.access_account_journal_group_manager
+DEL ir.model.access: account.access_account_journal_group_readonly
+DEL ir.model.access: account.access_account_journal_invoice
+DEL ir.model.access: account.access_account_journal_manager
+DEL ir.model.access: account.access_account_journal_readonly
+DEL ir.model.access: account.access_account_lock_exception
+DEL ir.model.access: account.access_account_lock_exception_manager
+DEL ir.model.access: account.access_account_merge_wizard_line_manager
+DEL ir.model.access: account.access_account_merge_wizard_manager
+DEL ir.model.access: account.access_account_move_line_manager
+DEL ir.model.access: account.access_account_move_line_readonly
+DEL ir.model.access: account.access_account_move_line_uinvoice
+DEL ir.model.access: account.access_account_move_manager
+DEL ir.model.access: account.access_account_move_readonly
+DEL ir.model.access: account.access_account_move_reversal
+DEL ir.model.access: account.access_account_move_send_batch_wizard
+DEL ir.model.access: account.access_account_move_send_wizard
+DEL ir.model.access: account.access_account_move_uinvoice
+DEL ir.model.access: account.access_account_partial_reconcile
+DEL ir.model.access: account.access_account_partial_reconcile_group_invoice
+DEL ir.model.access: account.access_account_partial_reconcile_readonly
+DEL ir.model.access: account.access_account_payment
+DEL ir.model.access: account.access_account_payment_method
+DEL ir.model.access: account.access_account_payment_method_line
+DEL ir.model.access: account.access_account_payment_method_line_readonly
+DEL ir.model.access: account.access_account_payment_method_readonly
+DEL ir.model.access: account.access_account_payment_readonly
+DEL ir.model.access: account.access_account_payment_register
+DEL ir.model.access: account.access_account_payment_term_line_manager
+DEL ir.model.access: account.access_account_payment_term_line_partner_manager
+DEL ir.model.access: account.access_account_payment_term_manager
+DEL ir.model.access: account.access_account_payment_term_partner_manager
+DEL ir.model.access: account.access_account_payment_term_portal
+DEL ir.model.access: account.access_account_reconcile_model
+DEL ir.model.access: account.access_account_reconcile_model_billing
+DEL ir.model.access: account.access_account_reconcile_model_line
+DEL ir.model.access: account.access_account_reconcile_model_line_billing
+DEL ir.model.access: account.access_account_reconcile_model_line_readonly
+DEL ir.model.access: account.access_account_reconcile_model_readonly
+DEL ir.model.access: account.access_account_report_ac_user
+DEL ir.model.access: account.access_account_report_basic
+DEL ir.model.access: account.access_account_report_column_ac_user
+DEL ir.model.access: account.access_account_report_column_basic
+DEL ir.model.access: account.access_account_report_column_readonly
+DEL ir.model.access: account.access_account_report_expression_ac_user
+DEL ir.model.access: account.access_account_report_expression_basic
+DEL ir.model.access: account.access_account_report_expression_readonly
+DEL ir.model.access: account.access_account_report_external_value_ac_user
+DEL ir.model.access: account.access_account_report_external_value_readonly
+DEL ir.model.access: account.access_account_report_line_ac_user
+DEL ir.model.access: account.access_account_report_line_basic
+DEL ir.model.access: account.access_account_report_line_readonly
+DEL ir.model.access: account.access_account_report_readonly
+DEL ir.model.access: account.access_account_resequence
+DEL ir.model.access: account.access_account_root
+DEL ir.model.access: account.access_account_root_manager
+DEL ir.model.access: account.access_account_secure_entries_wizard
+DEL ir.model.access: account.access_account_setup_bank_manual_config
+DEL ir.model.access: account.access_account_tag_internal_user
+DEL ir.model.access: account.access_account_tax_group
+DEL ir.model.access: account.access_account_tax_group_internal_user
+DEL ir.model.access: account.access_account_tax_group_manager
+DEL ir.model.access: account.access_account_tax_group_readonly
+DEL ir.model.access: account.access_account_tax_internal_user
+DEL ir.model.access: account.access_account_tax_invoice
+DEL ir.model.access: account.access_account_tax_manager
+DEL ir.model.access: account.access_account_tax_readonly
+DEL ir.model.access: account.access_account_tax_repartition_line_invoice
+DEL ir.model.access: account.access_account_tax_repartition_line_manager
+DEL ir.model.access: account.access_account_tax_repartition_line_readonly
+DEL ir.model.access: account.access_account_tax_repartition_line_user
+DEL ir.model.access: account.access_product_product_account_user
+DEL ir.model.access: account.access_res_currency_account_manager
+DEL ir.model.access: account.access_res_currency_rate_account_manager
+DEL ir.model.access: account.access_res_partner_group_account_manager
+DEL ir.model.access: account.access_validate_account_move
+ir.model.constraint: account.constraint_account_account_tag_name_uniq (changed definition: is now 'False' ('unique(name, applicability, country_id)'))
+ir.model.constraint: account.constraint_account_bank_statement_first_line_index_idx (changed definition: is now 'False' ('INDEX (journal_id, first_line_index)'))
+ir.model.constraint: account.constraint_account_bank_statement_journal_id_date_desc_id_desc_idx (changed definition: is now 'False' ('INDEX (journal_id, date DESC, id DESC)'))
+ir.model.constraint: account.constraint_account_bank_statement_line_main_idx (changed definition: is now 'False' ('INDEX (journal_id, company_id, internal_index)'))
+ir.model.constraint: account.constraint_account_bank_statement_line_orphan_idx (changed definition: is now 'False' ('INDEX (journal_id, company_id, internal_index) WHERE statement_id IS NULL'))
+ir.model.constraint: account.constraint_account_bank_statement_line_unreconciled_idx (changed definition: is now 'False' ('INDEX (journal_id, company_id, internal_index) WHERE is_reconciled IS NOT TRUE'))
+ir.model.constraint: account.constraint_account_fiscal_position_account_account_src_dest_uniq (changed definition: is now 'False' ('unique (position_id,account_src_id,account_dest_id)'))
+ir.model.constraint: account.constraint_account_journal_code_company_uniq (changed definition: is now 'False' ('unique (company_id, code)'))
+ir.model.constraint: account.constraint_account_journal_group_uniq_name (changed definition: is now 'False' ('unique(company_id, name)'))
+ir.model.constraint: account.constraint_account_lock_exception_company_id_end_datetime_idx (changed definition: is now 'False' ('INDEX (company_id, user_id, end_datetime) WHERE active IS TRUE'))
+ir.model.constraint: account.constraint_account_move_account_move_sanitize_payment_ref_idx (changed definition: is now 'False' ('INDEX (regexp_replace(COALESCE(payment_reference, ''), '[^a-zA-Z0-9]', '', 'g'))'))
+NEW ir.model.constraint: account.constraint_account_move_check_document_tax_mode_set
+ir.model.constraint: account.constraint_account_move_checked_idx (changed definition: is now 'False' ('INDEX (journal_id) WHERE (checked IS NOT TRUE)'))
+ir.model.constraint: account.constraint_account_move_duplicate_bills_idx (changed definition: is now 'False' ('INDEX (ref) WHERE (move_type IN ('in_invoice', 'in_refund'))'))
+ir.model.constraint: account.constraint_account_move_journal_id_company_id_idx (changed definition: is now 'False' ('INDEX (journal_id, company_id, date)'))
+ir.model.constraint: account.constraint_account_move_journal_id_date_idx (changed definition: is now 'False' ('INDEX (journal_id, date)'))
+ir.model.constraint: account.constraint_account_move_line_account_id_date_idx (changed definition: is now 'False' ('INDEX (account_id, date)'))
+ir.model.constraint: account.constraint_account_move_line_check_accountable_required_fields (changed definition: is now 'False' ('CHECK(display_type IN ('line_section', 'line_subsection', 'line_note') OR account_id IS NOT NULL)'))
+ir.model.constraint: account.constraint_account_move_line_check_amount_currency_balance_sign (changed definition: is now 'False' ('CHECK( display_type IN ('line_section', 'line_subsection', 'line_note') OR ( (balance <= 0 AND amount_currency <= 0) OR (balance >= 0 AND amount_currency >= 0) ) )'))
+ir.model.constraint: account.constraint_account_move_line_check_credit_debit (changed definition: is now 'False' ('CHECK(display_type IN ('line_section', 'line_subsection', 'line_note') OR credit * debit=0)'))
+ir.model.constraint: account.constraint_account_move_line_check_non_accountable_fields_null (changed definition: is now 'False' ('CHECK(display_type NOT IN ('line_section', 'line_subsection', 'line_note') OR (amount_currency = 0 AND debit = 0 AND credit = 0 AND account_id IS NULL))'))
+ir.model.constraint: account.constraint_account_move_line_date_name_id_idx (changed definition: is now 'False' ('INDEX (date desc, move_name desc, id)'))
+ir.model.constraint: account.constraint_account_move_line_journal_id_neg_amnt_residual_idx (changed definition: is now 'False' ('INDEX (journal_id) WHERE amount_residual < 0'))
+ir.model.constraint: account.constraint_account_move_line_partner_id_ref_idx (changed definition: is now 'False' ('INDEX (partner_id, ref)'))
+ir.model.constraint: account.constraint_account_move_line_unreconciled_index (changed definition: is now 'False' ('INDEX (account_id, partner_id) WHERE reconciled IS NOT TRUE'))
+ir.model.constraint: account.constraint_account_move_made_gaps (changed definition: is now 'False' ('INDEX (journal_id, state, payment_state, move_type, date) WHERE (made_sequence_gap IS TRUE)'))
+ir.model.constraint: account.constraint_account_move_payment_idx (changed definition: is now 'False' ('INDEX (journal_id, state, payment_state, move_type, date)'))
+ir.model.constraint: account.constraint_account_move_unique_name (changed definition: is now 'False' ('UNIQUE INDEX (name, journal_id) WHERE (state = 'posted'AND name != '/')'))
+ir.model.constraint: account.constraint_account_payment_check_amount_not_negative (changed definition: is now 'False' ('CHECK(amount >= 0.0)'))
+ir.model.constraint: account.constraint_account_payment_journal_id_company_id_idx (changed definition: is now 'False' ('INDEX (journal_id, company_id)'))
+ir.model.constraint: account.constraint_account_payment_method_name_code_unique (changed definition: is now 'False' ('unique (code, payment_type)'))
+ir.model.constraint: account.constraint_account_payment_unmatched_idx (changed definition: is now 'False' ('INDEX (journal_id, company_id) WHERE is_matched IS NOT TRUE'))
+NEW ir.model.constraint: account.constraint_account_report_column_expression_label_uniq
+ir.model.constraint: account.constraint_account_report_expression_domain_engine_subformula_required (changed definition: is now 'False' ('CHECK(engine != 'domain' OR subformula IS NOT NULL)'))
+ir.model.constraint: account.constraint_account_report_expression_line_label_uniq (changed definition: is now 'False' ('UNIQUE(report_line_id,label)'))
+ir.model.constraint: account.constraint_account_report_line_code_uniq (changed definition: is now 'False' ('unique (report_id, code)'))
+DEL ir.model.constraint: account.constraint_account_group_check_length_prefix
+DEL ir.rule: account.account_analytic_line_rule_billing_user (noupdate)
+DEL ir.rule: account.account_analytic_line_rule_readonly_user (noupdate)
+DEL ir.rule: account.account_bank_statement_comp_rule (noupdate)
+DEL ir.rule: account.account_bank_statement_line_comp_rule (noupdate)
+DEL ir.rule: account.account_comp_rule (noupdate)
+DEL ir.rule: account.account_fiscal_position_comp_rule (noupdate)
+DEL ir.rule: account.account_group_comp_rule (noupdate)
+DEL ir.rule: account.account_invoice_line_rule_portal (noupdate)
+DEL ir.rule: account.account_invoice_rule_portal (noupdate)
+DEL ir.rule: account.account_move_comp_rule (noupdate)
+DEL ir.rule: account.account_move_line_comp_rule (noupdate)
+DEL ir.rule: account.account_move_line_rule_group_invoice (noupdate)
+DEL ir.rule: account.account_move_line_rule_group_readonly (noupdate)
+DEL ir.rule: account.account_move_line_see_all (noupdate)
+DEL ir.rule: account.account_move_rule_group_invoice (noupdate)
+DEL ir.rule: account.account_move_rule_group_readonly (noupdate)
+DEL ir.rule: account.account_move_see_all (noupdate)
+DEL ir.rule: account.account_move_send_batch_rule_group_invoice (noupdate)
+DEL ir.rule: account.account_move_send_single_rule_group_invoice (noupdate)
+DEL ir.rule: account.account_payment_comp_rule (noupdate)
+DEL ir.rule: account.account_payment_term_comp_rule (noupdate)
+DEL ir.rule: account.account_reconcile_model_line_template_comp_rule (noupdate)
+DEL ir.rule: account.account_reconcile_model_template_comp_rule (noupdate)
+DEL ir.rule: account.invoice_analysis_comp_rule (noupdate)
+DEL ir.rule: account.ir_rule_res_partner_bank_billing_officers (noupdate)
+DEL ir.rule: account.journal_comp_rule (noupdate)
+DEL ir.rule: account.journal_group_comp_rule (noupdate)
+DEL ir.rule: account.report_external_value_comp_rule (noupdate)
+DEL ir.rule: account.tax_comp_rule (noupdate)
+DEL ir.rule: account.tax_group_comp_rule (noupdate)
+DEL ir.rule: account.tax_rep_comp_rule (noupdate)
+ir.sequence: account.seq_account_payment (noupdate switched)
+NEW ir.ui.menu: account.menu_action_account_cashflow_analysis
+DEL ir.ui.menu: account.account_logs_menu
+DEL ir.ui.menu: account.root_payment_menu
+NEW ir.ui.view: account.account_bank_statement_line_view_graph_cashflow
+NEW ir.ui.view: account.account_bank_statement_line_view_pivot_cashflow
+NEW ir.ui.view: account.account_bank_statement_line_view_search_cashflow
+NEW ir.ui.view: account.address_form_additional_identifiers
+ir.ui.view: account.email_template_mail_gateway_failed (noupdate switched)
+NEW ir.ui.view: account.tax_repartition_line_form
+NEW ir.ui.view: account.tax_repartition_line_kanban
+NEW ir.ui.view: account.uom_uom_view_form
+NEW ir.ui.view: account.view_account_list_from_entry
+NEW ir.ui.view: account.view_account_move_graph_invoice
+NEW ir.ui.view: account.view_account_move_pivot_invoice
+NEW ir.ui.view: account.view_bank_statement_kanban
+NEW ir.ui.view: account.view_move_line_tree_open_on
+NEW ir.ui.view: account.view_partner_bank_kanban_account
+DEL ir.ui.view: account.portal_my_home_invoice
+DEL ir.ui.view: account.product_uom_form_view_inherit
+DEL ir.ui.view: account.product_view_search_catalog
+DEL ir.ui.view: account.view_account_group_form
+DEL ir.ui.view: account.view_account_group_search
+DEL ir.ui.view: account.view_account_group_tree
+DEL ir.ui.view: account_add_gln.view_partner_form_inherit
+mail.message.subtype: account.mt_invoice_created (noupdate switched)
+mail.message.subtype: account.mt_invoice_paid (noupdate switched)
+mail.message.subtype: account.mt_invoice_validated (noupdate switched)
+mail.template: account.email_template_edi_credit_note (noupdate switched)
+mail.template: account.email_template_edi_invoice (noupdate switched)
+mail.template: account.email_template_edi_self_billing_credit_note (noupdate switched)
+mail.template: account.email_template_edi_self_billing_invoice (noupdate switched)
+mail.template: account.mail_template_data_payment_receipt (noupdate switched)
+mail.template: account.mail_template_einvoice_notification (noupdate switched)
+mail.template: account.mail_template_invoice_subscriber (noupdate switched)
+onboarding.onboarding: account.onboarding_onboarding_account_dashboard (noupdate switched)
+NEW onboarding.onboarding: account.onboarding_onboarding_account_return_dashboard
+onboarding.onboarding.step: account.onboarding_onboarding_step_base_document_layout (noupdate switched)
+onboarding.onboarding.step: account.onboarding_onboarding_step_chart_of_accounts (noupdate switched)
+onboarding.onboarding.step: account.onboarding_onboarding_step_company_data (noupdate switched)
+onboarding.onboarding.step: account.onboarding_onboarding_step_fiscal_year (noupdate switched)
+onboarding.onboarding.step: account.onboarding_onboarding_step_sales_tax (noupdate switched)
+NEW portal.entry: account.portal_invoice_client
+NEW portal.entry: account.portal_invoice_vendor
+res.country.group: account.europe_vat (noupdate switched)
+res.country.group: account.intrastat (noupdate switched)
diff --git a/openupgrade_scripts/scripts/account/tests/data_account_migration.py b/openupgrade_scripts/scripts/account/tests/data_account_migration.py
new file mode 100644
index 00000000000..014848eb1d3
--- /dev/null
+++ b/openupgrade_scripts/scripts/account/tests/data_account_migration.py
@@ -0,0 +1,44 @@
+env = locals().get("env")
+
+# 19.0's `checked` ("Reviewed") becomes 20.0's review_state, and only a posted
+# move whose checked is FALSE carries information: 19.0's compute would have set
+# it True, so a False there was put there by hand.
+#
+# This seed contains no such row -- `checked` equals `state = 'posted'` on all
+# 3223 of its moves -- so the branch that writes 'todo' is unreachable without
+# this, and a test over the seed alone would pass against a migration that does
+# nothing at all.
+#
+# An existing move is unticked rather than a new one built: posting a journal
+# entry from a shell needs a journal, balanced lines and an open period, none of
+# which is what is under test, and each of which is a way for the fixture to
+# fail for its own reasons.
+move = env["account.move"].search([("state", "=", "posted")], order="id", limit=1)
+assert move, "the seed has no posted move to untick"
+
+# Written straight to the column. `checked` is a stored compute in 19.0, so
+# assigning it through the ORM invites the compute to put it back; and the field
+# does not exist in 20.0, so nothing recomputes it during the upgrade either.
+env.cr.execute("UPDATE account_move SET checked = false WHERE id = %s", (move.id,))
+
+# A second, untouched posted move, so the test can say the rule discriminates
+# rather than sweeping every posted entry into the review queue.
+other = env["account.move"].search(
+ [("state", "=", "posted"), ("id", "!=", move.id)], order="id", limit=1
+)
+assert other, "the seed has only one posted move, so nothing can be left alone"
+
+for record, name in (
+ (move, "ou19_move_unreviewed_by_hand"),
+ (other, "ou19_move_left_alone"),
+):
+ env["ir.model.data"].create(
+ {
+ "module": "__ou19__",
+ "name": name,
+ "model": "account.move",
+ "res_id": record.id,
+ }
+ )
+
+env.cr.commit()
diff --git a/openupgrade_scripts/scripts/account/tests/test_account_migration.py b/openupgrade_scripts/scripts/account/tests/test_account_migration.py
new file mode 100644
index 00000000000..de7ab4f06e0
--- /dev/null
+++ b/openupgrade_scripts/scripts/account/tests/test_account_migration.py
@@ -0,0 +1,76 @@
+from odoo.tests import TransactionCase
+
+from odoo.addons.openupgrade_framework import openupgrade_test
+
+
+@openupgrade_test
+class TestAccountMigration(TransactionCase):
+ """Assertions on 19.0's Reviewed flag reaching 20.0's review queue.
+
+ Every method opens by resolving its fixture. The data snippet runs in a
+ separate process through the 19.0 shell, and if its commit were lost it
+ would exit 0 having written nothing -- an assertion whose empty case is a
+ pass would then report success for a migration that never happened.
+ """
+
+ def _move(self, name):
+ record = self.env.ref(f"__ou19__.{name}", raise_if_not_found=False)
+ self.assertTrue(
+ record, f"{name} is missing: the 19.0 fixture never reached the database"
+ )
+ return record
+
+ def test_a_move_unreviewed_by_hand_lands_in_the_review_queue(self):
+ """The branch the seed cannot reach on its own.
+
+ 19.0's compute sets checked True for a posted move, so a posted move
+ carrying False was unticked by somebody. 20.0 calls that 'todo'.
+ """
+ move = self._move("ou19_move_unreviewed_by_hand")
+ self.env.cr.execute(
+ "SELECT checked, state FROM account_move WHERE id = %s", (move.id,)
+ )
+ checked, state = self.env.cr.fetchone()
+ self.assertFalse(checked, "the fixture's 19.0 answer did not survive")
+ self.assertEqual(state, "posted")
+ self.assertEqual(
+ move.review_state,
+ "todo",
+ "a move somebody had marked as not reviewed came out indistinguishable "
+ "from one nobody ever looked at",
+ )
+
+ def test_a_move_that_only_carried_the_computed_default_is_left_alone(self):
+ """The half that says the rule discriminates.
+
+ Mapping checked=True to 'reviewed' would assert a review of every posted
+ invoice in the database on the strength of a value that is really just
+ "posted", so nothing is written for those.
+ """
+ move = self._move("ou19_move_left_alone")
+ self.env.cr.execute(
+ "SELECT checked FROM account_move WHERE id = %s", (move.id,)
+ )
+ self.assertTrue(self.env.cr.fetchone()[0], "the fixture is no longer checked")
+ self.assertEqual(
+ move.review_state,
+ "no_review",
+ "a posted entry was put into the review queue on the strength of the "
+ "computed default",
+ )
+
+ def test_no_posted_move_was_swept_into_the_queue_wholesale(self):
+ """3206 of the seed's moves are posted; one of them is the fixture."""
+ self.env.cr.execute(
+ "SELECT count(*) FROM account_move WHERE review_state = 'todo'"
+ )
+ in_queue = self.env.cr.fetchone()[0]
+ self.env.cr.execute(
+ "SELECT count(*) FROM account_move WHERE state = 'posted' AND NOT checked"
+ )
+ self.assertEqual(
+ in_queue,
+ self.env.cr.fetchone()[0],
+ "the review queue holds more than the posted moves that were "
+ "explicitly unticked in 19.0",
+ )