From 8ed9285ceac3cf33af56519d81766dfb7d928ca3 Mon Sep 17 00:00:00 2001 From: Andres Calle Date: Thu, 18 May 2017 19:06:06 -0500 Subject: [PATCH 1/5] [ADD] stock: Added migration scripts for stock module --- .../10.0.1.1/openupgrade_analysis_work.txt | 22 ++--- .../migrations/10.0.1.1/post-migration.py | 94 +++++++++++++++++++ .../migrations/10.0.1.1/pre-migration.py | 24 +++++ odoo/openupgrade/doc/source/modules90-100.rst | 2 +- 4 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 addons/stock/migrations/10.0.1.1/post-migration.py create mode 100644 addons/stock/migrations/10.0.1.1/pre-migration.py diff --git a/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt b/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt index f9eabfe94213..7d76f691939f 100644 --- a/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt +++ b/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt @@ -3,11 +3,11 @@ stock / barcode.rule / type (False) : NEW se # NOTHING TO DO stock / procurement.rule / picking_type_id (many2one) : now required -# TODO: pre-migration. Default to some value, guessing by looking at source +# Done: post-migration. Default to some value, guessing by looking at source # and destination locations, and warehouse. + stock / procurement.rule / route_sequence (float) : type is now 'integer' ('float') -# TODO: pre-migration: copy column -# TODO: post-migration: move values from old column +# Done: pre-migration: copy column and then convert float to integer stock / product.product / stock_move_ids (one2many) : NEW relation: stock.move stock / product.product / stock_quant_ids (one2many) : NEW relation: stock.quant @@ -15,7 +15,7 @@ stock / product.product / stock_quant_ids (one2many) : NEW re stock / product.template / location_id (many2one) : not a function anymore stock / product.template / warehouse_id (many2one) : not a function anymore -# TODO: ??? IN V9 were defined as fields.dummy +# NOTHING TO DO as in v9 were dummy fields (existed only for backwards compatibility) stock / product.template / type (False) : NEW selection_keys: ['consu', 'product', 'service'], mode: modify # NOTHING TO DO @@ -29,17 +29,16 @@ stock / stock.inventory.line / state (char) : type i # NOTHING TO DO stock / stock.location.path / auto (selection) : selection_keys is now '['manual', 'transparent']' ('['auto', 'manual', 'transparent']') -# TODO: pre-migration. copy column -# TODO: post-migration. Move 'auto' to some other value +# Done: pre-migration. copy column and then replace value "auto" with value "manual" stock / stock.location.path / route_sequence (float) : type is now 'integer' ('float') -# TODO: pre-migration. copy column -# TODO: post-migration. copy values to new field converting to integer +# Done!: pre-migration: copy column and then convert float to integer stock / stock.move / ordered_qty (float) : NEW -# TODO: post-migration. Default to product_uom_qty +# Done: post-migration. Default to product_uom_qty + stock / stock.pack.operation / ordered_qty (float) : NEW -# TODO: post-migration. Default to product_uom_qty +# Done: post-migration. Default to product_qty stock / stock.pack.operation / processed_boolean (boolean) : was renamed to is_done [nothing to do] # NOTHING TO DO @@ -69,8 +68,7 @@ stock / stock.scrap / product_uom_id (many2one) : NEW re stock / stock.scrap / scrap_location_id (many2one) : NEW relation: stock.location stock / stock.scrap / scrap_qty (float) : NEW required: required, req_default: function stock / stock.scrap / state (selection) : NEW selection_keys: ['done', 'draft'] -# TODO: Create one record for each move that had as destionation a scrap -# location +# Done: pre-migration: Create one record for each move that had as destionation a scrap location stock / stock.warehouse / active (boolean) : NEW stock / stock.warehouse / resupply_from_wh (boolean) : DEL diff --git a/addons/stock/migrations/10.0.1.1/post-migration.py b/addons/stock/migrations/10.0.1.1/post-migration.py new file mode 100644 index 000000000000..b7a0e7ca4c41 --- /dev/null +++ b/addons/stock/migrations/10.0.1.1/post-migration.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Trescloud +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openupgradelib import openupgrade + +def update_picking_type_id(env): + """Updates picking_type_id, defaulting to some value, guessing by looking at source + and destination locations, and warehouse. + :param env: enviroment variable (self) + """ + #load xml data to be used for filling in missing info + xml_stock_picking_type_internal = env.ref("stock.picking_type_internal") + xml_stock_picking_type_out = env.ref("stock.picking_type_out") + xml_stock_picking_type_in = env.ref("stock.picking_type_in") + xml_stock_picking_type_manufacturing = env.ref("mrp.picking_type_manufacturing") + #verify for each procument rule to set + procurement_rules_to_set = env['procurement.rule'].search([]) + for procurement_rule in procurement_rules_to_set: + if not procurement_rule.picking_type_id: + picking_type_id = False + env.cr.execute( + ''' + SELECT id from stock_picking_type + WHERE warehouse_id = %s AND + default_location_dest_id = %s AND + default_location_src_id = %s''' % ( + procurement_rule.warehouse_id, + procurement_rule.location_id, + procurement_rule.location_src_id, + ) + ) + picking_type_ids = cr.fetchone() + if picking_type_ids: + picking_type_id = picking_type_ids[0] + if not picking_type_id: #fallback values when everything else fails + if procurement_rule.action == 'buy': + #location_src_id is not considered as is not mandatory in this case + if xml_stock_picking_type_in: + picking_type_id = xml_stock_picking_type_in.id + elif procurement_rule.action == 'move': + if procurement_rule.location_id and procurement_rule.location_id.usage == 'customer': + #special case when is a delivarable to a customer location + if xml_stock_picking_type_out: + picking_type_id = xml_stock_picking_type_out.id + else: + if xml_stock_picking_type_internal: + picking_type_id = xml_stock_picking_type_internal.id + elif procurement_rule.action == 'manufacture': + if xml_stock_picking_type_manufacturing: + picking_type_id = xml_stock_picking_type_manufacturing.id + procurement_rule.write({'picking_type_id': picking_type_id}) + +def update_ordered_qty(env): + """ Set the value of new field ordered_qty as: + - for stock moves the value of field product_uom_qty + - for stock_pack_operation the value of product_qty + :param env: enviroment variable (self) + """ + env.cr.execute( + ''' + UPDATE stock_move SET ordered_qty = product_uom_qty + ''') + env.cr.execute( + ''' + UPDATE stock_pack_operation SET ordered_qty = product_qty + ''') + +def populate_stock_scrap(env): + """ Fills up new object "stock.scrap" based on moves with destination scrap + :param env: enviroment variable (self) + """ + env.cr.execute( + ''' + SELECT id from stock_location + WHERE scrap_location is True + ''' + ) + scrap_location_ids = env.cr.fetchone() + #do not call stock_scrap.create as it will create a duplicated stock move, use SQL instead + #field package_id not set as no value is defined + env.cr.execute( + ''' + INSERT INTO stock_scrap (date_expected,location_id,lot_id,move_id,name,origin,owner_id,picking_id,product_id,product_uom_id,scrap_location_id,scrap_qty,state) + SELECT date_expected,location_id,restrict_lot_id,id,name,origin,restrict_partner_id,picking_id,product_id,product_uom,location_dest_id,product_uom_qty,state + FROM stock_move + WHERE location_id IN %s AND product_uom_qty < 0.0 AND state = 'done' + OR location_dest_id IN %s AND product_uom_qty >= 0.0 AND state = 'done' + ''',(scrap_location_ids,scrap_location_ids)) + +@openupgrade.migrate(use_env=True) +def migrate(env, version): + update_picking_type_id(env) + update_ordered_qty(env) + populate_stock_scrap(env) \ No newline at end of file diff --git a/addons/stock/migrations/10.0.1.1/pre-migration.py b/addons/stock/migrations/10.0.1.1/pre-migration.py new file mode 100644 index 000000000000..590f5c35084d --- /dev/null +++ b/addons/stock/migrations/10.0.1.1/pre-migration.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Trescloud +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openupgradelib import openupgrade + +column_copies = { + 'procurement_rule': [ + ('route_sequence', None, None), + ], + 'stock_location_path': [ + ('auto', None, None), + ('route_sequence', None, None), + ], + } + +@openupgrade.migrate(use_env=True) +def migrate(env, version): + openupgrade.copy_columns(env.cr, column_copies) + openupgrade.float_to_integer(env.cr, 'stock_location_path', 'route_sequence') + openupgrade.float_to_integer(env.cr, 'procurement_rule', 'route_sequence') + env.cr.execute( + """ + UPDATE stock_location_path SET auto = 'manual' WHERE auto = 'auto'; + """) \ No newline at end of file diff --git a/odoo/openupgrade/doc/source/modules90-100.rst b/odoo/openupgrade/doc/source/modules90-100.rst index 2bc8d8494705..ec09c5030cf3 100644 --- a/odoo/openupgrade/doc/source/modules90-100.rst +++ b/odoo/openupgrade/doc/source/modules90-100.rst @@ -453,7 +453,7 @@ missing in the new release are marked with |del|. +-----------------------------------+-----------------------------------+ |sales_team | Done | +-----------------------------------+-----------------------------------+ -|stock | | +|stock | Done | +-----------------------------------+-----------------------------------+ |stock_account | Nothing to do | +-----------------------------------+-----------------------------------+ From a0a9121da4f356cc13f8dd6144d1184d2043639c Mon Sep 17 00:00:00 2001 From: mreficent Date: Fri, 26 May 2017 14:03:17 +0200 Subject: [PATCH 2/5] [IMP] stock: Some adjustments as per review comments --- .../10.0.1.1/openupgrade_analysis_work.txt | 6 +- .../migrations/10.0.1.1/post-migration.py | 138 +++++++++++------- .../migrations/10.0.1.1/pre-migration.py | 20 ++- 3 files changed, 97 insertions(+), 67 deletions(-) diff --git a/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt b/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt index 7d76f691939f..bc45c4150a8f 100644 --- a/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt +++ b/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt @@ -29,10 +29,10 @@ stock / stock.inventory.line / state (char) : type i # NOTHING TO DO stock / stock.location.path / auto (selection) : selection_keys is now '['manual', 'transparent']' ('['auto', 'manual', 'transparent']') -# Done: pre-migration. copy column and then replace value "auto" with value "manual" +# Done: post-migration. move values 'auto' to 'manual' stock / stock.location.path / route_sequence (float) : type is now 'integer' ('float') -# Done!: pre-migration: copy column and then convert float to integer +# Done: pre-migration: copy column and then convert float to integer stock / stock.move / ordered_qty (float) : NEW # Done: post-migration. Default to product_uom_qty @@ -68,7 +68,7 @@ stock / stock.scrap / product_uom_id (many2one) : NEW re stock / stock.scrap / scrap_location_id (many2one) : NEW relation: stock.location stock / stock.scrap / scrap_qty (float) : NEW required: required, req_default: function stock / stock.scrap / state (selection) : NEW selection_keys: ['done', 'draft'] -# Done: pre-migration: Create one record for each move that had as destionation a scrap location +# Done: post-migration: Create one record for each move linked to a scrap location stock / stock.warehouse / active (boolean) : NEW stock / stock.warehouse / resupply_from_wh (boolean) : DEL diff --git a/addons/stock/migrations/10.0.1.1/post-migration.py b/addons/stock/migrations/10.0.1.1/post-migration.py index b7a0e7ca4c41..fb64fbb644b7 100644 --- a/addons/stock/migrations/10.0.1.1/post-migration.py +++ b/addons/stock/migrations/10.0.1.1/post-migration.py @@ -3,92 +3,124 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from openupgradelib import openupgrade + +def map_location_auto(cr): + openupgrade.map_values( + cr, + openupgrade.get_legacy_name('auto'), 'auto', + [('auto', 'manual')], + table='stock_location_path', write='sql') + + def update_picking_type_id(env): - """Updates picking_type_id, defaulting to some value, guessing by looking at source - and destination locations, and warehouse. - :param env: enviroment variable (self) + """Updates picking_type_id, defaulting to some value, guessing by looking + at source and destination locations, and warehouse. + :param env: environment variable (self) """ - #load xml data to be used for filling in missing info - xml_stock_picking_type_internal = env.ref("stock.picking_type_internal") + # load xml data to be used for filling in missing info + xml_stock_picking_type_int = env.ref("stock.picking_type_internal") xml_stock_picking_type_out = env.ref("stock.picking_type_out") xml_stock_picking_type_in = env.ref("stock.picking_type_in") - xml_stock_picking_type_manufacturing = env.ref("mrp.picking_type_manufacturing") - #verify for each procument rule to set + + # verify for each procurement rule to set procurement_rules_to_set = env['procurement.rule'].search([]) for procurement_rule in procurement_rules_to_set: if not procurement_rule.picking_type_id: picking_type_id = False env.cr.execute( - ''' + """ SELECT id from stock_picking_type WHERE warehouse_id = %s AND - default_location_dest_id = %s AND - default_location_src_id = %s''' % ( - procurement_rule.warehouse_id, + default_location_dest_id = %s AND + default_location_src_id = %s""" % ( + procurement_rule.warehouse_id, procurement_rule.location_id, procurement_rule.location_src_id, ) ) - picking_type_ids = cr.fetchone() + picking_type_ids = env.cr.fetchone() if picking_type_ids: picking_type_id = picking_type_ids[0] - if not picking_type_id: #fallback values when everything else fails + + # fallback values when everything else fails + if not picking_type_id: if procurement_rule.action == 'buy': - #location_src_id is not considered as is not mandatory in this case + # location_src_id is not considered + # (as is not mandatory in this case) if xml_stock_picking_type_in: picking_type_id = xml_stock_picking_type_in.id elif procurement_rule.action == 'move': - if procurement_rule.location_id and procurement_rule.location_id.usage == 'customer': - #special case when is a delivarable to a customer location + if procurement_rule.location_id and procurement_rule.\ + location_id.usage == 'customer': + # delivery case to a customer location if xml_stock_picking_type_out: picking_type_id = xml_stock_picking_type_out.id else: - if xml_stock_picking_type_internal: - picking_type_id = xml_stock_picking_type_internal.id - elif procurement_rule.action == 'manufacture': - if xml_stock_picking_type_manufacturing: - picking_type_id = xml_stock_picking_type_manufacturing.id + if xml_stock_picking_type_int: + picking_type_id = xml_stock_picking_type_int.id + procurement_rule.write({'picking_type_id': picking_type_id}) -def update_ordered_qty(env): + +def update_ordered_qty(cr): """ Set the value of new field ordered_qty as: - for stock moves the value of field product_uom_qty - for stock_pack_operation the value of product_qty - :param env: enviroment variable (self) + :param cr: cursor variable (self.env) """ - env.cr.execute( - ''' - UPDATE stock_move SET ordered_qty = product_uom_qty - ''') - env.cr.execute( - ''' - UPDATE stock_pack_operation SET ordered_qty = product_qty - ''') - -def populate_stock_scrap(env): - """ Fills up new object "stock.scrap" based on moves with destination scrap - :param env: enviroment variable (self) + + cr.execute( + "UPDATE stock_move SET ordered_qty = product_uom_qty") + cr.execute( + "UPDATE stock_pack_operation SET ordered_qty = product_qty") + + +def populate_stock_scrap(cr): """ - env.cr.execute( - ''' + Fills up new object "stock.scrap" based on moves linked to scrap location + :param cr: cursor variable (self.env) + """ + + cr.execute( + """ SELECT id from stock_location WHERE scrap_location is True - ''' - ) - scrap_location_ids = env.cr.fetchone() - #do not call stock_scrap.create as it will create a duplicated stock move, use SQL instead - #field package_id not set as no value is defined - env.cr.execute( - ''' - INSERT INTO stock_scrap (date_expected,location_id,lot_id,move_id,name,origin,owner_id,picking_id,product_id,product_uom_id,scrap_location_id,scrap_qty,state) - SELECT date_expected,location_id,restrict_lot_id,id,name,origin,restrict_partner_id,picking_id,product_id,product_uom,location_dest_id,product_uom_qty,state - FROM stock_move - WHERE location_id IN %s AND product_uom_qty < 0.0 AND state = 'done' - OR location_dest_id IN %s AND product_uom_qty >= 0.0 AND state = 'done' - ''',(scrap_location_ids,scrap_location_ids)) - + """ + ) + scrap_location_ids = cr.fetchone() + + cr.execute( + """ + INSERT INTO stock_scrap (date_expected,location_id,lot_id,move_id, + name,origin,owner_id,package_id,picking_id,product_id, + product_uom_id,scrap_location_id,scrap_qty,state) + WITH Q1 as (SELECT DISTINCT sq.package_id,sr.move_id + FROM stock_quant_move_rel sr + INNER JOIN stock_quant as sq ON sq.id = sr.quant_id), + Q2 as (SELECT COUNT(Q1.package_id) as n,Q1.move_id + FROM Q1 + GROUP BY Q1.move_id), + Q3 as (SELECT DISTINCT Q2.move_id,sq.package_id + FROM Q2 + LEFT JOIN stock_quant_move_rel sr ON sr.move_id = Q2.move_id + LEFT JOIN stock_quant as sq ON sq.id = sr.quant_id + WHERE Q2.n = 1) + SELECT date_expected,location_id,restrict_lot_id,id,name,origin, + restrict_partner_id,Q3.package_id,picking_id,product_id, + product_uom,location_dest_id,product_uom_qty,state + FROM stock_move sm + LEFT JOIN Q3 ON sm.id = Q3.move_id + WHERE (location_id IN %s AND product_uom_qty < 0.0 AND + state = 'done') + OR (location_dest_id IN %s AND product_uom_qty >= 0.0 AND + state = 'done') + """, (scrap_location_ids, scrap_location_ids)) + + @openupgrade.migrate(use_env=True) def migrate(env, version): + cr = env.cr + map_location_auto(cr) update_picking_type_id(env) - update_ordered_qty(env) - populate_stock_scrap(env) \ No newline at end of file + update_ordered_qty(cr) + populate_stock_scrap(cr) diff --git a/addons/stock/migrations/10.0.1.1/pre-migration.py b/addons/stock/migrations/10.0.1.1/pre-migration.py index 590f5c35084d..59291a8b67eb 100644 --- a/addons/stock/migrations/10.0.1.1/pre-migration.py +++ b/addons/stock/migrations/10.0.1.1/pre-migration.py @@ -6,19 +6,17 @@ column_copies = { 'procurement_rule': [ ('route_sequence', None, None), - ], + ], 'stock_location_path': [ ('auto', None, None), ('route_sequence', None, None), - ], - } + ], +} + @openupgrade.migrate(use_env=True) -def migrate(env, version): - openupgrade.copy_columns(env.cr, column_copies) - openupgrade.float_to_integer(env.cr, 'stock_location_path', 'route_sequence') - openupgrade.float_to_integer(env.cr, 'procurement_rule', 'route_sequence') - env.cr.execute( - """ - UPDATE stock_location_path SET auto = 'manual' WHERE auto = 'auto'; - """) \ No newline at end of file +def migrate(env, version): + cr = env.cr + openupgrade.copy_columns(cr, column_copies) + openupgrade.float_to_integer(cr, 'procurement_rule', 'route_sequence') + openupgrade.float_to_integer(cr, 'stock_location_path', 'route_sequence') From f848280e790cbfe300e74bbb9c70178cf4df9ea2 Mon Sep 17 00:00:00 2001 From: Andres Calle Date: Fri, 26 May 2017 14:15:31 -0500 Subject: [PATCH 3/5] [IMP] stock: Minor fixes - Added reate_date to stock_scrap, - Removed positive qtys filter as positive and negative are supported - Removed scrapped source location as domains avoids this in v10 - Added explanation about using SQL instead of ORM - Included case for MRP for ease of coding --- .../migrations/10.0.1.1/post-migration.py | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/addons/stock/migrations/10.0.1.1/post-migration.py b/addons/stock/migrations/10.0.1.1/post-migration.py index fb64fbb644b7..f7d28599926e 100644 --- a/addons/stock/migrations/10.0.1.1/post-migration.py +++ b/addons/stock/migrations/10.0.1.1/post-migration.py @@ -18,9 +18,10 @@ def update_picking_type_id(env): :param env: environment variable (self) """ # load xml data to be used for filling in missing info - xml_stock_picking_type_int = env.ref("stock.picking_type_internal") - xml_stock_picking_type_out = env.ref("stock.picking_type_out") - xml_stock_picking_type_in = env.ref("stock.picking_type_in") + xml_stock_picking_type_int = env.ref("stock.picking_type_internal",False) + xml_stock_picking_type_out = env.ref("stock.picking_type_out",False) + xml_stock_picking_type_in = env.ref("stock.picking_type_in",False) + xml_stock_picking_type_manufacturing = env.ref("mrp.picking_type_manufacturing",False) # verify for each procurement rule to set procurement_rules_to_set = env['procurement.rule'].search([]) @@ -58,6 +59,12 @@ def update_picking_type_id(env): else: if xml_stock_picking_type_int: picking_type_id = xml_stock_picking_type_int.id + + # special case for mrp module put here for not repeating the logic. + # If mrp not installed won't break + elif procurement_rule.action == 'manufacture': + if xml_stock_picking_type_manufacturing: + picking_type_id = xml_stock_picking_type_manufacturing.id procurement_rule.write({'picking_type_id': picking_type_id}) @@ -88,10 +95,11 @@ def populate_stock_scrap(cr): """ ) scrap_location_ids = cr.fetchone() - + + # Use SQL instead of ORM, otherwise stock_scrap.create() will create a duplicated stock move cr.execute( """ - INSERT INTO stock_scrap (date_expected,location_id,lot_id,move_id, + INSERT INTO stock_scrap (date_expected,create_date,location_id,lot_id,move_id, name,origin,owner_id,package_id,picking_id,product_id, product_uom_id,scrap_location_id,scrap_qty,state) WITH Q1 as (SELECT DISTINCT sq.package_id,sr.move_id @@ -105,16 +113,13 @@ def populate_stock_scrap(cr): LEFT JOIN stock_quant_move_rel sr ON sr.move_id = Q2.move_id LEFT JOIN stock_quant as sq ON sq.id = sr.quant_id WHERE Q2.n = 1) - SELECT date_expected,location_id,restrict_lot_id,id,name,origin, + SELECT date_expected,create_date,location_id,restrict_lot_id,id,name,origin, restrict_partner_id,Q3.package_id,picking_id,product_id, product_uom,location_dest_id,product_uom_qty,state FROM stock_move sm LEFT JOIN Q3 ON sm.id = Q3.move_id - WHERE (location_id IN %s AND product_uom_qty < 0.0 AND - state = 'done') - OR (location_dest_id IN %s AND product_uom_qty >= 0.0 AND - state = 'done') - """, (scrap_location_ids, scrap_location_ids)) + WHERE location_dest_id IN %s AND state = 'done' + """, (scrap_location_ids,)) @openupgrade.migrate(use_env=True) From bca97c5d2a113a5f635aa8349df489164da27ad8 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Wed, 31 May 2017 11:49:03 +0200 Subject: [PATCH 4/5] [FIX+IMP] stock: * PEP8 * Fixes * Some things not attended --- .../10.0.1.1/openupgrade_analysis_work.txt | 14 +- .../migrations/10.0.1.1/post-migration.py | 135 ++++++++++-------- .../migrations/10.0.1.1/pre-migration.py | 45 ++++++ 3 files changed, 137 insertions(+), 57 deletions(-) diff --git a/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt b/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt index bc45c4150a8f..a58696d0e85a 100644 --- a/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt +++ b/addons/stock/migrations/10.0.1.1/openupgrade_analysis_work.txt @@ -20,6 +20,10 @@ stock / product.template / warehouse_id (many2one) : not a stock / product.template / type (False) : NEW selection_keys: ['consu', 'product', 'service'], mode: modify # NOTHING TO DO +stock / res.partner / picking_warn (selection) : NEW +stock / res.partner / picking_warn_msg (text) : NEW +# Done: Reassign module from 'warning' to 'stock' + stock / stock.inventory / category_id (many2one) : NEW relation: product.category stock / stock.inventory / exhausted (boolean) : NEW # NOTHING TO DO @@ -107,8 +111,16 @@ NEW ir.ui.view: stock.stock_scrap_tree_view NEW ir.ui.view: stock.stock_warehouse_view_search NEW ir.ui.view: stock.view_partner_stock_warnings_form DEL ir.ui.view: stock.view_stock_move_scrap_wizard +# Nothing to do + NEW res.groups: stock.group_stock_multi_locations NEW res.groups: stock.group_stock_multi_warehouses -NEW res.groups: stock.group_warning_stock DEL res.groups: stock.group_locations +# Done: Rename the old group to one of the new, and then assign also the second + new one to the same users + +NEW res.groups: stock.group_warning_stock +# Done: Add the group to all users if the module 'warning' is installed + NEW res.users: base.default_user +# Nothing to do diff --git a/addons/stock/migrations/10.0.1.1/post-migration.py b/addons/stock/migrations/10.0.1.1/post-migration.py index f7d28599926e..f7358f125791 100644 --- a/addons/stock/migrations/10.0.1.1/post-migration.py +++ b/addons/stock/migrations/10.0.1.1/post-migration.py @@ -1,6 +1,9 @@ # -*- coding: utf-8 -*- # Copyright 2017 Trescloud +# Copyright 2017 Eficent - Miquel +# Copyright 2017 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from openupgradelib import openupgrade @@ -14,65 +17,64 @@ def map_location_auto(cr): def update_picking_type_id(env): """Updates picking_type_id, defaulting to some value, guessing by looking - at source and destination locations, and warehouse. + at source and destination locations, and warehouse. :param env: environment variable (self) """ # load xml data to be used for filling in missing info - xml_stock_picking_type_int = env.ref("stock.picking_type_internal",False) - xml_stock_picking_type_out = env.ref("stock.picking_type_out",False) - xml_stock_picking_type_in = env.ref("stock.picking_type_in",False) - xml_stock_picking_type_manufacturing = env.ref("mrp.picking_type_manufacturing",False) - + xml_stock_picking_type_int = env.ref("stock.picking_type_internal") + xml_stock_picking_type_out = env.ref("stock.picking_type_out") + xml_stock_picking_type_in = env.ref("stock.picking_type_in") + xml_stock_picking_type_manufacturing = env.ref( + "mrp.picking_type_manufacturing", False + ) # verify for each procurement rule to set - procurement_rules_to_set = env['procurement.rule'].search([]) + procurement_rules_to_set = env['procurement.rule'].search([ + ('picking_type_id', '=', False), + ]) for procurement_rule in procurement_rules_to_set: - if not procurement_rule.picking_type_id: - picking_type_id = False - env.cr.execute( - """ - SELECT id from stock_picking_type - WHERE warehouse_id = %s AND - default_location_dest_id = %s AND - default_location_src_id = %s""" % ( - procurement_rule.warehouse_id, - procurement_rule.location_id, - procurement_rule.location_src_id, - ) + picking_type_id = False + env.cr.execute( + """ + SELECT id from stock_picking_type + WHERE warehouse_id = %s AND + default_location_dest_id = %s AND + default_location_src_id = %s""" % ( + procurement_rule.warehouse_id, + procurement_rule.location_id, + procurement_rule.location_src_id, ) - picking_type_ids = env.cr.fetchone() - if picking_type_ids: - picking_type_id = picking_type_ids[0] - - # fallback values when everything else fails - if not picking_type_id: - if procurement_rule.action == 'buy': - # location_src_id is not considered - # (as is not mandatory in this case) - if xml_stock_picking_type_in: - picking_type_id = xml_stock_picking_type_in.id - elif procurement_rule.action == 'move': - if procurement_rule.location_id and procurement_rule.\ - location_id.usage == 'customer': - # delivery case to a customer location - if xml_stock_picking_type_out: - picking_type_id = xml_stock_picking_type_out.id - else: - if xml_stock_picking_type_int: - picking_type_id = xml_stock_picking_type_int.id - - # special case for mrp module put here for not repeating the logic. - # If mrp not installed won't break - elif procurement_rule.action == 'manufacture': - if xml_stock_picking_type_manufacturing: - picking_type_id = xml_stock_picking_type_manufacturing.id - - procurement_rule.write({'picking_type_id': picking_type_id}) + ) + picking_type_ids = env.cr.fetchone() + if picking_type_ids: + picking_type_id = picking_type_ids[0] + # fallback values when everything else fails + if not picking_type_id: + if procurement_rule.action == 'buy': + # location_src_id is not considered + # (as is not mandatory in this case) + if xml_stock_picking_type_in: + picking_type_id = xml_stock_picking_type_in.id + elif procurement_rule.action == 'move': + if procurement_rule.location_id and procurement_rule.\ + location_id.usage == 'customer': + # delivery case to a customer location + if xml_stock_picking_type_out: + picking_type_id = xml_stock_picking_type_out.id + else: + if xml_stock_picking_type_int: + picking_type_id = xml_stock_picking_type_int.id + # special case for mrp module put here for not repeating the + # logic. If mrp is not installed, it won't break + elif procurement_rule.action == 'manufacture': + if xml_stock_picking_type_manufacturing: + picking_type_id = xml_stock_picking_type_manufacturing.id + procurement_rule.picking_type_id = picking_type_id def update_ordered_qty(cr): """ Set the value of new field ordered_qty as: - for stock moves the value of field product_uom_qty - - for stock_pack_operation the value of product_qty + - for stock_pack_operation the value of product_qty :param cr: cursor variable (self.env) """ @@ -87,19 +89,19 @@ def populate_stock_scrap(cr): Fills up new object "stock.scrap" based on moves linked to scrap location :param cr: cursor variable (self.env) """ - cr.execute( """ - SELECT id from stock_location + SELECT id from stock_location WHERE scrap_location is True """ ) scrap_location_ids = cr.fetchone() - - # Use SQL instead of ORM, otherwise stock_scrap.create() will create a duplicated stock move + # Use SQL instead of ORM, otherwise stock_scrap.create() will create a + # duplicated stock move cr.execute( """ - INSERT INTO stock_scrap (date_expected,create_date,location_id,lot_id,move_id, + INSERT INTO stock_scrap + (date_expected,create_date,location_id,lot_id,move_id, name,origin,owner_id,package_id,picking_id,product_id, product_uom_id,scrap_location_id,scrap_qty,state) WITH Q1 as (SELECT DISTINCT sq.package_id,sr.move_id @@ -113,15 +115,35 @@ def populate_stock_scrap(cr): LEFT JOIN stock_quant_move_rel sr ON sr.move_id = Q2.move_id LEFT JOIN stock_quant as sq ON sq.id = sr.quant_id WHERE Q2.n = 1) - SELECT date_expected,create_date,location_id,restrict_lot_id,id,name,origin, - restrict_partner_id,Q3.package_id,picking_id,product_id, - product_uom,location_dest_id,product_uom_qty,state + SELECT date_expected,create_date,location_id,restrict_lot_id,id, + name,origin,restrict_partner_id,Q3.package_id,picking_id, + product_id,product_uom,location_dest_id,product_uom_qty,state FROM stock_move sm LEFT JOIN Q3 ON sm.id = Q3.move_id WHERE location_dest_id IN %s AND state = 'done' """, (scrap_location_ids,)) +def assign_security_groups(env): + """Assign the group that has been unfolded in 2 in the new version to the + users that had the old one. + + Assign also the warning group if the old module is installed. + + :param env: Environment + """ + users = env['res.users'].search([ + ('groups_id', '=', env.ref('stock.group_stock_multi_locations').id) + ]) + users.write({ + 'groups_id': [(4, env.ref('stock.group_stock_multi_warehouses').id)], + }) + if openupgrade.is_module_installed(env.cr, 'warning'): + env['res.users'].search([]).write({ + 'groups_id': [(4, env.ref('stock.group_warning_stock').id)], + }) + + @openupgrade.migrate(use_env=True) def migrate(env, version): cr = env.cr @@ -129,3 +151,4 @@ def migrate(env, version): update_picking_type_id(env) update_ordered_qty(cr) populate_stock_scrap(cr) + assign_security_groups(env) diff --git a/addons/stock/migrations/10.0.1.1/pre-migration.py b/addons/stock/migrations/10.0.1.1/pre-migration.py index 59291a8b67eb..f2e563184239 100644 --- a/addons/stock/migrations/10.0.1.1/pre-migration.py +++ b/addons/stock/migrations/10.0.1.1/pre-migration.py @@ -13,6 +13,49 @@ ], } +xmlid_renames = [ + ('stock.group_locations', 'stock.group_stock_multi_locations'), +] + + +def warning_update_module_names_partial(cr): + """We don't use openupgrade.update_module_names here because only the + fields picking_warn and picking_warn_msg are moved from the old warning + module to the stock one. Other fields are moved in other modules (e. g. + field purchase_warn in purchase module). If we would using + openupgrade.update_module_names there might be problems when + first use openupgrade.update_module_names in stock module and then again in + purchase module and so on. + Because the field names didn't change and we only deal with text fields + without constraints etc. we only have to change the related + ir_model_data and ir_translation entries. + """ + new_name = 'stock' + old_name = 'warning' + if not openupgrade.is_module_installed(cr, old_name): + return + # get moved model fields + moved_fields = [ + 'picking_warn', + 'picking_warn_msg', + ] + cr.execute(""" + SELECT id + FROM ir_model_fields + WHERE model = 'res.partner' AND name in %s + """, (moved_fields,)) + field_ids = [r[0] for r in cr.fetchall()] + # update ir_model_data, the subselect allows to avoid duplicated XML-IDs + query = ("UPDATE ir_model_data SET module = %s " + "WHERE module = %s AND res_id IN %s AND name NOT IN " + "(SELECT name FROM ir_model_data WHERE module = %s)") + openupgrade.logged_query(cr, query, (new_name, old_name, field_ids, + new_name)) + # update ir_translation + query = ("UPDATE ir_translation SET module = %s " + "WHERE module = %s AND res_id IN %s") + openupgrade.logged_query(cr, query, (new_name, old_name, field_ids)) + @openupgrade.migrate(use_env=True) def migrate(env, version): @@ -20,3 +63,5 @@ def migrate(env, version): openupgrade.copy_columns(cr, column_copies) openupgrade.float_to_integer(cr, 'procurement_rule', 'route_sequence') openupgrade.float_to_integer(cr, 'stock_location_path', 'route_sequence') + openupgrade.rename_xmlids(env.cr, xmlid_renames) + warning_update_module_names_partial(cr) From 0ca64f2f9db0e0b1c1576719594521a7dc796fe0 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Tue, 6 Jun 2017 19:04:07 +0200 Subject: [PATCH 5/5] [FIX] base: Merge modules instead of removing them --- .../base/migrations/10.0.1.3/pre-migration.py | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/odoo/addons/base/migrations/10.0.1.3/pre-migration.py b/odoo/addons/base/migrations/10.0.1.3/pre-migration.py index 37e0c9862c71..f1f042f55e98 100644 --- a/odoo/addons/base/migrations/10.0.1.3/pre-migration.py +++ b/odoo/addons/base/migrations/10.0.1.3/pre-migration.py @@ -53,16 +53,13 @@ def migrate(cr, version): end, 'res.lang', id from res_lang''') - # set some obsolete modules to auto uninstall (and remove dependencies) - cr.execute( - '''update ir_module_module - set state = 'to remove' - where name in ( - 'web_tip', 'web_view_editor', 'mail_tip', 'im_odoo_support' - ) - ''') - cr.execute( - """DELETE FROM ir_module_module_dependency - WHERE name in ('web_tip', 'web_view_editor') - """ + openupgrade.update_module_names( + cr, [ + ('account_full_reconcile', 'account'), + ('share', 'base'), + ('web_tip', 'web'), + ('web_view_editor', 'web'), + ('mail_tip', 'mail'), + ('im_odoo_support', 'im_livechat'), + ], merge_modules=True, )