Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 41 additions & 4 deletions stock_picking_report_valued/models/stock_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,47 @@ def _compute_amount_all(self):
records...).
"""
for pick in self:
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 = pick.with_company(pick.company_id)
move_lines = pick.move_line_ids.filtered(lambda x: x.sale_line)

if pick.company_id.tax_calculation_rounding_method == "round_globally":
# With global rounding, we need to use the same method as sale.order
# to calculate taxes on all lines together, not sum line by line
tax_lines_data = []
for line in move_lines:
valued_line = line.sale_line
quantity = line._get_report_valued_quantity()
different_uom = valued_line.product_uom != line.product_uom_id
different_qty = float_compare(
quantity,
valued_line.product_uom_qty,
precision_rounding=line.product_uom_id.rounding,
)
if different_uom or different_qty:
# Create virtual sale line with move line quantity
valued_line.mapped("tax_id") # Force cache
sol_vals = valued_line._convert_to_write(valued_line._cache)
sol_vals["product_uom_qty"] = quantity
sol_vals.pop("price_subtotal", None)
valued_line = valued_line.new(sol_vals)

tax_line_dict = valued_line._convert_to_tax_base_line_dict()
tax_lines_data.append(tax_line_dict)

if tax_lines_data:
tax_results = pick.env["account.tax"]._compute_taxes(tax_lines_data)
totals = tax_results["totals"]
amount_untaxed = totals.get(pick.currency_id, {}).get(
"amount_untaxed", 0.0
)
amount_tax = totals.get(pick.currency_id, {}).get("amount_tax", 0.0)
else:
amount_untaxed = amount_tax = 0.0
else:
# With round_per_line, sum the tax from each line (current behavior)
amount_untaxed = sum(move_lines.mapped("sale_price_subtotal"))
amount_tax = sum(move_lines.mapped("sale_price_tax"))

pick.update(
{
"amount_untaxed": amount_untaxed,
Expand Down
38 changes: 38 additions & 0 deletions stock_picking_report_valued/tests/test_stock_picking_valued.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,41 @@ def _patched_get_report_valued_total_amount(self):
finally:
# Restore original method
StockPicking._get_report_valued_total_amount = original_method

def test_08_partial_delivery_with_round_globally(self):
"""
Test partial delivery (different quantity) with global tax rounding.
This tests the code path that creates a virtual sale line with
different quantity when round_globally is active.
"""
self.sale_order.company_id.tax_calculation_rounding_method = "round_globally"
self.sale_order.action_confirm()
self.assertTrue(len(self.sale_order.picking_ids))
picking = self.sale_order.picking_ids[0]
picking.action_assign()
# Change quantity to trigger the different_qty code path
picking.move_line_ids.quantity = 0.5
# Force recompute
picking.invalidate_recordset(["amount_untaxed", "amount_tax", "amount_total"])
# With 0.5 quantity: 100 * 0.5 = 50, tax = 50 * 0.15 = 7.5
self.assertEqual(picking.amount_untaxed, 50.0)
self.assertEqual(picking.amount_tax, 7.5)
self.assertEqual(picking.amount_total, 57.5)

def test_09_empty_picking_with_round_globally(self):
"""
Test picking without sale lines with global tax rounding.
This tests the code path when tax_lines_data is empty.
"""
self.sale_order.company_id.tax_calculation_rounding_method = "round_globally"
self.sale_order.action_confirm()
picking = self.sale_order.picking_ids[0]
picking.action_assign()
# Unreserve to clear move_line_ids with sale_line
picking.do_unreserve()
# Force recompute
picking.invalidate_recordset(["amount_untaxed", "amount_tax", "amount_total"])
# Should be 0.0 when no lines
self.assertEqual(picking.amount_untaxed, 0.0)
self.assertEqual(picking.amount_tax, 0.0)
self.assertEqual(picking.amount_total, 0.0)
Loading