diff --git a/docsource/modules150-160.rst b/docsource/modules150-160.rst index 5338fc8c56e1..62b1c7e16133 100644 --- a/docsource/modules150-160.rst +++ b/docsource/modules150-160.rst @@ -170,7 +170,7 @@ Module coverage 15.0 -> 16.0 +-------------------------------------------------+----------------------+-------------------------------------------------+ | hr_contract | Done | | +-------------------------------------------------+----------------------+-------------------------------------------------+ -| hr_expense |Done | | +| hr_expense | Done | | +-------------------------------------------------+----------------------+-------------------------------------------------+ | hr_fleet | | | +-------------------------------------------------+----------------------+-------------------------------------------------+ diff --git a/openupgrade_scripts/scripts/hr_expense/16.0.2.0/post-migration.py b/openupgrade_scripts/scripts/hr_expense/16.0.2.0/post-migration.py index e8379095b57e..67a0a5d31fc7 100644 --- a/openupgrade_scripts/scripts/hr_expense/16.0.2.0/post-migration.py +++ b/openupgrade_scripts/scripts/hr_expense/16.0.2.0/post-migration.py @@ -1,22 +1,20 @@ # Copyright 2023 Tecnativa - Víctor Martínez +# Copyright 2024 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from openupgradelib import openupgrade def _hr_expense_process(env): - """Set amount_tax_company value only when it is necessary with ORM.""" + """Set amount_tax_company by ORM only when different currency.""" env.cr.execute( """ - SELECT id - FROM hr_expense - WHERE total_amount_company != total_amount AND amount_tax > 0 - AND amount_tax_company != 0 + SELECT he.id + FROM hr_expense he + JOIN res_company rc ON rc.id = he.company_id + WHERE rc.currency_id = he.currency_id """ ) - expense_model = env["hr.expense"] - for expense_id in env.cr.fetchall(): - expense = expense_model.browse(expense_id) - expense._compute_amount_tax() + env["hr.expense"].browse([x[0] for x in env.cr.fetchall()])._compute_amount_tax() def _hr_expense_sheet_process(env): @@ -28,7 +26,7 @@ def _hr_expense_sheet_process(env): SELECT SUM(amount_tax_company) FROM hr_expense WHERE sheet_id = hr_expense_sheet.id - ) WHERE total_amount_taxes = 0 + ) """, ) openupgrade.logged_query( @@ -36,18 +34,21 @@ def _hr_expense_sheet_process(env): """ UPDATE hr_expense_sheet SET untaxed_amount = (total_amount - total_amount_taxes) - WHERE untaxed_amount = 0 """, ) def _hr_expense_analytic_tag(env): - """If table exists and there are any records, we set the module - hr_expense_analytic_tag to be installed.""" + """If table exists and there are any record with no distribution (used just as tag), + we set the module hr_expense_analytic_tag to be installed. + """ if openupgrade.table_exists(env.cr, "account_analytic_tag_hr_expense_rel"): env.cr.execute( """SELECT COUNT(*) - FROM account_analytic_tag_hr_expense_rel""", + FROM account_analytic_tag_hr_expense_rel rel + JOIN account_analytic_tag aat ON rel.account_analytic_tag_id = aat.id + WHERE NOT aat.active_analytic_distribution + """, ) if env.cr.fetchone()[0]: openupgrade.logged_query( @@ -64,3 +65,9 @@ def migrate(env, version): _hr_expense_process(env) _hr_expense_sheet_process(env) _hr_expense_analytic_tag(env) + openupgrade.set_xml_ids_noupdate_value( + env, + "hr_expense", + ["product_product_no_cost"], + True, + ) diff --git a/openupgrade_scripts/scripts/hr_expense/16.0.2.0/pre-migration.py b/openupgrade_scripts/scripts/hr_expense/16.0.2.0/pre-migration.py index 700906cc6008..cb397ef6ba51 100644 --- a/openupgrade_scripts/scripts/hr_expense/16.0.2.0/pre-migration.py +++ b/openupgrade_scripts/scripts/hr_expense/16.0.2.0/pre-migration.py @@ -1,67 +1,53 @@ -from openupgradelib import openupgrade +# Copyright 2023 Tecnativa - Víctor Martínez +# Copyright 2024 Tecnativa - Pedro M. Baeza +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openupgradelib import openupgrade, openupgrade_160 def _hr_expense_table_new_columns(env): """Custom process to create new columns: - - amount_tax: (total_amount - untaxed_amount). - - amount_tax_company: set 0 value to re-set in post-migration.""" - # amount_tax + - amount_tax: (total_amount - untaxed_amount). It will be similar enough. + - amount_tax_company: the same value as amount_tax if same currency, and let + for post-migration for different currency. + """ if not openupgrade.column_exists(env.cr, "hr_expense", "amount_tax"): openupgrade.logged_query( env.cr, - """ - ALTER TABLE hr_expense - ADD COLUMN IF NOT EXISTS amount_tax numeric; - """, + "ALTER TABLE hr_expense ADD COLUMN amount_tax numeric", ) openupgrade.logged_query( env.cr, "UPDATE hr_expense SET amount_tax = (total_amount - untaxed_amount)" ) - # amount_tax_company field (to be filled in post-migration with ORM) if not openupgrade.column_exists(env.cr, "hr_expense", "amount_tax_company"): openupgrade.logged_query( env.cr, - """ - ALTER TABLE hr_expense - ADD COLUMN IF NOT EXISTS amount_tax_company numeric; - """, - ) - openupgrade.logged_query(env.cr, "UPDATE hr_expense SET amount_tax_company = 0") - - -def _hr_expense_sheet_table_new_columns(env): - """Custom process to create new columns: - - total_amount_taxes: set 0 value to re-set in post-migration. - - untaxed_amount: set 0 value to re-set in post-migration""" - # total_amount_taxes - if not openupgrade.column_exists(env.cr, "hr_expense_sheet", "total_amount_taxes"): - openupgrade.logged_query( - env.cr, - """ - ALTER TABLE hr_expense_sheet - ADD COLUMN IF NOT EXISTS total_amount_taxes numeric; - """, - ) - openupgrade.logged_query( - env.cr, "UPDATE hr_expense_sheet SET total_amount_taxes = 0" + "ALTER TABLE hr_expense ADD COLUMN amount_tax_company numeric", ) - # untaxed_amount field - if not openupgrade.column_exists(env.cr, "hr_expense_sheet", "untaxed_amount"): openupgrade.logged_query( env.cr, - """ - ALTER TABLE hr_expense_sheet - ADD COLUMN IF NOT EXISTS untaxed_amount numeric; + """UPDATE hr_expense he + SET amount_tax_company = amount_tax + FROM res_company rc + WHERE rc.id = he.company_id AND rc.currency_id = he.currency_id """, ) - openupgrade.logged_query( - env.cr, "UPDATE hr_expense_sheet SET untaxed_amount = 0" - ) + + +def _hr_expense_sheet_table_new_columns(env): + """Pre-create columns to be processed on post-migration.""" + openupgrade.logged_query( + env.cr, + """ALTER TABLE hr_expense_sheet + ADD COLUMN IF NOT EXISTS total_amount_taxes numeric""", + ) + openupgrade.logged_query( + env.cr, + """ALTER TABLE hr_expense_sheet + ADD COLUMN IF NOT EXISTS untaxed_amount numeric""", + ) def _fast_fill_analytic_distribution_on_hr_expense(env): - """Similar process to the one performed at - https://github.com/OCA/OpenUpgrade/pull/4004""" if not openupgrade.column_exists(env.cr, "hr_expense", "analytic_distribution"): openupgrade.logged_query( env.cr, @@ -70,47 +56,37 @@ def _fast_fill_analytic_distribution_on_hr_expense(env): ADD COLUMN IF NOT EXISTS analytic_distribution jsonb; """, ) + openupgrade_160.fill_analytic_distribution( + env, + table="hr_expense", + m2m_rel="account_analytic_tag_hr_expense_rel", + m2m_column1="hr_expense_id", + ) + +def _convert_expense_sheet_entries_to_invoices(env): + """From v16 onwards, account_move related to hr_expense_sheet are created with + move_type = "in_invoice" as per + https://github.com/odoo/odoo/blob/87f4667d81f7d8a40dcf225f3daf1a9e2795680d/ + addons/hr_expense/models/hr_expense.py#L1297 + on contrary than on v15, which was "entry". + + Then, in _compute_payment_state from account.move it will check if the move_type is + "entry", putting payment_state = "not_paid" for that cases, no matter the + reconcilation: + https://github.com/odoo/odoo/blob/87f4667d81f7d8a40dcf225f3daf1a9e2795680d/ + addons/account/models/account_move.py#L926 + + As the sheet payment state is taken from the move's payment_state, we need to + switch all the existing expenses entries to "in_invoice". + """ openupgrade.logged_query( env.cr, """ - WITH distribution_data AS ( - WITH sub AS ( - SELECT - all_line_data.expense_id, - all_line_data.analytic_account_id, - SUM(all_line_data.percentage) AS percentage - FROM ( - SELECT - he.id AS expense_id, - account.id AS analytic_account_id, - 100 AS percentage - FROM hr_expense he - JOIN account_analytic_account account - ON account.id = he.analytic_account_id - WHERE he.analytic_account_id IS NOT NULL - UNION ALL - SELECT - he.id AS expense_id, - dist.account_id AS analytic_account_id, - dist.percentage AS percentage - FROM hr_expense he - JOIN account_analytic_tag_hr_expense_rel tag_rel - ON tag_rel.hr_expense_id = he.id - JOIN account_analytic_distribution dist - ON dist.tag_id = tag_rel.account_analytic_tag_id - ) AS all_line_data - GROUP BY all_line_data.expense_id, all_line_data.analytic_account_id - ) - SELECT - sub.expense_id, - jsonb_object_agg(sub.analytic_account_id::text, sub.percentage) - AS analytic_distribution - FROM sub - GROUP BY sub.expense_id - ) - UPDATE hr_expense he SET analytic_distribution = dist.analytic_distribution - FROM distribution_data dist WHERE he.id = dist.expense_id + UPDATE account_move am + SET move_type = 'in_invoice' + FROM hr_expense_sheet hes + WHERE hes.account_move_id = am.id AND am.move_type <> 'in_invoice' """, ) @@ -128,4 +104,5 @@ def migrate(env, version): _hr_expense_table_new_columns(env) _hr_expense_sheet_table_new_columns(env) _fast_fill_analytic_distribution_on_hr_expense(env) + _convert_expense_sheet_entries_to_invoices(env) openupgrade.rename_xmlids(env.cr, _xmlid_renames) diff --git a/openupgrade_scripts/scripts/hr_expense/16.0.2.0/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/hr_expense/16.0.2.0/upgrade_analysis_work.txt index adb674bd65d7..c56c54c559d4 100644 --- a/openupgrade_scripts/scripts/hr_expense/16.0.2.0/upgrade_analysis_work.txt +++ b/openupgrade_scripts/scripts/hr_expense/16.0.2.0/upgrade_analysis_work.txt @@ -6,32 +6,34 @@ new model hr.expense.split.wizard [transient] ---Fields in module 'hr_expense'--- hr_expense / hr.expense / amount_tax (float) : NEW isfunction: function, stored -# DONE: pre-migration (set value) +# DONE: pre-migration: set value hr_expense / hr.expense / amount_tax_company (float) : NEW isfunction: function, stored -# DONE: pre-migration (inital value) + post-migration (set value) +# DONE: pre-migration: pre-create column for same currency +# DONE: post-migration: set value by ORM for different currency hr_expense / hr.expense / analytic_account_id (many2one): DEL relation: account.analytic.account hr_expense / hr.expense / analytic_distribution_stored_char (char): NEW isfunction: function, stored -# DONE: fast fill analytic_distribution in pre-migration +# DONE: pre-migration: fast fill analytic_distribution hr_expense / hr.expense / analytic_tag_ids (many2many) : DEL relation: account.analytic.tag -# DONE: post-migration (hr_expense_analytic_tag OCA) +# DONE: post-migration: if there are tags with no distribution, we plan OCA module hr_expense_analytic_tag to be installed hr_expense / hr.expense.sheet / total_amount_taxes (float) : NEW isfunction: function, stored -# DONE: pre-migration (inital value) + post-migration (set value) - hr_expense / hr.expense.sheet / untaxed_amount (float) : NEW isfunction: function, stored -# DONE: pre-migration (inital value) + post-migration (set value) +# DONE: pre-migration: pre-create columns +# DONE: post-migration: set values by SQL hr_expense / account.analytic.applicability / business_domain (False) : NEW selection_keys: ['bill', 'expense', 'general', 'invoice'], mode: modify hr_expense / account.move / expense_sheet_id (one2many) : NEW relation: hr.expense.sheet hr_expense / hr.expense / name (char) : not a function anymore hr_expense / hr.expense / unit_amount (float) : not a function anymore hr_expense / hr.expense.sheet / payment_state (selection) : selection_keys is now 'function' ('['in_payment', 'invoicing_legacy', 'not_paid', 'paid', 'partial', 'reversed']') +# NOTHING TO DO + hr_expense / res.company / company_expense_journal_id (many2one): NEW relation: account.journal hr_expense / res.company / expense_journal_id (many2one) : NEW relation: account.journal -# NOTHING TO DO +# NOTHING TO DO: Preference values for being set by company, but if none selected, the previous default ones are used. ---XML records in module 'hr_expense'--- DEL ir.actions.act_window: hr_expense.action_hr_expense_sheet_all_to_approve @@ -60,9 +62,10 @@ NEW product.product: hr_expense.expense_product_gift (noupdate) NEW product.product: hr_expense.expense_product_meal (noupdate) NEW product.product: hr_expense.expense_product_mileage (noupdate) NEW product.product: hr_expense.expense_product_travel_accommodation (noupdate) -NEW product.product: hr_expense.product_product_no_cost (noupdate) DEL product.product: hr_expense.product_product_fixed_cost (noupdate) # NOTHING TO DO DEL product.product: hr_expense.product_product_zero_cost +NEW product.product: hr_expense.product_product_no_cost (noupdate) # DONE: pre-migration: renamed product_product_zero_cost -> product_product_no_cost +# DONE: post-migration: switch noupdate after updating new data