diff --git a/docsource/modules180-190.rst b/docsource/modules180-190.rst index ab1b85ae959..b907e5e8a2a 100644 --- a/docsource/modules180-190.rst +++ b/docsource/modules180-190.rst @@ -68,9 +68,9 @@ Module coverage 18.0 -> 19.0 +---------------------------------------------------+----------------------+-------------------------------------------------+ | auth_totp_portal | | | +---------------------------------------------------+----------------------+-------------------------------------------------+ -| barcodes | |No DB layout changes. | +| barcodes |Nothing to do |No DB layout changes. | +---------------------------------------------------+----------------------+-------------------------------------------------+ -| barcodes_gs1_nomenclature | |No DB layout changes. | +| barcodes_gs1_nomenclature |Done |No DB layout changes. | +---------------------------------------------------+----------------------+-------------------------------------------------+ | base |Done | | +---------------------------------------------------+----------------------+-------------------------------------------------+ @@ -1084,9 +1084,9 @@ Module coverage 18.0 -> 19.0 +---------------------------------------------------+----------------------+-------------------------------------------------+ | spreadsheet_dashboard_website_sale_slides | | | +---------------------------------------------------+----------------------+-------------------------------------------------+ -| stock | | | +| stock |Done | | +---------------------------------------------------+----------------------+-------------------------------------------------+ -| stock_account | | | +| stock_account |Done | | +---------------------------------------------------+----------------------+-------------------------------------------------+ | stock_delivery | | | +---------------------------------------------------+----------------------+-------------------------------------------------+ diff --git a/openupgrade_scripts/apriori.py b/openupgrade_scripts/apriori.py index 819dcfff24e..1f94fe1a1dd 100644 --- a/openupgrade_scripts/apriori.py +++ b/openupgrade_scripts/apriori.py @@ -60,6 +60,7 @@ "product.packaging": "product.uom", "stock.package_level": "stock.package.history", "stock.quant.package": "stock.package", + "stock.valuation.layer": "product.value", "web_editor.assets": "website.assets", "web_editor.converter.test": "html_editor.converter.test", "web_editor.converter.test.sub": "html_editor.converter.test.sub", diff --git a/openupgrade_scripts/scripts/barcodes_gs1_nomenclature/19.0.1.0/post-migration.py b/openupgrade_scripts/scripts/barcodes_gs1_nomenclature/19.0.1.0/post-migration.py new file mode 100644 index 00000000000..1a52db04169 --- /dev/null +++ b/openupgrade_scripts/scripts/barcodes_gs1_nomenclature/19.0.1.0/post-migration.py @@ -0,0 +1,11 @@ +# Copyright 2026 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.load_data( + env, "barcodes_gs1_nomenclature", "19.0.1.0/noupdate_changes.xml" + ) diff --git a/openupgrade_scripts/scripts/stock/19.0.1.1/end-migration.py b/openupgrade_scripts/scripts/stock/19.0.1.1/end-migration.py new file mode 100644 index 00000000000..af0a8afcd5b --- /dev/null +++ b/openupgrade_scripts/scripts/stock/19.0.1.1/end-migration.py @@ -0,0 +1,13 @@ +# Copyright 2026 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + env["stock.picking"].search( + [ + ("move_line_ids", "not in", ("done", "cancel")), + ] + )._check_entire_pack() diff --git a/openupgrade_scripts/scripts/stock/19.0.1.1/post-migration.py b/openupgrade_scripts/scripts/stock/19.0.1.1/post-migration.py new file mode 100644 index 00000000000..6b729918c81 --- /dev/null +++ b/openupgrade_scripts/scripts/stock/19.0.1.1/post-migration.py @@ -0,0 +1,144 @@ +# Copyright 2026 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + + +def stock_move_reference_ids(env): + """ + Fill stock.move#reference_ids from obsolete group_id + """ + env.cr.execute( + """ + INSERT INTO stock_reference_move_rel + (move_id, reference_id) + SELECT id, group_id FROM stock_move + WHERE group_id IS NOT NULL + """ + ) + + +def stock_move_packaging_uom_id(env): + """ + Use stock.move#product_packaging_id to fill stock.move#packaging_uom_id + """ + env.cr.execute( + """ + UPDATE stock_move + SET packaging_uom_id=product_uom.uom_id + FROM + product_uom + WHERE product_packaging_id=product_uom.id + """ + ) + + +def stock_picking_package_history_ids(env): + """ + Use stock.package_level#picking_id to fill stock.picking#package_history_ids + """ + env.cr.execute( + """ + INSERT INTO stock_package_history_stock_picking_rel + (stock_picking_id, stock_package_history_id) + SELECT picking_id, id + FROM stock_package_history + WHERE picking_id IS NOT NULL + """ + ) + + +def stock_package_type_package_use(env): + """ + Set stock.package.type#package_use to 'reusable' if all previous stock.quant.package + records using this type had package_use = 'reusable' + """ + env.cr.execute( + """ + UPDATE stock_package_type + SET package_use='reusable' + WHERE id IN ( + SELECT package_type_id + FROM stock_package + GROUP BY package_type_id + HAVING array_agg(distinct package_use) <@ '{"reusable"}' + ) + """ + ) + + +def uom_uom_package_type_id(env): + """ + Set uom.uom#package_type_id from previous product.packaging#packaging_type + """ + env.cr.execute( + """ + UPDATE uom_uom + SET package_type_id=product_uom.package_type_id + FROM product_uom + WHERE product_uom.uom_id=uom_uom.id + AND product_uom.package_type_id IS NOT NULL + """ + ) + + +def stock_packaging_type_route_ids(env): + """ + Set stock.packaging.type#route_ids from previous product.packaging#route_ids + """ + env.cr.execute( + """ + INSERT INTO stock_package_type_stock_route_rel + (stock_package_type_id, stock_route_id) + SELECT DISTINCT + product_uom.package_type_id, stock_route_packaging.route_id + FROM + stock_route_packaging + JOIN product_uom + ON stock_route_packaging.packaging_id=product_uom.id + """ + ) + + +def stock_package_history_package_name(env): + """ + Set stock.package.history#package_name from package_id#name + """ + env.cr.execute( + """ + UPDATE stock_package_history + SET package_name=stock_package.name + FROM stock_package + WHERE + stock_package_history.package_id=stock_package.id + AND package_name IS NULL + """ + ) + + +_deleted_xmlids = [ + "stock.stock_location_locations_virtual", + "stock.stock_location_locations_partner", + "stock.stock_location_locations", +] + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.load_data(env, "stock", "19.0.1.1/noupdate_changes.xml") + openupgrade.delete_record_translations( + env.cr, + "stock", + [ + "mail_template_data_delivery_confirmation", + ], + ["body_html"], + ) + stock_move_reference_ids(env) + stock_move_packaging_uom_id(env) + stock_picking_package_history_ids(env) + stock_package_type_package_use(env) + uom_uom_package_type_id(env) + stock_packaging_type_route_ids(env) + stock_package_history_package_name(env) + openupgrade.delete_records_safely_by_xml_id(env, _deleted_xmlids) diff --git a/openupgrade_scripts/scripts/stock/19.0.1.1/pre-migration.py b/openupgrade_scripts/scripts/stock/19.0.1.1/pre-migration.py new file mode 100644 index 00000000000..8c3244e68a8 --- /dev/null +++ b/openupgrade_scripts/scripts/stock/19.0.1.1/pre-migration.py @@ -0,0 +1,42 @@ +# Copyright 2026 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + +_renamed_models = [ + ("procurement.group", "stock.reference"), + ("stock.package_level", "stock.package.history"), + ("stock.quant.package", "stock.package"), +] + +_renamed_tables = [ + ("procurement_group", "stock_reference"), + ("stock_package_level", "stock_package_history"), + ("stock_quant_package", "stock_package"), +] + +_renamed_fields = [ + ("stock.reference", "stock_reference", "stock_move_ids", "move_ids"), + ("stock.move.line", "stock_move_line", "package_level_id", "package_history_id"), + ("stock.picking", "stock_picking", "package_level_ids", "package_history_ids"), + ("stock.route", "stock_route", "packaging_selectable", "package_type_selectable"), +] + +_renamed_xmlids = [ + ("stock.seq_quant_package", "stock.seq_package"), +] + +_deleted_xmlids = [ + "stock.stock_quant_package_comp_rule", + "stock.sequence_proc_group", + "stock.constraint_stock_warehouse_orderpoint_qty_multiple_check", +] + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.rename_models(env.cr, _renamed_models) + openupgrade.rename_tables(env.cr, _renamed_tables) + openupgrade.rename_fields(env, _renamed_fields) + openupgrade.rename_xmlids(env.cr, _renamed_xmlids) + openupgrade.delete_records_safely_by_xml_id(env, _deleted_xmlids) diff --git a/openupgrade_scripts/scripts/stock/19.0.1.1/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/stock/19.0.1.1/upgrade_analysis_work.txt new file mode 100644 index 00000000000..1c760208dbc --- /dev/null +++ b/openupgrade_scripts/scripts/stock/19.0.1.1/upgrade_analysis_work.txt @@ -0,0 +1,367 @@ +---Models in module 'stock'--- +obsolete model procurement.group (renamed to stock.reference) + +# DONE: renamed in pre-migration + +obsolete model stock.change.product.qty [transient] +obsolete model stock.lot.report [sql_view] + +# NOTHING TO DO + +obsolete model stock.package_level (renamed to stock.package.history) +obsolete model stock.quant.package (renamed to stock.package) + +# DONE: renamed in pre-migration + +obsolete model stock.track.confirmation [transient] +obsolete model stock.track.line [transient] + +# NOTHING TO DO + +new model stock.package (renamed from stock.quant.package) +new model stock.package.history (renamed from stock.package_level) + +# DONE: renamed in pre-migration + +new model stock.put.in.pack [transient] + +# NOTHING TO DO + +new model stock.reference (renamed from procurement.group) + +# DONE: renamed in pre-migration + +---Fields in module 'stock'--- +stock / procurement.group / _order : _order is now 'id' ('id desc') +stock / procurement.group / move_type (selection) : DEL selection_keys: ['direct', 'one'] +stock / procurement.group / partner_id (many2one) : DEL relation: res.partner + +# NOTHING TO DO + +stock / procurement.group / stock_move_ids (one2many) : DEL relation: stock.move + +# DONE: renamed to move_ids in pre-migration + +stock / product.packaging / package_type_id (many2one) : DEL relation: stock.package.type + +# DONE: set package_type_id of corresponding uom + +stock / product.packaging / route_ids (many2many) : DEL relation: stock.route + +# DONE: used to set stock.package.type#route_ids + +stock / product.template / lot_sequence_id (many2one) : NEW relation: ir.sequence, hasdefault: default +stock / res.company / horizon_days (float) : NEW required, hasdefault: default +stock / res.company / stock_confirmation_type (selection): NEW selection_keys: ['sms'], hasdefault: default +stock / res.company / stock_text_confirmation (boolean): NEW + +# NOTHING TO DO: default is fine + +stock / res.partner / picking_warn (selection) : DEL selection_keys: ['block', 'no-message', 'warning'] +stock / stock.location / comment (html) : DEL +stock / stock.location / posx (integer) : DEL +stock / stock.location / posy (integer) : DEL +stock / stock.location / posz (integer) : DEL +stock / stock.location / scrap_location (boolean) : DEL +stock / stock.lot / product_uom_id (many2one) : not stored anymore +stock / stock.move / description_picking (text) : not stored anymore +stock / stock.move / description_picking (text) : now a function +stock / stock.move / description_picking_manual (text): NEW + +# NOTHING TO DO + +stock / stock.move / group_id (many2one) : DEL relation: procurement.group + +# DONE: used to fill reference_ids in post-migration + +stock / stock.move / inventory_name (char) : NEW +stock / stock.move / name (char) : DEL required +stock / stock.move / package_level_id (many2one) : DEL relation: stock.package_level + +# NOTHING TO DO + +stock / stock.move / packaging_uom_id (many2one) : NEW relation: uom.uom, isfunction: function, stored + +# DONE: filled from product_packaging_id in post-migration + +stock / stock.move / packaging_uom_qty (float) : NEW isfunction: function, stored +stock / stock.move / procurement_values (json) : NEW stored: False + +# NOTHING TO DO + +stock / stock.move / product_packaging_id (many2one): DEL relation: product.packaging + +# DONE: used to fill packaging_uom_id in post-migration + +stock / stock.move / reference_ids (many2many) : NEW relation: stock.reference + +# DONE: filled from group_id in post-migration + +stock / stock.move / scrapped (boolean) : DEL +stock / stock.move.line / description_picking (text) : not stored anymore +stock / stock.move.line / description_picking (text) : now related + +# NOTHING TO DO + +stock / stock.move.line / is_entire_pack (boolean) : NEW + +# DONE: computed for pending pickings in end-migration + +stock / stock.move.line / package_history_id (many2one) : NEW relation: stock.package.history + +# DONE: renamed from package_level_id in pre-migration + +stock / stock.move.line / package_id (many2one) : relation is now 'stock.package' ('stock.quant.package') [nothing to do] + +# NOTHING TO DO + +stock / stock.move.line / package_level_id (many2one) : DEL relation: stock.package_level + +# DONE: renamed to package_history_id in pre-migration + +stock / stock.move.line / reference (char) : not stored anymore +stock / stock.move.line / result_package_id (many2one) : relation is now 'stock.package' ('stock.quant.package') [nothing to do] + +# NOTHING TO DO + +stock / stock.package / child_package_dest_ids (one2many): NEW relation: stock.package +stock / stock.package / child_package_ids (one2many) : NEW relation: stock.package +stock / stock.package / complete_name (char) : NEW isfunction: function, stored +stock / stock.package / package_dest_id (many2one) : NEW relation: stock.package +stock / stock.package / parent_package_id (many2one) : NEW relation: stock.package +stock / stock.package / parent_path (char) : NEW +stock / stock.package.history / outermost_dest_id (many2one) : NEW relation: stock.package + +# NOTHING TO DO: new feature + +stock / stock.package.history / package_name (char) : NEW required + +# DONE: set from package_id.name in post-migration + +stock / stock.package.history / parent_dest_id (many2one) : NEW relation: stock.package +stock / stock.package.history / parent_dest_name (char) : NEW +stock / stock.package.history / parent_orig_id (many2one) : NEW relation: stock.package +stock / stock.package.history / parent_orig_name (char) : NEW + +# NOTHING TO DO: new feature + +stock / stock.package.history / picking_ids (many2many) : NEW relation: stock.picking + +# DONE: set from stock.package_level#picking_id + +stock / stock.package.type / package_use (selection) : NEW required, selection_keys: ['disposable', 'reusable'], hasdefault: default + +# DONE: set to reusable if all previous stock.quant.package had this use + +stock / stock.package.type / route_ids (many2many) : NEW relation: stock.route + +# DONE: set from stock.packaging#route_ids + +stock / stock.package.type / sequence_id (many2one) : NEW relation: ir.sequence +stock / stock.package_level / location_id (many2one) : is now stored +stock / stock.package_level / location_id (many2one) : not a function anymore +stock / stock.package_level / move_ids (one2many) : DEL relation: stock.move +stock / stock.package_level / move_line_ids (one2many) : now required +stock / stock.package_level / package_id (many2one) : relation is now 'stock.package' ('stock.quant.package') [nothing to do] + +# NOTHING TO DO + +stock / stock.package_level / picking_id (many2one) : DEL relation: stock.picking + +# DONE: see stock.package.history#picking_ids + +stock / stock.picking / date (datetime) : DEL +stock / stock.picking / group_id (many2one) : DEL relation: procurement.group +stock / stock.picking / move_ids_without_package (one2many): DEL relation: stock.move +stock / stock.picking / move_line_ids_without_package (one2many): DEL relation: stock.move.line + +# NOTHING TO DO + +stock / stock.picking / package_history_ids (many2many): NEW relation: stock.package.history +stock / stock.picking / package_level_ids (one2many) : DEL relation: stock.package_level + +# DONE: renamed in pre-migration + +stock / stock.picking / package_level_ids_details (one2many): DEL relation: stock.package_level +stock / stock.picking / shipping_weight (float) : is now stored +stock / stock.picking.type / set_package_type (boolean) : NEW hasdefault: default +stock / stock.quant / package_id (many2one) : relation is now 'stock.package' ('stock.quant.package') [nothing to do] +stock / stock.quant / storage_category_id (many2one): not stored anymore +stock / stock.quant.package / _order : _order is now 'name, id' ('name') + +# NOTHING TO DO + +stock / stock.quant.package / package_use (selection) : DEL required, selection_keys: ['disposable', 'reusable'] + +# DONE: used to set stock.package.type#package_use + +stock / stock.reference / move_ids (many2many) : NEW relation: stock.move + +# DONE: renamed from stock_move_ids in pre-migration + +stock / stock.route / package_type_selectable (boolean): NEW + +# DONE: renamed from packaging_selectable + +stock / stock.route / packaging_ids (many2many) : DEL relation: product.packaging + +# DONE: used to set stock.package.type#route_ids + +stock / stock.route / packaging_selectable (boolean): DEL + +# DONE: renamed to package_type_selectable + +stock / stock.rule / group_id (many2one) : DEL relation: procurement.group +stock / stock.rule / group_propagation_option (selection): DEL selection_keys: ['fixed', 'none', 'propagate'] +stock / stock.rule / picking_type_code_domain (char): type is now 'json' ('char') +stock / stock.rule / propagate_warehouse_id (many2one): DEL relation: stock.warehouse +stock / stock.scrap / package_id (many2one) : relation is now 'stock.package' ('stock.quant.package') [nothing to do] +stock / stock.warehouse / crossdock_route_id (many2one) : DEL relation: stock.route +stock / stock.warehouse.orderpoint / deadline_date (date) : NEW isfunction: function, stored +stock / stock.warehouse.orderpoint / group_id (many2one) : DEL relation: procurement.group +stock / stock.warehouse.orderpoint / product_category_id (many2one): not stored anymore +stock / stock.warehouse.orderpoint / qty_multiple (float) : DEL required +stock / stock.warehouse.orderpoint / qty_to_order_computed (float) : is now stored +stock / stock.warehouse.orderpoint / replenishment_uom_id (many2one): NEW relation: uom.uom + +# NOTHING TO DO + +stock / uom.uom / package_type_id (many2one) : NEW relation: stock.package.type + +# NOTHING TO DO: see above for product.packaging + +---XML records in module 'stock'--- +NEW ir.actions.act_window: stock.action_put_in_pack_wizard +NEW ir.actions.act_window: stock.action_stock_reference +NEW ir.actions.act_window: stock.stock_quant_action +DEL ir.actions.act_window: stock.action_change_product_quantity +DEL ir.actions.act_window: stock.action_lot_report +DEL ir.actions.act_window: stock.dashboard_open_quants +DEL ir.actions.act_window: stock.do_view_pickings +DEL ir.actions.act_window: stock.location_open_quants +NEW ir.actions.report: stock.action_report_package_barcode +NEW ir.actions.report: stock.action_report_package_barcode_small +NEW ir.actions.report: stock.action_report_package_history_barcode +NEW ir.actions.report: stock.action_report_package_history_barcode_small +NEW ir.actions.report: stock.label_package_history_template +NEW ir.actions.report: stock.label_packaging_barcode +DEL ir.actions.report: stock.action_report_quant_package_barcode +DEL ir.actions.report: stock.action_report_quant_package_barcode_small +DEL ir.actions.report: stock.label_product_packaging +NEW ir.actions.server: stock.action_product_replenishment +NEW ir.actions.server: stock.action_product_template_replenishment +NEW ir.actions.server: stock.action_stock_quant_relocate +NEW ir.model.access: stock.access_stock_package_all +NEW ir.model.access: stock.access_stock_package_history_user +NEW ir.model.access: stock.access_stock_package_stock_manager +NEW ir.model.access: stock.access_stock_package_stock_user +NEW ir.model.access: stock.access_stock_put_in_pack_user +NEW ir.model.access: stock.access_stock_reference +DEL ir.model.access: stock.access_procurement_group +DEL ir.model.access: stock.access_product_category_stock_manager +DEL ir.model.access: stock.access_product_packaging_stock_manager +DEL ir.model.access: stock.access_product_pricelist_item_stock_manager +DEL ir.model.access: stock.access_product_product_attribute_manager +DEL ir.model.access: stock.access_product_product_stock_manager +DEL ir.model.access: stock.access_product_supplierinfo_stock_manager +DEL ir.model.access: stock.access_product_tag_stock_manager +DEL ir.model.access: stock.access_product_template_attribute_exclusion_manager +DEL ir.model.access: stock.access_product_template_attribute_line_manager +DEL ir.model.access: stock.access_product_template_stock_manager +DEL ir.model.access: stock.access_stock_change_product_qty +DEL ir.model.access: stock.access_stock_location_user +DEL ir.model.access: stock.access_stock_lot_report +DEL ir.model.access: stock.access_stock_package_level_all +DEL ir.model.access: stock.access_stock_package_level_stock_manager +DEL ir.model.access: stock.access_stock_package_level_stock_user +DEL ir.model.access: stock.access_stock_quant_package_all +DEL ir.model.access: stock.access_stock_quant_package_stock_manager +DEL ir.model.access: stock.access_stock_quant_package_stock_user +DEL ir.model.access: stock.access_stock_track_confirmation +DEL ir.model.access: stock.access_stock_track_line +DEL ir.model.access: stock.access_uom_category_stock_manager +DEL ir.model.access: stock.access_uom_uom_stock_manager +NEW ir.model.constraint: stock.constraint_stock_location_parent_path_id_idx +NEW ir.model.constraint: stock.constraint_stock_move_line_free_reservation_index +NEW ir.model.constraint: stock.constraint_stock_move_product_location_index + +# NOTHING TO DO + +DEL ir.model.constraint: stock.constraint_stock_warehouse_orderpoint_qty_multiple_check + +# DONE: deleted in pre-migration + +NEW ir.rule: stock.stock_package_comp_rule (noupdate) + +# NOTHING TO DO + +DEL ir.rule: stock.stock_quant_package_comp_rule (noupdate) + +# DONE: deleted in pre-migration + +NEW ir.sequence: stock.seq_package (noupdate) +DEL ir.sequence: stock.seq_quant_package (noupdate) + +# DONE: renamed in pre-migration + +DEL ir.sequence: stock.sequence_proc_group (noupdate) + +# DONE: deleted in pre-migration + +NEW ir.ui.menu: stock.menu_stock_references +DEL ir.ui.menu: stock.menu_product_packagings +DEL ir.ui.menu: stock.menu_stock_unit_measure_stock +DEL ir.ui.menu: stock.menu_stock_uom_categ_form_action +DEL ir.ui.menu: stock.product_uom_menu +NEW ir.ui.view: stock.alternative_zpl_label +NEW ir.ui.view: stock.jewelry_zpl_label +NEW ir.ui.view: stock.label_package_history_template_view +NEW ir.ui.view: stock.label_packaging_barcode_view +NEW ir.ui.view: stock.normal_zpl_label +NEW ir.ui.view: stock.package_history_search_view +NEW ir.ui.view: stock.product_label_layout_form_stock +NEW ir.ui.view: stock.product_uom_form_view_inherit +NEW ir.ui.view: stock.product_uom_tree_view_inherit +NEW ir.ui.view: stock.report_package_barcode_content +NEW ir.ui.view: stock.report_package_history_barcode +NEW ir.ui.view: stock.report_package_history_barcode_small +NEW ir.ui.view: stock.report_return_document +NEW ir.ui.view: stock.small_zpl_label +NEW ir.ui.view: stock.stock_package_view_add_list +NEW ir.ui.view: stock.stock_package_view_form +NEW ir.ui.view: stock.stock_package_view_kanban +NEW ir.ui.view: stock.stock_package_view_list +NEW ir.ui.view: stock.stock_package_view_list_editable +NEW ir.ui.view: stock.stock_package_view_search +NEW ir.ui.view: stock.stock_put_in_pack_form +NEW ir.ui.view: stock.stock_reference_form_view +NEW ir.ui.view: stock.stock_reference_search_view +NEW ir.ui.view: stock.stock_reference_tree_view +NEW ir.ui.view: stock.view_stock_package_history_list +NEW ir.ui.view: stock.view_warehouse_orderpoint_tree_editable_show_trigger +DEL ir.ui.view: stock.duplicated_sn_warning +DEL ir.ui.view: stock.label_product_packaging_view +DEL ir.ui.view: stock.package_level_form_edit_view +DEL ir.ui.view: stock.package_level_form_view +DEL ir.ui.view: stock.package_level_tree_view_picking +DEL ir.ui.view: stock.procurement_group_form_view +DEL ir.ui.view: stock.product_packaging_form_view +DEL ir.ui.view: stock.product_packaging_tree_view +DEL ir.ui.view: stock.product_product_view_form_easy_inherit_stock +DEL ir.ui.view: stock.quant_package_search_view +DEL ir.ui.view: stock.search_customer_lot_filter +DEL ir.ui.view: stock.stock_lot_customer_report_view_list +DEL ir.ui.view: stock.view_change_product_quantity +DEL ir.ui.view: stock.view_quant_package_form +DEL ir.ui.view: stock.view_quant_package_kanban +DEL ir.ui.view: stock.view_quant_package_tree +DEL ir.ui.view: stock.view_stock_track_confirmation +NEW res.groups.privilege: stock.res_groups_privilege_inventory + +# NOTHING TO DO + +DEL stock.location: stock.stock_location_locations (noupdate) +DEL stock.location: stock.stock_location_locations_partner (noupdate) +DEL stock.location: stock.stock_location_locations_virtual (noupdate) + +# DONE: deleted in post-migration diff --git a/openupgrade_scripts/scripts/stock_account/19.0.1.1/end-migration.py b/openupgrade_scripts/scripts/stock_account/19.0.1.1/end-migration.py new file mode 100644 index 00000000000..4a5b37c7248 --- /dev/null +++ b/openupgrade_scripts/scripts/stock_account/19.0.1.1/end-migration.py @@ -0,0 +1,114 @@ +# Copyright 2026 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + +from odoo import fields + + +def update_from_coa_generic(env, spec): + """ + Update some models from the COA according to spec: + {model_name1: [fieldname1, fieldname2, ...], model_name2: [...], ...} + + TODO: Move this to openupgradelib if needed for more migrations than + account, stock_account + """ + + for company in env["res.company"].search([]): + AccountChartTemplate = env["account.chart.template"].with_context( + default_company_id=company.id, + allowed_company_ids=company.ids, + tracking_disable=True, + delay_account_group_sync=True, + lang="en_US", + chart_template_load=True, + ) + + if company.chart_template not in AccountChartTemplate._template_register: + openupgrade.logger.error( + "chart template %s unknown (not yet migrated?)", + company.chart_template, + ) + continue + + def ref_or_id(ref_or_id, model_name, AccountChartTemplate=AccountChartTemplate): + if isinstance(ref_or_id, int): + return env[model_name].browse(ref_or_id) + return AccountChartTemplate.ref(ref_or_id, False) or env[model_name].browse( + [] + ) + + template_data = AccountChartTemplate._get_chart_template_data( + company.chart_template + ) + + company_data = {} + for model_name, field_names in spec.items(): + company_data[model_name] = { + record_id: { + key: value + for key, value in record_data.items() + if key in field_names and not ref_or_id(record_id, model_name)[key] + } + for record_id, record_data in template_data[model_name].items() + if any(record_data.get(key) for key in field_names) + } + AccountChartTemplate._load_data(company_data) + + +def update_from_coa(env): + """ + Set fields account.account#{account_stock_expense_id,account_stock_variation_id} + and res.company#{account_stock_journal_id,account_stock_valuation_id} + from localization if not set elsewhere and the localization sets it + """ + update_from_coa_generic( + env, + { + "res.company": ["account_stock_journal_id", "account_stock_valuation_id"], + "account.account": [ + "account_stock_expense_id", + "account_stock_variation_id", + ], + }, + ) + + +def stock_lot_avg_cost(env): + """ + Run compute method on stock.lot#avg_cost + """ + lots = ( + env["stock.lot"] + .search( + [ + ("lot_valuated", "=", True), + ] + ) + .with_context(to_date=fields.Datetime.now()) + ) + for records in openupgrade.chunked(lots): + records._compute_avg_cost() + + +def stock_move_is_fields(env): + """ + Run compute methods for stock.move#is_* + """ + moves = env["stock.move"].search( + [ + ("state", "=", "done"), + ] + ) + for records in openupgrade.chunked(moves): + records._compute_is_in() + records._compute_is_out() + records._compute_is_dropship() + + +@openupgrade.migrate() +def migrate(env, version): + update_from_coa(env) + stock_lot_avg_cost(env) + stock_move_is_fields(env) diff --git a/openupgrade_scripts/scripts/stock_account/19.0.1.1/post-migration.py b/openupgrade_scripts/scripts/stock_account/19.0.1.1/post-migration.py new file mode 100644 index 00000000000..c90e05afd15 --- /dev/null +++ b/openupgrade_scripts/scripts/stock_account/19.0.1.1/post-migration.py @@ -0,0 +1,103 @@ +# Copyright 2026 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + + +def product_value_product_id(env): + """ + Fill product.value#product_id from move_id.product_id + """ + env.cr.execute( + """ + UPDATE product_value + SET product_id=stock_move.product_id + FROM stock_move + WHERE product_value.move_id=stock_move.id + AND product_value.product_id IS NULL + """ + ) + + +def stock_move_account_move_id(env): + """ + Fill stock.move#account_move_id from account.move#stock_move_id + """ + env.cr.execute( + """ + UPDATE stock_move + SET account_move_id=account_move.id + FROM account_move + WHERE + account_move.stock_move_id=stock_move.id + AND stock_move.account_move_id IS NULL + """ + ) + + +def product_category_property_valuation(env): + """ + Change value 'manual_periodic' to 'periodic' + """ + env["ir.default"].search( + [ + ("field_id.name", "=", "property_valuation"), + ("field_id.model_id.model", "=", "product.category"), + ("json_value", "=", '"manual_periodic"'), + ] + ).write({"json_value": '"periodic"'}) + + for company in env["res.company"].search([]): + env.cr.execute( + f""" + UPDATE product_category + SET + property_valuation = property_valuation || '{{"{company.id}": "periodic"}}' + WHERE + property_valuation->>'{company.id}' = 'manual_periodic' + """ + ) + + +def stock_location_valuation_account_id(env): + """ + Set stock.location#valuation_account_id from valuation_in_account_id and + valuation_out_account_id if they are the same + """ + env.cr.execute( + """ + UPDATE stock_location + SET valuation_account_id=valuation_in_account_id + WHERE + valuation_in_account_id=valuation_out_account_id + """ + ) + + +def stock_move_value(env): + """ + Set stock.move#value to sum of product.value#value for this move + """ + env.cr.execute( + """ + UPDATE stock_move + SET value=aggregated_values.value + FROM ( + SELECT + move_id, sum(value) value + FROM + product_value + GROUP BY move_id + ) aggregated_values + WHERE aggregated_values.move_id=stock_move.id + """ + ) + + +@openupgrade.migrate() +def migrate(env, version): + product_value_product_id(env) + stock_move_account_move_id(env) + product_category_property_valuation(env) + stock_location_valuation_account_id(env) + stock_move_value(env) diff --git a/openupgrade_scripts/scripts/stock_account/19.0.1.1/pre-migration.py b/openupgrade_scripts/scripts/stock_account/19.0.1.1/pre-migration.py new file mode 100644 index 00000000000..74b694fb728 --- /dev/null +++ b/openupgrade_scripts/scripts/stock_account/19.0.1.1/pre-migration.py @@ -0,0 +1,90 @@ +# Copyright 2026 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + +_renamed_models = [ + ("stock.valuation.layer", "product.value"), +] + +_renamed_tables = [ + ("stock_valuation_layer", "product_value"), +] + +_renamed_fields = [ + ("product.value", "product_value", "", ""), +] + +_copied_columns = { + "product_value": [ + ("create_date", "date", None), + ("create_uid", "user_id", None), + ("stock_move_id", "move_id", None), + ], +} + +_deleted_xmlids = [ + "stock_account.stock_valuation_layer_company_rule", + "stock_account.group_stock_accounting_automatic", +] + + +def stock_lot_avg_cost(env): + """ + Precreate stock.lot#avg_cost to avoid compute method + """ + openupgrade.add_fields( + env, + [ + ("avg_cost", "stock.lot", "stock_lot", "float", None, "stock_account", 0), + ], + ) + + +def stock_move_is_fields(env): + """ + Precreate stock.move#is_* to avoid compute method + """ + openupgrade.add_fields( + env, + [ + ( + "is_in", + "stock.move", + "stock_move", + "boolean", + None, + "stock_account", + False, + ), + ( + "is_out", + "stock.move", + "stock_move", + "boolean", + None, + "stock_account", + False, + ), + ( + "is_dropship", + "stock.move", + "stock_move", + "boolean", + None, + "stock_account", + False, + ), + ], + ) + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.rename_models(env.cr, _renamed_models) + openupgrade.rename_tables(env.cr, _renamed_tables) + openupgrade.rename_fields(env, _renamed_fields) + openupgrade.copy_columns(env.cr, _copied_columns) + openupgrade.delete_records_safely_by_xml_id(env, _deleted_xmlids) + stock_lot_avg_cost(env) + stock_move_is_fields(env) diff --git a/openupgrade_scripts/scripts/stock_account/19.0.1.1/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/stock_account/19.0.1.1/upgrade_analysis_work.txt new file mode 100644 index 00000000000..70b6412d352 --- /dev/null +++ b/openupgrade_scripts/scripts/stock_account/19.0.1.1/upgrade_analysis_work.txt @@ -0,0 +1,222 @@ +---Models in module 'stock_account'--- +obsolete model stock.valuation.layer + +# DONE: renamed to product.value + +obsolete model stock.valuation.layer.revaluation [transient] + +# NOTHING TO DO + +new model product.value + +# DONE: renamed from stock.valuation.layer + +new model stock_account.stock.valuation.report [abstract] +new model stock.avco.report [abstract] + +# NOTHING TO DO + +---Fields in module 'stock_account'--- +stock_account / account.account / account_stock_expense_id (many2one): NEW relation: account.account +stock_account / account.account / account_stock_variation_id (many2one): NEW relation: account.account + +# DONE: set in end-migration + +stock_account / account.move / stock_move_id (many2one) : DEL relation: stock.move +stock_account / account.move / stock_move_ids (one2many) : NEW relation: stock.move + +# DONE: filled from account.move#stock_move_id + +stock_account / account.move / stock_valuation_layer_ids (one2many): DEL relation: stock.valuation.layer +stock_account / account.move.line / stock_valuation_layer_ids (one2many): DEL relation: stock.valuation.layer + +# NOTHING TO DO + +stock_account / product.category / property_price_difference_account_id (many2one): NEW relation: account.account +stock_account / product.category / property_stock_account_input_categ_id (many2one): DEL relation: account.account +stock_account / product.category / property_stock_account_output_categ_id (many2one): DEL relation: account.account + +# NOTHING TO DO + +stock_account / product.category / property_valuation (selection): selection_keys added: [periodic], removed: [manual_periodic] + +# DONE: changed 'manual_periodic' to 'periodoc' + +stock_account / product.product / stock_valuation_layer_ids (one2many): DEL relation: stock.valuation.layer + +# NOTHING TO DO + +stock_account / product.template / cost_method (selection) : not related anymore +stock_account / product.template / cost_method (selection) : now a function +stock_account / product.template / cost_method (selection) : selection_keys is now '['average', 'fifo', 'standard']' ('function') + +# NOTHING TO DO: non-stored + +stock_account / product.template / property_price_difference_account_id (many2one): NEW relation: account.account + +# NOTHING TO DO: seems unused on products anyways + +stock_account / product.template / valuation (selection) : not related anymore +stock_account / product.template / valuation (selection) : now a function +stock_account / product.template / valuation (selection) : selection_keys is now '['periodic', 'real_time']' ('function') + +# NOTHING TO DO: non-stored + +stock_account / product.value / company_id (many2one) : NEW relation: res.company, required, hasdefault: compute + +# NOTHING TO DO + +stock_account / product.value / date (datetime) : NEW required, hasdefault: default + +# DONE: set from create_date + +stock_account / product.value / description (char) : NEW +stock_account / product.value / lot_id (many2one) : NEW relation: stock.lot + +# NOTHING TO DO + +stock_account / product.value / move_id (many2one) : NEW relation: stock.move + +# DONE: renamed from stock_move_id + +stock_account / product.value / product_id (many2one) : NEW relation: product.product + +# DONE: set from move_id + +stock_account / product.value / user_id (many2one) : NEW relation: res.users, required, hasdefault: default + +# DONE: set from create_uid + +stock_account / product.value / value (float) : NEW required + +# NOTHING TO DO + +stock_account / res.company / account_stock_journal_id (many2one): NEW relation: account.journal +stock_account / res.company / account_stock_valuation_id (many2one): NEW relation: account.account + +# DONE: set in end-migration + +stock_account / res.company / cost_method (selection) : NEW required, selection_keys: ['average', 'fifo', 'standard'], hasdefault: default +stock_account / res.company / inventory_period (selection) : NEW required, selection_keys: ['daily', 'manual', 'monthly'], hasdefault: default +stock_account / res.company / inventory_valuation (selection): NEW selection_keys: ['periodic', 'real_time'], hasdefault: default + +# NOTHING TO DO: defaults are fine or won't matter for a migrated db + +stock_account / stock.location / valuation_account_id (many2one): NEW relation: account.account + +# DONE: set from valuation_in_account_id and valuation_out_account_id + +stock_account / stock.location / valuation_in_account_id (many2one): DEL relation: account.account +stock_account / stock.location / valuation_out_account_id (many2one): DEL relation: account.account + +# NOTHING TO DO + +stock_account / stock.lot / avg_cost (float) : is now stored + +# DONE: delayed computation to end-migration + +stock_account / stock.lot / stock_valuation_layer_ids (one2many): DEL relation: stock.valuation.layer + +# NOTHING TO DO + +stock_account / stock.move / account_move_id (many2one) : NEW relation: account.move + +# DONE: filled from account.move#stock_move_id + +stock_account / stock.move / account_move_ids (one2many) : DEL relation: account.move +stock_account / stock.move / company_currency_id (many2one): previously in module l10n_in_ewaybill_stock + +# NOTHING TO DO + +stock_account / stock.move / is_dropship (boolean) : NEW isfunction: function, stored +stock_account / stock.move / is_in (boolean) : NEW isfunction: function, stored +stock_account / stock.move / is_out (boolean) : NEW isfunction: function, stored + +# DONE: delayed computation to end-migration + +stock_account / stock.move / stock_valuation_layer_ids (one2many): DEL relation: stock.valuation.layer + +# NOTHING TO DO + +stock_account / stock.move / value (float) : NEW + +# DONE: computed from product.value#value + +stock_account / stock.quant / cost_method (selection) : not related anymore +stock_account / stock.quant / cost_method (selection) : now a function +stock_account / stock.quant / cost_method (selection) : selection_keys is now '['average', 'fifo', 'standard']' ('function') +stock_account / stock.quant / currency_id (many2one) : not a function anymore +stock_account / stock.quant / currency_id (many2one) : now related + +# NOTHING TO DO: non-stored + +stock_account / stock.valuation.layer / account_move_id (many2one) : DEL relation: account.move +stock_account / stock.valuation.layer / account_move_line_id (many2one): DEL relation: account.move.line +stock_account / stock.valuation.layer / categ_id (many2one) : DEL relation: product.category +stock_account / stock.valuation.layer / company_id (many2one) : DEL relation: res.company, required +stock_account / stock.valuation.layer / description (char) : DEL +stock_account / stock.valuation.layer / lot_id (many2one) : DEL relation: stock.lot +stock_account / stock.valuation.layer / price_diff_value (float) : DEL +stock_account / stock.valuation.layer / product_id (many2one) : DEL relation: product.product, required +stock_account / stock.valuation.layer / quantity (float) : DEL +stock_account / stock.valuation.layer / remaining_qty (float) : DEL +stock_account / stock.valuation.layer / remaining_value (float) : DEL +stock_account / stock.valuation.layer / stock_move_id (many2one) : DEL relation: stock.move +stock_account / stock.valuation.layer / stock_valuation_layer_id (many2one): DEL relation: stock.valuation.layer +stock_account / stock.valuation.layer / stock_valuation_layer_ids (one2many): DEL relation: stock.valuation.layer +stock_account / stock.valuation.layer / unit_cost (float) : DEL +stock_account / stock.valuation.layer / value (float) : DEL + +# DONE: see product.value + +---XML records in module 'stock_account'--- +NEW ir.actions.act_window: stock_account.product_value_action +NEW ir.actions.act_window: stock_account.stock_avco_report_action +NEW ir.actions.act_window: stock_account.stock_move_valuation_action +DEL ir.actions.act_window: stock_account.action_revalue_layers +DEL ir.actions.act_window: stock_account.stock_valuation_layer_action +DEL ir.actions.act_window: stock_account.stock_valuation_layer_report_action +NEW ir.actions.client: stock_account.action_report_stock_valuation +NEW ir.actions.server: stock_account.stock_move_action_adjust_valuation +NEW ir.cron: stock_account.ir_cron_post_stock_valuation (noupdate) +NEW ir.model.access: stock_account.access_stock_avco_report_account_readonly +NEW ir.model.access: stock_account.access_stock_avco_report_stock_manager +NEW ir.model.access: stock_account.access_stock_product_value +DEL ir.model.access: stock_account.access_stock_valuation_layer +DEL ir.model.access: stock_account.access_stock_valuation_layer_revaluation +NEW ir.rule: stock_account.product_value_rule (noupdate) +NEW ir.rule: stock_account.stock_avco_report_rule (noupdate) + +# NOTHING TO DO + +DEL ir.rule: stock_account.stock_valuation_layer_company_rule (noupdate) + +# DONE: deleted in pre-migration + +DEL ir.ui.menu: stock_account.menu_valuation +NEW ir.ui.view: stock_account.product_product_view_list_at_date +NEW ir.ui.view: stock_account.product_value_form_view +NEW ir.ui.view: stock_account.stock_avco_report_view_list +NEW ir.ui.view: stock_account.stock_inventory_adjustment_name_form_view_inherit_stock_account +NEW ir.ui.view: stock_account.stock_move_view_list +NEW ir.ui.view: stock_account.stock_move_view_list_valuation +NEW ir.ui.view: stock_account.view_account_form +NEW ir.ui.view: stock_account.view_move_search +DEL ir.ui.view: stock_account.stock_inventory_request_count_form_view_inherit_stock_account +DEL ir.ui.view: stock_account.stock_valuation_layer_form +DEL ir.ui.view: stock_account.stock_valuation_layer_graph +DEL ir.ui.view: stock_account.stock_valuation_layer_picking +DEL ir.ui.view: stock_account.stock_valuation_layer_pivot +DEL ir.ui.view: stock_account.stock_valuation_layer_report_tree +DEL ir.ui.view: stock_account.stock_valuation_layer_revaluation_form_view +DEL ir.ui.view: stock_account.stock_valuation_layer_tree +DEL ir.ui.view: stock_account.stock_valuation_layer_valuation_at_date_tree_inherited +DEL ir.ui.view: stock_account.view_inventory_valuation_search +DEL ir.ui.view: stock_account.view_move_form_inherit +DEL ir.ui.view: stock_account.view_stock_quantity_history_inherit_stock_account + +# NOTHING TO DO + +DEL res.groups: stock_account.group_stock_accounting_automatic (noupdate) + +# DONE: deleted in pre-migration