fix the revaluation bugs
This commit is contained in:
parent
7775323294
commit
64cac68586
Binary file not shown.
@ -3,6 +3,8 @@
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import float_compare
|
||||
from datetime import timedelta
|
||||
|
||||
|
||||
class AccountMoveLine(models.Model):
|
||||
@ -158,5 +160,110 @@ class AccountMoveLine(models.Model):
|
||||
if was_locked:
|
||||
po.button_done()
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# INVENTORY VALUATION UPDATE (AVCO/FIFO FIX)
|
||||
# ---------------------------------------------------------
|
||||
# If PO is received, updating price should update Stock Value
|
||||
if po_line.state in ['purchase', 'done'] and po_line.product_id.type == 'product':
|
||||
for stock_move in po_line.move_ids.filtered(lambda m: m.state == 'done'):
|
||||
# Calculate Diff based on NEW Price (updated above)
|
||||
new_val = price_unit * stock_move.quantity
|
||||
# Current Value from SVLs
|
||||
current_val = sum(stock_move.stock_valuation_layer_ids.mapped('value'))
|
||||
diff = new_val - current_val
|
||||
|
||||
currency = stock_move.company_id.currency_id
|
||||
if not currency.is_zero(diff):
|
||||
# 1. Create Correction SVL
|
||||
svl_vals = {
|
||||
'company_id': stock_move.company_id.id,
|
||||
'product_id': stock_move.product_id.id,
|
||||
'description': _("Valuation correction from Vendor Bill %s") % line.move_id.name,
|
||||
'value': diff,
|
||||
'quantity': 0,
|
||||
'stock_move_id': stock_move.id,
|
||||
}
|
||||
svl = self.env['stock.valuation.layer'].create(svl_vals)
|
||||
|
||||
# Backdate SVL
|
||||
if stock_move.date:
|
||||
new_date = stock_move.date + timedelta(seconds=1)
|
||||
self.env.cr.execute("UPDATE stock_valuation_layer SET create_date = %s WHERE id = %s", (new_date, svl.id))
|
||||
|
||||
# 2. AVCO/FIFO Logic: Update Standard Price and Distribute Value
|
||||
product = stock_move.product_id
|
||||
if product.categ_id.property_cost_method in ['average', 'fifo'] and product.quantity_svl > 0:
|
||||
new_std_price = product.standard_price + (diff / product.quantity_svl)
|
||||
product.with_context(disable_auto_svl=True).sudo().write({'standard_price': new_std_price})
|
||||
|
||||
remaining_svls = self.env['stock.valuation.layer'].search([
|
||||
('product_id', '=', product.id),
|
||||
('remaining_qty', '>', 0),
|
||||
('company_id', '=', stock_move.company_id.id),
|
||||
])
|
||||
|
||||
if remaining_svls:
|
||||
remaining_qty_total = sum(remaining_svls.mapped('remaining_qty'))
|
||||
if remaining_qty_total > 0:
|
||||
remaining_value_to_distribute = diff
|
||||
remaining_value_unit_cost = remaining_value_to_distribute / remaining_qty_total
|
||||
|
||||
for layer in remaining_svls:
|
||||
if float_compare(layer.remaining_qty, remaining_qty_total, precision_rounding=product.uom_id.rounding) >= 0:
|
||||
taken_remaining_value = remaining_value_to_distribute
|
||||
else:
|
||||
taken_remaining_value = remaining_value_unit_cost * layer.remaining_qty
|
||||
|
||||
taken_remaining_value = stock_move.company_id.currency_id.round(taken_remaining_value)
|
||||
layer.sudo().write({'remaining_value': layer.remaining_value + taken_remaining_value})
|
||||
|
||||
remaining_value_to_distribute -= taken_remaining_value
|
||||
remaining_qty_total -= layer.remaining_qty
|
||||
|
||||
# 3. Create Accounting Entry
|
||||
if stock_move.product_id.categ_id.property_valuation == 'real_time':
|
||||
accounts = stock_move.product_id.product_tmpl_id.get_product_accounts()
|
||||
acc_expense = accounts.get('expense')
|
||||
acc_valuation = accounts.get('stock_valuation')
|
||||
|
||||
if acc_expense and acc_valuation:
|
||||
if diff > 0:
|
||||
debit_acc = acc_valuation.id
|
||||
credit_acc = acc_expense.id
|
||||
amount = diff
|
||||
else:
|
||||
debit_acc = acc_expense.id
|
||||
credit_acc = acc_valuation.id
|
||||
amount = abs(diff)
|
||||
|
||||
acc_date = stock_move.date.date() if stock_move.date else fields.Date.today()
|
||||
|
||||
move_vals = {
|
||||
'journal_id': accounts['stock_journal'].id,
|
||||
'company_id': stock_move.company_id.id,
|
||||
'ref': _("Revaluation for %s from Bill Edit") % stock_move.product_id.name,
|
||||
'date': acc_date,
|
||||
'move_type': 'entry',
|
||||
'stock_valuation_layer_ids': [(6, 0, [svl.id])],
|
||||
'line_ids': [
|
||||
(0, 0, {
|
||||
'name': _("Valuation Correction - %s") % stock_move.product_id.name,
|
||||
'account_id': debit_acc,
|
||||
'debit': amount,
|
||||
'credit': 0,
|
||||
'product_id': stock_move.product_id.id,
|
||||
}),
|
||||
(0, 0, {
|
||||
'name': _("Valuation Correction - %s") % stock_move.product_id.name,
|
||||
'account_id': credit_acc,
|
||||
'debit': 0,
|
||||
'credit': amount,
|
||||
'product_id': stock_move.product_id.id,
|
||||
})
|
||||
]
|
||||
}
|
||||
am = self.env['account.move'].create(move_vals)
|
||||
am._post()
|
||||
|
||||
return res
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user