diff --git a/docsource/modules170-180.rst b/docsource/modules170-180.rst index 7502209e2d6d..d73c320e134f 100644 --- a/docsource/modules170-180.rst +++ b/docsource/modules170-180.rst @@ -1030,7 +1030,7 @@ Module coverage 17.0 -> 18.0 +---------------------------------------------------+----------------------+-------------------------------------------------+ | spreadsheet_dashboard_website_sale_slides | | | +---------------------------------------------------+----------------------+-------------------------------------------------+ -| stock | | | +| stock | Done | | +---------------------------------------------------+----------------------+-------------------------------------------------+ | stock_account | | | +---------------------------------------------------+----------------------+-------------------------------------------------+ diff --git a/openupgrade_scripts/scripts/stock/18.0.1.1/post-migration.py b/openupgrade_scripts/scripts/stock/18.0.1.1/post-migration.py new file mode 100644 index 000000000000..ae2372ce6d17 --- /dev/null +++ b/openupgrade_scripts/scripts/stock/18.0.1.1/post-migration.py @@ -0,0 +1,99 @@ +# Copyright 2025 ForgeFlow S.L. (https://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from openupgradelib import openupgrade, openupgrade_180 + + +def convert_company_dependent(env): + openupgrade_180.convert_company_dependent( + env, "product.template", "property_stock_inventory" + ) + openupgrade_180.convert_company_dependent( + env, "product.template", "property_stock_production" + ) + openupgrade_180.convert_company_dependent(env, "product.template", "responsible_id") + openupgrade_180.convert_company_dependent( + env, "res.partner", "property_stock_customer" + ) + openupgrade_180.convert_company_dependent( + env, "res.partner", "property_stock_supplier" + ) + + +def _create_default_new_types_for_all_warehouses(env): + # method mainly based on _create_or_update_sequences_and_picking_types() + all_warehouses = env["stock.warehouse"].with_context(active_test=False).search([]) + for wh in all_warehouses: + sequence_data = wh._get_sequence_values() + for field in ["qc_type_id", "store_type_id", "xdock_type_id"]: + # choose the next available color for the operation types of this warehouse + all_used_colors = [ + res["color"] + for res in env["stock.picking.type"] + .with_context(active_test=False) + .search_read( + [("warehouse_id", "!=", False), ("color", "!=", False)], + ["color"], + order="color", + ) + ] + available_colors = [ + zef for zef in range(0, 12) if zef not in all_used_colors + ] + color = available_colors[0] if available_colors else 0 + # suit for each warehouse: reception, internal, pick, pack, ship + max_sequence = ( + env["stock.picking.type"] + .with_context(active_test=False) + .search_read( + [("sequence", "!=", False)], + ["sequence"], + limit=1, + order="sequence desc", + ) + ) + max_sequence = max_sequence and max_sequence[0]["sequence"] or 0 + values = wh._get_picking_type_update_values()[field] + create_data, _ = wh._get_picking_type_create_values(max_sequence) + values.update(create_data[field]) + sequence = env["ir.sequence"].create(sequence_data[field]) + values.update( + warehouse_id=wh.id, + color=color, + sequence_id=sequence.id, + sequence=max_sequence + 1, + company_id=wh.company_id.id, + active=wh.active, + ) + # create picking type + picking_type_id = env["stock.picking.type"].create(values).id + # update picking type for warehouse + wh.write({field: picking_type_id}) + + +def _set_inter_company_locations(env): + """See https://github.com/odoo/odoo/commit/08536d687880ca6d9ad5c37b639c0ad4c2599d74""" + companies = env["res.company"].search([]) + if len(companies) > 1: + inter_company_location = env.ref("stock.stock_location_inter_company") + inactive = False + if not inter_company_location.active: + inactive = True + inter_company_location.sudo().write({"active": True}) + for company in companies: + company.sudo()._set_per_company_inter_company_locations( + inter_company_location + ) + if inactive: + # we leave everything as it was + inter_company_location.sudo().write({"active": False}) + + +@openupgrade.migrate() +def migrate(env, version): + convert_company_dependent(env) + _create_default_new_types_for_all_warehouses(env) + _set_inter_company_locations(env) + openupgrade.load_data(env, "stock", "18.0.1.1/noupdate_changes.xml") + openupgrade.delete_records_safely_by_xml_id( + env, ["stock.property_stock_customer", "stock.property_stock_supplier"] + ) diff --git a/openupgrade_scripts/scripts/stock/18.0.1.1/pre-migration.py b/openupgrade_scripts/scripts/stock/18.0.1.1/pre-migration.py new file mode 100644 index 000000000000..5a95b0fd577b --- /dev/null +++ b/openupgrade_scripts/scripts/stock/18.0.1.1/pre-migration.py @@ -0,0 +1,81 @@ +# Copyright 2025 ForgeFlow S.L. (https://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from openupgradelib import openupgrade + +_field_renames = [ + ("stock.move", "stock_move", "location_dest_id", "location_final_id"), + ( + "stock.warehouse.orderpoint", + "stock_warehouse_orderpoint", + "qty_to_order", + "qty_to_order_manual", + ), +] + +_xmlid_renames = [ + ("stock.stock_location_inter_wh", "stock.stock_location_inter_company"), +] + +_new_columns = [ + ("product.template", "is_storable", "boolean", False), + ("stock.move", "location_dest_id", "many2one"), + ("stock.rule", "location_dest_from_rule", "boolean", False), + ("stock.picking.type", "move_type", "selection", "direct"), + ("stock.putaway.rule", "sublocation", "selection", "no"), +] + + +def fill_product_template_is_storable(env): + openupgrade.logged_query( + env.cr, + """ + UPDATE product_template + SET is_storable = TRUE, type = 'consu' + WHERE type = 'product'""", + ) + + +def fill_stock_move_location_dest_id(env): + openupgrade.logged_query( + env.cr, + """ + UPDATE stock_move sm2 + SET location_dest_id = COALESCE(sp.location_dest_id, + spt.default_location_dest_id, sm.location_final_id) + FROM stock_move sm + LEFT JOIN stock_picking sp ON sm.picking_id = sp.id + LEFT JOIN stock_picking_type spt ON sm.picking_type_id = spt.id + WHERE sm2.id = sm.id + """, + ) + openupgrade.logged_query( + env.cr, + """ + UPDATE stock_rule sr + SET location_dest_from_rule = TRUE + FROM stock_move sm + WHERE sm.rule_id = sr.id + AND sm.location_dest_id != sm.location_final_id + AND sr.action IN ('pull', 'pull_push') + """, + ) + + +def fill_stock_putaway_rule_sublocation(env): + openupgrade.logged_query( + env.cr, + """ + UPDATE stock_putaway_rule + SET sublocation = 'closest_location' + WHERE storage_category_id is not null""", + ) + + +@openupgrade.migrate() +def migrate(env, version=None): + openupgrade.rename_fields(env, _field_renames) + openupgrade.rename_xmlids(env.cr, _xmlid_renames) + openupgrade.add_columns(env, _new_columns) + fill_product_template_is_storable(env) + fill_stock_move_location_dest_id(env) + fill_stock_putaway_rule_sublocation(env) diff --git a/openupgrade_scripts/scripts/stock/18.0.1.1/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/stock/18.0.1.1/upgrade_analysis_work.txt new file mode 100644 index 000000000000..281bbd6324d4 --- /dev/null +++ b/openupgrade_scripts/scripts/stock/18.0.1.1/upgrade_analysis_work.txt @@ -0,0 +1,139 @@ +---Models in module 'stock'--- +obsolete model stock.assign.serial [transient] +obsolete model stock.scheduler.compute [transient] +new model stock.lot.report [sql_view] +new model stock.replenish.mixin [abstract] +new model stock.scrap.reason.tag +# NOTHING TO DO + +---Fields in module 'stock'--- +stock / product.template / detailed_type (False) : DEL selection_keys: ['consu', 'product', 'service'], mode: modify +stock / product.template / type (False) : DEL selection_keys: ['consu', 'product', 'service'], mode: modify +stock / product.template / is_storable (boolean) : NEW hasdefault: default +# DONE: pre-migration:: pre-create and fill is_storable and move 'product' to 'consu' + +stock / product.template / route_from_categ_ids (many2many): table is now 'False' ('stock.route') +# NOTHING TO DO: related field + +stock / product.template / property_stock_inventory (many2one): needs conversion to v18-style company dependent +stock / product.template / property_stock_production (many2one): needs conversion to v18-style company dependent +stock / product.template / responsible_id (many2one) : needs conversion to v18-style company dependent +stock / res.partner / property_stock_customer (many2one): needs conversion to v18-style company dependent +stock / res.partner / property_stock_supplier (many2one): needs conversion to v18-style company dependent +# DONE: post-migration: used openupgrade_180.convert_company_dependent + +stock / stock.location / return_location (boolean) : DEL +stock / stock.picking.type / default_location_return_id (many2one): DEL relation: stock.location +# NOTHING TO DO: now is using _can_return() method instead + +stock / stock.move / location_dest_id (many2one) : now a function +stock / stock.move / location_final_id (many2one) : NEW relation: stock.location +stock / stock.rule / location_dest_from_rule (boolean): NEW hasdefault: default +# DONE: pre-migration: rename location_dest_id to location_final_id, pre-create and fill location_dest_id and location_dest_from_rule + +stock / stock.move / never_product_template_attribute_value_ids (many2many): NEW relation: product.template.attribute.value +# NOTHING TO DO: new technical feature + +stock / stock.move.line / product_category_name (char) : not stored anymore +# NOTHING TO DO + +stock / stock.picking / search_date_category (selection): NEW selection_keys: ['after', 'before', 'day_1', 'day_2', 'today', 'yesterday'], stored: False +stock / stock.picking / shipping_weight (float) : previously in module stock_delivery +stock_delivery / stock.picking / shipping_weight (float) : not a function anymore +stock / stock.picking / weight_bulk (float) : previously in module stock_delivery +# NOTHING TO DO: not stored + +stock / stock.picking.type / _order : _order is now 'is_favorite desc, sequence, id' ('sequence, id') +# NOTHING TO DO: is_favorite is not stored + +stock / stock.picking.type / default_location_dest_id (many2one): now required +stock / stock.picking.type / default_location_src_id (many2one): now required +# NOTHING TO DO? (not sure if we can assure it someway) + +stock / stock.picking.type / favorite_user_ids (many2many) : NEW relation: res.users +# NOTHING TO DO: new feature + +stock / stock.picking.type / move_type (selection) : NEW required, selection_keys: ['direct', 'one'], hasdefault: default +# DONE: pre-migration: pre-create and fill it with default 'direct' + +stock / stock.picking.type / show_reserved (boolean) : DEL +# NOTHING TO DO: obsolete, see https://github.com/odoo/odoo/commit/54a795bf11d1ef5d791e587b0c9e4d260b97a79d + +stock / stock.putaway.rule / sublocation (selection) : NEW selection_keys: ['closest_location', 'last_used', 'no'], hasdefault: default +# DONE: pre-migration: pre-create and fill it ('no' by default, 'closest_location' if storage_category_id is not null) + +stock / stock.quant.package / location_id (many2one) : not a function anymore +# NOTHING TO DO: not sure why marked this way, it's the same in both v17 and v18 + +stock / stock.quant.package / shipping_weight (float) : previously in module stock_delivery +# NOTHING TO DO + +stock / stock.rule / push_domain (char) : NEW +# NOTHING TO DO: new feature + +stock / stock.scrap / scrap_reason_tag_ids (many2many): NEW relation: stock.scrap.reason.tag +stock / stock.scrap.reason.tag / color (char) : NEW hasdefault: default +stock / stock.scrap.reason.tag / name (char) : NEW required +stock / stock.scrap.reason.tag / sequence (integer) : NEW hasdefault: default +# NOTHING TO DO: new feature + +stock / stock.warehouse / qc_type_id (many2one) : NEW relation: stock.picking.type +stock / stock.warehouse / store_type_id (many2one) : NEW relation: stock.picking.type +stock / stock.warehouse / xdock_type_id (many2one) : NEW relation: stock.picking.type +# DONE: post-migration: created / updated default picking types for all warehouses + +stock / stock.warehouse.orderpoint / qty_to_order (float) : not stored anymore +stock / stock.warehouse.orderpoint / qty_to_order (float) : now a function +stock / stock.warehouse.orderpoint / qty_to_order_manual (float) : NEW +# DONE: pre-migration: rename qty_to_order to qty_to_order_manual + +---XML records in module 'stock'--- +NEW digest.tip: stock.digest_tip_stock_1 +NEW ir.actions.act_window: stock.action_get_picking_type_ready_moves +NEW ir.actions.act_window: stock.action_inventory_at_date +NEW ir.actions.act_window: stock.action_lot_report +NEW ir.actions.act_window: stock.action_picking_tree_graph +# NOTHING TO DO + +ir.actions.act_window: stock.stock_picking_action_picking_type (deleted domain) +# NOTHING TO DO: domain was already empty + +DEL ir.actions.act_window: stock.act_assign_serial_numbers +DEL ir.actions.act_window: stock.action_procurement_compute +NEW ir.actions.server: stock.action_install_barcode +NEW ir.actions.server: stock.action_print_labels +NEW ir.actions.server: stock.click_dashboard_graph +NEW ir.actions.server: stock.method_action_picking_tree_incoming +NEW ir.actions.server: stock.method_action_picking_tree_internal +NEW ir.actions.server: stock.method_action_picking_tree_outgoing +NEW ir.actions.server: stock.stock_split_picking +NEW ir.config_parameter: stock.barcode_separator (noupdate) +NEW ir.model.access: stock.access_stock_inventory_adjustment_name_manager +NEW ir.model.access: stock.access_stock_inventory_adjustment_name_user +NEW ir.model.access: stock.access_stock_location_all_user +NEW ir.model.access: stock.access_stock_lot_report +NEW ir.model.access: stock.access_stock_scrap_reason_tag_manager +NEW ir.model.access: stock.access_stock_scrap_reason_tag_user +NEW ir.model.access: stock.access_update_product_attribute_value_stock_manager +DEL ir.model.access: stock.access_stock_assign_serial +DEL ir.model.access: stock.access_stock_inventory_adjustment_name +DEL ir.model.access: stock.access_stock_scheduler_compute +NEW ir.model.constraint: stock.constraint_stock_scrap_reason_tag_name_uniq +DEL ir.ui.menu: stock.menu_reordering_rules_config +NEW ir.ui.view: stock.help_message_template +NEW ir.ui.view: stock.product_template_search_view_inherit_stock +NEW ir.ui.view: stock.search_customer_lot_filter +NEW ir.ui.view: stock.stock_lot_customer_report_view_list +DEL ir.ui.view: stock.view_assign_serial_numbers +DEL ir.ui.view: stock.view_procurement_compute_wizard +DEL res.groups: stock.group_stock_picking_wave +DEL res.groups: stock.group_stock_storage_categories +# NOTHING TO DO + +DEL ir.property: stock.property_stock_customer (noupdate) +DEL ir.property: stock.property_stock_supplier (noupdate) +# DONE: post-migration: safely delete records + +NEW stock.location: stock.stock_location_inter_company (noupdate) +DEL stock.location: stock.stock_location_inter_wh (noupdate) +# DONE: pre-migration: rename xmlid