[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:
Josse Colpaert
2016-08-19 17:16:18 +02:00
parent 7a77209149
commit c3665fb5c9
2 changed files with 35 additions and 15 deletions
+2 -2
View File
@@ -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
+33 -13
View File
@@ -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):