Skip to content

Commit

Permalink
[FIX] stock_account: anglo saxon and corrections
Browse files Browse the repository at this point in the history
Don't ignore correction layers when computing the anglo saxon price
unit. We use the `stock_valuation_layer_id` field on the layer to point
the correction layer to the corrected layer. When computing the average
price of the delivered things, ignore correction entry but take them
into account when choosing a corrected entry.

opw-2179900

closes odoo#44498

Signed-off-by: Simon Lejeune (sle) <[email protected]>
  • Loading branch information
sle-odoo committed Feb 3, 2020
1 parent 8a6c5cb commit 3831649
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
76 changes: 76 additions & 0 deletions addons/sale_stock/tests/test_anglo_saxon_valuation.py
Original file line number Diff line number Diff line change
Expand Up @@ -855,3 +855,79 @@ def test_fifo_delivered_invoice_post_delivery(self):
self.assertEqual(income_aml.debit, 0)
self.assertEqual(income_aml.credit, 24)

def test_fifo_delivered_invoice_post_delivery_2(self):
"""Receive at 8 then at 10. Sale order 10@12 and deliver without receiving the 2 missing.
receive 2@12. Invoice."""
self.product.categ_id.property_cost_method = 'fifo'
self.product.invoice_policy = 'delivery'
self.product.standard_price = 10

in_move_1 = self.env['stock.move'].create({
'name': 'a',
'product_id': self.product.id,
'location_id': self.env.ref('stock.stock_location_suppliers').id,
'location_dest_id': self.stock_location.id,
'product_uom': self.product.uom_id.id,
'product_uom_qty': 8,
'price_unit': 10,
})
in_move_1._action_confirm()
in_move_1.quantity_done = 8
in_move_1._action_done()

# Create and confirm a sale order for 2@12
sale_order = self.env['sale.order'].create({
'partner_id': self.customer.id,
'order_line': [
(0, 0, {
'name': self.product.name,
'product_id': self.product.id,
'product_uom_qty': 10.0,
'product_uom': self.product.uom_id.id,
'price_unit': 12,
'tax_id': False, # no love taxes amls
})],
})
sale_order.action_confirm()

# Deliver 10
sale_order.picking_ids.move_lines.quantity_done = 10
sale_order.picking_ids.button_validate()

# Make the second receipt
in_move_2 = self.env['stock.move'].create({
'name': 'a',
'product_id': self.product.id,
'location_id': self.env.ref('stock.stock_location_suppliers').id,
'location_dest_id': self.stock_location.id,
'product_uom': self.product.uom_id.id,
'product_uom_qty': 2,
'price_unit': 12,
})
in_move_2._action_confirm()
in_move_2.quantity_done = 2
in_move_2._action_done()
self.assertEqual(self.product.stock_valuation_layer_ids[-1].value, -4) # we sent two at 10 but they should have been sent at 12
self.assertEqual(self.product.stock_valuation_layer_ids[-1].quantity, 0)
self.assertEqual(sale_order.order_line.move_ids.stock_valuation_layer_ids[-1].quantity, 0)

# Invoice the sale order.
invoice = sale_order._create_invoices()
invoice.post()

# Check the resulting accounting entries
amls = invoice.line_ids
self.assertEqual(len(amls), 4)
stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account)
self.assertEqual(stock_out_aml.debit, 0)
self.assertEqual(stock_out_aml.credit, 104)
cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account)
self.assertEqual(cogs_aml.debit, 104)
self.assertEqual(cogs_aml.credit, 0)
receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account)
self.assertEqual(receivable_aml.debit, 120)
self.assertEqual(receivable_aml.credit, 0)
income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account)
self.assertEqual(income_aml.debit, 0)
self.assertEqual(income_aml.credit, 120)

6 changes: 5 additions & 1 deletion addons/stock_account/models/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ def _run_fifo_vacuum(self, company=None):
'stock_move_id': move.id,
'company_id': move.company_id.id,
'description': 'Revaluation of %s (negative inventory)' % move.picking_id.name or move.name,
'stock_valuation_layer_id': svl_to_vacuum.id,
}
vacuum_svl = self.env['stock.valuation.layer'].sudo().create(vals)

Expand Down Expand Up @@ -596,6 +597,8 @@ def _compute_average_price(self, qty_invoiced, qty_to_invoice, stock_moves):
tmp_value = 0 # to accumulate the value taken on the candidates
for candidate in candidates:
candidate_quantity = abs(candidate.quantity)
if float_is_zero(candidate_quantity, precision_rounding=candidate.uom_id.rounding):
continue # correction entries
if not float_is_zero(qty_invoiced, precision_rounding=candidate.uom_id.rounding):
qty_ignored = min(qty_invoiced, candidate_quantity)
qty_invoiced -= qty_ignored
Expand All @@ -605,7 +608,8 @@ def _compute_average_price(self, qty_invoiced, qty_to_invoice, stock_moves):
qty_taken_on_candidate = min(qty_to_take_on_candidates, candidate_quantity)

qty_to_take_on_candidates -= qty_taken_on_candidate
tmp_value += qty_taken_on_candidate * (candidate.value / candidate.quantity)
tmp_value += qty_taken_on_candidate * \
((candidate.value + sum(candidate.stock_valuation_layer_ids.mapped('value'))) / candidate.quantity)
if float_is_zero(qty_to_take_on_candidates, precision_rounding=candidate.uom_id.rounding):
break

Expand Down

0 comments on commit 3831649

Please sign in to comment.