Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docsource/modules150-160.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ Module coverage 15.0 -> 16.0
+-------------------------------------------------+----------------------+-------------------------------------------------+
| hr_contract | Done | |
+-------------------------------------------------+----------------------+-------------------------------------------------+
| hr_expense | | |
| hr_expense | Done | |
+-------------------------------------------------+----------------------+-------------------------------------------------+
| hr_fleet | | |
+-------------------------------------------------+----------------------+-------------------------------------------------+
Expand Down
73 changes: 73 additions & 0 deletions openupgrade_scripts/scripts/hr_expense/16.0.2.0/post-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# 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 by ORM only when different currency."""
env.cr.execute(
"""
SELECT he.id
FROM hr_expense he
JOIN res_company rc ON rc.id = he.company_id
WHERE rc.currency_id = he.currency_id
"""
)
env["hr.expense"].browse([x[0] for x in env.cr.fetchall()])._compute_amount_tax()


def _hr_expense_sheet_process(env):
"""With the hr.expense values already defined, we can now set the missing data."""
openupgrade.logged_query(
env.cr,
"""
UPDATE hr_expense_sheet SET total_amount_taxes = (
SELECT SUM(amount_tax_company)
FROM hr_expense
WHERE sheet_id = hr_expense_sheet.id
)
""",
)
openupgrade.logged_query(
env.cr,
"""
UPDATE hr_expense_sheet
SET untaxed_amount = (total_amount - total_amount_taxes)
""",
)


def _hr_expense_analytic_tag(env):
"""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 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(
env.cr,
"""UPDATE ir_module_module
SET state = 'to install'
WHERE name = 'hr_expense_analytic_tag'""",
)


@openupgrade.migrate()
def migrate(env, version):
openupgrade.load_data(env.cr, "hr_expense", "16.0.2.0/noupdate_changes.xml")
_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,
)
108 changes: 108 additions & 0 deletions openupgrade_scripts/scripts/hr_expense/16.0.2.0/pre-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# 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). 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 amount_tax numeric",
)
openupgrade.logged_query(
env.cr, "UPDATE hr_expense SET amount_tax = (total_amount - untaxed_amount)"
)
if not openupgrade.column_exists(env.cr, "hr_expense", "amount_tax_company"):
openupgrade.logged_query(
env.cr,
"ALTER TABLE hr_expense ADD COLUMN amount_tax_company numeric",
)
openupgrade.logged_query(
env.cr,
"""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
""",
)


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):
if not openupgrade.column_exists(env.cr, "hr_expense", "analytic_distribution"):
openupgrade.logged_query(
env.cr,
"""
ALTER TABLE hr_expense
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,
"""
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'
""",
)


_xmlid_renames = [
(
"hr_expense.product_product_zero_cost",
"hr_expense.product_product_no_cost",
),
]


@openupgrade.migrate()
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)
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---Models in module 'hr_expense'---
new model hr.expense.split [transient]
new model hr.expense.split.wizard [transient]
# NOTHING TO DO

---Fields in module 'hr_expense'---

hr_expense / hr.expense / amount_tax (float) : NEW isfunction: function, stored
# DONE: pre-migration: set value

hr_expense / hr.expense / amount_tax_company (float) : NEW isfunction: function, stored
# 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: pre-migration: fast fill analytic_distribution

hr_expense / hr.expense / analytic_tag_ids (many2many) : DEL relation: account.analytic.tag
# 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
hr_expense / hr.expense.sheet / untaxed_amount (float) : NEW isfunction: function, stored
# 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: 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
DEL ir.actions.act_window: hr_expense.action_hr_expense_sheet_all_to_pay
DEL ir.actions.act_window: hr_expense.action_hr_expense_sheet_all_to_post
DEL ir.actions.act_window: hr_expense.hr_expense_actions_my_unsubmitted
DEL ir.actions.act_window.view: hr_expense.hr_expense_actions_all_kanban
DEL ir.actions.act_window.view: hr_expense.hr_expense_actions_my_unsubmitted_kanban
DEL ir.actions.act_window.view: hr_expense.hr_expense_actions_my_unsubmitted_tree
NEW ir.model.access: hr_expense.access_hr_expense_split_manager
NEW ir.model.access: hr_expense.access_hr_expense_split_wizard_manager
NEW ir.rule: hr_expense.ir_rule_hr_expense_sheet_employee_not_draft (noupdate)
DEL ir.ui.menu: hr_expense.menu_hr_expense_my_expenses_to_submit
DEL ir.ui.menu: hr_expense.menu_hr_expense_sheet_all
DEL ir.ui.menu: hr_expense.menu_hr_expense_sheet_all_to_approve
DEL ir.ui.menu: hr_expense.menu_hr_expense_sheet_all_to_pay
DEL ir.ui.menu: hr_expense.menu_hr_expense_sheet_all_to_post
NEW ir.ui.view: hr_expense.hr_expense_sheet_view_search_with_panel
NEW ir.ui.view: hr_expense.hr_expense_split
NEW ir.ui.view: hr_expense.product_product_expense_categories_tree_view
NEW ir.ui.view: hr_expense.view_move_form_inherit_expense
NEW ir.ui.view: hr_expense.view_product_hr_expense_form
DEL ir.ui.view: hr_expense.view_hr_expense_sheet_dashboard_tree
NEW product.product: hr_expense.expense_product_communication (noupdate)
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)
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