Skip to content
Snippets Groups Projects
Commit 3b88958f authored by yhu-odoo's avatar yhu-odoo
Browse files

[FIX] stock_account: valuation layer is zero when return dropshipping


To reproduce:
1. Create a Sales Order for a product whose product category is set to
   FIFO and automated. Use route "dropship".
2. Confirm the PO created.
3. Deliver the products (DS transfer)
4. Create the customer invoice
5. Return, for example, 1 unit of product
6. Add a credit note to the invoice for that 1 unit returned (reset to
   draft then change qty and post)
Issues:
The value on the valuation layers of the returned picking is 0, posted
entries for COGS and stock interim (delivered) account for credit note
is also 0.

Since #85751, When create valuation layer for return, we take all svls
of origin_returned_move_id into account to calculate the price unit.
However, then dropshiping, 2 svls are created for the original move, and
the sum of them is 0 since there is no impact of the stock when
dropshiping. So when return, the price unit will be calculated as 0.

To fix, when calculate price unit for return of dropshiping, we only
take non-negative svls into account. Note that we use non-negative ones
instead of positive ones because when subcontract dropshiping,
additional negative svls will be added for the cost of the components.

opw-3283436

closes odoo/odoo#123529

Signed-off-by: default avatarArnold Moyaux (arm) <arm@odoo.com>
parent 54dce61e
No related branches found
No related tags found
No related merge requests found
......@@ -5,7 +5,7 @@ from collections import defaultdict
from odoo import api, fields, models, _
from odoo.exceptions import UserError
from odoo.tools import float_is_zero, OrderedSet
from odoo.tools import float_compare, float_is_zero, OrderedSet
import logging
_logger = logging.getLogger(__name__)
......@@ -40,6 +40,10 @@ class StockMove(models.Model):
# If the move is a return, use the original move's price unit.
if self.origin_returned_move_id and self.origin_returned_move_id.sudo().stock_valuation_layer_ids:
layers = self.origin_returned_move_id.sudo().stock_valuation_layer_ids
# dropshipping create additional positive svl to make sure there is no impact on the stock valuation
# We need to remove them from the computation of the price unit.
if self.origin_returned_move_id._is_dropshipped():
layers = layers.filtered(lambda l: float_compare(l.value, 0, precision_rounding=l.product_id.uom_id.rounding) <= 0)
layers |= layers.stock_valuation_layer_ids
quantity = sum(layers.mapped("quantity"))
return layers.currency_id.round(sum(layers.mapped("value")) / quantity) if not float_is_zero(quantity, precision_rounding=layers.uom_id.rounding) else 0
......
......@@ -298,3 +298,29 @@ class TestStockValuation(ValuationReconciliationTestCommon):
}
self._check_results(expected_aml, 4, all_amls_return - all_amls)
def test_dropship_fifo_return(self):
"""Test the return of a dropship order with a product set to FIFO costing
method. The unit price is correctly computed on the return picking svl.
"""
self.env.company.anglo_saxon_accounting = True
self.product1.product_tmpl_id.categ_id.property_cost_method = 'fifo'
self.product1.product_tmpl_id.categ_id.property_valuation = 'real_time'
self.product1.product_tmpl_id.invoice_policy = 'order'
self._dropship_product1()
self.assertTrue(8 in self.purchase_order1.picking_ids.move_lines.stock_valuation_layer_ids.mapped('value'))
self.assertTrue(-8 in self.purchase_order1.picking_ids.move_lines.stock_valuation_layer_ids.mapped('value'))
# return what we've done
stock_return_picking_form = Form(self.env['stock.return.picking']
.with_context(active_ids=self.sale_order1.picking_ids.ids, active_id=self.sale_order1.picking_ids.ids[0],
active_model='stock.picking'))
stock_return_picking = stock_return_picking_form.save()
stock_return_picking_action = stock_return_picking.create_returns()
return_pick = self.env['stock.picking'].browse(stock_return_picking_action['res_id'])
return_pick.move_lines[0].move_line_ids[0].qty_done = 1.0
return_pick._action_done()
self.assertTrue(8 in return_pick.move_lines.stock_valuation_layer_ids.mapped('value'))
self.assertTrue(-8 in return_pick.move_lines.stock_valuation_layer_ids.mapped('value'))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment