[FIX] purchase_stock: valuation layer wrong when different currency
To reproduce: 1. Create a storable product with ordered quantities policy for purchase and with a category set as FIFO automated 2. Create a purchase order in a different currency and set quantities for partial deliveries 3. Create a partial delivery 4. Fully invoice the purchase order 5. Create the delivery of the complementary units 6. Check the stock valuation layer The valuation of backorder is wrong. The value on valuation layer is in company's currency, while the value on invoice line is in the PO's currency. When create valuation line for backorder, we didn't convert them to same currency. opw-3300266 closes odoo/odoo#125206 X-original-commit: c2de679fcba7f153201dde5b3aa989eb3f329910 Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com> Signed-off-by: Yuchen Huang (yhu) <yhu@odoo.com>
This commit is contained in:
@@ -45,13 +45,20 @@ class StockMove(models.Model):
|
||||
if float_compare(line.qty_invoiced, received_qty, precision_rounding=line.product_uom.rounding) > 0:
|
||||
move_layer = line.move_ids.stock_valuation_layer_ids
|
||||
invoiced_layer = line.invoice_lines.stock_valuation_layer_ids
|
||||
receipt_value = sum(move_layer.mapped('value')) + sum(invoiced_layer.mapped('value'))
|
||||
# value on valuation layer is in company's currency, while value on invoice line is in order's currency
|
||||
receipt_value = 0
|
||||
if move_layer:
|
||||
receipt_value += sum(move_layer.mapped(lambda l: l.currency_id._convert(
|
||||
l.value, order.currency_id, order.company_id, l.account_move_id.date, round=False)))
|
||||
if invoiced_layer:
|
||||
receipt_value += sum(invoiced_layer.mapped(lambda l: l.currency_id._convert(
|
||||
l.value, order.currency_id, order.company_id, l.account_move_id.date, round=False)))
|
||||
invoiced_value = 0
|
||||
invoiced_qty = 0
|
||||
for invoice_line in line.invoice_lines:
|
||||
if invoice_line.tax_ids:
|
||||
invoiced_value += invoice_line.tax_ids.with_context(round=False).compute_all(
|
||||
invoice_line.price_unit, currency=invoice_line.account_id.currency_id, quantity=invoice_line.quantity)['total_void']
|
||||
invoice_line.price_unit, currency=invoice_line.currency_id, quantity=invoice_line.quantity)['total_void']
|
||||
else:
|
||||
invoiced_value += invoice_line.price_unit * invoice_line.quantity
|
||||
invoiced_qty += invoice_line.product_uom_id._compute_quantity(invoice_line.quantity, line.product_id.uom_id)
|
||||
|
||||
@@ -1887,3 +1887,48 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
|
||||
full_reconcile = input_amls[0].full_reconcile_id
|
||||
self.assertTrue(full_reconcile)
|
||||
self.assertTrue(all(aml.full_reconcile_id == full_reconcile for aml in input_amls))
|
||||
|
||||
def test_invoice_on_ordered_qty_with_backorder_and_different_currency(self):
|
||||
"""Create a PO with currency different from the company currency. Set the
|
||||
product to be invoiced on ordered quantities. Receive partially the products
|
||||
and create a backorder. Create an invoice for the ordered quantity. Then
|
||||
receive the backorder. Check if the valuation layer is correctly created.
|
||||
"""
|
||||
usd_currency = self.env.ref('base.USD')
|
||||
self.env.company.currency_id = usd_currency.id
|
||||
self.product1.categ_id.property_cost_method = 'fifo'
|
||||
self.product1.purchase_method = 'purchase'
|
||||
|
||||
price_unit_EUR = 100
|
||||
price_unit_USD = self.env.ref('base.EUR')._convert(price_unit_EUR, usd_currency, self.env.company, fields.Date.today(), round=False)
|
||||
po = self.env['purchase.order'].create({
|
||||
'partner_id': self.partner_id.id,
|
||||
'currency_id': self.env.ref('base.EUR').id,
|
||||
'order_line': [
|
||||
(0, 0, {
|
||||
'name': self.product1.name,
|
||||
'product_id': self.product1.id,
|
||||
'product_qty': 12.0,
|
||||
'product_uom': self.product1.uom_po_id.id,
|
||||
'price_unit': 100.0,
|
||||
'date_planned': datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
}),
|
||||
],
|
||||
})
|
||||
po.button_confirm()
|
||||
picking = po.picking_ids[0]
|
||||
move = picking.move_ids[0]
|
||||
move.quantity_done = 10
|
||||
res_dict = picking.button_validate()
|
||||
self.assertEqual(res_dict['res_model'], 'stock.backorder.confirmation')
|
||||
wizard = self.env[(res_dict.get('res_model'))].browse(res_dict.get('res_id')).with_context(res_dict['context'])
|
||||
wizard.process()
|
||||
self.assertAlmostEqual(move.stock_valuation_layer_ids.unit_cost, price_unit_USD)
|
||||
|
||||
po.action_create_invoice()
|
||||
|
||||
picking2 = po.picking_ids.filtered(lambda p: p.backorder_id)
|
||||
move2 = picking2.move_ids[0]
|
||||
move2.quantity_done = 2
|
||||
picking2.button_validate()
|
||||
self.assertAlmostEqual(move2.stock_valuation_layer_ids.unit_cost, price_unit_USD)
|
||||
|
||||
Reference in New Issue
Block a user