[FIX] purchase_stock: get_price_unit with manual valuation
layer.account_move_id may not be defined on 'manual' valuation. Use layer.create_date instead which is equal to layer.account_move_id.date. # HOW TO REPRODUCE: - Create a product P, storable in AVCO !! MANUAL !! - Set 'Control Policy' under Purchase to 'Ordered Quantity' - Create a PO for 10 units of P with for $1 each. - Create Vendor Bill -> Confirm - Receive 5 unit of P: Create backorder - Validate backorder ==>> Traceback OPW-3383833 closes odoo/odoo#127218 X-original-commit: b1351ee348207283dcdf7118440b31c03f0d0b4b Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com> Signed-off-by: David Fesquet (dafr) <dafr@odoo.com>
This commit is contained in:
@@ -50,10 +50,10 @@ class StockMove(models.Model):
|
||||
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)))
|
||||
l.value, order.currency_id, order.company_id, l.create_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)))
|
||||
l.value, order.currency_id, order.company_id, l.create_date, round=False)))
|
||||
invoiced_value = 0
|
||||
invoiced_qty = 0
|
||||
for invoice_line in line.invoice_lines:
|
||||
|
||||
@@ -1942,51 +1942,6 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
|
||||
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)
|
||||
|
||||
def test_pdiff_and_credit_notes(self):
|
||||
"""
|
||||
Auto FIFO
|
||||
@@ -2484,3 +2439,93 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
|
||||
svls = self.product1.stock_valuation_layer_ids
|
||||
self.assertEqual(svls.mapped('remaining_value'), [13.0, 12.0, 0.0, 0.0, 0.0, 0.0])
|
||||
self.assertEqual(svls.mapped('value'), [10.0, 10.0, 1.0, 2.0, -1.0, 3.0])
|
||||
|
||||
def test_invoice_on_ordered_qty_with_backorder_and_different_currency_automated(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.categ_id.property_valuation = 'real_time'
|
||||
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)
|
||||
|
||||
def test_invoice_on_ordered_qty_with_backorder_and_different_currency_manual(self):
|
||||
"""Same test as test_invoice_on_ordered_qty_with_backorder_and_different_currency_automated with manual_periodic valuation
|
||||
Ensure that the absence of account_move_id on the layers does not generate an Exception
|
||||
"""
|
||||
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.categ_id.property_valuation = 'manual_periodic'
|
||||
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