diff --git a/docsource/modules160-170.rst b/docsource/modules160-170.rst index d1f39c7a00f4..744a69c1eaaa 100644 --- a/docsource/modules160-170.rst +++ b/docsource/modules160-170.rst @@ -692,7 +692,7 @@ Module coverage 16.0 -> 17.0 +---------------------------------------------------+----------------------+-------------------------------------------------+ | privacy_lookup | |No DB layout changes. | +---------------------------------------------------+----------------------+-------------------------------------------------+ -| product | | | +| product | Done | | +---------------------------------------------------+----------------------+-------------------------------------------------+ | product_email_template | |No DB layout changes. | +---------------------------------------------------+----------------------+-------------------------------------------------+ diff --git a/openupgrade_scripts/scripts/product/17.0.1.2/post-migration.py b/openupgrade_scripts/scripts/product/17.0.1.2/post-migration.py new file mode 100644 index 000000000000..f9f41aa324cc --- /dev/null +++ b/openupgrade_scripts/scripts/product/17.0.1.2/post-migration.py @@ -0,0 +1,68 @@ +# Copyright 2024 Viindoo Technology Joint Stock Company (Viindoo) +# Copyright 2024 Hunki enterprises - Holger Brunn +# Copyright 2024 Tecnativa - Pedro M. Baeza +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + + +def _preserve_pricelist_order(env): + """As the order determines which priority to apply the pricelists, we should assure + that with the new order criteria, everything remains the same, so let's rewrite the + sequence for not depending on the id. + """ + openupgrade.logged_query( + env.cr, + """ + UPDATE product_pricelist pp + SET sequence = sub.row_number + FROM ( + SELECT id, row_number() + OVER (PARTITION BY True order by sequence, id desc) + FROM product_pricelist + ) as sub + WHERE sub.id = pp.id + """, + ) + + +def _remove_if_applicable_base_pricelist(env): + """As this pricelist may be used by users for adding extra rules, we can't just + remove it. Let's check the content, and if the pricelist hasn't been touched, then + try to remove it. If any modification, we just remove the XML-ID. + """ + pricelist = env.ref("product.list0", False) + if not pricelist: + return + if len(pricelist.item_ids) == 1: + item = pricelist.item_ids + if ( + item.compute_price == "formula" + and item.base == "list_price" + and item.applied_on == "3_global" + and item.price_discount == 0 + and item.price_surcharge == 0 + ): + openupgrade.delete_records_safely_by_xml_id(env, ["product.list0"]) + return + openupgrade.logged_query( + env.cr, "DELETE FROM ir_model_date WHERE module = 'product' AND name='list0'" + ) + + +@openupgrade.migrate() +def migrate(env, version): + _preserve_pricelist_order(env) + openupgrade.load_data(env, "product", "17.0.1.2/noupdate_changes.xml") + openupgrade.logged_query( + env.cr, + """ + INSERT INTO product_document ( + ir_attachment_id, active, create_uid, write_uid, create_date, write_date + ) + SELECT id, True, create_uid, write_uid, create_date, write_date + FROM ir_attachment + WHERE res_model IN ('product.product', 'product.template') + AND res_field IS NULL + """, + ) diff --git a/openupgrade_scripts/scripts/product/17.0.1.2/pre-migration.py b/openupgrade_scripts/scripts/product/17.0.1.2/pre-migration.py new file mode 100644 index 000000000000..ca3926660a88 --- /dev/null +++ b/openupgrade_scripts/scripts/product/17.0.1.2/pre-migration.py @@ -0,0 +1,45 @@ +# Copyright 2024 Viindoo Technology Joint Stock Company (Viindoo) +# Copyright 2024 Hunki enterprises - Holger Brunn +# Copyright 2024 Tecnativa - Pedro M. Baeza +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + + +def _clean_incorrect_packaging_records(env): + """If there's any record of this kind, it's invalid and maybe a leftover of a + non-cascade removal operation. Let's clean the table. There's a chance that this + package was used elsewhere, so this will crash, but in that case, it seems legit to + do it, for checking what's going on. + """ + openupgrade.logged_query( + env.cr, "DELETE FROM product_packaging WHERE product_id IS NULL" + ) + + +@openupgrade.migrate() +def migrate(env, version): + _clean_incorrect_packaging_records(env) + openupgrade.logged_query( + env.cr, + """ + ALTER TABLE product_tag + ALTER COLUMN color TYPE VARCHAR USING color::VARCHAR; + + UPDATE product_tag + SET color = CASE + WHEN color = '1' THEN '#F06050' + WHEN color = '2' THEN '#F4A460' + WHEN color = '3' THEN '#F7CD1F' + WHEN color = '4' THEN '#6CC1ED' + WHEN color = '5' THEN '#814968' + WHEN color = '6' THEN '#EB7E7F' + WHEN color = '7' THEN '#2C8397' + WHEN color = '8' THEN '#475577' + WHEN color = '9' THEN '#D6145F' + WHEN color = '10' THEN '#30C381' + WHEN color = '11' THEN '#9365B8' + ELSE '#3C3C3C' + END; + """, + ) diff --git a/openupgrade_scripts/scripts/product/17.0.1.2/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/product/17.0.1.2/upgrade_analysis_work.txt new file mode 100644 index 000000000000..85daab8fc766 --- /dev/null +++ b/openupgrade_scripts/scripts/product/17.0.1.2/upgrade_analysis_work.txt @@ -0,0 +1,97 @@ +---Models in module 'product'--- +obsolete model report.product.report_producttemplatelabel [abstract] +new model product.catalog.mixin [abstract] +new model product.document +new model report.product.report_producttemplatelabel2x7 [abstract] +new model report.product.report_producttemplatelabel4x12 [abstract] +new model report.product.report_producttemplatelabel4x12noprice [abstract] +new model report.product.report_producttemplatelabel4x7 [abstract] +# NOTHING TO DO + +---Fields in module 'product'--- +product / product.attribute / display_type (selection) : selection_keys is now '['color', 'multi', 'pills', 'radio', 'select']' ('['color', 'pills', 'radio', 'select']') +# NOTHING TO DO: add new selection: multi + +product / product.attribute.value / default_extra_price (float) : NEW +# NOTHING TO DO: new feature for filling with this value the product variant attribute values created from this + +product / product.attribute.value / image (binary) : NEW attachment: True +# NOTHING TO DO: new feature for having an image linked to this value + +product / product.category / product_properties_definition (properties_definition): NEW +product / product.template / product_properties (properties): NEW hasdefault: compute +# NOTHING TO DO: new feature for having properties on products + +product / product.document / _inherits : NEW _inherits: {'ir.attachment': 'ir_attachment_id'} +product / product.document / active (boolean) : NEW hasdefault: default +product / product.document / ir_attachment_id (many2one) : NEW relation: ir.attachment, required +product / product.product / product_document_ids (one2many): NEW relation: product.document +product / product.template / product_document_ids (one2many): NEW relation: product.document +# DONE: post-migration: populated with attachments on product.template and product.product + +product / product.packaging / product_id (many2one) : now required +# DONE: pre-migration: delete records with no product_id, as they are not valid + +product / product.pricelist / _order : _order is now 'sequence asc, id asc' ('sequence asc, id desc') +# DONE: post-migration: Write sequence for making sure the old pricelist order is preserved + +product / product.pricelist / activity_ids (one2many) : NEW relation: mail.activity +product / product.pricelist / message_follower_ids (one2many): NEW relation: mail.followers +product / product.pricelist / message_ids (one2many) : NEW relation: mail.message +# NOTHING TO DO: Chatter + activity new feature + +product / product.pricelist.item / active (boolean) : DEL +# NOTHING TO DO: It was a related stored of the pricelist active, so not adding value + +product / product.product / activity_user_id (many2one) : not related anymore +product / product.product / activity_user_id (many2one) : now a function +product / product.product / message_main_attachment_id (many2one): DEL relation: ir.attachment +# NOTHING TO DO + +product / product.supplierinfo / discount (float) : NEW +# NOTHING TO DO + +product / product.tag / color (integer) : type is now 'char' ('integer') +# DONE: pre-migration: converted to the corresponding hexadecimal values + +product / product.template / activity_user_id (many2one) : not related anymore +product / product.template / activity_user_id (many2one) : now a function +product / product.template / message_main_attachment_id (many2one): DEL relation: ir.attachment +# NOTHING TO DO + +product / product.template.attribute.line / _order : _order is now 'sequence, attribute_id, id' ('attribute_id, id') +product / product.template.attribute.line / sequence (integer) : NEW hasdefault: default +# NOTHING TO DO: new feature + +---XML records in module 'product'--- +NEW ir.actions.report: product.report_product_template_label_2x7 +NEW ir.actions.report: product.report_product_template_label_4x12 +NEW ir.actions.report: product.report_product_template_label_4x12_noprice +NEW ir.actions.report: product.report_product_template_label_4x7 +DEL ir.actions.report: product.report_product_template_label +NEW ir.model.access: product.access_product_document_user +NEW ir.model.constraint: product.constraint_product_attribute_check_multi_checkbox_no_variant +# NOTHING TO DO + +NEW ir.rule: product.product_document_comp_rule (noupdate) +NEW ir.ui.view: product.product_attribute_value_list +NEW ir.ui.view: product.product_document_form +NEW ir.ui.view: product.product_document_kanban +NEW ir.ui.view: product.product_document_list +NEW ir.ui.view: product.product_document_search +NEW ir.ui.view: product.product_product_view_tree_tag +NEW ir.ui.view: product.product_template_view_tree_tag +NEW ir.ui.view: product.product_view_kanban_catalog +NEW ir.ui.view: product.product_view_search_catalog +NEW ir.ui.view: product.report_producttemplatelabel2x7 +NEW ir.ui.view: product.report_producttemplatelabel4x12 +NEW ir.ui.view: product.report_producttemplatelabel4x12noprice +NEW ir.ui.view: product.report_producttemplatelabel4x7 +NEW ir.ui.view: product.report_simple_label4x12_no_price +# NOTHING TO DO + +DEL ir.ui.view: product.report_producttemplatelabel +# NOTHING TO DO + +DEL product.pricelist: product.list0 (noupdate) +DONE: post-migration: Only remove it if it wasn't not touched and it contains the basic rule. If not, we remove the XML-ID and preserve it