[FIX] (purchase_)stock(_dropshipping): move partner depends on picking partner

Stock moves don't have a `partner_id` if they are created before setting
the picking's `partner_id`

Steps to reproduce (from v15):
1. Create a new transfer with operation type 'Delivery Orders'
2. Add a move, then a delivery address and save
3. Mark as todo and validate
4. Print the delivery slip
5. The warehouse address is printed but it should be the delivery
   address

Solution:
Replace `onchange_partner_id` of `stock.picking` by a compute method in
`stock.move`. It assigns the partner_id of the `stock.move` to its
picking's partner_id if the move is part of the picking's
`move_ids_without_package` (in purchase_stock, also check that it is not
a dropshipping)

Problem:
When creating a picking, its moves' `partner_id` is only set if the
picking's `partner_id` was already set in the form

opw-3091139

closes odoo/odoo#107625

Signed-off-by: Tiffany Chang <tic@odoo.com>
This commit is contained in:
MerlinGuillaume
2023-01-03 14:32:52 +01:00
parent d326a9c4c4
commit c9b1f1c932
4 changed files with 64 additions and 10 deletions
@@ -26,6 +26,11 @@ class StockMove(models.Model):
def _prepare_merge_negative_moves_excluded_distinct_fields(self):
return super()._prepare_merge_negative_moves_excluded_distinct_fields() + ['created_purchase_line_id']
def _compute_partner_id(self):
# dropshipped moves should have their partner_ids directly set
not_dropshipped_moves = self.filtered(lambda m: not m._is_dropshipped())
super(StockMove, not_dropshipped_moves)._compute_partner_id()
def _get_price_unit(self):
""" Returns the unit price for the move"""
self.ensure_one()
+7 -1
View File
@@ -85,7 +85,8 @@ class StockMove(models.Model):
partner_id = fields.Many2one(
'res.partner', 'Destination Address ',
states={'done': [('readonly', True)]},
help="Optional address where goods are to be delivered, specifically used for allotment")
help="Optional address where goods are to be delivered, specifically used for allotment",
compute='_compute_partner_id', store=True, readonly=False)
move_dest_ids = fields.Many2many(
'stock.move', 'stock_move_move_rel', 'move_orig_id', 'move_dest_id', 'Destination Moves',
copy=False,
@@ -299,6 +300,11 @@ class StockMove(models.Model):
move.product_qty = move.product_uom._compute_quantity(
move.product_uom_qty, move.product_id.uom_id, rounding_method='HALF-UP')
@api.depends('picking_id.partner_id')
def _compute_partner_id(self):
for move in self.filtered(lambda m: m.picking_id):
move.partner_id = move.picking_id.partner_id
def _get_move_lines(self):
""" 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."""
-9
View File
@@ -709,15 +709,6 @@ class Picking(models.Model):
late_stock_moves = self.env['stock.move'].search([('delay_alert_date', operator, value)])
return [('move_ids', 'in', late_stock_moves.ids)]
@api.onchange('partner_id')
def onchange_partner_id(self):
for picking in self:
picking_id = isinstance(picking.id, int) and picking.id or getattr(picking, '_origin', False) and picking._origin.id
if picking_id:
moves = self.env['stock.move'].search([('picking_id', '=', picking_id)])
for move in moves:
move.write({'partner_id': picking.partner_id.id})
@api.onchange('picking_type_id', 'partner_id')
def _onchange_picking_type(self):
if self.picking_type_id and self.state == 'draft':
@@ -130,3 +130,55 @@ class TestDropship(common.TransactionCase):
('location_dest_id', '=', self.env.ref('stock.stock_location_customers').id),
('product_id', '=', drop_shop_product.id)])
self.assertEqual(len(move_line.ids), 1, 'There should be exactly one move line')
def test_sale_order_picking_partner(self):
""" Test that the partner is correctly set on the picking and the move when the product is dropshipped or not."""
# Create a vendor and a customer
supplier_dropship = self.env['res.partner'].create({'name': 'Vendor'})
customer = self.env['res.partner'].create({'name': 'Customer'})
# Create new product without any routes
super_product = self.env['product.product'].create({
'name': "Super product",
'seller_ids': [(0, 0, {
'partner_id': supplier_dropship.id,
})],
})
# Create a sale order
so_form = Form(self.env['sale.order'])
so_form.partner_id = customer
with so_form.order_line.new() as line:
line.product_id = super_product
sale_order = so_form.save()
# Confirm sale order
sale_order.action_confirm()
# Check the partner of the related picking and move
self.assertEqual(sale_order.picking_ids.partner_id, customer)
self.assertEqual(sale_order.picking_ids.move_ids.partner_id, customer)
# Add a dropship route to the product
super_product.route_ids = [self.env.ref('stock_dropshipping.route_drop_shipping').id]
# Create a sale order
so_form = Form(self.env['sale.order'])
so_form.partner_id = customer
with so_form.order_line.new() as line:
line.product_id = super_product
sale_order = so_form.save()
# Confirm sale order
sale_order.action_confirm()
# Check a quotation was created to a certain vendor and confirm it, so it becomes a confirmed purchase order
purchase = self.env['purchase.order'].search([('partner_id', '=', supplier_dropship.id)])
self.assertTrue(purchase, "an RFQ should have been created by the scheduler")
purchase.button_confirm()
self.assertEqual(purchase.state, 'purchase', 'Purchase order should be in the approved state')
# Check the partner of the related picking and move
self.assertEqual(sale_order.picking_ids.partner_id, supplier_dropship)
self.assertEqual(sale_order.picking_ids.move_ids.partner_id, customer)