[11.0][IMP] multi_level_mrp: replace plain queries with orm methods.

This commit is contained in:
Lois Rilo
2018-06-20 14:12:03 +02:00
committed by Jordi Ballester Alomar
parent a3a6992ba7
commit d613212ae7
3 changed files with 93 additions and 86 deletions

View File

@@ -8,9 +8,13 @@ from odoo import api, fields, models
class MrpProduct(models.Model):
_name = 'mrp.product'
mrp_area_id = fields.Many2one('mrp.area', 'MRP Area')
current_qty_available = fields.Float(string='Current Qty Available',
related='product_id.qty_available')
mrp_area_id = fields.Many2one(
comodel_name='mrp.area', string='MRP Area',
)
current_qty_available = fields.Float(
string='Current Qty Available',
related='product_id.qty_available',
)
main_supplier_id = fields.Many2one(
comodel_name='res.partner', string='Main Supplier',
compute='_compute_main_supplier', store=True,

View File

@@ -254,9 +254,22 @@ class TestMultiLevelMRP(SavepointCase):
self.assertEqual(pp_2_line_4.demand_qty, 48.0)
self.assertEqual(pp_2_line_4.to_procure, 48.0)
def test_05_actions_count(self):
"""Test actions counters."""
pass
def test_05_moves_extra_info(self):
"""Test running availability and actions counters computation on
mrp moves."""
# Running availability for PP-1:
moves = self.mrp_move_obj.search([
('product_id', '=', self.pp_1.id)],
order='mrp_date, mrp_type desc, id')
self.assertEqual(len(moves), 6)
expected = [200.0, 290.0, 90.0, 0.0, 72.0, 0.0]
self.assertEqual(moves.mapped('running_availability'), expected)
# Actions counters for PP-1:
mrp_product = self.mrp_product_obj.search([
('product_id', '=', self.pp_1.id)
])
self.assertEqual(mrp_product.nbr_mrp_actions, 3)
self.assertEqual(mrp_product.nbr_mrp_actions_4w, 3)
def test_06_procure_mo(self):
"""Test procurement wizard with MOs."""

View File

@@ -5,11 +5,14 @@
from odoo import api, fields, models, exceptions, _
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from datetime import date, datetime, timedelta
import logging
logger = logging.getLogger(__name__)
ODOO_READ_GROUP_DAY_FORMAT = '%d %b %Y'
class MultiLevelMrp(models.TransientModel):
_name = 'multi.level.mrp'
@@ -718,7 +721,6 @@ class MultiLevelMrp(models.TransientModel):
mrp_product = self._init_mrp_product(product, mrp_area)
# for mrp_product in self.env['mrp.product'].search([]):
self._init_mrp_move(mrp_product)
# self.env.cr.commit()
logger.info('END MRP INITIALISATION')
@api.model
@@ -796,7 +798,6 @@ class MultiLevelMrp(models.TransientModel):
for mrp_area in self.env['mrp.area'].search([]):
llc = 0
while mrp_lowest_llc > llc:
# self.env.cr.commit()
mrp_products = mrp_product_obj.search(
[('mrp_llc', '=', llc),
('mrp_area_id', '=', mrp_area.id)])
@@ -839,71 +840,71 @@ class MultiLevelMrp(models.TransientModel):
qty_ordered = cm['qty_ordered']
onhand += qty_ordered
counter += 1
# self.env.cr.commit()
log_msg = 'MRP CALCULATION LLC %s FINISHED - NBR PRODUCTS: %s' % (
llc - 1, counter)
logger.info(log_msg)
# self.env.cr.commit()
logger.info('END MRP CALCULATION')
@api.model
def _init_mrp_inventory(self, mrp_product):
mrp_move_obj = self.env['mrp.move']
# Read Demand
# TODO: Replace with ORM read_group
demand_groups = mrp_move_obj.read_group(
[('mrp_product_id', '=', mrp_product.id),
('mrp_type', '=', 'd')],
['mrp_date', 'mrp_qty'], ['mrp_date:day'],
)
demand_qty_by_date = {}
sql_stat = '''SELECT mrp_date, sum(mrp_qty) as demand_qty
FROM mrp_move
WHERE mrp_product_id = %d
AND mrp_type = 'd'
GROUP BY mrp_date''' % (mrp_product.id, )
self.env.cr.execute(sql_stat)
for sql_res in self.env.cr.dictfetchall():
demand_qty_by_date[sql_res['mrp_date']] = sql_res['demand_qty']
for group in demand_groups:
# Reformat date back to default server format.
group_date = datetime.strptime(
group['mrp_date:day'], ODOO_READ_GROUP_DAY_FORMAT).strftime(
DEFAULT_SERVER_DATE_FORMAT)
demand_qty_by_date[group_date] = group['mrp_qty']
# Read Supply
# TODO: Replace with ORM read_group
supply_groups = mrp_move_obj.read_group(
[('mrp_product_id', '=', mrp_product.id),
('mrp_type', '=', 's'),
('mrp_action', '=', 'none')],
['mrp_date', 'mrp_qty'], ['mrp_date:day'],
)
supply_qty_by_date = {}
sql_stat = '''SELECT mrp_date, sum(mrp_qty) as supply_qty
FROM mrp_move
WHERE mrp_product_id = %d
AND mrp_type = 's'
AND mrp_action = 'none'
GROUP BY mrp_date''' % (mrp_product.id, )
self.env.cr.execute(sql_stat)
for sql_res in self.env.cr.dictfetchall():
supply_qty_by_date[sql_res['mrp_date']] = sql_res['supply_qty']
for group in supply_groups:
# Reformat date back to default server format.
group_date = datetime.strptime(
group['mrp_date:day'], ODOO_READ_GROUP_DAY_FORMAT).strftime(
DEFAULT_SERVER_DATE_FORMAT)
supply_qty_by_date[group_date] = group['mrp_qty']
# Read supply actions
supply_actions_qty_by_date = {}
mrp_type = 's'
# TODO: if we remove cancel take it into account here,
# TODO: as well as mrp_type ('r').
exclude_mrp_actions = ['none', 'cancel']
sql_stat = '''SELECT mrp_date, sum(mrp_qty) as actions_qty
FROM mrp_move
WHERE mrp_product_id = %d
AND mrp_qty <> 0.0
AND mrp_type = 's'
AND mrp_action not in %s
GROUP BY mrp_date''' % (mrp_product.id,
tuple(exclude_mrp_actions))
self.env.cr.execute(sql_stat)
for sql_res in self.env.cr.dictfetchall():
supply_actions_qty_by_date[sql_res['mrp_date']] = \
sql_res['actions_qty']
action_groups = mrp_move_obj.read_group(
[('mrp_product_id', '=', mrp_product.id),
('mrp_qty', '!=', 0.0),
('mrp_type', '=', 's'),
('mrp_action', 'not in', exclude_mrp_actions)],
['mrp_date', 'mrp_qty'], ['mrp_date:day'],
)
supply_actions_qty_by_date = {}
for group in action_groups:
# Reformat date back to default server format.
group_date = datetime.strptime(
group['mrp_date:day'], ODOO_READ_GROUP_DAY_FORMAT).strftime(
DEFAULT_SERVER_DATE_FORMAT)
supply_actions_qty_by_date[group_date] = group['mrp_qty']
# Dates
sql_stat = '''SELECT mrp_date
FROM mrp_move
WHERE mrp_product_id = %d
GROUP BY mrp_date
ORDER BY mrp_date''' % (mrp_product.id, )
self.env.cr.execute(sql_stat)
on_hand_qty = mrp_product.current_qty_available
for sql_res in self.env.cr.dictfetchall():
mdt = sql_res['mrp_date']
mrp_dates = set(mrp_move_obj.search([
('mrp_product_id', '=', mrp_product.id)],
order='mrp_date').mapped('mrp_date'))
on_hand_qty = mrp_product.current_qty_available # TODO: unreserved?
for mdt in sorted(mrp_dates):
mrp_inventory_data = {
'mrp_product_id': mrp_product.id,
'date': mdt,
@@ -928,46 +929,35 @@ class MultiLevelMrp(models.TransientModel):
@api.model
def _mrp_final_process(self):
logger.info('START MRP FINAL PROCESS')
mrp_areas = self.env['mrp.area'].search([])
mrp_product_ids = self.env['mrp.product'].search(
[('mrp_llc', '<', 9999),
('mrp_area_id', 'in', mrp_areas.ids)])
mrp_product_ids = self.env['mrp.product'].search([
('mrp_llc', '<', 9999),
('mrp_area_id', '!=', False)])
for mrp_product in mrp_product_ids:
# Build the time-phased inventory
self._init_mrp_inventory(mrp_product)
# Complete the info on mrp_move
# Complete info on mrp_move (running availability and nbr actions)
qoh = mrp_product.mrp_qty_available
nbr_actions = 0
nbr_actions_4w = 0
sql_stat = 'SELECT id, mrp_date, mrp_qty, mrp_action FROM ' \
'mrp_move WHERE mrp_product_id = %d ' \
'ORDER BY ' \
'mrp_date, ' \
'mrp_type desc, id' % (mrp_product.id, )
self.env.cr.execute(sql_stat)
for sql_res in self.env.cr.dictfetchall():
qoh = qoh + sql_res['mrp_qty']
self.env['mrp.move'].search(
[('id', '=', sql_res['id'])]).write(
{'running_availability': qoh})
for move in mrp_product.mrp_move_ids:
if move.mrp_action != 'none':
nbr_actions += 1
if move.mrp_date:
if move.mrp_action != 'none' and \
datetime.date(datetime.strptime(
move.mrp_action_date, '%Y-%m-%d')) < \
date.today()+timedelta(days=29):
nbr_actions_4w += 1
if nbr_actions > 0:
self.env['mrp.product'].search(
[('id', '=', mrp_product.id)]).write(
{'nbr_mrp_actions': nbr_actions,
'nbr_mrp_actions_4w': nbr_actions_4w})
# self.env.cr.commit()
moves = self.env['mrp.move'].search([
('mrp_product_id', '=', mrp_product.id)],
order='mrp_date, mrp_type desc, id')
for move in moves:
qoh = qoh + move.mrp_qty
move.running_availability = qoh
nbr_actions = mrp_product.mrp_move_ids.filtered(
lambda m: m.mrp_action != 'none')
horizon_4w = fields.Date.to_string(
date.today() + timedelta(weeks=4))
nbr_actions_4w = nbr_actions.filtered(
lambda m: m.mrp_action_date < horizon_4w)
if nbr_actions:
mrp_product.write({
'nbr_mrp_actions': len(nbr_actions),
'nbr_mrp_actions_4w': len(nbr_actions_4w),
})
logger.info('END MRP FINAL PROCESS')
@api.multi