Files
odoo_source/addons/mrp/models/procurement.py
T
Josse Colpaert 2ddc35a530 [REF][NEWPIE] mrp: new MRP
This commit contains the core of the new MRP. It contains a whole refactoring
of the MRP application, with improved and new features, written in new API.
Among other here are the main manufacturing workflow improvements :

 - Picking type not only for pickings but also for manufacturing orders
 - Properties replaced by picking type
 - BoM can only be produced with its routing (no other)
 - Either produce without routing with only production orders, or produce with
   routing
 - By default, there is an order in the work orders (serially), but you can
   override it to be able to work in parallel
 - Time clocking on work orders and block time on work centers with reporting
   on OEE, performance, losses, ...
 - Real-time adaptation of timings on operations
 - Lots/serial numbers can be inputted like in the pickings on manufacturing
   orders.  It is also possible to input them in the work orders.
 - Material availability independent of production order state (possibility to
   start production when only part of it is there)
 - Work sheets on work orders
 - Put messages on work orders to make your workers pay attention to something
 - Full traceability link to see for each produced piece of stock, the
   consumed pieces, ...
 - Separate scrap object (a scrap is not done based on an original move
   anymore)
 - Separate unbuild system (if you want to unbuild into its original
   components)

Thanks to all people that helped during this development, notably but not
limited to Chirag A Dodiya (cod@odoo.com), Gaurav Panchal (gan@odoo.com),
Jignesh Rathod (jir@odoo.com), Mansi Trivedi (mtr@odoo.com), Pariket Trivedi
(ptr@odoo.com).
2016-07-04 16:22:37 +02:00

93 lines
3.8 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, _
class ProcurementRule(models.Model):
_inherit = 'procurement.rule'
@api.model
def _get_action(self):
return [('manufacture', _('Manufacture'))] + super(ProcurementRule, self)._get_action()
class ProcurementOrder(models.Model):
_inherit = 'procurement.order'
bom_id = fields.Many2one('mrp.bom', 'BoM', index=True, ondelete='cascade')
production_id = fields.Many2one('mrp.production', 'Manufacturing Order')
@api.multi
def propagate_cancels(self):
cancel_man_orders = self.filtered(lambda procurement: procurement.rule_id.action == 'manufacture' and procurement.production_id).mapped('production_id')
if cancel_man_orders:
cancel_man_orders.action_cancel()
return super(ProcurementOrder, self).propagate_cancels()
@api.multi
def _run(self):
self.ensure_one()
if self.rule_id.action == 'manufacture':
# make a manufacturing order for the procurement
return self.make_mo()[self.id]
return super(ProcurementOrder, self)._run()
@api.multi
def _check(self):
return self.production_id.state == 'done' or super(ProcurementOrder, self)._check()
@api.multi
def _get_matching_bom(self):
""" Finds the bill of material for the product from procurement order. """
if self.bom_id:
return self.bom_id
return self.env['mrp.bom'].with_context(
company_id=self.company_id.id, force_company=self.company_id.id
)._bom_find(product=self.product_id, picking_type=self.rule_id.picking_type_id) # TDE FIXME: context bullshit
def _get_date_planned(self):
format_date_planned = fields.Datetime.from_string(self.date_planned)
date_planned = format_date_planned - relativedelta(days=self.product_id.produce_delay or 0.0)
date_planned = date_planned - relativedelta(days=self.company_id.manufacturing_lead)
return date_planned
def _prepare_mo_vals(self, bom):
return {
'origin': self.origin,
'product_id': self.product_id.id,
'product_qty': self.product_qty,
'product_uom_id': self.product_uom.id,
'location_src_id': self.rule_id.location_src_id.id or self.location_id.id,
'location_dest_id': self.location_id.id,
'bom_id': bom.id,
'date_planned_start': fields.Datetime.to_string(self._get_date_planned()),
'date_planned_finished': self.date_planned,
'procurement_group_id': self.group_id.id,
'propagate': self.rule_id.propagate,
'picking_type_id': self.rule_id.picking_type_id.id or self.warehouse_id.manu_type_id.id,
'company_id': self.company_id.id,
'procurement_ids': [(6, 0, [self.id])],
}
@api.multi
def make_mo(self):
""" Create production orders from procurements """
res = {}
Production = self.env['mrp.production']
for procurement in self:
ProductionSudo = Production.sudo().with_context(force_company=procurement.company_id.id)
bom = procurement._get_matching_bom()
if bom:
# create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example)
production = ProductionSudo.create(procurement._prepare_mo_vals(bom))
res[procurement.id] = production.id
procurement.message_post(body=_("Manufacturing Order <em>%s</em> created.") % (production.name))
else:
res[procurement.id] = False
procurement.message_post(body=_("No BoM exists for this product!"))
return res