From 10c90e3515a343b4e4dc6b5e16217203cbf1d13a Mon Sep 17 00:00:00 2001 From: Ahmad Khanalizadeh Date: Wed, 15 Mar 2023 13:13:04 +0000 Subject: [PATCH] [FIX] delivery: group by products when creating commodities Before this commit, if you made a product to be tracked by unique serial number and then make a sale order with hundreds of units of the same product, each unit will make a separate line with qty = 1. The issue is each serial makes a different `stock.move.line` and `_get_commodities_from_stock_move_lines` groups by move lines, which leads to the issue. To solve the problem we need to group the move lines by product. opw-3212809 closes odoo/odoo#116882 X-original-commit: 3c4a12bac1302c8e39dc2a1c617e6536c2d07d3d Signed-off-by: Arnold Moyaux (arm) Signed-off-by: Khanalizadeh Ahmad (khah) --- .../stock_delivery/models/delivery_carrier.py | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/addons/stock_delivery/models/delivery_carrier.py b/addons/stock_delivery/models/delivery_carrier.py index 3d0a9212f11..cfebcac0183 100644 --- a/addons/stock_delivery/models/delivery_carrier.py +++ b/addons/stock_delivery/models/delivery_carrier.py @@ -4,6 +4,7 @@ from odoo import _, fields, models from odoo.exceptions import UserError, ValidationError from odoo.tools.float_utils import float_round +from odoo.tools.misc import groupby from .delivery_request_objects import DeliveryCommodity, DeliveryPackage @@ -199,18 +200,19 @@ class DeliveryCarrier(models.Model): def _get_commodities_from_stock_move_lines(self, move_lines): commodities = [] - for line in move_lines.filtered(lambda line: line.product_id.type in ['product', 'consu']): - qty = line.qty_done if line.state == 'done' else line.reserved_uom_qty - unit_quantity = line.product_uom_id._compute_quantity(qty, line.product_id.uom_id) + + product_lines = move_lines.filtered(lambda line: line.product_id.type in ['product', 'consu']) + for product, lines in groupby(product_lines, lambda x: x.product_id): + unit_quantity = sum( + line.product_uom_id._compute_quantity( + line.qty_done if line.state == 'done' else line.reserved_uom_qty, + product.uom_id) + for line in lines) rounded_qty = max(1, float_round(unit_quantity, precision_digits=0)) - country_of_origin = line.product_id.country_of_origin.code or \ - line.picking_id.picking_type_id.warehouse_id.partner_id.country_id.code - commodities.append(DeliveryCommodity( - line.product_id, - amount=rounded_qty, - monetary_value=line.sale_price, - country_of_origin=country_of_origin - )) + country_of_origin = product.country_of_origin.code or lines[0].picking_id.picking_type_id.warehouse_id.partner_id.country_id.code + sale_price = sum(line.sale_price for line in lines) + commodities.append(DeliveryCommodity(product, amount=rounded_qty, monetary_value=sale_price, country_of_origin=country_of_origin)) + return commodities def _product_price_to_company_currency(self, quantity, product, company):