diff --git a/docsource/modules180-190.rst b/docsource/modules180-190.rst index 9972d60128f1..b1bb0ec79ff6 100644 --- a/docsource/modules180-190.rst +++ b/docsource/modules180-190.rst @@ -112,7 +112,7 @@ Module coverage 18.0 -> 19.0 +---------------------------------------------------+----------------------+-------------------------------------------------+ | contacts |Nothing to do | | +---------------------------------------------------+----------------------+-------------------------------------------------+ -| crm | | | +| crm |Done | | +---------------------------------------------------+----------------------+-------------------------------------------------+ | crm_iap_enrich | |No DB layout changes. | +---------------------------------------------------+----------------------+-------------------------------------------------+ diff --git a/openupgrade_scripts/scripts/crm/19.0.1.9/post-migration.py b/openupgrade_scripts/scripts/crm/19.0.1.9/post-migration.py new file mode 100644 index 000000000000..f72daa184384 --- /dev/null +++ b/openupgrade_scripts/scripts/crm/19.0.1.9/post-migration.py @@ -0,0 +1,67 @@ +# Copyright 2026 Tecnativa - Eduardo Ezerouali +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from openupgradelib import openupgrade + + +def _migrate_lead_mobile(env): + # Case 1: phone is empty → fill it with the old mobile value + openupgrade.logged_query( + env.cr, + """ + UPDATE crm_lead + SET phone = mobile + WHERE (phone IS NULL OR phone = '') + AND (mobile IS NOT NULL AND mobile != '') + """, + ) + # Case 2: both phone and mobile exist and differ → concatenate them + openupgrade.logged_query( + env.cr, + """ + UPDATE crm_lead + SET phone = phone || ' / ' || mobile + WHERE phone IS NOT NULL AND phone != '' + AND mobile IS NOT NULL AND mobile != '' + AND btrim(phone) != btrim(mobile) + """, + ) + + +def _load_data_pls_fields_param(env): + # New PLS fields added in v19. Merge them into the existing value instead of + # overwriting it, so a customized/removed `crm.pls_fields` param is preserved + new_fields = {"state_id", "country_id", "source_id", "lang_id", "tag_ids"} + param = env["ir.config_parameter"].sudo().get_param("crm.pls_fields") + if param: + current = set(param.split(",")) + merged = current | new_fields + env["ir.config_parameter"].sudo().set_param( + "crm.pls_fields", ",".join(sorted(merged)) + ) + + +def _load_data_stage_colors(env): + # Only color the default stages that still exist, + # skip any the user deleted in v18. + colors = { + "stage_lead1": 11, + "stage_lead2": 5, + "stage_lead3": 8, + "stage_lead4": 10, + } + for xml_id, color in colors.items(): + record = env.ref(f"crm.{xml_id}", raise_if_not_found=False) + if record: + record.color = color + + +@openupgrade.migrate() +def migrate(env, version): + # Do not load noupdate_changes.xml: every entry is problematic (deleted stages, + # customized pls param). the necessary changes are done manually in + # the _load_data_* functions below + + openupgrade.m2o_to_x2m(env.cr, env["crm.stage"], "crm_stage", "team_ids", "team_id") + _load_data_stage_colors(env) + _load_data_pls_fields_param(env) + _migrate_lead_mobile(env) diff --git a/openupgrade_scripts/scripts/crm/19.0.1.9/pre-migration.py b/openupgrade_scripts/scripts/crm/19.0.1.9/pre-migration.py new file mode 100644 index 000000000000..de0553ca345e --- /dev/null +++ b/openupgrade_scripts/scripts/crm/19.0.1.9/pre-migration.py @@ -0,0 +1,36 @@ +# Copyright 2026 Tecnativa - Eduardo Ezerouali +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from openupgradelib import openupgrade + + +def _won_status_set(env): + # Precreate won_status and set with sql + openupgrade.add_columns( + env, + [ + ("crm.lead", "won_status", "selection", None, "crm_lead"), + ], + ) + openupgrade.logged_query( + env.cr, + """ + UPDATE crm_lead cl + SET won_status = CASE + WHEN cl.probability = 100 + AND cs.is_won = TRUE + THEN 'won' + WHEN cl.active = FALSE + AND cl.probability = 0 + THEN 'lost' + ELSE 'pending' + END + FROM crm_lead cl2 + LEFT JOIN crm_stage cs ON cs.id = cl2.stage_id + WHERE cl2.id = cl.id + """, + ) + + +@openupgrade.migrate() +def migrate(env, version): + _won_status_set(env) diff --git a/openupgrade_scripts/scripts/crm/19.0.1.9/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/crm/19.0.1.9/upgrade_analysis_work.txt new file mode 100644 index 000000000000..6012c880ff01 --- /dev/null +++ b/openupgrade_scripts/scripts/crm/19.0.1.9/upgrade_analysis_work.txt @@ -0,0 +1,37 @@ +---Models in module 'crm'--- +---Fields in module 'crm'--- +crm / crm.lead / commercial_partner_id (many2one): NEW relation: res.partner, hasdefault: compute, stored: False +# NOTHING TO DO + +crm / crm.lead / mobile (char) : DEL +# DONE: pos-migration: if phone is empty and mobile not set phone with mobile and concatenate the mobile in the pone field in case both exist + +crm / crm.lead / title (many2one) : DEL relation: res.partner.title +# NOTHING TO DO + +crm / crm.lead / won_status (selection) : NEW selection_keys: ['lost', 'pending', 'won'], isfunction: function, stored +# DONE: pre-migration: pre-created column and set it to prevent massive computation + +crm / crm.lead.scoring.frequency.field / color (integer) : NEW hasdefault: default +crm / crm.stage / color (integer) : NEW +# NOTHING TO DO + +crm / crm.stage / rotting_threshold_days (integer): NEW hasdefault: default +# NOTHING TO DO: default is set to 0 to keep old behavoir + +crm / crm.stage / team_id (many2one) : DEL relation: crm.team +crm / crm.stage / team_ids (many2many) : NEW relation: crm.team +# Done: post-migration: Transform m2o to m2m + +crm / crm.team.member / assignment_domain_preferred (char): NEW +crm / res.users / target_sales_done (integer) : DEL +crm / res.users / target_sales_won (integer) : DEL +# NOTHING TO DO + +---XML records in module 'crm'--- +NEW ir.actions.act_window: crm.mail_followers_edit_action_from_lead +NEW ir.model.constraint: crm.constraint_crm_lead_create_date_team_id_idx +NEW ir.model.constraint: crm.constraint_crm_lead_default_order_idx +NEW ir.model.constraint: crm.constraint_crm_lead_user_id_team_id_type_index +DEL ir.ui.view: crm.crm_lead_partner_kanban_view +# NOTHING TO DO