diff --git a/addons/mrp_subcontracting/models/stock_move.py b/addons/mrp_subcontracting/models/stock_move.py index ac48625a9a2..dd4afc6eb1b 100644 --- a/addons/mrp_subcontracting/models/stock_move.py +++ b/addons/mrp_subcontracting/models/stock_move.py @@ -105,7 +105,7 @@ class StockMove(models.Model): 'show_lots_text': False, }) elif self.env.user.has_group('base.group_portal'): - if self.picking_type_id.show_reserved: + if self.show_reserved: action['views'] = [(self.env.ref('mrp_subcontracting.mrp_subcontracting_view_stock_move_operations').id, 'form')] else: action['views'] = [(self.env.ref('mrp_subcontracting.mrp_subcontracting_view_stock_move_nosuggest_operations').id, 'form')] diff --git a/addons/mrp_subcontracting/wizard/stock_picking_return.py b/addons/mrp_subcontracting/wizard/stock_picking_return.py index 6a62b86db47..e03391858c6 100644 --- a/addons/mrp_subcontracting/wizard/stock_picking_return.py +++ b/addons/mrp_subcontracting/wizard/stock_picking_return.py @@ -16,11 +16,12 @@ class ReturnPicking(models.TransientModel): record.picking_id.company_id ).property_stock_subcontractor - @api.onchange('picking_id') - def _onchange_picking_id(self): - res = super(ReturnPicking, self)._onchange_picking_id() - if any(return_line.quantity > 0 and return_line.move_id.is_subcontract for return_line in self.product_return_moves): - self.location_id = self.picking_id.partner_id.with_company(self.picking_id.company_id).property_stock_subcontractor + @api.depends('picking_id') + def _compute_moves_locations(self): + res = super()._compute_moves_locations() + for wizard in self: + if any(return_line.quantity > 0 and return_line.move_id.is_subcontract for return_line in wizard.product_return_moves): + wizard.location_id = wizard.picking_id.partner_id.with_company(wizard.picking_id.company_id).property_stock_subcontractor return res def _prepare_move_default_values(self, return_line, new_picking): diff --git a/addons/purchase_stock/models/stock.py b/addons/purchase_stock/models/stock.py index b8d0b7a8a11..7bff8e91ec7 100644 --- a/addons/purchase_stock/models/stock.py +++ b/addons/purchase_stock/models/stock.py @@ -75,9 +75,17 @@ class ReturnPicking(models.TransientModel): def _prepare_move_default_values(self, return_line, new_picking): vals = super(ReturnPicking, self)._prepare_move_default_values(return_line, new_picking) - vals['purchase_line_id'] = return_line.move_id.purchase_line_id.id + if self.location_id.usage == "supplier": + vals['purchase_line_id'], vals['partner_id'] = return_line.move_id._get_purchase_line_and_partner_from_chain() return vals + def _create_returns(self): + new_picking_id, picking_type_id = super()._create_returns() + picking = self.env['stock.picking'].browse(new_picking_id) + if len(picking.move_ids.partner_id) == 1: + picking.partner_id = picking.move_ids.partner_id + return new_picking_id, picking_type_id + class Orderpoint(models.Model): _inherit = "stock.warehouse.orderpoint" diff --git a/addons/purchase_stock/models/stock_move.py b/addons/purchase_stock/models/stock_move.py index e5a6710feaa..05636b6d2a5 100644 --- a/addons/purchase_stock/models/stock_move.py +++ b/addons/purchase_stock/models/stock_move.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from collections import deque from odoo import api, Command, fields, models, _ from odoo.tools.float_utils import float_round, float_is_zero, float_compare @@ -219,3 +220,16 @@ class StockMove(models.Model): def _get_all_related_sm(self, product): return super()._get_all_related_sm(product) | self.filtered(lambda m: m.purchase_line_id.product_id == product) + + def _get_purchase_line_and_partner_from_chain(self): + moves_to_check = deque(self) + seen_moves = set() + while moves_to_check: + current_move = moves_to_check.popleft() + if current_move.purchase_line_id: + return current_move.purchase_line_id.id, current_move.picking_id.partner_id.id + seen_moves.add(current_move) + moves_to_check.extend( + [move for move in current_move.move_orig_ids if move not in moves_to_check and move not in seen_moves] + ) + return None, None diff --git a/addons/purchase_stock/models/stock_rule.py b/addons/purchase_stock/models/stock_rule.py index 942e3434abb..05c1dfb8973 100644 --- a/addons/purchase_stock/models/stock_rule.py +++ b/addons/purchase_stock/models/stock_rule.py @@ -322,4 +322,6 @@ class StockRule(models.Model): def _push_prepare_move_copy_values(self, move_to_copy, new_date): res = super(StockRule, self)._push_prepare_move_copy_values(move_to_copy, new_date) res['purchase_line_id'] = None + if self.location_dest_id.usage == "supplier": + res['purchase_line_id'], res['partner_id'] = move_to_copy._get_purchase_line_and_partner_from_chain() return res diff --git a/addons/purchase_stock/tests/test_create_picking.py b/addons/purchase_stock/tests/test_create_picking.py index cd4fe98058a..725ec7651a4 100644 --- a/addons/purchase_stock/tests/test_create_picking.py +++ b/addons/purchase_stock/tests/test_create_picking.py @@ -640,3 +640,67 @@ class TestCreatePicking(common.TestProductCommon): # check that the price has been updated in the purchase order line and in the stock.move self.assertEqual(purchase_order.order_line.price_unit, 0) self.assertEqual(purchase_order.picking_ids.move_ids.price_unit, 0) + + def test_return_to_vendor_multi_step(self): + self.env.user.groups_id += self.env.ref('stock.group_stock_multi_locations') + self.env.user.groups_id += self.env.ref('stock.group_adv_location') + warehouse = self.env['stock.warehouse'].search([], limit=1) + + with Form(warehouse) as w: + w.reception_steps = 'three_steps' + + vendor_returns_loc = self.env['stock.location'].create({ + 'name': 'Vendor returns processing', + 'usage': 'internal', + 'location_id': warehouse.view_location_id.id, + }) + + self.env['stock.rule'].create({ + 'name': 'Vendor returns', + 'route_id': warehouse.reception_route_id.id, + 'location_dest_id': self.env.ref('stock.stock_location_suppliers').id, + 'location_src_id': vendor_returns_loc.id, + 'action': 'push', + 'auto': 'manual', + 'picking_type_id': self.env.ref('stock.picking_type_out').id, + }) + + po_form = Form(self.env['purchase.order']) + po_form.partner_id = self.partner_id + with po_form.order_line.new() as line: + line.product_id = self.product_id_1 + line.product_qty = 10 + po = po_form.save() + po.button_approve() + + first_picking = po.picking_ids + first_picking.move_ids.quantity_done = 10 + first_picking.button_validate() + second_picking = first_picking.move_ids.move_dest_ids.picking_id + second_picking.move_ids.quantity_done = 10 + second_picking.button_validate() + + self.assertEqual(po.order_line.qty_received, 10) + + stock_return_picking_form = Form( + self.env['stock.return.picking'].with_context( + active_ids=second_picking.ids, + active_id=second_picking.ids[0], + active_model='stock.picking' + ) + ) + stock_return_picking_form.location_id = vendor_returns_loc + stock_return_picking_form.product_return_moves._records[0]['quantity'] = 2 + stock_return_picking = stock_return_picking_form.save() + stock_return_picking_action = stock_return_picking.create_returns() + return_pick = self.env['stock.picking'].browse(stock_return_picking_action['res_id']) + return_pick.action_assign() + return_pick.move_ids.quantity_done = 2 + return_pick._action_done() + push_pick = return_pick.move_ids.move_dest_ids.picking_id + push_pick.action_assign() + push_pick.move_ids.quantity_done = 2 + push_pick._action_done() + + self.assertEqual(po.order_line.qty_received, 8) + self.assertEqual(push_pick.partner_id, po.partner_id) diff --git a/addons/repair/tests/test_repair.py b/addons/repair/tests/test_repair.py index 08fd2aee461..73b0a83772a 100644 --- a/addons/repair/tests/test_repair.py +++ b/addons/repair/tests/test_repair.py @@ -337,7 +337,7 @@ class TestRepair(AccountTestInvoicingCommon): # Required for `location_dest_id` to be visible in the view self.env.user.groups_id += self.env.ref('stock.group_stock_multi_locations') picking_form = Form(self.env['stock.picking']) - picking_form.picking_type_id = self.stock_warehouse.return_type_id + picking_form.picking_type_id = self.stock_warehouse.in_type_id picking_form.partner_id = self.res_partner_1 picking_form.location_dest_id = self.stock_location_14 return_picking = picking_form.save() diff --git a/addons/sale_stock/controllers/portal.py b/addons/sale_stock/controllers/portal.py index 4bf4240f37f..1c8ab0effe7 100644 --- a/addons/sale_stock/controllers/portal.py +++ b/addons/sale_stock/controllers/portal.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from werkzeug.exceptions import NotFound from odoo import exceptions, SUPERUSER_ID from odoo.addons.sale.controllers.portal import CustomerPortal @@ -26,8 +27,8 @@ class SaleStockPortal(CustomerPortal): to be sure customer has access """ try: picking_sudo = self._stock_picking_check_access(picking_id, access_token=access_token) - except exceptions.AccessError: - return request.redirect('/my') + except (exceptions.AccessError, exceptions.MissingError): + return NotFound() # print report with sudo, since it require access to product, taxes, payment term etc.. and portal does not have those access rights. pdf = request.env['ir.actions.report'].sudo()._render_qweb_pdf('stock.action_report_delivery', [picking_sudo.id])[0] @@ -36,3 +37,20 @@ class SaleStockPortal(CustomerPortal): ('Content-Length', len(pdf)), ] return request.make_response(pdf, headers=pdfhttpheaders) + + @route(['/my/picking/return/pdf/'], type='http', auth="public", website=True) + def portal_my_picking_return_report(self, picking_id, access_token=None, **kw): + """ Print return label for customer, using either access rights or access token + to be sure customer has access """ + try: + picking_sudo = self._stock_picking_check_access(picking_id, access_token=access_token) + except (exceptions.AccessError, exceptions.MissingError): + return NotFound() + + pdf = \ + request.env['ir.actions.report'].sudo()._render_qweb_pdf('stock.return_label_report', [picking_sudo.id])[0] + pdfhttpheaders = [ + ('Content-Type', 'application/pdf'), + ('Content-Length', len(pdf)), + ] + return request.make_response(pdf, headers=pdfhttpheaders) diff --git a/addons/sale_stock/views/sale_stock_portal_template.xml b/addons/sale_stock/views/sale_stock_portal_template.xml index f5ca8581751..1d049a9ebf1 100644 --- a/addons/sale_stock/views/sale_stock_portal_template.xml +++ b/addons/sale_stock/views/sale_stock_portal_template.xml @@ -38,10 +38,15 @@ t-options="{'date_only': True}"/> - - Shipped - +
+ + Shipped + + + RETURN + +
Cancelled @@ -54,6 +59,48 @@ + + +
+ Returns +
+
+ + +
+
+ + + +
+ Date: + + +
+
+ + Received + + + Cancelled + + + Awaiting arrival + +
+
+
+
diff --git a/addons/stock/__manifest__.py b/addons/stock/__manifest__.py index 158ec6c8f29..f65bcb55b9f 100644 --- a/addons/stock/__manifest__.py +++ b/addons/stock/__manifest__.py @@ -41,6 +41,7 @@ 'report/picking_templates.xml', 'report/product_templates.xml', 'report/product_packaging.xml', + 'report/report_return_slip.xml', 'data/mail_template_data.xml', 'views/stock_menu_views.xml', diff --git a/addons/stock/data/stock_data.xml b/addons/stock/data/stock_data.xml index 98ee8a8ec64..85f030a958c 100644 --- a/addons/stock/data/stock_data.xml +++ b/addons/stock/data/stock_data.xml @@ -42,6 +42,7 @@ Vendors supplier + True @@ -115,10 +116,6 @@ 'xml_id': 'stock.picking_type_out', 'record': obj().env.ref('stock.warehouse0').out_type_id, 'noupdate': True, - },{ - 'xml_id': 'stock.picking_type_return', - 'record': obj().env.ref('stock.warehouse0').return_type_id, - 'noupdate': True, }]"/> diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index 8fa7fa56251..7fab3b6c7f3 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -189,6 +189,7 @@ class StockMove(models.Model): help="Computes when a move should be reserved") product_packaging_id = fields.Many2one('product.packaging', 'Packaging', domain="[('product_id', '=', product_id)]", check_company=True) from_immediate_transfer = fields.Boolean(related="picking_id.immediate_transfer") + show_reserved = fields.Boolean(compute='_compute_show_reserved') @api.depends('product_id') def _compute_product_uom(self): @@ -310,7 +311,7 @@ class StockMove(models.Model): """ This will return the move lines to consider when applying _quantity_done_compute on a stock.move. In some context, such as MRP, it is necessary to compute quantity_done on filtered sock.move.line.""" self.ensure_one() - if self.picking_type_id.show_reserved is False: + if not self.show_reserved: return self.move_line_nosuggest_ids return self.move_line_ids @@ -327,6 +328,11 @@ class StockMove(models.Model): else: move.delay_alert_date = False + @api.depends('picking_type_id', 'origin_returned_move_id') + def _compute_show_reserved(self): + for move in self: + move.show_reserved = move.picking_type_id.show_reserved or move.origin_returned_move_id + def _quantity_done_sml(self): self.ensure_one() quantity = 0 @@ -551,14 +557,14 @@ Please change the quantity done or the rounding precision of your unit of measur ) lots_by_move_id_list.append({move.id: lot_ids for move, lot_ids in lots_by_move_id}) for move in self: - move.lot_ids = lots_by_move_id_list[0 if move.picking_type_id.show_reserved else 1].get(move._origin.id, []) + move.lot_ids = lots_by_move_id_list[0 if move.show_reserved else 1].get(move._origin.id, []) def _set_lot_ids(self): for move in self: if move.product_id.tracking != 'serial': continue move_lines_commands = [] - if move.picking_type_id.show_reserved is False: + if not move.show_reserved: mls = move.move_line_nosuggest_ids else: mls = move.move_line_ids @@ -789,7 +795,7 @@ Please change the quantity done or the rounding precision of your unit of measur # reserved move lines. We do this by displaying `move_line_nosuggest_ids`. We use # different views to display one field or another so that the webclient doesn't have to # fetch both. - if self.picking_type_id.show_reserved: + if self.show_reserved: view = self.env.ref('stock.view_stock_move_operations') else: view = self.env.ref('stock.view_stock_move_nosuggest_operations') @@ -834,7 +840,7 @@ Please change the quantity done or the rounding precision of your unit of measur since there's no way to undo the action. """ self.ensure_one() - if self.picking_type_id.show_reserved: + if self.show_reserved: move_lines = self.move_line_ids else: move_lines = self.move_line_nosuggest_ids @@ -910,7 +916,7 @@ Please change the quantity done or the rounding precision of your unit of measur lot_names = self.env['stock.lot'].generate_lot_names(next_serial, next_serial_count or self.next_serial_count) field_data = [{'lot_name': lot_name[0], 'qty_done': lot_name[1]} for lot_name in lot_names] move_lines_commands = self._generate_serial_move_line_commands(field_data) - if self.picking_type_id.show_reserved: + if self.show_reserved: self.move_line_ids = move_lines_commands else: self.move_line_nosuggest_ids = move_lines_commands @@ -954,7 +960,7 @@ Please change the quantity done or the rounding precision of your unit of measur break move_lines_vals.append(move_line_vals) move_lines_commands = self._generate_serial_move_line_commands(move_lines_vals, location_dest_id=location_id) - if self.picking_type_id.show_reserved: + if self.show_reserved: self.update({'move_line_ids': move_lines_commands}) else: self.update({'move_line_nosuggest_ids': move_lines_commands}) @@ -1279,7 +1285,7 @@ Please change the quantity done or the rounding precision of your unit of measur 'product_uom_id': self.product_id.uom_id.id, } # Select the right move lines depending of the picking type's configuration. - move_lines = self['move_line_ids' if self.picking_type_id.show_reserved else 'move_line_nosuggest_ids'] + move_lines = self['move_line_ids' if self.show_reserved else 'move_line_nosuggest_ids'] move_lines = move_lines.filtered(lambda ml: not ml.lot_id and not ml.lot_name) if origin_move_line: diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index 07b5c959a5c..ecc74970a3a 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -43,6 +43,9 @@ class PickingType(models.Model): 'stock.location', 'Default Destination Location', check_company=True, help="This is the default destination location when you create a picking manually with this operation type. It is possible however to change it or that the routes put another location. If it is empty, it will check for the customer location on the partner. ") + default_location_return_id = fields.Many2one('stock.location', 'Default returns location', check_company=True, + help="This is the default location for returns created from a picking with this operation type.", + domain="[('return_location', '=', 'True')]") code = fields.Selection([('incoming', 'Receipt'), ('outgoing', 'Delivery'), ('internal', 'Internal Transfer')], 'Type of Operation', required=True) return_picking_type_id = fields.Many2one( 'stock.picking.type', 'Operation Type for Returns', @@ -67,7 +70,8 @@ class PickingType(models.Model): show_reserved = fields.Boolean( 'Pre-fill Detailed Operations', default=True, help="If this checkbox is ticked, Odoo will automatically pre-fill the detailed " - "operations with the corresponding products, locations and lot/serial numbers.") + "operations with the corresponding products, locations and lot/serial numbers. " + "For moves that are returns, the detailed operations will always be prefilled, regardless of this option.") reservation_method = fields.Selection( [('at_confirm', 'At Confirmation'), ('manual', 'Manually'), ('by_date', 'Before scheduled date')], 'Reservation Method', required=True, default='at_confirm', @@ -301,6 +305,11 @@ class Picking(models.Model): check_company=True, help="If this shipment was split, then this field links to the shipment which contains the already processed part.") backorder_ids = fields.One2many('stock.picking', 'backorder_id', 'Back Orders') + return_id = fields.Many2one('stock.picking', 'Return of', copy=False, index='btree_not_null', readonly=True, check_company=True, + help="If this picking was created as a return of another picking, this field links to the original picking.") + return_ids = fields.One2many('stock.picking', 'return_id', 'Returns') + return_count = fields.Integer('# Returns', compute='_compute_return_count', compute_sudo=False) + move_type = fields.Selection([ ('direct', 'As soon as possible'), ('one', 'When all products are ready')], 'Shipping Policy', default='direct', required=True, @@ -685,6 +694,11 @@ class Picking(models.Model): picking.location_id = location_id picking.location_dest_id = location_dest_id + @api.depends('return_ids') + def _compute_return_count(self): + for picking in self: + picking.return_count = len(picking.return_ids) + def _get_show_allocation(self, picking_type_id): """ Helper method for computing "show_allocation" value. Separated out from _compute function so it can be reused in other models (e.g. batch). @@ -1612,5 +1626,22 @@ class Picking(models.Model): ) return True + def action_see_returns(self): + self.ensure_one() + if len(self.return_ids) == 1: + return { + "type": "ir.actions.act_window", + "res_model": "stock.picking", + "views": [[False, "form"]], + "res_id": self.return_ids.id + } + return { + 'name': _('Returns'), + "type": "ir.actions.act_window", + "res_model": "stock.picking", + "views": [[False, "tree"], [False, "form"]], + "domain": [('id', 'in', self.return_ids.ids)], + } + def _get_report_lang(self): return self.move_ids and self.move_ids[0].partner_id.lang or self.partner_id.lang or self.env.lang diff --git a/addons/stock/models/stock_warehouse.py b/addons/stock/models/stock_warehouse.py index 77ffa6bd102..1c6fdc14295 100644 --- a/addons/stock/models/stock_warehouse.py +++ b/addons/stock/models/stock_warehouse.py @@ -76,7 +76,6 @@ class Warehouse(models.Model): out_type_id = fields.Many2one('stock.picking.type', 'Out Type', check_company=True) in_type_id = fields.Many2one('stock.picking.type', 'In Type', check_company=True) int_type_id = fields.Many2one('stock.picking.type', 'Internal Type', check_company=True) - return_type_id = fields.Many2one('stock.picking.type', 'Return Type', check_company=True) crossdock_route_id = fields.Many2one('stock.route', 'Crossdock Route', ondelete='restrict') reception_route_id = fields.Many2one('stock.route', 'Receipt Route', ondelete='restrict') delivery_route_id = fields.Many2one('stock.route', 'Delivery Route', ondelete='restrict') @@ -349,7 +348,7 @@ class Warehouse(models.Model): warehouse_data[picking_type] = PickingType.create(values).id if 'out_type_id' in warehouse_data: - PickingType.browse(warehouse_data['out_type_id']).write({'return_picking_type_id': warehouse_data.get('return_type_id', False)}) + PickingType.browse(warehouse_data['out_type_id']).write({'return_picking_type_id': warehouse_data.get('in_type_id', False)}) if 'in_type_id' in warehouse_data: PickingType.browse(warehouse_data['in_type_id']).write({'return_picking_type_id': warehouse_data.get('out_type_id', False)}) return warehouse_data @@ -941,11 +940,7 @@ class Warehouse(models.Model): }, 'int_type_id': { 'barcode': self.code.replace(" ", "").upper() + "-INTERNAL", - }, - 'return_type_id': { - 'default_location_dest_id': output_loc.id, - 'barcode': self.code.replace(" ", "").upper() + "-RETURNS", - }, + } } def _get_picking_type_create_values(self, max_sequence): @@ -1007,16 +1002,6 @@ class Warehouse(models.Model): 'sequence': max_sequence + 2, 'sequence_code': 'INT', 'company_id': self.company_id.id, - }, 'return_type_id': { - 'name': _('Returns'), - 'code': 'incoming', - 'use_create_lots': False, - 'use_existing_lots': True, - 'default_location_src_id': False, - 'sequence': max_sequence + 6, - 'show_reserved': True, - 'sequence_code': 'IN', - 'company_id': self.company_id.id, }, }, max_sequence + 6 @@ -1052,11 +1037,6 @@ class Warehouse(models.Model): 'prefix': code + '/INT/', 'padding': 5, 'company_id': self.company_id.id, }, - 'return_type_id': { - 'name': name + ' ' + _('Sequence return'), - 'prefix': code + '/RET/', 'padding': 5, - 'company_id': self.company_id.id, - }, } def _format_rulename(self, from_loc, dest_loc, suffix): diff --git a/addons/stock/report/report_return_slip.xml b/addons/stock/report/report_return_slip.xml new file mode 100644 index 00000000000..a37f7801077 --- /dev/null +++ b/addons/stock/report/report_return_slip.xml @@ -0,0 +1,47 @@ + + + + + + Return slip + stock.picking + qweb-pdf + stock.report_return_slip + return_slip + + report + + diff --git a/addons/stock/tests/test_move2.py b/addons/stock/tests/test_move2.py index c88d70f3064..83e50f97142 100644 --- a/addons/stock/tests/test_move2.py +++ b/addons/stock/tests/test_move2.py @@ -858,7 +858,7 @@ class TestPickShip(TestStockCommon): self.assertEqual(return_pick.move_line_ids[0].reserved_uom_qty, 4) self.assertEqual(return_pick.move_line_ids[1].lot_id, lot3) self.assertEqual(return_pick.move_line_ids[1].reserved_uom_qty, 6) - self.assertEqual(return_pick.picking_type_id, picking_client.location_id.warehouse_id.return_type_id) + self.assertEqual(return_pick.picking_type_id, picking_client.location_id.warehouse_id.in_type_id) class TestSinglePicking(TestStockCommon): def test_backorder_1(self): diff --git a/addons/stock/tests/test_stock_return_picking.py b/addons/stock/tests/test_stock_return_picking.py index cd6ceafb597..cbf8c1db929 100644 --- a/addons/stock/tests/test_stock_return_picking.py +++ b/addons/stock/tests/test_stock_return_picking.py @@ -32,11 +32,11 @@ class TestReturnPicking(TestStockCommon): move_1.quantity_done = 2 move_2.quantity_done = 1 picking_out.button_validate() - return_wizard = StockReturnObj.with_context(active_id=picking_out.id, active_ids=picking_out.ids).create({ + return_picking = StockReturnObj.with_context(active_id=picking_out.id, active_ids=picking_out.ids).create({ 'location_id': self.stock_location, 'picking_id': picking_out.id, }) - return_wizard._onchange_picking_id() + return_picking._compute_moves_locations() ReturnPickingLineObj = self.env['stock.return.picking.line'] # Check return line of uom_unit move diff --git a/addons/stock/views/stock_picking_type_views.xml b/addons/stock/views/stock_picking_type_views.xml index 6613e9400f4..0e5e0fbbbbf 100644 --- a/addons/stock/views/stock_picking_type_views.xml +++ b/addons/stock/views/stock_picking_type_views.xml @@ -98,6 +98,7 @@ + diff --git a/addons/stock/views/stock_picking_views.xml b/addons/stock/views/stock_picking_views.xml index ecaa05c901a..a496b345bbc 100644 --- a/addons/stock/views/stock_picking_views.xml +++ b/addons/stock/views/stock_picking_views.xml @@ -149,6 +149,11 @@
+