stock_inventory_backdate/models/stock_move.py
2025-12-08 10:28:06 +07:00

86 lines
4.3 KiB
Python

from odoo import api, models, fields
from odoo.tools import float_round
class StockMove(models.Model):
_inherit = 'stock.move'
def _action_done(self, cancel_backorder=False):
moves = super(StockMove, self)._action_done(cancel_backorder=cancel_backorder)
forced_inventory_date = self.env.context.get('force_inventory_date')
if forced_inventory_date:
for move in moves:
move.write({'date': forced_inventory_date})
# If valuation is real-time, we might need to adjust the account move date too.
# But account move creation usually happens in _action_done -> _create_account_move_line
# which might use the move date.
# Let's check if we need to update account moves.
# Account move date field is Date type, so convert datetime to date
if move.account_move_ids:
account_date = forced_inventory_date.date() if hasattr(forced_inventory_date, 'date') else forced_inventory_date
move.account_move_ids.write({'date': account_date})
return moves
def _create_account_move_line(self, credit_account_id, debit_account_id, journal_id, qty, description, svl_id, cost):
# Override to force date on account move creation if needed.
# However, if we update the move date in _action_done, it might be too late for this method
# if it's called during super()._action_done().
# So we might need to rely on context here too.
forced_inventory_date = self.env.context.get('force_inventory_date')
forced_valuation_date = self.env.context.get('force_valuation_date')
# Use valuation date if present, otherwise inventory date
target_date = forced_valuation_date or forced_inventory_date
if target_date:
# We can't easily change the arguments passed to this method without signature change,
# but we can patch the context or check if we can modify the created move later.
# Actually, this method creates 'account.move'.
# Let's see if we can intercept the creation.
pass
return super(StockMove, self)._create_account_move_line(credit_account_id, debit_account_id, journal_id, qty, description, svl_id, cost)
def _prepare_account_move_vals(self, credit_account_id, debit_account_id, journal_id, qty, description, svl_id, cost):
# This method prepares the values for account.move.create.
vals = super(StockMove, self)._prepare_account_move_vals(credit_account_id, debit_account_id, journal_id, qty, description, svl_id, cost)
forced_inventory_date = self.env.context.get('force_inventory_date')
forced_valuation_date = self.env.context.get('force_valuation_date')
target_date = forced_valuation_date or forced_inventory_date
if target_date:
# Account move date field is Date type, so convert datetime to date if needed
account_date = target_date.date() if hasattr(target_date, 'date') else target_date
vals['date'] = account_date
return vals
def _create_in_svl(self, forced_quantity=None):
# Override to force date on stock valuation layer
svl = super(StockMove, self)._create_in_svl(forced_quantity=forced_quantity)
self._update_svl_date(svl)
return svl
def _create_out_svl(self, forced_quantity=None):
# Override to force date on stock valuation layer
svl = super(StockMove, self)._create_out_svl(forced_quantity=forced_quantity)
self._update_svl_date(svl)
return svl
def _update_svl_date(self, svl):
forced_inventory_date = self.env.context.get('force_inventory_date')
forced_valuation_date = self.env.context.get('force_valuation_date')
target_date = forced_valuation_date or forced_inventory_date
if target_date and svl:
# create_date is a magic field, we need to update it via SQL
self.env.cr.execute(
"UPDATE stock_valuation_layer SET create_date = %s WHERE id IN %s",
(target_date, tuple(svl.ids))
)
svl.invalidate_recordset(['create_date'])