diff --git a/docsource/modules160-170.rst b/docsource/modules160-170.rst
index 744a69c1eaaa..c014f0c1d8bd 100644
--- a/docsource/modules160-170.rst
+++ b/docsource/modules160-170.rst
@@ -6,7 +6,7 @@ Module coverage 16.0 -> 17.0
+---------------------------------------------------+----------------------+-------------------------------------------------+
| Module | Status + Extra Information |
+===================================================+======================+=================================================+
-| account | | |
+| account | Done | |
+---------------------------------------------------+----------------------+-------------------------------------------------+
| |new| account_audit_trail | | |
+---------------------------------------------------+----------------------+-------------------------------------------------+
diff --git a/openupgrade_scripts/scripts/account/17.0.1.2/end-migration.py b/openupgrade_scripts/scripts/account/17.0.1.2/end-migration.py
new file mode 100644
index 000000000000..6bf5e52c90d0
--- /dev/null
+++ b/openupgrade_scripts/scripts/account/17.0.1.2/end-migration.py
@@ -0,0 +1,13 @@
+# Copyright 2024 Viindoo Technology Joint Stock Company (Viindoo)
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+from openupgradelib import openupgrade
+
+
+def _res_partner_bank_computation(env):
+ partner_banks = env["res.partner.bank"].with_context(active_test=False).search([])
+ partner_banks._compute_display_account_warning()
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+ _res_partner_bank_computation(env)
diff --git a/openupgrade_scripts/scripts/account/17.0.1.2/noupdate_changes.xml b/openupgrade_scripts/scripts/account/17.0.1.2/noupdate_changes.xml
index 3f88cf19fce0..d9df6a524d18 100644
--- a/openupgrade_scripts/scripts/account/17.0.1.2/noupdate_changes.xml
+++ b/openupgrade_scripts/scripts/account/17.0.1.2/noupdate_changes.xml
@@ -18,40 +18,59 @@
[('company_id', 'in', company_ids)]
+
+
+
+
10 Days after End of Next Month
Payment terms: 10 Days after End of Next Month
+
+
7
2
True
+
+
['|', ('company_id', '=', False), ('company_id', 'parent_of', company_ids)]
+
+
[('company_id', 'parent_of', company_ids)]
diff --git a/openupgrade_scripts/scripts/account/17.0.1.2/post-migration.py b/openupgrade_scripts/scripts/account/17.0.1.2/post-migration.py
new file mode 100644
index 000000000000..5e18569ff92b
--- /dev/null
+++ b/openupgrade_scripts/scripts/account/17.0.1.2/post-migration.py
@@ -0,0 +1,410 @@
+# Copyright 2024 Viindoo Technology Joint Stock Company (Viindoo)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from openupgradelib import openupgrade
+
+from odoo.addons.base.models.ir_property import TYPE2FIELD as ir_property_TYPE2FIELD
+
+_deleted_xml_records = [
+ "account.tax_group_taxes",
+ "account.account_invoice_send_rule_group_invoice",
+ "account.sequence_reconcile_seq",
+]
+
+
+def _am_update_invoice_pdf_report_file(env):
+ openupgrade.logged_query(
+ env.cr,
+ """
+ UPDATE ir_attachment ia
+ SET res_field = 'invoice_pdf_report_file',
+ res_id = am.id
+ FROM account_move am
+ WHERE am.message_main_attachment_id = ia.id
+ """,
+ )
+
+
+def _onboarding_state_migration(env):
+ """
+ Following pr: https://github.com/odoo/odoo/pull/104223/
+ """
+ env.cr.execute(
+ """
+ SELECT id, account_onboarding_create_invoice_state_flag,
+ account_onboarding_invoice_layout_state,
+ account_onboarding_sale_tax_state, account_setup_bank_data_state,
+ account_setup_bill_state, account_setup_coa_state, account_setup_fy_data_state,
+ account_setup_taxes_state FROM res_company
+ """
+ )
+ for (
+ company_id,
+ account_onboarding_create_invoice_state_flag,
+ account_onboarding_invoice_layout_state,
+ account_onboarding_sale_tax_state,
+ account_setup_bank_data_state,
+ account_setup_bill_state,
+ account_setup_coa_state,
+ account_setup_fy_data_state,
+ account_setup_taxes_state,
+ ) in env.cr.fetchall():
+ OnboardingStep = env["onboarding.onboarding.step"].with_company(company_id)
+ company = env["res.company"].browse(company_id)
+ if company.street and company.street.strip():
+ # Same behaviour for this base setup company data in v16
+ # Check method 'action_save_onboarding_company_step' in v16
+ # Note in v17 you only need to save it then it will be done
+ OnboardingStep.action_validate_step(
+ "account.onboarding_onboarding_step_company_data"
+ )
+ if account_onboarding_create_invoice_state_flag:
+ step = env.ref(
+ "account.onboarding_onboarding_step_create_invoice",
+ raise_if_not_found=False,
+ )
+ if step and step.current_step_state == "not_done":
+ if env["account.move"].search(
+ [
+ ("company_id", "=", company_id),
+ ("move_type", "=", "out_invoice"),
+ ],
+ limit=1,
+ ):
+ step.action_set_just_done()
+ if account_onboarding_invoice_layout_state in ("just_done", "done"):
+ step = env.ref(
+ "account.onboarding_onboarding_step_base_document_layout",
+ raise_if_not_found=False,
+ )
+ if step:
+ step.with_company(company_id).action_set_just_done()
+ if account_onboarding_sale_tax_state in ("just_done", "done"):
+ OnboardingStep.action_validate_step(
+ "account.onboarding_onboarding_step_sales_tax"
+ )
+ if account_setup_bank_data_state in ("just_done", "done"):
+ OnboardingStep.action_validate_step(
+ "account.onboarding_onboarding_step_bank_account"
+ )
+ if account_setup_bill_state in ("just_done", "done"):
+ OnboardingStep.action_validate_step(
+ "account.onboarding_onboarding_step_setup_bill"
+ )
+ if account_setup_coa_state in ("just_done", "done"):
+ OnboardingStep.action_validate_step(
+ "account.onboarding_onboarding_step_chart_of_accounts"
+ )
+ if account_setup_fy_data_state in ("just_done", "done"):
+ OnboardingStep.action_validate_step(
+ "account.onboarding_onboarding_step_fiscal_year"
+ )
+ if account_setup_taxes_state in ("just_done", "done"):
+ OnboardingStep.action_validate_step(
+ "account.onboarding_onboarding_step_default_taxes"
+ )
+
+
+def _account_payment_term_migration(env):
+ """
+ Switch balance lines to percent and compute the remaining percentage, and convert
+ old multiple column system to the new delay_type + nb_days.
+
+ https://github.com/odoo/odoo/pull/110274
+ """
+ openupgrade.logged_query(
+ env.cr,
+ """
+ UPDATE account_payment_term_line
+ SET value = 'percent',
+ value_amount = 100.0 - COALESCE(percentages.percentage, 0)
+ FROM (
+ SELECT
+ payment_id,
+ SUM(
+ CASE WHEN l.value='percent' THEN l.value_amount
+ ELSE 0 END
+ ) percentage
+ FROM account_payment_term_line l
+ GROUP BY payment_id
+ ) percentages
+ WHERE
+ value = 'balance' AND
+ percentages.payment_id = account_payment_term_line.payment_id
+ """,
+ )
+ openupgrade.logged_query(
+ env.cr,
+ """
+ UPDATE account_payment_term_line
+ SET delay_type = CASE
+ WHEN end_month AND COALESCE(months, 0) = 0
+ AND COALESCE(days, 0) = 0
+ THEN 'days_after_end_of_month'
+ WHEN end_month AND months = 1 AND COALESCE(days, 0) = 0
+ THEN 'days_after_end_of_next_month'
+ WHEN end_month AND COALESCE(months, 0) <= 1 AND days > 0
+ THEN 'days_end_of_month_on_the'
+ ELSE 'days_after'
+ END,
+ nb_days = CASE
+ WHEN end_month AND months <= 1
+ THEN COALESCE(days, 0) + COALESCE(days_after, 0)
+ ELSE
+ COALESCE(months, 0)*30 + COALESCE(days, 0) +
+ COALESCE(days_after, 0)
+ END
+ """,
+ )
+
+
+def _account_payment_term_early_payment_discount(env):
+ """Only payment terms with one line and the early payment discount activated are
+ valid now, so we are going to discard other previous configurations.
+ """
+ openupgrade.logged_query(
+ env.cr,
+ """
+ WITH sub AS (
+ SELECT * FROM (
+ SELECT *,
+ row_number() over (partition BY payment_id ORDER BY id) AS rnum
+ FROM account_payment_term_line
+ ) t
+ WHERE t.rnum = 1
+ AND t.discount_days IS NOT NULL
+ AND t.discount_percentage > 0
+ )
+ UPDATE account_payment_term apt
+ SET early_discount = True,
+ discount_days = sub.discount_days,
+ discount_percentage = sub.discount_percentage
+ FROM sub
+ WHERE sub.payment_id = apt.id
+ """,
+ )
+
+
+def convert_from_company_dependent(
+ env,
+ model_name,
+ origin_field_name,
+ destination_field_name,
+ origin_id_column_name,
+ model_table_name=None,
+):
+ """
+ Move a company-dependent field back to the model table.
+
+ The usual setting is: A model didn't have a company_id field in version
+ (n-1), but got company-aware in version (n). Then company-dependent fields
+ don't make sense, and are replaced with plain database columns.
+
+ You're responsible for duplicating records for all companies in whatever way
+ makes sense for the model before calling this function, and link the
+ duplicate to the original record in column `origin_id_column_name`, which
+ you have to create yourself beforehand.
+
+ :param model_name: Name of the model.
+ :param origin_field_name: Name of the company-dependent field
+ :param destination_field_name: Name of plain field
+ :param origin_id_column_name: Name of the column you created to link record
+ duplicates to the record they were duplicated from
+ :param model_table_name: Name of the table. Optional. If not provided
+ the table name is taken from the model (so the model must be
+ registered previously).
+ """
+ # If you want to recycle this function for your own migration, better
+ # add it to openupgradelib
+ table_name = model_table_name or env[model_name]._table
+
+ env.cr.execute(
+ "SELECT id, ttype FROM ir_model_fields "
+ f"WHERE model='{model_name}' AND name='{origin_field_name}'"
+ )
+ field_id, field_type = env.cr.fetchone()
+
+ value_expression = ir_property_TYPE2FIELD.get(field_type)
+ if value_expression == "value_reference":
+ value_expression = "SPLIT_PART(ip.value_reference, ',', 2)::integer"
+
+ return openupgrade.logged_query(
+ env.cr,
+ f"""
+ UPDATE {table_name}
+ SET {destination_field_name} = (
+ SELECT {value_expression}
+ FROM ir_property ip
+ WHERE ip.fields_id={field_id} --- {origin_field_name}
+ AND (
+ ip.res_id = '{model_name}.' || COALESCE(
+ {table_name}.{origin_id_column_name}, {table_name}.id
+ )
+ OR ip.res_id IS NULL
+ )
+ AND (
+ ip.company_id = {table_name}.company_id
+ OR ip.company_id IS NULL
+ )
+ ORDER BY ip.company_id NULLS LAST, ip.res_id NULLS LAST
+ LIMIT 1
+ )
+ """,
+ )
+
+
+def _account_tax_group_migration(env):
+ """
+ In v17 tax groups are company-aware (company_id added):
+
+ - Find which tax groups have accounts with different companies,
+ duplicate them for each of that company
+ - Update accounts to point to the newly created groups for their
+ companies
+ - Rename ir model data (xml_id), the format will be
+ "{module_name}.{company_id}_xml_id"
+ - Fill new fields tax_receivable_account_id, tax_payable_account_id,
+ advance_tax_payment_account_id with the value of the properties
+ they replace
+
+ Example in v16:
+ 2 VN CoA company: tax 0, tax 5, tax 10
+ 2 Generic CoA company tax 15
+ 1 Belgium CoA company tax 6, 12, 21
+
+ -> After migration we will have 2 tax 0, 2 tax 5, 2 tax 10
+ and 2 tax 15 of course with only different company_id
+ Also the new one will have their own xml_id using create method
+ of ir.model.data
+ And then in each l10n module, only need to perform rename xml_id like
+ https://github.com/Viindoo/OpenUpgrade/pull/655
+ """
+ origin_id_column = openupgrade.get_legacy_name("origin_id")
+ openupgrade.logged_query(
+ env.cr,
+ f"""
+ ALTER TABLE account_tax_group
+ ADD COLUMN IF NOT EXISTS {origin_id_column} INTEGER;
+ """,
+ )
+
+ env.cr.execute(
+ """
+ SELECT tax_group_id, array_agg(DISTINCT(company_id))
+ FROM account_tax
+ GROUP BY tax_group_id
+ HAVING COUNT(DISTINCT company_id) > 1
+ """
+ )
+
+ for tax_group_id, company_ids in env.cr.fetchall():
+ tax_group = env["account.tax.group"].browse(tax_group_id)
+ first_company_id = min(company_ids)
+ tax_group.company_id = first_company_id
+
+ imd = env["ir.model.data"].search(
+ [("res_id", "=", tax_group.id), ("model", "=", "account.tax.group")],
+ limit=1,
+ )
+ tax_group_name = imd.name
+ imd.write({"name": f"{first_company_id}_{imd.name}"})
+
+ for company_id in company_ids:
+ if company_id == first_company_id:
+ continue
+ new_tax_group = tax_group.copy({"company_id": company_id})
+
+ openupgrade.logged_query(
+ env.cr,
+ f"""
+ UPDATE account_tax_group
+ SET {origin_id_column} = {tax_group.id}
+ WHERE id = {new_tax_group.id}
+ """,
+ )
+
+ if tax_group_name:
+ new_imd = imd.copy({"res_id": new_tax_group.id})
+ new_imd.write({"name": f"{company_id}_{tax_group_name}"})
+
+ openupgrade.logged_query(
+ env.cr,
+ f"""
+ UPDATE account_tax
+ SET tax_group_id = {new_tax_group.id}
+ WHERE tax_group_id = {tax_group.id} AND company_id = {company_id}
+ """,
+ )
+
+ convert_from_company_dependent(
+ env,
+ "account.tax.group",
+ "property_tax_receivable_account_id",
+ "tax_receivable_account_id",
+ origin_id_column,
+ )
+ convert_from_company_dependent(
+ env,
+ "account.tax.group",
+ "property_tax_payable_account_id",
+ "tax_payable_account_id",
+ origin_id_column,
+ )
+ convert_from_company_dependent(
+ env,
+ "account.tax.group",
+ "property_advance_tax_payment_account_id",
+ "advance_tax_payment_account_id",
+ origin_id_column,
+ )
+
+
+def _force_install_account_payment_term_module_module(env):
+ """
+ Force install account_payment_term if we need
+ key 'days_end_of_month_on_the' of it
+ it has already merged in odoo master
+ """
+ account_payment_term_module = env["ir.module.module"].search(
+ [("name", "=", "account_payment_term")]
+ )
+ needs_account_payment_term = bool(
+ env["account.payment.term.line"].search(
+ [("delay_type", "=", "days_end_of_month_on_the")], limit=1
+ )
+ )
+ if needs_account_payment_term and account_payment_term_module:
+ account_payment_term_module.state = "to install"
+ openupgrade.copy_columns(
+ env.cr,
+ {
+ "account_payment_term_line": [
+ ("days_after", "days_next_month", "CHARACTER VARYING")
+ ]
+ },
+ )
+ openupgrade.logged_query(
+ env.cr,
+ """
+ UPDATE account_payment_term_line
+ SET
+ nb_days = nb_days - days_after,
+ days_next_month = days_after
+ WHERE delay_type = 'days_end_of_month_on_the'
+ """,
+ )
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+ _account_payment_term_migration(env)
+ _account_payment_term_early_payment_discount(env)
+ _force_install_account_payment_term_module_module(env)
+ openupgrade.load_data(env, "account", "17.0.1.2/noupdate_changes.xml")
+ openupgrade.delete_records_safely_by_xml_id(
+ env,
+ _deleted_xml_records,
+ )
+ _am_update_invoice_pdf_report_file(env)
+ _onboarding_state_migration(env)
+ _account_tax_group_migration(env)
diff --git a/openupgrade_scripts/scripts/account/17.0.1.2/pre-migration.py b/openupgrade_scripts/scripts/account/17.0.1.2/pre-migration.py
new file mode 100644
index 000000000000..4142edbef0a7
--- /dev/null
+++ b/openupgrade_scripts/scripts/account/17.0.1.2/pre-migration.py
@@ -0,0 +1,355 @@
+# Copyright 2024 Viindoo Technology Joint Stock Company (Viindoo)
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+from openupgradelib import openupgrade
+
+from odoo.tools.sql import convert_column_translatable
+
+_fields_renames = [
+ (
+ "res.company",
+ "res_company",
+ "invoice_is_print",
+ "invoice_is_download",
+ ),
+]
+
+COA_MAPPING = {
+ "l10n_ae.uae_chart_template_standard": "ae",
+ "l10n_ar.l10nar_base_chart_template": "ar_base",
+ "l10n_ar.l10nar_ex_chart_template": "ar_ex",
+ "l10n_ar.l10nar_ri_chart_template": "ar_ri",
+ "l10n_at.l10n_at_chart_template": "at",
+ "l10n_au.l10n_au_chart_template": "au",
+ "l10n_be.l10nbe_chart_template": "be_comp",
+ "l10n_bg.l10n_bg_chart_template": "bg",
+ "l10n_bo.bo_chart_template": "bo",
+ "l10n_br.l10n_br_account_chart_template": "br",
+ "l10n_ca.ca_en_chart_template_en": "ca_2023",
+ "l10n_ch.l10nch_chart_template": "ch",
+ "l10n_cl.cl_chart_template": "cl",
+ "l10n_cn.l10n_chart_china_small_business": "cn",
+ "l10n_co.l10n_co_chart_template_generic": "co",
+ "l10n_cr.account_chart_template_0": "cr",
+ "l10n_cz.cz_chart_template": "cz",
+ "l10n_de.l10n_de_chart_template": "de_skr03",
+ "l10n_de.l10n_chart_de_skr04": "de_skr04",
+ "l10n_de_skr03.l10n_de_chart_template": "de_skr03",
+ "l10n_de_skr04.l10n_chart_de_skr04": "de_skr04",
+ "l10n_dk.dk_chart_template": "dk",
+ "l10n_do.do_chart_template": "do",
+ "l10n_dz.l10n_dz_pcg_chart_template": "dz",
+ "l10n_ec.l10n_ec_ifrs": "ec",
+ "l10n_ee.l10nee_chart_template": "ee",
+ "l10n_eg.egypt_chart_template_standard": "eg",
+ "l10n_es.account_chart_template_assoc": "es_assec",
+ "l10n_es.account_chart_template_common": "es_common",
+ "l10n_es.account_chart_template_full": "es_full",
+ "l10n_es.account_chart_template_pymes": "es_pymes",
+ "l10n_et.l10n_et": "et",
+ "l10n_fi.fi_chart_template": "fi",
+ "l10n_fr.l10n_fr_pcg_chart_template": "fr",
+ "l10n_generic_coa.configurable_chart_template": "generic_coa",
+ "l10n_gr.l10n_gr_chart_template": "gr",
+ "l10n_gt.cuentas_plantilla": "gt",
+ "l10n_hk.l10n_hk_chart_template": "hk",
+ "l10n_hn.cuentas_plantilla": "hn",
+ "l10n_hr.l10n_hr_chart_template_rrif": "hr",
+ "l10n_hr.l10n_hr_euro_chart_template": "hr",
+ "l10n_hr_kuna.l10n_hr_kuna_chart_template_rrif": "hr_kuna",
+ "l10n_hu.hungarian_chart_template": "hu",
+ "l10n_id.l10n_id_chart": "id",
+ "l10n_ie.l10n_ie": "ie",
+ "l10n_il.il_chart_template": "il",
+ "l10n_in.indian_chart_template_standard": "in",
+ "l10n_it.l10n_it_chart_template_generic": "it",
+ "l10n_jp.l10n_jp1": "jp",
+ "l10n_jp.l10n_jp_chart_template": "jp",
+ "l10n_ke.l10nke_chart_template": "ke",
+ "l10n_kz.l10nkz_chart_template": "kz",
+ "l10n_lt.account_chart_template_lithuania": "lt",
+ "l10n_lu.lu_2011_chart_1": "lu",
+ "l10n_lv.chart_template_latvia": "lv",
+ "l10n_ma.l10n_ma_chart_template": "ma",
+ "l10n_mn.mn_chart_1": "mn",
+ "l10n_mx.mx_coa": "mx",
+ "l10n_my.l10n_my_chart_template": "my",
+ "l10n_mz.l10n_mz_chart_template": "mz",
+ "l10n_nl.l10nnl_chart_template": "nl",
+ "l10n_no.no_chart_template": "no",
+ "l10n_nz.l10n_nz_chart_template": "nz",
+ "l10n_pa.l10npa_chart_template": "pa",
+ "l10n_pe.pe_chart_template": "pe",
+ "l10n_ph.l10n_ph_chart_template": "ph",
+ "l10n_pk.l10n_pk_chart_template": "pk",
+ "l10n_pl.pl_chart_template": "pl",
+ "l10n_pt.pt_chart_template": "pt",
+ "l10n_ro.ro_chart_template": "ro",
+ "l10n_rs.l10n_rs_chart_template": "rs",
+ "l10n_sa.sa_chart_template_standard": "sa",
+ "l10n_se.l10nse_chart_template": "se",
+ "l10n_se.l10nse_chart_template_K2": "se_K2",
+ "l10n_se.l10nse_chart_template_K3": "se_K3",
+ "l10n_sg.sg_chart_template": "sg",
+ "l10n_si.gd_chart": "si",
+ "l10n_sk.sk_chart_template": "sk",
+ "l10n_syscohada.syscohada_chart_template": "syscohada",
+ "l10n_th.chart": "th",
+ "l10n_tr.chart_template_common": "tr",
+ "l10n_tr.l10n_tr_chart_template": "tr",
+ "l10n_tw.l10n_tw_chart_template": "tw",
+ "l10n_ua.l10n_ua_ias_chart_template": "ua_ias",
+ "l10n_ua.l10n_ua_psbo_chart_template": "ua_psbo",
+ "l10n_uk.l10n_uk": "uk",
+ "l10n_uy.uy_chart_template": "uy",
+ "l10n_ve.ve_chart_template_amd": "ve",
+ "l10n_vn.vn_template": "vn",
+ "l10n_za.default_chart_template": "za",
+}
+
+_l10n_generic_coa_tax_group_xmlid = [
+ "l10n_generic_coa.tax_group_15",
+]
+
+_l10n_generic_coa_tax_xmlid = [
+ "l10n_generic_coa.sale_tax_template",
+ "l10n_generic_coa.purchase_tax_template",
+]
+
+
+def _map_account_report_filter_account_type(env):
+ openupgrade.rename_columns(
+ env.cr, {"account_report": [("filter_account_type", None)]}
+ )
+ openupgrade.logged_query(
+ env.cr,
+ """
+ ALTER TABLE account_report
+ ADD COLUMN filter_account_type character varying;
+ """,
+ )
+ openupgrade.logged_query(
+ env.cr,
+ f"""
+ UPDATE account_report
+ SET filter_account_type = CASE
+ WHEN {openupgrade.get_legacy_name('filter_account_type')} THEN 'both'
+ ELSE 'disabled'
+ END
+ """,
+ )
+
+
+def _map_chart_template_id_to_chart_template(
+ env, model, coa_m2o="chart_template_id", coa_str="chart_template"
+):
+ openupgrade.logged_query(
+ env.cr,
+ f"""
+ ALTER TABLE {model}
+ ADD COLUMN {coa_str} character varying;
+ """,
+ )
+ env.cr.execute(
+ f"""SELECT m.id AS m_id, CONCAT(imd.module, '.', imd.name) AS coa_xml_id
+ FROM {model} m
+ JOIN ir_model_data imd
+ ON imd.model='account.chart.template'
+ AND m.{coa_m2o} = imd.res_id
+ WHERE m.{coa_m2o} IS NOT NULL
+ """
+ )
+ for line in env.cr.dictfetchall():
+ if line["coa_xml_id"] in COA_MAPPING:
+ openupgrade.logged_query(
+ env.cr,
+ f"""
+ UPDATE {model}
+ SET {coa_str} = '{COA_MAPPING[line['coa_xml_id']]}'
+ WHERE id = {line['m_id']}
+ """,
+ )
+
+
+def _generic_coa_rename_xml_id(env):
+ """
+ Since the removal of account.chart.template
+ we need to rename some xml_id like tax or tax.group
+ in order to avoid duplication
+ """
+ env.cr.execute(
+ """SELECT id, name FROM res_company WHERE chart_template = 'generic_coa'"""
+ )
+ xmlids_renames = []
+ for company_id, _ in env.cr.fetchall():
+ if company_id == env.company.id:
+ for tax_group_xmlid in _l10n_generic_coa_tax_group_xmlid:
+ new_xmlid = f"account.{company_id}_" + tax_group_xmlid.split(".")[1]
+ xmlids_renames.append((tax_group_xmlid, new_xmlid))
+ for tax_xmlid in _l10n_generic_coa_tax_xmlid:
+ old_xmlid = f"l10n_generic_coa.{company_id}_" + tax_xmlid.split(".")[1]
+ new_xmlid = f"account.{company_id}_" + tax_xmlid.split(".")[1]
+ xmlids_renames.append((old_xmlid, new_xmlid))
+ openupgrade.rename_xmlids(env.cr, xmlids_renames)
+
+
+def _convert_account_tax_description(env):
+ openupgrade.rename_columns(env.cr, {"account_tax": [("description", None)]})
+ openupgrade.logged_query(env.cr, "ALTER TABLE account_tax ADD description JSONB")
+ openupgrade.logged_query(
+ env.cr,
+ f"""UPDATE account_tax
+ SET description = {'en_US': {openupgrade.get_legacy_name('description')}}
+ """,
+ )
+
+
+def _am_create_delivery_date_column(env):
+ """
+ Create column then in module need them like l10n_de and sale_stock will fill value,
+ https://github.com/odoo/odoo/pull/116643
+ """
+ openupgrade.logged_query(
+ env.cr,
+ """
+ ALTER TABLE account_move
+ ADD COLUMN IF NOT EXISTS delivery_date DATE
+ """,
+ )
+
+
+def _am_create_incoterm_location_column(env):
+ """
+ Create column then in sale_stock, purchase_stock will fill it in pre,
+ pr: https://github.com/odoo/odoo/pull/118954
+ """
+ openupgrade.logged_query(
+ env.cr,
+ """
+ ALTER TABLE account_move
+ ADD COLUMN IF NOT EXISTS incoterm_location CHARACTER VARYING
+ """,
+ )
+
+
+def _am_uniquify_name(env):
+ """
+ Make move names unique per journal to satisfy the constraint v17 creates
+ """
+ openupgrade.logged_query(
+ env.cr,
+ """
+ UPDATE account_move SET name=name || ' [' || id || ']'
+ FROM (
+ SElECT array_agg(id) ids FROM account_move
+ GROUP BY journal_id, name HAVING COUNT(id)>1
+ ) duplicate_names
+ WHERE account_move.id=ANY(duplicate_names.ids);
+ """,
+ )
+
+
+def _account_report_update_figure_type(env):
+ openupgrade.copy_columns(
+ env.cr,
+ {
+ "account_report_column": [("figure_type", None, None)],
+ "account_report_expression": [("figure_type", None, None)],
+ },
+ )
+ old_column = openupgrade.get_legacy_name("figure_type")
+ openupgrade.map_values(
+ env.cr,
+ old_column,
+ "figure_type",
+ {"none": "string"},
+ False,
+ "account_report_column",
+ )
+ openupgrade.map_values(
+ env.cr,
+ old_column,
+ "figure_type",
+ {"none": "string"},
+ False,
+ "account_report_expression",
+ )
+
+
+def _account_tax_repartition_line_merge_repartition_lines_m2o(env):
+ openupgrade.logged_query(
+ env.cr,
+ """
+ ALTER TABLE account_tax_repartition_line
+ ADD COLUMN IF NOT EXISTS document_type VARCHAR,
+ ADD COLUMN IF NOT EXISTS tax_id INTEGER;
+ """,
+ )
+ openupgrade.logged_query(
+ env.cr,
+ """
+ UPDATE account_tax_repartition_line
+ SET document_type = CASE
+ WHEN invoice_tax_id IS NOT NULL THEN 'invoice'
+ WHEN refund_tax_id IS NOT NULL THEN 'refund'
+ END,
+ tax_id = CASE
+ WHEN invoice_tax_id IS NOT NULL THEN invoice_tax_id
+ WHEN refund_tax_id IS NOT NULL THEN refund_tax_id
+ END
+ """,
+ )
+
+
+def _res_partner_bank_create_column(env):
+ openupgrade.logged_query(
+ env.cr,
+ """
+ ALTER TABLE res_partner_bank
+ ADD COLUMN IF NOT EXISTS has_iban_warning BOOLEAN,
+ ADD COLUMN IF NOT EXISTS has_money_transfer_warning BOOLEAN;
+ """,
+ )
+
+
+def _pre_create_early_pay_discount_computation(env):
+ """Avoid triggering the computed method and fill the corresponding value from
+ companies.
+ """
+ openupgrade.logged_query(
+ env.cr, "ALTER TABLE res_company ADD early_pay_discount_computation VARCHAR"
+ )
+ openupgrade.logged_query(
+ env.cr,
+ """
+ UPDATE account_payment_term apt
+ SET early_pay_discount_computation = com.early_pay_discount_computation
+ FROM res_company rc
+ WHERE apt.company_id = rc.id
+ """,
+ )
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+ _map_account_report_filter_account_type(env)
+ _map_chart_template_id_to_chart_template(env, "res_company")
+ _map_chart_template_id_to_chart_template(env, "account_report")
+ _generic_coa_rename_xml_id(env)
+ # Drop triagram index on name column of account.account
+ # to avoid error when loading registry, it will be recreated
+ openupgrade.logged_query(
+ env.cr,
+ """
+ DROP INDEX IF EXISTS account_account_name_index;
+ """,
+ )
+ openupgrade.rename_fields(env, _fields_renames)
+ convert_column_translatable(env.cr, "account_tax", "description", "jsonb")
+ _convert_account_tax_description(env)
+ _am_create_delivery_date_column(env)
+ _am_create_incoterm_location_column(env)
+ _am_uniquify_name(env)
+ _account_report_update_figure_type(env)
+ _account_tax_repartition_line_merge_repartition_lines_m2o(env)
+ _res_partner_bank_create_column(env)
+ _pre_create_early_pay_discount_computation(env)
diff --git a/openupgrade_scripts/scripts/account/17.0.1.2/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/account/17.0.1.2/upgrade_analysis_work.txt
new file mode 100644
index 000000000000..a7ebff7df77d
--- /dev/null
+++ b/openupgrade_scripts/scripts/account/17.0.1.2/upgrade_analysis_work.txt
@@ -0,0 +1,507 @@
+---Models in module 'account'---
+obsolete model account.account.template
+obsolete model account.fiscal.position.account.template
+obsolete model account.fiscal.position.tax.template
+obsolete model account.fiscal.position.template
+obsolete model account.group.template
+obsolete model account.reconcile.model.line.template
+obsolete model account.reconcile.model.template
+obsolete model account.tax.repartition.line.template
+obsolete model account.tax.template
+# NOTHING TO DO: these models has been converted to CSV definition and existing company records XML-ID follow the same logic
+
+obsolete model account.invoice.send [transient]
+new model account.move.send [transient]
+# NOTHING TO DO: Replaced feature, but nothing to transfer, being transient models
+
+---Fields in module 'account'---
+account / account.account / _order : _order is now 'code, company_id' ('is_off_balance, code, company_id')
+account / account.account / is_off_balance (boolean) : DEL
+# NOTHING TO DO: is_off_balance dissapears, but nobody will miss it, as it was underused and even incorrect (due to blocking certain operations)
+
+account / account.account / message_main_attachment_id (many2one): DEL relation: ir.attachment
+# NOTHING TO DO: Feature not used in general
+
+account / account.account / rating_ids (one2many) : NEW relation: rating.rating
+# NOTHING TO DO: New feature
+
+account / account.account.template / account_type (selection) : DEL selection_keys: ['asset_cash', 'asset_current', 'asset_fixed', 'asset_non_current', 'asset_prepayments', 'asset_receivable', 'equity', 'equity_unaffected', 'expense', 'expense_depreciation', 'expense_direct_cost', 'income', 'income_other', 'liability_credit_card', 'liability_current', 'liability_non_current', 'liability_payable', 'off_balance']
+account / account.account.template / chart_template_id (many2one) : DEL relation: account.chart.template
+account / account.account.template / code (char) : DEL required
+account / account.account.template / currency_id (many2one) : DEL relation: res.currency
+account / account.account.template / message_follower_ids (one2many): DEL relation: mail.followers
+account / account.account.template / message_ids (one2many) : DEL relation: mail.message
+account / account.account.template / message_main_attachment_id (many2one): DEL relation: ir.attachment
+account / account.account.template / name (char) : DEL required
+account / account.account.template / nocreate (boolean) : DEL
+account / account.account.template / note (text) : DEL
+account / account.account.template / reconcile (boolean) : DEL
+account / account.account.template / tag_ids (many2many) : DEL relation: account.account.tag
+account / account.account.template / tax_ids (many2many) : DEL relation: account.tax.template
+account / account.account.template / website_message_ids (one2many): DEL relation: mail.message
+account / account.bank.statement.line / amount_total_words (char) : previously in module l10n_dz
+account / account.bank.statement.line / transaction_details (json) : NEW
+account / account.chart.template / account_ids (one2many) : DEL relation: account.account.template
+account / account.chart.template / account_journal_early_pay_discount_gain_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / account_journal_early_pay_discount_loss_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / account_journal_payment_credit_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / account_journal_payment_debit_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / account_journal_suspense_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / bank_account_code_prefix (char): DEL required
+account / account.chart.template / cash_account_code_prefix (char): DEL required
+account / account.chart.template / code_digits (integer) : DEL required
+account / account.chart.template / country_id (many2one) : DEL relation: res.country
+account / account.chart.template / currency_id (many2one) : DEL relation: res.currency, required
+account / account.chart.template / default_cash_difference_expense_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / default_cash_difference_income_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / default_pos_receivable_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / expense_currency_exchange_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / income_currency_exchange_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / name (char) : DEL required
+account / account.chart.template / parent_id (many2one) : DEL relation: account.chart.template
+account / account.chart.template / property_account_expense_categ_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_account_expense_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_account_income_categ_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_account_income_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_account_payable_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_account_receivable_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_advance_tax_payment_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_cash_basis_base_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_stock_account_input_categ_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_stock_account_output_categ_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_stock_valuation_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_tax_payable_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / property_tax_receivable_account_id (many2one): DEL relation: account.account.template
+account / account.chart.template / tax_template_ids (one2many) : DEL relation: account.tax.template
+account / account.chart.template / transfer_account_code_prefix (char): DEL required
+account / account.chart.template / use_anglo_saxon (boolean) : DEL
+account / account.chart.template / use_storno_accounting (boolean): DEL
+account / account.chart.template / visible (boolean) : DEL
+account / account.fiscal.position.account.template / account_dest_id (many2one) : DEL relation: account.account.template, required
+account / account.fiscal.position.account.template / account_src_id (many2one) : DEL relation: account.account.template, required
+account / account.fiscal.position.account.template / position_id (many2one) : DEL relation: account.fiscal.position.template, required
+account / account.fiscal.position.tax.template / position_id (many2one) : DEL relation: account.fiscal.position.template, required
+account / account.fiscal.position.tax.template / tax_dest_id (many2one) : DEL relation: account.tax.template
+account / account.fiscal.position.tax.template / tax_src_id (many2one) : DEL relation: account.tax.template, required
+account / account.fiscal.position.template / account_ids (one2many) : DEL relation: account.fiscal.position.account.template
+account / account.fiscal.position.template / auto_apply (boolean) : DEL
+account / account.fiscal.position.template / chart_template_id (many2one) : DEL relation: account.chart.template, required
+account / account.fiscal.position.template / country_group_id (many2one) : DEL relation: res.country.group
+account / account.fiscal.position.template / country_id (many2one) : DEL relation: res.country
+account / account.fiscal.position.template / name (char) : DEL required
+account / account.fiscal.position.template / note (text) : DEL
+account / account.fiscal.position.template / sequence (integer) : DEL
+account / account.fiscal.position.template / state_ids (many2many) : DEL relation: res.country.state
+account / account.fiscal.position.template / tax_ids (one2many) : DEL relation: account.fiscal.position.tax.template
+account / account.fiscal.position.template / vat_required (boolean) : DEL
+account / account.fiscal.position.template / zip_from (char) : DEL
+account / account.fiscal.position.template / zip_to (char) : DEL
+account / account.group.template / chart_template_id (many2one) : DEL relation: account.chart.template, required
+account / account.group.template / code_prefix_end (char) : DEL
+account / account.group.template / code_prefix_start (char) : DEL
+account / account.group.template / name (char) : DEL required
+account / account.group.template / parent_id (many2one) : DEL relation: account.group.template
+# NOTHING TO DO: These models has been converted to CSV definition and existing company records XML-ID follow the same logic
+
+account / account.full.reconcile / name (char) : DEL required
+account / account.move.line / matching_number (char) : not a function anymore
+# NOTHING TO DO: The matching is now expressed through the record ID stored in the aml, instead of a sequence stored in the afr, so no real feature loss
+
+account / account.journal / access_token (char) : NEW
+# NOTHING TO DO: It's filled dynamically when the content is shared
+
+account / account.journal / activity_user_id (many2one) : not related anymore
+account / account.journal / activity_user_id (many2one) : now a function
+account / account.journal / alias_domain (char) : not a function anymore
+account / account.journal / alias_domain (char) : now related
+account / account.journal / alias_name (char) : not a function anymore
+account / account.journal / alias_name (char) : now related
+# NOTHING TO DO: Changes on the underlying mixins, but without impact
+
+account / account.journal / message_main_attachment_id (many2one): DEL relation: ir.attachment
+# NOTHING TO DO: Non used feature removed
+
+account / account.journal / rating_ids (one2many) : NEW relation: rating.rating
+# NOTHING TO DO: New feature (not used, but brought by inheritance)
+
+account / account.move / _order : _order is now 'date desc, name desc, invoice_date desc, id desc' ('date desc, name desc, id desc')
+# NOTHING TO DO: Criteria order added, but in third place, not impacting in usual cases
+
+account / account.move / activity_user_id (many2one) : not related anymore
+account / account.move / activity_user_id (many2one) : now a function
+# NOTHING TO DO: Changes on the underlying mixins, but without impact
+
+account / account.move / amount_total_words (char) : previously in module l10n_dz
+# NOTHING TO DO: compute no store
+
+account / account.move / delivery_date (date) : NEW isfunction: function, stored
+# DONE: pre-migration: Pre-create the column for not triggering the method. Modules modifying the computation (l10n_de and sale_stock) will fill the value. More info at https://github.com/odoo/odoo/pull/116643
+
+account / account.move / incoterm_location (char) : NEW hasdefault: compute
+# DONE: pre-migration: Pre-create the column for not triggering the method. Modules modifying the computation (sale_stock and purchase_stock) will fill the value. More info at https://github.com/odoo/odoo/pull/118954
+
+account / account.move / invoice_pdf_report_file (binary): NEW attachment: True
+# DONE: post-migration: update message_main_attachment_id with res_field and res_id of each invoice, see '_link_invoice_documents' in 'account.move.send'
+
+account / account.move / rating_ids (one2many) : NEW relation: rating.rating
+# NOTHING TO DO: New feature by inheritance (although not used)
+
+account / account.move / send_and_print_values (json) : NEW
+# NOTHING TO DO: This field is for storing transient data to indicate that the invoice is "programmed" to be sent, which is a new feature, so empty is OK.
+
+account / account.move.line / discount_percentage (float) : DEL
+# NOTHING TO DO: Auxiliary field for Early Payment discounts from payment terms that seems unused.
+
+account / account.move.line / display_type (selection) : selection_keys is now '['cogs', 'discount', 'epd', 'line_note', 'line_section', 'payment_term', 'product', 'rounding', 'tax']' ('['cogs', 'epd', 'line_note', 'line_section', 'payment_term', 'product', 'rounding', 'tax']')
+# NOTHING TO DO: new feature "Discount allocation" https://github.com/odoo/odoo/pull/133286
+
+account / account.move.line / invoice_date (date) : NEW isrelated: related, stored
+# NOTHING TO DO: ORM resolves by SQL this filling being a direct related field with 1 level depth.
+
+account / account.move.line / tax_audit (char) : DEL
+# NOTHING TO DO: deprecated
+
+account / account.partial.reconcile / company_id (many2one) : not related anymore
+# NOTHING TO DO
+
+account / account.payment / activity_user_id (many2one) : not related anymore
+account / account.payment / activity_user_id (many2one) : now a function
+# NOTHING TO DO: New feature by inheritance.
+
+account / account.payment / amount_total_words (char) : previously in module l10n_dz
+# NOTHING TO DO: Compute non stored field.
+
+account / account.payment / rating_ids (one2many) : NEW relation: rating.rating
+# NOTHING TO DO: New feature by inheritance.
+
+account / account.payment / qr_code (char) : type is now 'html' ('char')
+# NOTHING TO DO: no store field
+
+account / account.payment.term / discount_days (integer) : NEW hasdefault: default
+account / account.payment.term / discount_percentage (float) : NEW hasdefault: default
+account / account.payment.term / early_discount (boolean) : NEW
+account / account.payment.term.line / discount_days (integer) : DEL
+account / account.payment.term.line / discount_percentage (float) : DEL
+# DONE: post-migration: Transfer when possible the early payment discount from lines to header.
+
+account / account.payment.term / early_pay_discount_computation (selection): NEW selection_keys: ['excluded', 'included', 'mixed'], hasdefault: compute
+account / res.company / early_pay_discount_computation (selection): DEL selection_keys: ['excluded', 'included', 'mixed']
+# DONE: pre-migration: Pre-create the column for avoiding triggering the compute and transfer data from companies to all the payment terms.
+
+account / account.payment.term / currency_id (many2one) : NEW relation: res.currency, hasdefault: default
+# NOTHING TO DO: Compute non stored
+
+account / account.payment.term.line / days (integer) : DEL required
+account / account.payment.term.line / days_after (integer) : DEL
+account / account.payment.term.line / delay_type (selection) : NEW required, selection_keys: ['days_after', 'days_after_end_of_month', 'days_after_end_of_next_month'], hasdefault: default
+account / account.payment.term.line / end_month (boolean) : DEL
+account / account.payment.term.line / months (integer) : DEL required
+account / account.payment.term.line / nb_days (integer) : NEW hasdefault: compute
+account / account.payment.term.line / value (selection) : selection_keys is now '['fixed', 'percent']' ('['balance', 'fixed', 'percent']')
+# DONE: post-migration: convert columns, type and percentage https://github.com/odoo/odoo/pull/110274/
+
+account / account.reconcile.model / message_main_attachment_id (many2one): DEL relation: ir.attachment
+account / account.reconcile.model / rating_ids (one2many) : NEW relation: rating.rating
+account / account.reconcile.model.line.template / account_id (many2one) : DEL relation: account.account.template
+account / account.reconcile.model.line.template / amount_string (char) : DEL
+account / account.reconcile.model.line.template / amount_type (selection) : DEL required, selection_keys: ['fixed', 'percentage', 'regex']
+account / account.reconcile.model.line.template / force_tax_included (boolean) : DEL
+account / account.reconcile.model.line.template / label (char) : DEL
+account / account.reconcile.model.line.template / model_id (many2one) : DEL relation: account.reconcile.model.template
+account / account.reconcile.model.line.template / sequence (integer) : DEL required
+account / account.reconcile.model.line.template / tax_ids (many2many) : DEL relation: account.tax.template
+account / account.reconcile.model.template / allow_payment_tolerance (boolean): DEL
+account / account.reconcile.model.template / auto_reconcile (boolean) : DEL
+account / account.reconcile.model.template / chart_template_id (many2one) : DEL relation: account.chart.template, required
+account / account.reconcile.model.template / decimal_separator (char) : DEL
+account / account.reconcile.model.template / line_ids (one2many) : DEL relation: account.reconcile.model.line.template
+account / account.reconcile.model.template / match_amount (selection) : DEL selection_keys: ['between', 'greater', 'lower']
+account / account.reconcile.model.template / match_amount_max (float) : DEL
+account / account.reconcile.model.template / match_amount_min (float) : DEL
+account / account.reconcile.model.template / match_journal_ids (many2many) : DEL relation: account.journal
+account / account.reconcile.model.template / match_label (selection) : DEL selection_keys: ['contains', 'match_regex', 'not_contains']
+account / account.reconcile.model.template / match_label_param (char) : DEL
+account / account.reconcile.model.template / match_nature (selection) : DEL required, selection_keys: ['amount_paid', 'amount_received', 'both']
+account / account.reconcile.model.template / match_note (selection) : DEL selection_keys: ['contains', 'match_regex', 'not_contains']
+account / account.reconcile.model.template / match_note_param (char) : DEL
+account / account.reconcile.model.template / match_partner (boolean) : DEL
+account / account.reconcile.model.template / match_partner_category_ids (many2many): DEL relation: res.partner.category
+account / account.reconcile.model.template / match_partner_ids (many2many) : DEL relation: res.partner
+account / account.reconcile.model.template / match_same_currency (boolean) : DEL
+account / account.reconcile.model.template / match_text_location_label (boolean): DEL
+account / account.reconcile.model.template / match_text_location_note (boolean): DEL
+account / account.reconcile.model.template / match_text_location_reference (boolean): DEL
+account / account.reconcile.model.template / match_transaction_type (selection): DEL selection_keys: ['contains', 'match_regex', 'not_contains']
+account / account.reconcile.model.template / match_transaction_type_param (char): DEL
+account / account.reconcile.model.template / matching_order (selection) : DEL selection_keys: ['new_first', 'old_first']
+account / account.reconcile.model.template / name (char) : DEL required
+account / account.reconcile.model.template / payment_tolerance_param (float): DEL
+account / account.reconcile.model.template / payment_tolerance_type (selection): DEL required, selection_keys: ['fixed_amount', 'percentage']
+account / account.reconcile.model.template / rule_type (selection) : DEL required, selection_keys: ['invoice_matching', 'writeoff_button', 'writeoff_suggestion']
+account / account.reconcile.model.template / sequence (integer) : DEL required
+account / account.reconcile.model.template / to_check (boolean) : DEL
+account / account.report / _order : _order is now 'sequence, id' ('id')
+account / account.report / active (boolean) : NEW hasdefault: default
+# NOTHING TO DO
+
+account / account.report / chart_template (selection) : NEW selection_keys: function
+account / account.report / chart_template_id (many2one) : DEL relation: account.chart.template
+# DONE: map chart_template_id > chart_template in pre-migration
+
+account / account.report / default_opening_date_filter (selection): selection_keys is now '['last_month', 'last_quarter', 'last_tax_period', 'last_year', 'this_month', 'this_quarter', 'this_tax_period', 'this_year', 'today']' ('['last_month', 'last_quarter', 'last_year', 'this_month', 'this_quarter', 'this_year', 'today']')
+# NOTHING TO DO: new feature
+
+account / account.report / filter_account_type (boolean) : selection_keys is now '['both', 'disabled', 'payable', 'receivable']' ('False')
+account / account.report / filter_account_type (boolean) : type is now 'selection' ('boolean')
+# DONE: pre-migration: map False > disabled and True > both.
+
+account / account.report / filter_aml_ir_filters (boolean): NEW hasdefault: compute
+account / account.report / filter_hide_0_lines (selection): NEW selection_keys: ['by_default', 'never', 'optional'], hasdefault: compute
+account / account.report / prefix_groups_threshold (integer): NEW
+account / account.report / section_main_report_ids (many2many): NEW relation: account.report
+account / account.report / section_report_ids (many2many): NEW relation: account.report
+account / account.report / sequence (integer) : NEW
+account / account.report / use_sections (boolean) : NEW hasdefault: compute
+account / account.report.external.value / text_value (char) : NEW
+account / account.report.line / external_formula (char) : NEW
+account / account.report.line / user_groupby (char) : NEW
+# NOTHING TO DO: probably need to do in module that add Localization report
+
+account / account.report.column / figure_type (selection) : selection_keys is now '['boolean', 'date', 'datetime', 'float', 'integer', 'monetary', 'percentage', 'string']' ('['date', 'datetime', 'float', 'integer', 'monetary', 'none', 'percentage']')
+account / account.report.expression / figure_type (selection) : selection_keys is now '['boolean', 'date', 'datetime', 'float', 'integer', 'monetary', 'percentage', 'string']' ('['date', 'datetime', 'float', 'integer', 'monetary', 'none', 'percentage']')
+# DONE pre-migration: copy column for preservation and update none -> string
+
+account / account.tax / invoice_label (char) : NEW
+# DONE pre-migration: create jsonb column(because translate=True) and fill value with 'description' field https://github.com/odoo/odoo/pull/113236
+
+account / account.tax / message_follower_ids (one2many): NEW relation: mail.followers
+account / account.tax / message_ids (one2many) : NEW relation: mail.message
+account / account.tax / rating_ids (one2many) : NEW relation: rating.rating
+# NOTHING TO DO
+
+account / account.tax / real_amount (float) : DEL
+# NOTHING TO DO
+
+account / account.tax / repartition_line_ids (one2many): NEW relation: account.tax.repartition.line
+# NOTHING TO DO: https://github.com/odoo/odoo/pull/110016/commits/a4c1f62ebd2710b3810c2d01195d88e4a9f13a9f
+
+account / account.tax / website_message_ids (one2many): NEW relation: mail.messag
+# NOTHING TO DO
+
+account / account.tax.group / advance_tax_payment_account_id (many2one): NEW relation: account.account
+account / account.tax.group / property_advance_tax_payment_account_id (many2one): DEL relation: account.account
+account / account.tax.group / property_tax_payable_account_id (many2one): DEL relation: account.account
+account / account.tax.group / property_tax_receivable_account_id (many2one): DEL relation: account.account
+account / account.tax.group / tax_payable_account_id (many2one): NEW relation: account.account
+account / account.tax.group / tax_receivable_account_id (many2one): NEW relation: account.account
+# DONE pre-migration: update value base on ir.property
+
+account / account.tax.group / company_id (many2one) : NEW relation: res.company, required, hasdefault: default
+# DONE pre-migration: create column and fill value base on account.tax
+
+account / account.tax.repartition.line / _order : _order is now 'document_type, repartition_type, sequence, id' ('sequence, repartition_type, id')
+account / account.tax.repartition.line / company_id (many2one) : not a function anymore
+account / account.tax.repartition.line / company_id (many2one) : now related
+# NOTHING TO DO
+
+account / account.tax.repartition.line / document_type (selection) : is now stored
+account / account.tax.repartition.line / document_type (selection) : not a function anymore
+account / account.tax.repartition.line / document_type (selection) : now required
+account / account.tax.repartition.line / invoice_tax_id (many2one) : DEL relation: account.tax
+account / account.tax.repartition.line / refund_tax_id (many2one) : DEL relation: account.tax
+account / account.tax.repartition.line / tax_id (many2one) : is now stored
+account / account.tax.repartition.line / tax_id (many2one) : not a function anymore
+# DONE : fill document_type and tax_id base on invoice_tax_id and refund_tax_id https://github.com/odoo/odoo/pull/110016/commits/a4c1f62ebd2710b3810c2d01195d88e4a9f13a9f
+
+account / account.tax.repartition.line.template / account_id (many2one) : DEL relation: account.account.template
+account / account.tax.repartition.line.template / factor_percent (float) : DEL required
+account / account.tax.repartition.line.template / invoice_tax_id (many2one) : DEL relation: account.tax.template
+account / account.tax.repartition.line.template / minus_report_expression_ids (many2many): DEL relation: account.report.expression
+account / account.tax.repartition.line.template / plus_report_expression_ids (many2many): DEL relation: account.report.expression
+account / account.tax.repartition.line.template / refund_tax_id (many2one) : DEL relation: account.tax.template
+account / account.tax.repartition.line.template / repartition_type (selection) : DEL required, selection_keys: ['base', 'tax']
+account / account.tax.repartition.line.template / tag_ids (many2many) : DEL relation: account.account.tag
+account / account.tax.repartition.line.template / use_in_tax_closing (boolean) : DEL
+account / account.tax.template / active (boolean) : DEL
+account / account.tax.template / amount (float) : DEL required
+account / account.tax.template / amount_type (selection) : DEL required, selection_keys: ['division', 'fixed', 'group', 'percent']
+account / account.tax.template / analytic (boolean) : DEL
+account / account.tax.template / cash_basis_transition_account_id (many2one): DEL relation: account.account.template
+account / account.tax.template / chart_template_id (many2one) : DEL relation: account.chart.template, required
+account / account.tax.template / children_tax_ids (many2many) : DEL relation: account.tax.template
+account / account.tax.template / description (char) : DEL
+account / account.tax.template / include_base_amount (boolean) : DEL
+account / account.tax.template / invoice_repartition_line_ids (one2many): DEL relation: account.tax.repartition.line.template
+account / account.tax.template / is_base_affected (boolean) : DEL
+account / account.tax.template / name (char) : DEL required
+account / account.tax.template / price_include (boolean) : DEL
+account / account.tax.template / refund_repartition_line_ids (one2many): DEL relation: account.tax.repartition.line.template
+account / account.tax.template / sequence (integer) : DEL required
+account / account.tax.template / tax_exigibility (selection) : DEL selection_keys: ['on_invoice', 'on_payment']
+account / account.tax.template / tax_group_id (many2one) : DEL relation: account.tax.group
+account / account.tax.template / tax_scope (selection) : DEL selection_keys: ['consu', 'service']
+account / account.tax.template / type_tax_use (selection) : DEL required, selection_keys: ['none', 'purchase', 'sale']
+# NOTHING TO DO
+
+account / res.company / account_dashboard_onboarding_state (selection): DEL selection_keys: ['closed', 'done', 'just_done', 'not_done']
+account / res.company / account_invoice_onboarding_state (selection): DEL selection_keys: ['closed', 'done', 'just_done', 'not_done']
+account / res.company / account_onboarding_create_invoice_state_flag (boolean): DEL
+account / res.company / account_onboarding_invoice_layout_state (selection): DEL selection_keys: ['done', 'just_done', 'not_done']
+account / res.company / account_onboarding_sale_tax_state (selection): DEL selection_keys: ['done', 'just_done', 'not_done']
+account / res.company / account_setup_bank_data_state (selection): DEL selection_keys: ['done', 'just_done', 'not_done']
+account / res.company / account_setup_bill_state (selection): DEL selection_keys: ['done', 'just_done', 'not_done']
+account / res.company / account_setup_coa_state (selection): DEL selection_keys: ['done', 'just_done', 'not_done']
+account / res.company / account_setup_fy_data_state (selection): DEL selection_keys: ['done', 'just_done', 'not_done']
+account / res.company / account_setup_taxes_state (selection): DEL selection_keys: ['done', 'just_done', 'not_done']
+# DONE post-migration: update base on onboarding module
+
+account / res.company / account_discount_expense_allocation_id (many2one): NEW relation: account.account
+account / res.company / account_discount_income_allocation_id (many2one): NEW relation: account.account
+# NOTHING TO DO: new feature
+
+account / res.company / chart_template (selection) : NEW selection_keys: function
+account / res.company / chart_template_id (many2one) : DEL relation: account.chart.template
+# DONE: map chart_template_id > chart_template in pre-migration
+
+account / res.company / display_invoice_amount_total_words (boolean): NEW
+# NOTHING TO DO: new feature
+
+account / res.company / invoice_is_download (boolean) : NEW hasdefault: default
+account / res.company / invoice_is_print (boolean) : DEL
+# DONE pre-migration: rename field https://github.com/odoo/odoo/pull/119397
+
+account / res.company / message_main_attachment_id (many2one): DEL relation: ir.attachment
+# NOTHING TO DO
+
+account / res.company / property_stock_account_input_categ_id (many2one): DEL relation: account.account
+account / res.company / property_stock_account_output_categ_id (many2one): DEL relation: account.account
+account / res.company / property_stock_valuation_account_id (many2one): DEL relation: account.account
+# NOTHING TO DO
+
+account / res.company / rating_ids (one2many) : NEW relation: rating.rating
+account / res.partner.bank / activity_user_id (many2one) : not related anymore
+account / res.partner.bank / activity_user_id (many2one) : now a function
+# NOTHING TO DO
+
+account / res.partner.bank / has_iban_warning (boolean) : NEW isfunction: function, stored
+account / res.partner.bank / has_money_transfer_warning (boolean): NEW isfunction: function, stored
+# DONE create column in pre-migration and compute using orm in end-migration
+
+account / res.partner.bank / message_main_attachment_id (many2one): DEL relation: ir.attachment
+account / res.partner.bank / rating_ids (one2many) : NEW relation: rating.rating
+account / res.partner.bank / related_moves (one2many) : NEW relation: account.move
+# NOTHING TO DO
+
+---XML records in module 'account'---
+DEL account.payment.term: account.account_payment_term_2months (noupdate)
+DEL account.tax.group: account.tax_group_taxes (noupdate)
+# DONE: removed in post-migration
+
+NEW ir.actions.act_window: account.action_account_all_payments
+NEW ir.actions.act_window: account.action_account_supplier_accounts
+NEW ir.actions.act_window: account.action_analytic_reporting
+NEW ir.actions.act_window: account.action_open_payment_items
+NEW ir.actions.act_window: account.action_open_sale_payment_items
+DEL ir.actions.act_window: account.action_account_tax_template_form
+DEL ir.actions.act_window: account.action_open_account_onboarding_create_invoice
+DEL ir.actions.act_window: account.action_open_account_onboarding_sale_tax
+NEW ir.actions.server: account.action_automatic_entry_change_account
+NEW ir.actions.server: account.action_automatic_entry_change_period
+NEW ir.actions.server: account.action_move_switch_move_type
+DEL ir.actions.server: account.action_automatic_entry
+DEL ir.actions.server: account.action_move_switch_invoice_to_credit_note
+NEW ir.cron: account.ir_cron_account_move_send
+NEW ir.model.access: account.access_account_journal_group_invoice
+NEW ir.model.access: account.access_account_journal_group_readonly
+NEW ir.model.access: account.access_account_move_send
+DEL ir.model.access: account.access_account_account_template
+DEL ir.model.access: account.access_account_chart_template
+DEL ir.model.access: account.access_account_fiscal_position_account_template
+DEL ir.model.access: account.access_account_fiscal_position_tax_template
+DEL ir.model.access: account.access_account_fiscal_position_template
+DEL ir.model.access: account.access_account_group_template
+DEL ir.model.access: account.access_account_invoice_send
+DEL ir.model.access: account.access_account_journal_group_all
+DEL ir.model.access: account.access_account_reconcile_model_line_template
+DEL ir.model.access: account.access_account_reconcile_model_template
+DEL ir.model.access: account.access_account_tag_internal_user
+DEL ir.model.access: account.access_account_tax_repartition_line_template_manager
+DEL ir.model.access: account.access_account_tax_template
+DEL ir.model.access: account.access_product_template_account_manager
+DEL ir.model.constraint: account.constraint_account_account_code_company_uniq
+DEL ir.model.constraint: account.constraint_account_fiscal_position_account_account_src_dest_uniq
+DEL ir.model.constraint: account.constraint_account_fiscal_position_tax_tax_src_dest_uniq
+DEL ir.model.constraint: account.constraint_account_group_check_length_prefix
+DEL ir.model.constraint: account.constraint_account_journal_code_company_uniq
+DEL ir.model.constraint: account.constraint_account_journal_group_uniq_name
+DEL ir.model.constraint: account.constraint_account_move_line_check_accountable_required_fields
+DEL ir.model.constraint: account.constraint_account_move_line_check_amount_currency_balance_sign
+DEL ir.model.constraint: account.constraint_account_move_line_check_credit_debit
+DEL ir.model.constraint: account.constraint_account_move_line_check_non_accountable_fields_null
+DEL ir.model.constraint: account.constraint_account_payment_check_amount_not_negative
+DEL ir.model.constraint: account.constraint_account_payment_method_name_code_unique
+DEL ir.model.constraint: account.constraint_account_reconcile_model_name_unique
+DEL ir.model.constraint: account.constraint_account_report_line_code_uniq
+DEL ir.model.constraint: account.constraint_account_tax_name_company_uniq
+DEL ir.model.constraint: account.constraint_account_tax_template_name_company_uniq
+DEL ir.model.constraint: account_sequence.constraint_account_move_unique_name
+NEW ir.module.category: account.module_category_accounting_bank
+NEW ir.rule: account.account_move_send_rule_group_invoice (noupdate)
+NEW ir.rule: account.ir_rule_res_partner_bank_billing_officers (noupdate)
+NEW ir.rule: account.tax_group_comp_rule (noupdate)
+# NOTHING TO DO
+
+DEL ir.rule: account.account_invoice_send_rule_group_invoice (noupdate)
+DEL ir.sequence: account.sequence_reconcile_seq (noupdate)
+# DONE: removed in post-migration
+
+NEW ir.ui.menu: account.menu_account_supplier_accounts
+NEW ir.ui.menu: account.menu_action_analytic_reporting
+NEW ir.ui.menu: account.menu_action_open_payment_items
+NEW ir.ui.menu: account.menu_action_open_sale_payment_items
+NEW ir.ui.view: account.account_move_send_form
+NEW ir.ui.view: account.account_move_view_activity
+NEW ir.ui.view: account.document_tax_totals_company_currency_template
+NEW ir.ui.view: account.document_tax_totals_template
+NEW ir.ui.view: account.product_uom_form_view_inherit
+NEW ir.ui.view: account.report_statement_internal_layout
+NEW ir.ui.view: account.res_company_form_view_onboarding
+NEW ir.ui.view: account.res_company_form_view_onboarding_sale_tax
+NEW ir.ui.view: account.view_account_move_line_payment_filter
+NEW ir.ui.view: account.view_account_payment_method_line_tree
+NEW ir.ui.view: account.view_move_line_payment_tree
+NEW ir.ui.view: account.view_partner_bank_search_inherit
+DEL ir.ui.view: account.account_dashboard_onboarding_panel
+DEL ir.ui.view: account.account_invoice_onboarding_panel
+DEL ir.ui.view: account.account_invoice_onboarding_sale_tax_form
+DEL ir.ui.view: account.account_invoice_send_wizard_form
+DEL ir.ui.view: account.onboarding_bank_account_step
+DEL ir.ui.view: account.onboarding_chart_of_account_step
+DEL ir.ui.view: account.onboarding_create_invoice_step
+DEL ir.ui.view: account.onboarding_fiscal_year_step
+DEL ir.ui.view: account.onboarding_invoice_layout_step
+DEL ir.ui.view: account.onboarding_sale_tax_step
+DEL ir.ui.view: account.onboarding_taxes_step
+DEL ir.ui.view: account.view_account_analytic_line_filter_inherit
+DEL ir.ui.view: account.view_account_position_template_form
+DEL ir.ui.view: account.view_account_position_template_search
+DEL ir.ui.view: account.view_account_position_template_tree
+DEL ir.ui.view: account.view_account_tax_template_form
+DEL ir.ui.view: account.view_account_tax_template_search
+DEL ir.ui.view: account.view_account_tax_template_tree
+NEW onboarding.onboarding: account.onboarding_onboarding_account_dashboard (noupdate)
+NEW onboarding.onboarding: account.onboarding_onboarding_account_invoice (noupdate)
+NEW onboarding.onboarding.step: account.onboarding_onboarding_step_bank_account (noupdate)
+NEW onboarding.onboarding.step: account.onboarding_onboarding_step_base_document_layout (noupdate)
+NEW onboarding.onboarding.step: account.onboarding_onboarding_step_chart_of_accounts (noupdate)
+NEW onboarding.onboarding.step: account.onboarding_onboarding_step_company_data (noupdate)
+NEW onboarding.onboarding.step: account.onboarding_onboarding_step_create_invoice (noupdate)
+NEW onboarding.onboarding.step: account.onboarding_onboarding_step_default_taxes (noupdate)
+NEW onboarding.onboarding.step: account.onboarding_onboarding_step_fiscal_year (noupdate)
+NEW onboarding.onboarding.step: account.onboarding_onboarding_step_sales_tax (noupdate)
+NEW onboarding.onboarding.step: account.onboarding_onboarding_step_setup_bill (noupdate)
+NEW report.paperformat: account.paperformat_euro_bank_statement
+NEW res.groups: account.group_validate_bank_account
+DEL res.groups: account.group_show_line_subtotals_tax_excluded
+DEL res.groups: account.group_show_line_subtotals_tax_included
+# NOTHING TO DO