[FIX] stock_picking_report_valued: Refactor code to avoid decimal differences

TT17492 TT26034 TT33957 TT34954
This commit is contained in:
Carlos Dauden
2022-03-08 18:11:03 +01:00
parent 495b24ee78
commit f648461d64
4 changed files with 44 additions and 50 deletions

View File

@@ -13,7 +13,7 @@
"website": "https://github.com/OCA/stock-logistics-reporting",
"category": "Warehouse Management",
"license": "AGPL-3",
"depends": ["sale_management", "stock"],
"depends": ["sale_stock"],
"data": ["views/res_partner_view.xml", "report/stock_picking_report_valued.xml"],
"installable": True,
}

View File

@@ -1,10 +1,11 @@
# Copyright 2014-2018 Tecnativa - Pedro M. Baeza
# Copyright 2015 Antonio Espinosa - Tecnativa <antonio.espinosa@tecnativa.com>
# Copyright 2018 Luis M. Ontalba - Tecnativa <luis.martinez@tecnativa.com>
# Copyright 2016-2018 Carlos Dauden - Tecnativa <carlos.dauden@tecnativa.com>
# Copyright 2015 Tecnativa - Antonio Espinosa
# Copyright 2018 Tecnativa - Luis M. Ontalba
# Copyright 2016-2022 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
from odoo.tools import float_compare
class StockMoveLine(models.Model):
@@ -42,38 +43,38 @@ class StockMoveLine(models.Model):
compute="_compute_sale_order_line_fields", string="Total", compute_sudo=True
)
def _get_report_valued_quantity(self):
return self.qty_done or self.product_qty
def _compute_sale_order_line_fields(self):
"""This is computed with sudo for avoiding problems if you don't have
access to sales orders (stricter warehouse users, inter-company
records...).
"""
for line in self:
sale_line = line.sale_line
price_unit = (
sale_line.price_subtotal / sale_line.product_uom_qty
if sale_line.product_uom_qty
else sale_line.price_reduce
)
taxes = line.sale_tax_id.compute_all(
price_unit=price_unit,
currency=line.currency_id,
quantity=line.qty_done or line.product_qty,
product=line.product_id,
partner=sale_line.order_id.partner_shipping_id,
)
if sale_line.company_id.tax_calculation_rounding_method == (
"round_globally"
quantity = line._get_report_valued_quantity()
valued_line = line.sale_line
# If order line quantity don't match with move line quantity compute values
if float_compare(
quantity,
line.sale_line.product_uom_qty,
precision_rounding=line.product_uom_id.rounding,
):
price_tax = sum(t.get("amount", 0.0) for t in taxes.get("taxes", []))
else:
price_tax = taxes["total_included"] - taxes["total_excluded"]
# Force read to cache M2M field for get values with _convert_to_write
line.sale_line.mapped("tax_id")
# Create virtual sale line with stock move line quantity
sol_vals = line.sale_line._convert_to_write(line.sale_line._cache)
valued_line = line.sale_line.new(sol_vals)
valued_line.product_uom_qty = quantity
# Force original price unit to avoid pricelist recomputed (not needed)
valued_line.price_unit = line.sale_line.price_unit
line.update(
{
"sale_tax_description": ", ".join(
t.name or t.description for t in line.sale_tax_id
),
"sale_price_subtotal": taxes["total_excluded"],
"sale_price_tax": price_tax,
"sale_price_total": taxes["total_included"],
"sale_price_subtotal": valued_line.price_subtotal,
"sale_price_tax": valued_line.price_tax,
"sale_price_total": valued_line.price_total,
}
)

View File

@@ -1,7 +1,7 @@
# Copyright 2014-2018 Tecnativa - Pedro M. Baeza
# Copyright 2015 Antonio Espinosa - Tecnativa <antonio.espinosa@tecnativa.com>
# Copyright 2016 Carlos Dauden - Tecnativa <carlos.dauden@tecnativa.com>
# Copyright 2016 Luis M. Ontalba - Tecnativa <luis.martinez@tecnativa.com>
# Copyright 2015 Tecnativa - Antonio Espinosa
# Copyright 2016-2022 Tecnativa - Carlos Dauden
# Copyright 2016 Tecnativa - Luis M. Ontalba
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
@@ -35,13 +35,10 @@ class StockPicking(models.Model):
records...).
"""
for pick in self:
round_curr = pick.sale_id.currency_id.round
amount_tax = 0.0
for tax_group in pick.get_taxes_values().values():
amount_tax += round_curr(tax_group["amount"])
amount_untaxed = sum(
line.sale_price_subtotal for line in pick.move_line_ids
)
amount_untaxed = amount_tax = 0.0
for line in pick.move_line_ids:
amount_untaxed += line.sale_price_subtotal
amount_tax += line.sale_price_tax
pick.update(
{
"amount_untaxed": amount_untaxed,
@@ -49,18 +46,3 @@ class StockPicking(models.Model):
"amount_total": amount_untaxed + amount_tax,
}
)
def get_taxes_values(self):
tax_grouped = {}
for line in self.move_line_ids:
for tax in line.sale_line.tax_id:
tax_id = tax.id
if tax_id not in tax_grouped:
tax_grouped[tax_id] = {"base": line.sale_price_subtotal, "tax": tax}
else:
tax_grouped[tax_id]["base"] += line.sale_price_subtotal
for tax_id, tax_group in tax_grouped.items():
tax_grouped[tax_id]["amount"] = tax_group["tax"].compute_all(
tax_group["base"], self.sale_id.currency_id
)["taxes"][0]["amount"]
return tax_grouped

View File

@@ -129,3 +129,14 @@ class TestStockPickingValued(common.SavepointCase):
self.assertEqual(picking.amount_untaxed, 300.0)
self.assertEqual(picking.amount_tax, 40.0)
self.assertEqual(picking.amount_total, 340.0)
def test_05_distinct_qty(self):
self.assertTrue(self.partner.valued_picking)
self.sale_order.action_confirm()
self.assertTrue(len(self.sale_order.picking_ids))
for picking in self.sale_order.picking_ids:
picking.action_assign()
picking.move_line_ids.qty_done = 2.0
self.assertEqual(picking.amount_untaxed, 200.0)
self.assertEqual(picking.amount_tax, 30.0)
self.assertEqual(picking.amount_total, 230.0)