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. if move.account_move_ids: move.account_move_ids.write({'date': forced_inventory_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: vals['date'] = target_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'])