Skip to content

Commit

Permalink
[FIX] stock: fix check of package all in move lines
Browse files Browse the repository at this point in the history
The `groupby` function is used to builds groups of(product, lot) keys
and their corresponding move lines / quants. `groupby` groups
*consecutive* keys, which is why the input is sorted by the keys.

`sorted` on recordsets keys will not sort as we would expect in this
particular situation, as the comparison operators on records act as
Set Comparison operators on the record ids, i.e. to compare the sets
superset/subset relationships:

```
>>> env["product.product"].browse(1) < env["product.product"].browse(2)
False
>>> env["product.product"].browse(1) < env["product.product"].browse([1, 2])
True
```

Example of sorted on stock.move.line records, where the product id 7313
is both in the slots 4 and 12 instead of being consecutive:

```
>>> [l.product_id.id for l in sorted(lines, key=itemgetter('product_id'))]
[7436, 7437, 7352, 7423, 7313, 7351, 7423, 7424, 7320, 7398, 7312, 7352, 7313, 7436, 7437, 7442, 7443, 7320, 7423, 7424, 7318, 7396, 7368, 7355, 7316]
```

Now when we group by id the 2 ids 7313 are correctly placed together in
slots 1 and 2:

```
>>> [l.product_id.id for l in sorted(lines, key=attrgetter('product_id.id'))]
[7312, 7313, 7313, 7316, 7318, 7320, 7320, 7351, 7352, 7352, 7355, 7368, 7396, 7398, 7423, 7423, 7423, 7424, 7424, 7436, 7436, 7437, 7437, 7442, 7443]
```

This commit aims to sort by "id" of the related records, to ensure the
same (product, lot) couples are consecutive.

closes #63541

Signed-off-by: Arnold Moyaux <amoyaux@users.noreply.github.com>
  • Loading branch information
guewen authored and sebalix committed May 21, 2021
1 parent 3e8b930 commit 3317249
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions addons/stock/models/stock_picking.py
Expand Up @@ -4,7 +4,7 @@
from ast import literal_eval
from datetime import date
from itertools import groupby
from operator import itemgetter
from operator import attrgetter, itemgetter
import time

from odoo import api, fields, models, SUPERUSER_ID, _
Expand Down Expand Up @@ -771,14 +771,15 @@ def _check_move_lines_map_quant_package(self, package):
all_in = True
pack_move_lines = self.move_line_ids.filtered(lambda ml: ml.package_id == package)
keys = ['product_id', 'lot_id']
keys_ids = ["{}.id".format(fname) for fname in keys]
precision_digits = self.env['decimal.precision'].precision_get('Product Unit of Measure')

grouped_quants = {}
for k, g in groupby(sorted(package.quant_ids, key=itemgetter(*keys)), key=itemgetter(*keys)):
for k, g in groupby(sorted(package.quant_ids, key=attrgetter(*keys_ids)), key=itemgetter(*keys)):
grouped_quants[k] = sum(self.env['stock.quant'].concat(*list(g)).mapped('quantity'))

grouped_ops = {}
for k, g in groupby(sorted(pack_move_lines, key=itemgetter(*keys)), key=itemgetter(*keys)):
for k, g in groupby(sorted(pack_move_lines, key=attrgetter(*keys_ids)), key=itemgetter(*keys)):
grouped_ops[k] = sum(self.env['stock.move.line'].concat(*list(g)).mapped('product_qty'))
if any(not float_is_zero(grouped_quants.get(key, 0) - grouped_ops.get(key, 0), precision_digits=precision_digits) for key in grouped_quants) \
or any(not float_is_zero(grouped_ops.get(key, 0) - grouped_quants.get(key, 0), precision_digits=precision_digits) for key in grouped_ops):
Expand Down

0 comments on commit 3317249

Please sign in to comment.