[FIX] mrp_mps, product: we need to be able to calculate stock in the past for the MPS
When calculating the stock quantity fields, we can put a from/to_date in the context. This should work in the past too. We see the to_date as the date in the past to calculate and calculate backwards from the stock now to the date in the past. This is done by doing an extra read_group on the stock moves, with a similar domain except that it takes the moves done from date_to.
This commit is contained in:
@@ -136,8 +136,8 @@ class MrpWorkorder(models.Model):
|
||||
def _compute_duration(self):
|
||||
self.duration = sum(self.time_ids.mapped('duration'))
|
||||
self.duration_unit = round(self.duration / max(self.qty_produced, 1), 2) # rounding 2 because it is a time
|
||||
if self.duration:
|
||||
self.duration_percent = 100 * (self.duration_expected - self.duration) / self.duration
|
||||
if self.duration_expected:
|
||||
self.duration_percent = 100 * (self.duration_expected - self.duration) / self.duration_expected
|
||||
else:
|
||||
self.duration_percent = 0
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from odoo.addons import decimal_precision as dp
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools.safe_eval import safe_eval as eval
|
||||
from odoo.tools.float_utils import float_round
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class Product(models.Model):
|
||||
@@ -105,16 +106,13 @@ class Product(models.Model):
|
||||
@api.multi
|
||||
def _compute_quantities_dict(self, lot_id, owner_id, package_id, from_date=False, to_date=False):
|
||||
domain_quant_loc, domain_move_in_loc, domain_move_out_loc = self._get_domain_locations()
|
||||
|
||||
domain_quant = [('product_id', 'in', self.ids)] + domain_quant_loc
|
||||
domain_move_in = [('state', 'not in', ('done', 'cancel', 'draft')), ('product_id', 'in', self.ids)] + domain_move_in_loc
|
||||
domain_move_out = [('state', 'not in', ('done', 'cancel', 'draft')), ('product_id', 'in', self.ids)] + domain_move_out_loc
|
||||
if from_date:
|
||||
domain_move_in += [('date', '>=', from_date)]
|
||||
domain_move_out += [('date', '>=', from_date)]
|
||||
if to_date:
|
||||
domain_move_in += [('date', '<=', to_date)]
|
||||
domain_move_out += [('date', '<=', to_date)]
|
||||
dates_in_the_past = False
|
||||
if to_date and to_date < fields.Datetime.now(): #Only to_date as to_date will correspond to qty_available
|
||||
dates_in_the_past = True
|
||||
|
||||
domain_move_in = [('product_id', 'in', self.ids)] + domain_move_in_loc
|
||||
domain_move_out = [('product_id', 'in', self.ids)] + domain_move_out_loc
|
||||
if lot_id:
|
||||
domain_quant += [('lot_id', '=', lot_id)]
|
||||
if owner_id:
|
||||
@@ -123,22 +121,44 @@ class Product(models.Model):
|
||||
domain_move_out += [('restrict_partner_id', '=', owner_id)]
|
||||
if package_id:
|
||||
domain_quant += [('package_id', '=', package_id)]
|
||||
if dates_in_the_past:
|
||||
domain_move_in_done = list(domain_move_in)
|
||||
domain_move_out_done = list(domain_move_out)
|
||||
if from_date:
|
||||
domain_move_in += [('date', '>=', from_date)]
|
||||
domain_move_out += [('date', '>=', from_date)]
|
||||
if to_date:
|
||||
domain_move_in += [('date', '<=', to_date)]
|
||||
domain_move_out += [('date', '<=', to_date)]
|
||||
|
||||
Move = self.env['stock.move']
|
||||
Quant = self.env['stock.quant']
|
||||
moves_in_res = dict((item['product_id'][0], item['product_qty']) for item in Move.read_group(domain_move_in, ['product_id', 'product_qty'], ['product_id']))
|
||||
moves_out_res = dict((item['product_id'][0], item['product_qty']) for item in Move.read_group(domain_move_out, ['product_id', 'product_qty'], ['product_id']))
|
||||
domain_move_in_todo = [('state', 'not in', ('done', 'cancel', 'draft'))] + domain_move_in
|
||||
domain_move_out_todo = [('state', 'not in', ('done', 'cancel', 'draft'))] + domain_move_out
|
||||
moves_in_res = dict((item['product_id'][0], item['product_qty']) for item in Move.read_group(domain_move_in_todo, ['product_id', 'product_qty'], ['product_id']))
|
||||
moves_out_res = dict((item['product_id'][0], item['product_qty']) for item in Move.read_group(domain_move_out_todo, ['product_id', 'product_qty'], ['product_id']))
|
||||
quants_res = dict((item['product_id'][0], item['qty']) for item in Quant.read_group(domain_quant, ['product_id', 'qty'], ['product_id']))
|
||||
if dates_in_the_past:
|
||||
# Calculate the moves that were done before now to calculate back in time (as most questions will be recent ones)
|
||||
domain_move_in_done = [('state', '=', 'done'), ('date', '>', to_date)] + domain_move_in_done
|
||||
domain_move_out_done = [('state', '=', 'done'), ('date', '>', to_date)] + domain_move_out_done
|
||||
moves_in_res_past = dict((item['product_id'][0], item['product_qty']) for item in Move.read_group(domain_move_in_done, ['product_id', 'product_qty'], ['product_id']))
|
||||
moves_out_res_past = dict((item['product_id'][0], item['product_qty']) for item in Move.read_group(domain_move_out_done, ['product_id', 'product_qty'], ['product_id']))
|
||||
|
||||
res = dict()
|
||||
for product in self.with_context(prefetch_fields=False):
|
||||
res[product.id] = {}
|
||||
res[product.id]['qty_available'] = float_round(quants_res.get(product.id, 0.0), precision_rounding=product.uom_id.rounding)
|
||||
if dates_in_the_past:
|
||||
qty_available = quants_res.get(product.id, 0.0) - moves_in_res_past.get(product.id, 0.0) + moves_out_res_past.get(product.id, 0.0)
|
||||
else:
|
||||
qty_available = quants_res.get(product.id, 0.0)
|
||||
res[product.id]['qty_available'] = float_round(qty_available, precision_rounding=product.uom_id.rounding)
|
||||
res[product.id]['incoming_qty'] = float_round(moves_in_res.get(product.id, 0.0), precision_rounding=product.uom_id.rounding)
|
||||
res[product.id]['outgoing_qty'] = float_round(moves_out_res.get(product.id, 0.0), precision_rounding=product.uom_id.rounding)
|
||||
res[product.id]['virtual_available'] = float_round(
|
||||
res[product.id]['qty_available'] + res[product.id]['incoming_qty'] - res[product.id]['outgoing_qty'],
|
||||
qty_available + res[product.id]['incoming_qty'] - res[product.id]['outgoing_qty'],
|
||||
precision_rounding=product.uom_id.rounding)
|
||||
|
||||
return res
|
||||
|
||||
def _get_domain_locations(self):
|
||||
|
||||
Reference in New Issue
Block a user