diff --git a/mrp_multi_level/__manifest__.py b/mrp_multi_level/__manifest__.py
index 7504f1284..a01fd421f 100644
--- a/mrp_multi_level/__manifest__.py
+++ b/mrp_multi_level/__manifest__.py
@@ -4,6 +4,7 @@
{
'name': 'MRP Multi Level',
'version': '11.0.1.0.0',
+ 'license': 'AGPL-3',
'author': 'Ucamco, '
'Eficent, '
'Odoo Community Association (OCA)',
diff --git a/mrp_multi_level/data/mrp_multi_level_cron.xml b/mrp_multi_level/data/mrp_multi_level_cron.xml
index 83c2417ca..40ec42e6d 100755
--- a/mrp_multi_level/data/mrp_multi_level_cron.xml
+++ b/mrp_multi_level/data/mrp_multi_level_cron.xml
@@ -1,17 +1,16 @@
-
-
- Multi Level MRP
-
-
- 1
- days
- -1
-
-
-
-
-
+
+
+ Multi Level MRP
+
+
+ 1
+ days
+ -1
+
+ code
+ model.run_mrp_multi_level()
+
diff --git a/mrp_multi_level/demo/initial_on_hand_demo.xml b/mrp_multi_level/demo/initial_on_hand_demo.xml
index a2cd4991c..2edf4c4b7 100644
--- a/mrp_multi_level/demo/initial_on_hand_demo.xml
+++ b/mrp_multi_level/demo/initial_on_hand_demo.xml
@@ -29,4 +29,4 @@
-
\ No newline at end of file
+
diff --git a/mrp_multi_level/models/mrp_area.py b/mrp_multi_level/models/mrp_area.py
index 2111dcd4a..2b3be32e5 100644
--- a/mrp_multi_level/models/mrp_area.py
+++ b/mrp_multi_level/models/mrp_area.py
@@ -8,12 +8,14 @@ from odoo import fields, models
class MrpArea(models.Model):
_name = 'mrp.area'
-
+
name = fields.Char('Name')
warehouse_id = fields.Many2one(
comodel_name='stock.warehouse', string='Warehouse',
- required=True)
+ required=True,
+ )
location_id = fields.Many2one(
comodel_name='stock.location', string='Location',
- required=True)
+ required=True,
+ )
active = fields.Boolean(default=True)
diff --git a/mrp_multi_level/models/mrp_inventory.py b/mrp_multi_level/models/mrp_inventory.py
index 3115b6e29..360a86069 100644
--- a/mrp_multi_level/models/mrp_inventory.py
+++ b/mrp_multi_level/models/mrp_inventory.py
@@ -15,7 +15,8 @@ class MrpInventory(models.Model):
_rec_name = 'mrp_product_id'
# TODO: name to pass to procurements?
- # TODO: compute procurement_date to pass to the wizard? not needed for PO at least. Check for MO and moves
+ # TODO: compute procurement_date to pass to the wizard? not needed for
+ # PO at least. Check for MO and moves
# TODO: substract qty already procured.
# TODO: show a LT based on the procure method?
diff --git a/mrp_multi_level/models/mrp_move.py b/mrp_multi_level/models/mrp_move.py
index 126d08741..c04049096 100644
--- a/mrp_multi_level/models/mrp_move.py
+++ b/mrp_multi_level/models/mrp_move.py
@@ -2,8 +2,7 @@
# © 2016-18 Eficent Business and IT Consulting Services S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
-from odoo import models, fields, api, _
-from odoo import exceptions
+from odoo import models, fields
class MrpMove(models.Model):
@@ -12,22 +11,22 @@ class MrpMove(models.Model):
# TODO: too many indexes...
- mrp_area_id = fields.Many2one('mrp.area', 'MRP Area')
- current_date = fields.Date('Current Date')
- current_qty = fields.Float('Current Qty')
- # TODO: remove purchase request and move to other module?
+ mrp_area_id = fields.Many2one(
+ comodel_name='mrp.area',
+ string='MRP Area',
+ )
+ current_date = fields.Date(string='Current Date')
+ current_qty = fields.Float(string='Current Qty')
# TODO: cancel is not needed I think...
mrp_action = fields.Selection(
selection=[('mo', 'Manufacturing Order'),
('po', 'Purchase Order'),
- ('pr', 'Purchase Request'),
- ('so', 'Sale Order'),
('cancel', 'Cancel'),
('none', 'None')],
string='Action',
)
- mrp_action_date = fields.Date('MRP Action Date')
- mrp_date = fields.Date('MRP Date')
+ mrp_action_date = fields.Date(string='MRP Action Date')
+ mrp_date = fields.Date(string='MRP Date')
mrp_move_down_ids = fields.Many2many(
comodel_name='mrp.move',
relation='mrp_move_rel',
@@ -46,40 +45,46 @@ class MrpMove(models.Model):
string='Minimum Stock',
related='product_id.mrp_minimum_stock',
)
- mrp_order_number = fields.Char('Order Number')
- # TODO: move purchase request to another module
+ mrp_order_number = fields.Char(string='Order Number')
+ # TODO: replace by a char origin?
mrp_origin = fields.Selection(
selection=[('mo', 'Manufacturing Order'),
('po', 'Purchase Order'),
- ('pr', 'Purchase Request'),
- ('so', 'Sale Order'),
('mv', 'Move'),
('fc', 'Forecast'), ('mrp', 'MRP')],
string='Origin')
- mrp_processed = fields.Boolean('Processed')
- mrp_product_id = fields.Many2one('mrp.product', 'Product', index=True)
- mrp_qty = fields.Float('MRP Quantity')
+ mrp_processed = fields.Boolean(string='Processed')
+ mrp_product_id = fields.Many2one(
+ comodel_name='mrp.product',
+ string='Product', index=True,
+ )
+ mrp_qty = fields.Float(string='MRP Quantity')
mrp_type = fields.Selection(
selection=[('s', 'Supply'), ('d', 'Demand')],
string='Type',
)
- name = fields.Char('Description')
+ name = fields.Char(string='Description')
parent_product_id = fields.Many2one(
comodel_name='product.product',
string='Parent Product', index=True,
)
- product_id = fields.Many2one('product.product',
- 'Product', index=True)
- production_id = fields.Many2one('mrp.production',
- 'Manufacturing Order', index=True)
- purchase_line_id = fields.Many2one('purchase.order.line',
- 'Purchase Order Line', index=True)
- purchase_order_id = fields.Many2one('purchase.order',
- 'Purchase Order', index=True)
- running_availability = fields.Float('Running Availability')
- sale_line_id = fields.Many2one('sale.order.line',
- 'Sale Order Line', index=True)
- sale_order_id = fields.Many2one('sale.order', 'Sale Order', index=True)
+ product_id = fields.Many2one(
+ comodel_name='product.product',
+ string='Product', index=True,
+ )
+ production_id = fields.Many2one(
+ comodel_name='mrp.production',
+ string='Manufacturing Order', index=True,
+ )
+ purchase_line_id = fields.Many2one(
+ comodel_name='purchase.order.line',
+ string='Purchase Order Line', index=True,
+ )
+ purchase_order_id = fields.Many2one(
+ comodel_name='purchase.order',
+ string='Purchase Order', index=True,
+ )
+ running_availability = fields.Float(string='Running Availability')
state = fields.Selection(
selection=[('draft', 'Draft'),
('assigned', 'Assigned'),
@@ -92,82 +97,7 @@ class MrpMove(models.Model):
('approved', 'Approved')],
string='State',
)
- stock_move_id = fields.Many2one('stock.move', 'Stock Move', index=True)
-
- @api.model
- def mrp_production_prepare(self, bom_id, routing_id):
- return {
- 'product_uos_qty': 0.00,
- 'product_uom': self.product_id.product_tmpl_id.uom_id.id,
- 'product_qty': self.mrp_qty,
- 'product_id': self.product_id.id,
- 'location_src_id': 12,
- 'date_planned': self.mrp_date,
- 'cycle_total': 0.00,
- 'company_id': 1,
- 'state': 'draft',
- 'hour_total': 0.00,
- 'bom_id': bom_id,
- 'routing_id': routing_id,
- 'allow_reorder': False
- }
-
- @api.model
- def mrp_process_mo(self):
- if self.mrp_action != 'mo':
- return True
- bom_id = False
- routing_id = False
- mrp_boms = self.env['mrp.bom'].search(
- [('product_id', '=', self.product_id.id),
- ('type', '=', 'normal')], limit=1)
- for mrp_bom in mrp_boms:
- bom_id = mrp_bom.id
- routing_id = mrp_bom.routing_id.id
-
- if self.product_id.track_production and self.mrp_qty > 1:
- raise exceptions.Warning(_('Not allowed to create '
- 'manufacturing order with '
- 'quantity higher than 1 '
- 'for serialized product'))
- else:
- production_data = self.mrp_production_prepare(bom_id, routing_id)
- pr = self.env['mrp.production'].create(production_data)
- self.production_id = pr.id
- self.current_qty = self.mrp_qty
- self.current_date = self.mrp_date
- self.mrp_processed = True
- self.name = pr.name
-
- # TODO: extension to purchase requisition in other module?
- @api.model
- def mrp_process_pr(self):
- if self.mrp_action != 'pr':
- return True
- seq = self.env['ir.sequence'].search(
- [('code', '=', 'purchase.order.requisition')])
- seqnbr = self.env['ir.sequence'].next_by_id(seq.id)
- self.env['purchase.requisition'].create({
- 'origin': 'MRP - [' + self.product_id.default_code + '] ' +
- self.product_id.name,
- 'exclusive': 'exclusive',
- 'message_follower_ids': False,
- 'date_end': False,
- 'date_start': self.mrp_date,
- 'company_id': 1,
- 'warehouse_id': 1,
- 'state': 'draft',
- 'line_ids': [[0, False,
- {'product_uom_id':
- self.product_id.product_tmpl_id.uom_id.id,
- 'product_id': self.product_id.id,
- 'product_qty': self.mrp_qty,
- 'name': self.product_id.name}]],
- 'message_ids': False,
- 'description': False,
- 'name': seqnbr
- })
- self.current_qty = self.mrp_qty
- self.current_date = self.mrp_date
- self.mrp_processed = True
- self.name = seqnbr
+ stock_move_id = fields.Many2one(
+ comodel_name='stock.move',
+ string='Stock Move', index=True,
+ )
diff --git a/mrp_multi_level/models/mrp_product.py b/mrp_multi_level/models/mrp_product.py
index 69ffd7d03..4ec561c06 100644
--- a/mrp_multi_level/models/mrp_product.py
+++ b/mrp_multi_level/models/mrp_product.py
@@ -25,7 +25,8 @@ class MrpProduct(models.Model):
compute='_compute_main_supplier', store=True,
)
mrp_inspection_delay = fields.Integer(
- string='Inspection Delay', related='product_id.mrp_inspection_delay')
+ string='Inspection Delay',
+ related='product_id.mrp_inspection_delay')
mrp_lead_time = fields.Float(
string='Lead Time',
related='product_id.produce_delay',
@@ -35,10 +36,12 @@ class MrpProduct(models.Model):
)
# TODO: minimun stock and max/min order qty assigned by area?
mrp_maximum_order_qty = fields.Float(
- string='Maximum Order Qty', related='product_id.mrp_maximum_order_qty',
+ string='Maximum Order Qty',
+ related='product_id.mrp_maximum_order_qty',
)
mrp_minimum_order_qty = fields.Float(
- string='Minimum Order Qty', related='product_id.mrp_minimum_order_qty',
+ string='Minimum Order Qty',
+ related='product_id.mrp_minimum_order_qty',
)
mrp_minimum_stock = fields.Float(
string='Minimum Stock',
@@ -50,14 +53,18 @@ class MrpProduct(models.Model):
)
mrp_nbr_days = fields.Integer(
string='Nbr. Days', related='product_id.mrp_nbr_days')
- mrp_qty_available = fields.Float('MRP Qty Available')
- mrp_qty_multiple = fields.Float(string='Qty Multiple',
- related='product_id.mrp_qty_multiple')
- # TODO: this was: mrp_transit_delay = fields.Integer(mrp_move_ids) ??¿?¿¿?
+ mrp_qty_available = fields.Float(
+ string='MRP Qty Available')
+ mrp_qty_multiple = fields.Float(
+ string='Qty Multiple',
+ related='product_id.mrp_qty_multiple',
+ )
mrp_transit_delay = fields.Integer(related='product_id.mrp_transit_delay')
- mrp_verified = fields.Boolean(string='MRP Verified',
- related='product_id.mrp_verified')
- name = fields.Char('Description')
+ mrp_verified = fields.Boolean(
+ string='MRP Verified',
+ related='product_id.mrp_verified',
+ )
+ name = fields.Char(string='Description')
# TODO: rename to mrp_action_count?
nbr_mrp_actions = fields.Integer(
string='Nbr Actions', index=True,
@@ -69,11 +76,11 @@ class MrpProduct(models.Model):
comodel_name='product.product', string='Product',
index=True,
)
- product_tmpl_id = fields.Many2one('product.template', 'Product Template',
- related='product_id.product_tmpl_id')
- # TODO: extension to purchase requisition in other module?
- # purchase_requisition = fields.Boolean(string='Purchase Requisition',
- # related='product_id.purchase_requisition')
+ product_tmpl_id = fields.Many2one(
+ comodel_name='product.template',
+ string='Product Template',
+ related='product_id.product_tmpl_id',
+ )
supply_method = fields.Selection(
selection=[('buy', 'Buy'),
('none', 'Undefined'),
@@ -90,7 +97,8 @@ class MrpProduct(models.Model):
for rec in self:
values = {
'warehouse_id': rec.mrp_area_id.warehouse_id,
- 'company_id': self.env.user.company_id.id, # TODO: better way to get company
+ 'company_id': self.env.user.company_id.id,
+ # TODO: better way to get company
}
rule = group_obj._get_rule(
rec.product_id, rec.mrp_area_id.location_id, values)
diff --git a/mrp_multi_level/models/product.py b/mrp_multi_level/models/product.py
index 21eb147b6..f0339d26c 100644
--- a/mrp_multi_level/models/product.py
+++ b/mrp_multi_level/models/product.py
@@ -1,6 +1,5 @@
-# © 2016 Ucamco - Wim Audenaert
-# © 2016 Eficent Business and IT Consulting Services S.L.
-# - Jordi Ballester Alomar
+# Copyright 2016 Ucamco - Wim Audenaert
+# Copyright 2016-18 Eficent Business and IT Consulting Services S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
@@ -8,40 +7,44 @@ from odoo import fields, models
class Product(models.Model):
_inherit = 'product.product'
-
- llc = fields.Integer('Low Level Code', default=0)
+
+ llc = fields.Integer(string='Low Level Code', default=0)
manufacturing_order_ids = fields.One2many(
comodel_name='mrp.production',
inverse_name='product_id',
string='Manufacturing Orders',
domain=[('state', '=', 'draft')],
)
- mrp_applicable = fields.Boolean('MRP Applicable')
- mrp_exclude = fields.Boolean('Exclude from MRP')
- mrp_inspection_delay = fields.Integer('Inspection Delay', default=0)
+ # TODO: applicable and exclude... redundant??
+ mrp_applicable = fields.Boolean(string='MRP Applicable')
+ mrp_exclude = fields.Boolean(string='Exclude from MRP')
+ mrp_inspection_delay = fields.Integer(string='Inspection Delay')
mrp_maximum_order_qty = fields.Float(
string='Maximum Order Qty', default=0.0,
)
mrp_minimum_order_qty = fields.Float(
string='Minimum Order Qty', default=0.0,
)
- mrp_minimum_stock = fields.Float('Minimum Stock')
+ mrp_minimum_stock = fields.Float(string='Minimum Stock')
mrp_nbr_days = fields.Integer(
string='Nbr. Days', default=0,
help="Number of days to group demand for this product during the "
"MRP run, in order to determine the quantity to order.",
)
- mrp_product_ids = fields.One2many('mrp.product',
- 'product_id', 'MRP Product data')
- mrp_qty_multiple = fields.Float('Qty Multiple', default=1.00)
- mrp_transit_delay = fields.Integer('Transit Delay', default=0)
- mrp_verified = fields.Boolean('Verified for MRP',
- help="Identifies that this product has "
- "been verified to be valid for the "
- "MRP.")
- purchase_order_line_ids = fields.One2many('purchase.order.line',
- 'product_id', 'Purchase Orders')
- # TODO: extension to purchase requisition in other module?
- # purchase_requisition_ids = fields.One2many('purchase.requisition.line',
- # 'product_id',
- # 'Purchase Requisitions')
+ mrp_product_ids = fields.One2many(
+ comodel_name='mrp.product',
+ inverse_name='product_id',
+ string='MRP Product data',
+ )
+ mrp_qty_multiple = fields.Float(string='Qty Multiple', default=1.00)
+ mrp_transit_delay = fields.Integer(string='Transit Delay', default=0)
+ mrp_verified = fields.Boolean(
+ string='Verified for MRP',
+ help="Identifies that this product has been verified "
+ "to be valid for the MRP.",
+ )
+ purchase_order_line_ids = fields.One2many(
+ comodel_name='purchase.order.line',
+ inverse_name='product_id',
+ string='Purchase Orders',
+ )
diff --git a/mrp_multi_level/models/stock_location.py b/mrp_multi_level/models/stock_location.py
index 3a6957b7f..c9d656256 100644
--- a/mrp_multi_level/models/stock_location.py
+++ b/mrp_multi_level/models/stock_location.py
@@ -8,7 +8,7 @@ from odoo import fields, models
class StockLocation(models.Model):
_inherit = 'stock.location'
-
+
mrp_area_id = fields.Many2one(
comodel_name='mrp.area', string='MRP Area',
help="Requirements for a particular MRP area are combined for the "
diff --git a/mrp_multi_level/tests/test_mrp_multi_level.py b/mrp_multi_level/tests/test_mrp_multi_level.py
index 7603218ce..a8b156bd9 100644
--- a/mrp_multi_level/tests/test_mrp_multi_level.py
+++ b/mrp_multi_level/tests/test_mrp_multi_level.py
@@ -10,7 +10,7 @@ from dateutil.rrule import WEEKLY
class TestMrpMultiLevel(SavepointCase):
-
+
@classmethod
def setUpClass(cls):
super(TestMrpMultiLevel, cls).setUpClass()
@@ -363,4 +363,4 @@ class TestMrpMultiLevel(SavepointCase):
self.assertEqual(mos.date_planned_start, datetime_5)
# TODO: test procure wizard: pos, multiple...
- # TODO: test multiple destination IDS:...
\ No newline at end of file
+ # TODO: test multiple destination IDS:...
diff --git a/mrp_multi_level/views/mrp_area_view.xml b/mrp_multi_level/views/mrp_area_view.xml
index 9bc182e0f..8f7f5dc2a 100644
--- a/mrp_multi_level/views/mrp_area_view.xml
+++ b/mrp_multi_level/views/mrp_area_view.xml
@@ -1,60 +1,46 @@
-
- mrp.area.tree
- mrp.area
- form
-
-
-
-
-
-
-
-
+
+ mrp.area.tree
+ mrp.area
+ tree
+
+
+
+
+
+
+
+
-
- mrp.area.form
- mrp.area
- form
-
-
-
-
+
+ mrp.area.form
+ mrp.area
+ form
+
+
+
+
-
-
- MRP Area
- mrp.area
- ir.actions.act_window
- form
- tree,form
-
-
-
-
-
- form
-
-
-
-
-
- tree
-
-
-
+
+ MRP Area
+ mrp.area
+ ir.actions.act_window
+ form
+ tree,form
+
+
diff --git a/mrp_multi_level/views/mrp_inventory_view.xml b/mrp_multi_level/views/mrp_inventory_view.xml
index 852f55c36..774434f61 100644
--- a/mrp_multi_level/views/mrp_inventory_view.xml
+++ b/mrp_multi_level/views/mrp_inventory_view.xml
@@ -1,54 +1,54 @@
-
- mrp.inventory.form
- mrp.inventory
- form
-
-
-
-
+
+ mrp.inventory.form
+ mrp.inventory
+ form
+
+
+
+
-
- mrp.inventory.tree
- mrp.inventory
- tree
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ mrp.inventory.tree
+ mrp.inventory
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
mrp.inventory.pivot
@@ -57,62 +57,62 @@
-
+
-
+
mrp.inventory.graph
mrp.inventory
-
-
+
+
-
- mrp.inventory.search
- mrp.inventory
- search
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ mrp.inventory.search
+ mrp.inventory
+ search
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- MRP Inventory
- mrp.inventory
- ir.actions.act_window
- form
- tree,form,pivot,graph
-
-
-
+
+ MRP Inventory
+ mrp.inventory
+ ir.actions.act_window
+ form
+ tree,form,pivot,graph
+
+
+
diff --git a/mrp_multi_level/views/mrp_product_view.xml b/mrp_multi_level/views/mrp_product_view.xml
index ade518fa8..9854c446b 100644
--- a/mrp_multi_level/views/mrp_product_view.xml
+++ b/mrp_multi_level/views/mrp_product_view.xml
@@ -1,176 +1,161 @@
-
- mrp.product.tree
- mrp.product
- form
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ mrp.product.tree
+ mrp.product
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- mrp.product.form
- mrp.product
- form
-
-
-
-
+
+ mrp.product.form
+ mrp.product
+ form
+
+
+
+
-
- mrp.filter.form
- mrp.product
- search
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ mrp.filter.form
+ mrp.product
+ search
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- MRP Products
- mrp.product
- ir.actions.act_window
- form
- tree,form
-
-
-
-
-
-
- form
-
-
-
-
-
- tree
-
-
-
+
+ MRP Products
+ mrp.product
+ ir.actions.act_window
+ form
+ tree,form
+
+
+
diff --git a/mrp_multi_level/views/product_view.xml b/mrp_multi_level/views/product_view.xml
index 8375ad8a3..8bb1aed12 100644
--- a/mrp_multi_level/views/product_view.xml
+++ b/mrp_multi_level/views/product_view.xml
@@ -1,32 +1,32 @@
-
- view.mrp.product.product.form
- product.product
-
- form
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ view.mrp.product.product.form
+ product.product
+
+ form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mrp_multi_level/wizards/mrp_inventory_procure.py b/mrp_multi_level/wizards/mrp_inventory_procure.py
index d3e01324c..68b45e253 100644
--- a/mrp_multi_level/wizards/mrp_inventory_procure.py
+++ b/mrp_multi_level/wizards/mrp_inventory_procure.py
@@ -52,7 +52,7 @@ class MrpInventoryProcure(models.TransientModel):
active_model = self.env.context['active_model']
if not mrp_inventory_ids or 'item_ids' not in fields:
return res
-
+
assert active_model == 'mrp.inventory', 'Bad context propagation'
items = item_obj = self.env['mrp.inventory.procure.item']
diff --git a/mrp_multi_level/wizards/mrp_multi_level.py b/mrp_multi_level/wizards/mrp_multi_level.py
index 68c4134da..0619a535d 100644
--- a/mrp_multi_level/wizards/mrp_multi_level.py
+++ b/mrp_multi_level/wizards/mrp_multi_level.py
@@ -51,8 +51,6 @@ class MultiLevelMrp(models.TransientModel):
'production_id': None,
'purchase_order_id': None,
'purchase_line_id': None,
- 'sale_order_id': None,
- 'sale_line_id': None,
'stock_move_id': None,
'mrp_qty': -estimate.daily_qty,
'current_qty': -estimate.daily_qty,
@@ -72,12 +70,11 @@ class MultiLevelMrp(models.TransientModel):
@api.model
def _prepare_mrp_move_data_from_stock_move(
self, mrp_product, move, direction='in'):
- # TODO: Clean up to reduce dependencies
if not((move.location_id.usage == 'internal' and
- move.location_dest_id.usage != 'internal') \
+ move.location_dest_id.usage != 'internal')
or (move.location_id.usage != 'internal' and
- move.location_dest_id.usage == 'internal')):
- # TODO: not sure about this...
+ move.location_dest_id.usage == 'internal')):
+ # TODO: not sure about this 'if'...
return {}
if direction == 'out':
mrp_type = 'd'
@@ -85,7 +82,7 @@ class MultiLevelMrp(models.TransientModel):
else:
mrp_type = 's'
product_qty = move.product_qty
- po = po_line = so = so_line = None
+ po = po_line = None
mo = origin = order_number = parent_product_id = None
if move.purchase_line_id:
order_number = move.purchase_line_id.order_id.name
@@ -125,8 +122,6 @@ class MultiLevelMrp(models.TransientModel):
'production_id': mo,
'purchase_order_id': po,
'purchase_line_id': po_line,
- 'sale_order_id': so,
- 'sale_line_id': so_line,
'stock_move_id': move.id,
'mrp_qty': product_qty,
'current_qty': product_qty,
@@ -154,8 +149,6 @@ class MultiLevelMrp(models.TransientModel):
'production_id': None,
'purchase_order_id': None,
'purchase_line_id': None,
- 'sale_order_id': None,
- 'sale_line_id': None,
'stock_move_id': None,
'mrp_qty': qty,
'current_qty': None,
@@ -187,8 +180,6 @@ class MultiLevelMrp(models.TransientModel):
'production_id': None,
'purchase_order_id': None,
'purchase_line_id': None,
- 'sale_order_id': None,
- 'sale_line_id': None,
'stock_move_id': None,
'mrp_qty': -(qty * bomline.product_qty), # TODO: review with UoM
'current_qty': None,
@@ -261,10 +252,12 @@ class MultiLevelMrp(models.TransientModel):
if bomline.product_qty <= 0.00:
continue
if self._exclude_from_mrp(
- mrp_product_id.mrp_area_id, bomline.product_id):
+ mrp_product_id.mrp_area_id,
+ bomline.product_id):
# Stop explosion.
continue
- mrp_date_demand_2 = mrp_date_demand - timedelta( # TODO: review this...
+ # TODO: review: mrp_transit_delay, mrp_inspection_delay
+ mrp_date_demand_2 = mrp_date_demand - timedelta(
days=(mrp_product_id.mrp_transit_delay +
mrp_product_id.mrp_inspection_delay))
move_data = \
@@ -327,66 +320,26 @@ class MultiLevelMrp(models.TransientModel):
logger.info('END LOW LEVEL CODE CALCULATION')
return mrp_lowest_llc
+ @api.model
+ def _adjust_mrp_applicable(self):
+ """This method is meant to modify the products that are applicable
+ to MRP Multi level calculation
+ """
+ return True
+
@api.model
def _calculate_mrp_applicable(self):
- # TODO: Refactor all code here
+ logger.info('CALCULATE MRP APPLICABLE')
+ self.env['product.product'].search([]).write({'mrp_applicable': False})
self.env['product.product'].search([
('type', '=', 'product'),
]).write({'mrp_applicable': True})
- return True
- logger.info('CALCULATE MRP APPLICABLE')
- sql_stat = '''UPDATE product_product SET mrp_applicable = False;'''
- self.env.cr.execute(sql_stat)
-
- sql_stat = """
- UPDATE product_product
- SET mrp_applicable=True
- FROM product_template
- WHERE product_tmpl_id = product_template.id
- AND product_template.active = True
- AND product_template.type = 'product'
- AND mrp_minimum_stock > (
- SELECT sum(quantity) FROM stock_quant, stock_location
- WHERE stock_quant.product_id = product_product.id
- AND stock_quant.location_id = stock_location.id
- AND stock_location.usage = 'internal');"""
- self.env.cr.execute(sql_stat)
-
- sql_stat = """
- UPDATE product_product
- SET mrp_applicable=True
- FROM product_template
- WHERE product_tmpl_id = product_template.id
- AND product_template.active = True
- AND product_template.type = 'product'
- AND product_product.id in (
- SELECT distinct product_id
- FROM stock_move
- WHERE state <> 'draft' AND state <> 'cancel');"""
- self.env.cr.execute(sql_stat)
-
- sql_stat = """
- UPDATE product_product
- SET mrp_applicable=True
- FROM product_template
- WHERE product_tmpl_id = product_template.id
- AND product_template.active = True
- AND product_template.type = 'product'
- AND llc > 0;"""
- self.env.cr.execute(sql_stat)
-
- # self.env.cr.commit()
- counter = 0
- sql_stat = """
- SELECT count(id) AS counter
- FROM product_product
- WHERE mrp_applicable = True"""
- self.env.cr.execute(sql_stat)
- sql_res = self.env.cr.dictfetchone()
- if sql_res:
- counter = sql_res['counter']
+ self._adjust_mrp_applicable()
+ counter = self.env['product.product'].search([
+ ('mrp_applicable', '=', True)], count=True)
log_msg = 'END CALCULATE MRP APPLICABLE: %s' % counter
logger.info(log_msg)
+ return True
@api.model
def _init_mrp_product(self, product, mrp_area):
@@ -420,7 +373,8 @@ class MultiLevelMrp(models.TransientModel):
mrp_date += delta
return True
- # TODO: move this methods to mrp_product?? to be able to show moves with an action
+ # TODO: move this methods to mrp_product?? to be able to
+ # show moves with an action
@api.model
def _in_stock_moves_domain(self, mrp_product):
locations = self.env['stock.location'].search(
@@ -466,64 +420,6 @@ class MultiLevelMrp(models.TransientModel):
mrp_move_obj.create(move_data)
return True
- # TODO: extension to purchase requisition in other module?
- @api.model
- def _prepare_mrp_move_data_from_purchase_requisition(self, preql,
- mrp_product):
- mrp_date = date.today()
- if preql.requisition_id.schedule_date and \
- datetime.date(datetime.strptime(
- preql.requisition_id.schedule_date,
- '%Y-%m-%d %H:%M:%S')) > date.today():
- mrp_date = datetime.date(datetime.strptime(
- preql.requisition_id.schedule_date,
- '%Y-%m-%d %H:%M:%S'))
- return {
- 'product_id': preql.product_id.id,
- 'mrp_product_id': mrp_product.id,
- 'production_id': None,
- 'purchase_order_id': None,
- 'purchase_line_id': None,
- 'sale_order_id': None,
- 'sale_line_id': None,
- 'stock_move_id': None,
- 'mrp_qty': preql.product_qty,
- 'current_qty': preql.product_qty,
- 'mrp_date': mrp_date,
- 'current_date': preql.requisition_id.schedule_date,
- 'mrp_action': 'none',
- 'mrp_type': 's',
- 'mrp_processed': False,
- 'mrp_origin': 'pr',
- 'mrp_order_number': preql.requisition_id.name,
- 'parent_product_id': None,
- 'running_availability': 0.00,
- 'name': preql.requisition_id.name,
- 'state': preql.requisition_id.state,
- }
-
- # TODO: extension to purchase requisition in other module?
- @api.model
- def _init_mrp_move_from_purchase_requisition(self, mrp_product):
- location_ids = self.env['stock.location'].search(
- [('id', 'child_of', mrp_product.mrp_area_id.location_id.id)])
- picking_types = self.env['stock.picking.type'].search(
- [('default_location_dest_id', 'in', location_ids.ids)])
- picking_type_ids = [ptype.id for ptype in picking_types]
- requisitions = self.env['purchase.requisition'].search(
- [('picking_type_id', 'in', picking_type_ids),
- ('state', '=', 'draft')])
- req_lines = self.env['purchase.requisition.line'].search(
- [('requisition_id', 'in', requisitions.ids),
- ('product_qty', '>', 0.0),
- ('product_id', '=', mrp_product.product_id.id)])
-
- for preql in req_lines:
- mrp_move_data = \
- self._prepare_mrp_move_data_from_purchase_requisition(
- preql, mrp_product)
- self.env['mrp.move'].create(mrp_move_data)
-
@api.model
def _prepare_mrp_move_data_from_purchase_order(self, poline, mrp_product):
mrp_date = date.today()
@@ -535,8 +431,6 @@ class MultiLevelMrp(models.TransientModel):
'production_id': None,
'purchase_order_id': poline.order_id.id,
'purchase_line_id': poline.id,
- 'sale_order_id': None,
- 'sale_line_id': None,
'stock_move_id': None,
'mrp_qty': poline.product_qty,
'current_qty': poline.product_qty,
@@ -575,38 +469,6 @@ class MultiLevelMrp(models.TransientModel):
line, mrp_product)
self.env['mrp.move'].create(mrp_move_data)
- @api.model
- def _prepare_mrp_move_data_from_mrp_production(self, mo, mrp_product):
- mrp_date = date.today()
- if datetime.date(datetime.strptime(
- mo.date_planned, '%Y-%m-%d %H:%M:%S')) > date.today():
- mrp_date = datetime.date(datetime.strptime(
- mo.date_planned, '%Y-%m-%d %H:%M:%S'))
- return {
- 'mrp_area_id': mrp_product.mrp_area_id.id,
- 'product_id': mo.product_id.id,
- 'mrp_product_id': mrp_product.id,
- 'production_id': mo.id,
- 'purchase_order_id': None,
- 'purchase_line_id': None,
- 'sale_order_id': None,
- 'sale_line_id': None,
- 'stock_move_id': None,
- 'mrp_qty': mo.product_qty,
- 'current_qty': mo.product_qty,
- 'mrp_date': mrp_date,
- 'current_date': mo.date_planned,
- 'mrp_action': 'none',
- 'mrp_type': 's',
- 'mrp_processed': False,
- 'mrp_origin': 'mo',
- 'mrp_order_number': mo.name,
- 'parent_product_id': None,
- 'running_availability': 0.00,
- 'name': mo.name,
- 'state': mo.state,
- }
-
@api.model
def _get_mrp_product_from_product_and_area(self, product, mrp_area):
return self.env['mrp.product'].search([
@@ -614,90 +476,11 @@ class MultiLevelMrp(models.TransientModel):
('mrp_area_id', '=', mrp_area.id),
], limit=1)
- @api.model
- def _prepare_mrp_move_data_from_mrp_production_bom(
- self, mo, bomline, mrp_date_demand, mrp_product):
- line_mrp_product = self._get_mrp_product_from_product_and_area(
- bomline.product_id, mrp_product.mrp_area_id)
- return {
- 'mrp_area_id': mrp_product.mrp_area_id.id,
- 'product_id': bomline.product_id.id,
- 'mrp_product_id': line_mrp_product.id,
- 'production_id': mo.id,
- 'purchase_order_id': None,
- 'purchase_line_id': None,
- 'sale_order_id': None,
- 'sale_line_id': None,
- 'stock_move_id': None,
- 'mrp_qty': -(mo.product_qty * bomline.product_qty),
- 'current_qty': None,
- 'mrp_date': mrp_date_demand,
- 'current_date': None,
- 'mrp_action': 'none',
- 'mrp_type': 'd',
- 'mrp_processed': False,
- 'mrp_origin': 'mo',
- 'mrp_order_number': mo.name,
- 'parent_product_id': mo.product_id.id,
- 'name': ('Demand Bom Explosion: ' + mo.name),
- }
-
- @api.model
- def _init_mrp_move_from_mrp_production_bom(self, mo, mrp_product):
- # TODO: iniciate this from moves with MOs and for other moves from bom lines??
- # TODO: fix this...
- # mrp_date = date.today()
- # mrp_date_demand = mrp_date - timedelta(
- # days=mrp_product.product_id.produce_delay)
- # if mrp_date_demand < date.today():
- # mrp_date_demand = date.today()
- mrp_date_demand = date.today()
- if mo.bom_id and mo.bom_id.bom_line_ids:
- for bomline in mo.bom_id.bom_line_ids:
- if bomline.product_qty <= 0.00:
- continue
- # TODO: ['mrp.bom.line'].date_start does not exist in v11. Remove:
- # if (bomline.date_start and datetime.date(
- # datetime.strptime(bomline.date_start, '%Y-%m-%d')) >=
- # mrp_date_demand):
- # continue
- # if (bomline.date_stop and datetime.date(
- # datetime.strptime(bomline.date_stop, '%Y-%m-%d')) <=
- # mrp_date_demand):
- # continue
- # TODO: add conditions to do this: ddmrp, not already existing MOs (MTO)...
- mrp_move_data = \
- self._prepare_mrp_move_data_from_mrp_production_bom(
- mo, bomline, mrp_date_demand, mrp_product)
- self.env['mrp.move'].create(mrp_move_data)
-
- @api.model
- def _init_mrp_move_from_mrp_production(self, mrp_product):
- location_ids = self.env['stock.location'].search(
- [('id', 'child_of', mrp_product.mrp_area_id.location_id.id)])
- # TODO: there is no 'draft' state anymore. there will always be stock.moves
- production_orders = self.env['mrp.production'].search([
- ('product_id', '=', mrp_product.product_id.id),
- ('location_dest_id', 'in', location_ids.ids),
- ('product_qty', '>', 0.0),
- ('state', 'in', ['confirmed', 'planned']),
- ]) # TODO: 'progress' as well?
- for mo in production_orders:
- # mrp_move_data = \
- # self._prepare_mrp_move_data_from_mrp_production(
- # mo, mrp_product)
- # self.env['mrp.move'].create(mrp_move_data)
- self._init_mrp_move_from_mrp_production_bom(mo, mrp_product)
-
@api.model
def _init_mrp_move(self, mrp_product):
self._init_mrp_move_from_forecast(mrp_product)
self._init_mrp_move_from_stock_move(mrp_product)
- # TODO: extension to purchase requisition in other module?
- # self._init_mrp_move_from_purchase_requisition(mrp_product)
self._init_mrp_move_from_purchase_order(mrp_product)
- # TODO: not needed I think... check case when MO are partially done and posted...
- # self._init_mrp_move_from_mrp_production(mrp_product)
@api.model
def _exclude_from_mrp(self, mrp_area, product):
@@ -720,7 +503,6 @@ class MultiLevelMrp(models.TransientModel):
init_counter, product.default_code)
logger.info(log_msg)
mrp_product = self._init_mrp_product(product, mrp_area)
- # for mrp_product in self.env['mrp.product'].search([]):
self._init_mrp_move(mrp_product)
logger.info('END MRP INITIALISATION')
@@ -728,6 +510,7 @@ class MultiLevelMrp(models.TransientModel):
def _init_mrp_move_grouped_demand(self, nbr_create, mrp_product):
last_date = None
last_qty = 0.00
+ onhand = mrp_product.mrp_qty_available
move_ids = []
for move in mrp_product.mrp_move_ids:
move_ids.append(move.id)
@@ -746,9 +529,8 @@ class MultiLevelMrp(models.TransientModel):
< mrp_product.mrp_minimum_stock \
or (onhand + last_qty) \
< mrp_product.mrp_minimum_stock:
- name = 'Grouped Demand for ' \
- '%d Days' % (
- mrp_product.mrp_nbr_days, )
+ name = 'Grouped Demand for %d Days' % \
+ mrp_product.mrp_nbr_days
qtytoorder = \
mrp_product.mrp_minimum_stock - \
mrp_product - last_qty
@@ -764,8 +546,8 @@ class MultiLevelMrp(models.TransientModel):
nbr_create += 1
if (onhand + last_qty + move.mrp_qty) < \
mrp_product.mrp_minimum_stock or \
- (onhand + last_qty) < \
- mrp_product.mrp_minimum_stock:
+ (onhand + last_qty) < \
+ mrp_product.mrp_minimum_stock:
if last_date is None:
last_date = datetime.date(
datetime.strptime(move.mrp_date,
@@ -806,7 +588,7 @@ class MultiLevelMrp(models.TransientModel):
for mrp_product in mrp_products:
nbr_create = 0
- onhand = mrp_product.mrp_qty_available # TODO: qty unreserved?
+ onhand = mrp_product.mrp_qty_available # TODO: unreserved?
if mrp_product.mrp_nbr_days == 0:
# todo: review ordering by date
for move in mrp_product.mrp_move_ids:
diff --git a/mrp_multi_level/wizards/mrp_multi_level_view.xml b/mrp_multi_level/wizards/mrp_multi_level_view.xml
index cb12f94f7..42d1e049b 100644
--- a/mrp_multi_level/wizards/mrp_multi_level_view.xml
+++ b/mrp_multi_level/wizards/mrp_multi_level_view.xml
@@ -1,27 +1,26 @@
-
- Run MRP
- mrp.multi.level
-
-
-
-
-
-
+
+ Run MRP
+ mrp.multi.level
+
+
+
+
+
+
-
+
-