[FIX] stock{,_dropshipping}: set last delivery partner on lot
If `stock_dropshipping` is installed, the "Transfer To" field of a lot does not work with standard flows To reproduce the issue: 1. Create a tracked-by-sn product 2. Update its quantity with 1 x SN 3. Deliver SN to a partner 4. Open the list view of lots/serial numbers and enable the column "Transfer To" Error: The field "Transfer To" for SN is empty, it should be the partner The field `last_delivery_partner_id` is a computed one and the compute method calls `_find_delivery_ids_by_lot` to get all relevant information. In this method, we search the SMLs based on a domain provided by `_get_delivery_ids_by_lot_domain`. If `stock_dropshipping` is not installed, the method will return a legit domain: https://github.com/odoo/odoo/blob/7adc661be1eb426a90842160b2e062446d3ccc03/addons/stock/models/stock_lot.py#L191-L196 However, if the dropshipping module is installed, an override creates the same domain (directly in the override, without any call to `super`) and adds a `OR` condition: https://github.com/odoo/odoo/blob/7adc661be1eb426a90842160b2e062446d3ccc03/addons/stock_dropshipping/models/stock.py#L62-L70 But it contains an error: the `AND` operator is missing, it should be ```py '&', ('location_dest_id.usage', '=', 'customer'), ('location_id.usage', '=', 'supplier') ``` As a result, for an SM to be found, its source location usage has to be `supplier`. This is the reason why, in the above use case, the lot does not have any `last_delivery_partner_id`: we did not find such an SML. OPW-3386247 closes odoo/odoo#128558 X-original-commit: 8ecc177478f0ffc8ba9cfc65f47386363bd6cb4a Signed-off-by: William Henrotin (whe) <whe@odoo.com>
This commit is contained in:
committed by
William Henrotin
parent
9616c9940d
commit
8a310ae2e4
@@ -6,6 +6,7 @@ from re import findall as regex_findall, split as regex_split
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.osv import expression
|
||||
|
||||
|
||||
class StockLot(models.Model):
|
||||
@@ -200,17 +201,23 @@ class StockLot(models.Model):
|
||||
})
|
||||
return action
|
||||
|
||||
def _get_delivery_ids_by_lot_domain(self):
|
||||
@api.model
|
||||
def _get_outgoing_domain(self):
|
||||
return [
|
||||
('lot_id', 'in', self.ids),
|
||||
('state', '=', 'done'),
|
||||
'|', ('picking_code', '=', 'outgoing'), ('produce_line_ids', '!=', False),
|
||||
'|',
|
||||
('picking_code', '=', 'outgoing'),
|
||||
('produce_line_ids', '!=', False),
|
||||
]
|
||||
|
||||
def _find_delivery_ids_by_lot(self, lot_path=None, delivery_by_lot=None):
|
||||
if lot_path is None:
|
||||
lot_path = set()
|
||||
domain = self._get_delivery_ids_by_lot_domain()
|
||||
domain = [
|
||||
('lot_id', 'in', self.ids),
|
||||
('state', '=', 'done'),
|
||||
]
|
||||
domain_restriction = self._get_outgoing_domain()
|
||||
domain = expression.AND([domain, domain_restriction])
|
||||
move_lines = self.env['stock.move.line'].search(domain)
|
||||
moves_by_lot = {
|
||||
lot_id: {'producing_lines': set(), 'barren_lines': set()}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from odoo.addons.stock.tests.common import TestStockCommon
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests import Form
|
||||
from odoo.tests import Form, tagged
|
||||
from odoo.tools import mute_logger, float_round
|
||||
from odoo import fields
|
||||
|
||||
@@ -2597,3 +2597,45 @@ class TestStockFlow(TestStockCommon):
|
||||
# trigger SQL constraints
|
||||
self.PickingObj.flush_model()
|
||||
self.assertEqual(self.PickingObj.search_count([('name', '=', picking_2.name)]), 1)
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestStockFlowPostInstall(TestStockCommon):
|
||||
|
||||
def test_last_delivery_partner_field_on_lot(self):
|
||||
stock_location = self.env['stock.location'].browse(self.stock_location)
|
||||
|
||||
partner = self.env['res.partner'].create({'name': 'Super Partner'})
|
||||
|
||||
product = self.env['product.product'].create({
|
||||
'name': 'Super Product',
|
||||
'type': 'product',
|
||||
'tracking': 'serial',
|
||||
})
|
||||
sn = self.env['stock.lot'].create({
|
||||
'name': 'super_sn',
|
||||
'product_id': product.id,
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
self.env['stock.quant']._update_available_quantity(product, stock_location, 1, lot_id=sn)
|
||||
|
||||
delivery = self.env['stock.picking'].create({
|
||||
'partner_id': partner.id,
|
||||
'picking_type_id': self.picking_type_out,
|
||||
'location_id': self.stock_location,
|
||||
'location_dest_id': self.customer_location,
|
||||
'move_ids': [(0, 0, {
|
||||
'name': product.name,
|
||||
'product_id': product.id,
|
||||
'product_uom': product.uom_id.id,
|
||||
'product_uom_qty': 1.0,
|
||||
'location_id': self.stock_location,
|
||||
'location_dest_id': self.customer_location,
|
||||
})],
|
||||
})
|
||||
delivery.action_confirm()
|
||||
delivery.action_assign()
|
||||
delivery.move_ids.move_line_ids.qty_done = 1
|
||||
delivery.button_validate()
|
||||
|
||||
self.assertEqual(sn.last_delivery_partner_id, partner)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models, fields
|
||||
from odoo.osv import expression
|
||||
|
||||
|
||||
class StockRule(models.Model):
|
||||
@@ -70,12 +71,9 @@ class StockLot(models.Model):
|
||||
if last_delivery.is_dropship:
|
||||
lot.last_delivery_partner_id = last_delivery.sale_id.partner_id
|
||||
|
||||
def _get_delivery_ids_by_lot_domain(self):
|
||||
return [
|
||||
('lot_id', 'in', self.ids),
|
||||
('state', '=', 'done'),
|
||||
'|',
|
||||
'|', ('picking_code', '=', 'outgoing'), ('produce_line_ids', '!=', False),
|
||||
# dropship transfers have an incoming picking_code but should be considered as well
|
||||
('location_dest_id.usage', '=', 'customer'), ('location_id.usage', '=', 'supplier')
|
||||
]
|
||||
def _get_outgoing_domain(self):
|
||||
res = super()._get_outgoing_domain()
|
||||
return expression.OR([res, [
|
||||
('location_dest_id.usage', '=', 'customer'),
|
||||
('location_id.usage', '=', 'supplier'),
|
||||
]])
|
||||
|
||||
Reference in New Issue
Block a user