Skip to content

Instantly share code, notes, and snippets.

@razvanioan
Forked from ahmedelbougha/stock_move.py
Created November 5, 2021 17:31
Show Gist options
  • Save razvanioan/d5ed5cd9fcbbd12b3751da8a9ca3c450 to your computer and use it in GitHub Desktop.
Save razvanioan/d5ed5cd9fcbbd12b3751da8a9ca3c450 to your computer and use it in GitHub Desktop.
Example of Odoo Multi-Threading - Background Process
from odoo import api, fields, models
from odoo.tools import float_is_zero
from odoo.exceptions import UserError, ValidationError
import threading
import time
import logging
class StockMove(models.Model):
_inherit = 'stock.move'
def _action_done(self, cancel_backorder=False):
res = super(StockMove, self)._action_done(
cancel_backorder=cancel_backorder)
for move in self:
threaded_calculation = threading.Thread(
target=self._run_delayed_calculations, args=([[move.id]]))
threaded_calculation.start()
return res
def _run_delayed_calculations(self, move_ids):
# sleeping time to make sure quantity done is already saved
time.sleep(3)
with api.Environment.manage():
new_cr = self.pool.cursor()
self = self.with_env(self.env(cr=new_cr))
moves = self.env['stock.move'].search(
[('id', 'in', move_ids)]).with_env(self.env(cr=new_cr))
lot_groups_calculated = False
weighted_average_total = 0
lot_groups = [{'lots': [], 'weighted_average':0},
{'lots': [], 'weighted_average':0},
{'lots': [], 'weighted_average':0}]
for move in moves:
cost = 0
runs = 0
valued_quantity = 0
move._sanity_check_for_valuation()
valued_move_lines = move.move_line_ids
for valued_move_line in valued_move_lines:
valued_quantity = valued_move_line.product_uom_id._compute_quantity(
valued_move_line.qty_done, move.product_id.uom_id)
if valued_quantity == 0:
continue
cost += move.product_id._prepare_out_svl_vals(
valued_quantity, move.company_id).get('value', 0)
# run the calculation of lot_groups and weighted_average_total just for the first move as
# it should be the same for all move in same current picking
if not lot_groups_calculated:
lot_groups_calculated = True
# dividing lot_ids into groups
for lot_id in move.picking_id.lot_ids:
# doing some calculations for lot_groups to prepare them
# in order to define weighted average for each of them
for i, lot_group in enumerate(lot_groups):
lot_group_count = len(lot_group['lots'])
if lot_group_count > 0:
runs += 1
# get the new unit cost of each lot in the group
unit_cost = - (cost * lot_group['weighted_average'])
for lot_id in lot_group['lots']:
in_move_line = self.env['stock.move.line'].search(
[('lot_id', '=', lot_id.id)], limit=1).with_env(self.env(cr=new_cr))
in_move = in_move_line.move_id
# get the traget valuation layer to increase the cost
linked_layer = in_move.stock_valuation_layer_ids[:1]
linked_layer.value += unit_cost
new_cr.commit()
return {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment