From 0da768c11454bdfe7285f4dd91cc8cc19e8391fb Mon Sep 17 00:00:00 2001 From: Fatemi Lokhandwala Date: Mon, 9 Jul 2018 18:07:58 +0530 Subject: [PATCH] [ADD]:Added Upstream Patch for mrp --- addons/mrp/models/mrp_bom.py | 2 + addons/mrp/models/mrp_production.py | 12 +++- addons/mrp/models/mrp_workorder.py | 70 ++++++++++++------- addons/mrp/models/stock_move.py | 7 ++ addons/mrp/models/stock_warehouse.py | 10 +-- .../report/mrp_bom_cost_report_templates.xml | 2 +- addons/mrp/report/mrp_bom_structure_report.py | 55 +++++++++------ addons/mrp/views/mrp_production_views.xml | 2 +- addons/mrp/views/mrp_routing_views.xml | 2 +- addons/mrp/views/mrp_workorder_views.xml | 8 ++- addons/mrp/views/stock_move_views.xml | 4 +- addons/mrp/wizard/change_production_qty.py | 3 +- addons/mrp/wizard/mrp_product_produce.py | 7 +- 13 files changed, 120 insertions(+), 64 deletions(-) diff --git a/addons/mrp/models/mrp_bom.py b/addons/mrp/models/mrp_bom.py index 386fb145..168e3471 100644 --- a/addons/mrp/models/mrp_bom.py +++ b/addons/mrp/models/mrp_bom.py @@ -80,6 +80,8 @@ class MrpBom(models.Model): def onchange_product_tmpl_id(self): if self.product_tmpl_id: self.product_uom_id = self.product_tmpl_id.uom_id.id + if self.product_id.product_tmpl_id != self.product_tmpl_id: + self.product_id = False @api.onchange('routing_id') def onchange_routing_id(self): diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index f69b80e4..0ae21971 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -389,7 +389,7 @@ class MrpProduction(models.Model): source_location = routing.location_id else: source_location = self.location_src_id - original_quantity = self.product_qty - self.qty_produced + original_quantity = (self.product_qty - self.qty_produced) or 1.0 data = { 'sequence': bom_line.sequence, 'name': self.name, @@ -474,10 +474,16 @@ class MrpProduction(models.Model): @api.multi def _generate_workorders(self, exploded_boms): workorders = self.env['mrp.workorder'] + original_one = False for bom, bom_data in exploded_boms: # If the routing of the parent BoM and phantom BoM are the same, don't recreate work orders, but use one master routing if bom.routing_id.id and (not bom_data['parent_line'] or bom_data['parent_line'].bom_id.routing_id.id != bom.routing_id.id): - workorders += self._workorders_create(bom, bom_data) + temp_workorders = self._workorders_create(bom, bom_data) + workorders += temp_workorders + if temp_workorders: # In order to avoid two "ending work orders" + if original_one: + temp_workorders[-1].next_work_order_id = original_one + original_one = temp_workorders[0] return workorders def _workorders_create(self, bom, bom_data): @@ -558,7 +564,7 @@ class MrpProduction(models.Model): order._cal_price(moves_to_do) moves_to_finish = order.move_finished_ids.filtered(lambda x: x.state not in ('done','cancel')) moves_to_finish._action_done() - #order.action_assign() + order.action_assign() consume_move_lines = moves_to_do.mapped('active_move_line_ids') for moveline in moves_to_finish.mapped('active_move_line_ids'): if moveline.product_id == order.product_id and moveline.move_id.has_tracking != 'none': diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py index ad5c1045..d95bc072 100644 --- a/addons/mrp/models/mrp_workorder.py +++ b/addons/mrp/models/mrp_workorder.py @@ -219,6 +219,7 @@ class MrpWorkorder(models.Model): 'done_wo': False, 'location_id': move.location_id.id, 'location_dest_id': move.location_dest_id.id, + 'date': move.date, }) qty_todo -= 1 elif float_compare(qty_todo, 0.0, precision_rounding=rounding) < 0: @@ -284,6 +285,18 @@ class MrpWorkorder(models.Model): self.final_lot_id = self.env['stock.production.lot'].search([('use_next_on_work_order_id', '=', self.id)], order='create_date, id', limit=1) + def _get_byproduct_move_line(self, by_product_move, quantity): + return { + 'move_id': by_product_move.id, + 'product_id': by_product_move.product_id.id, + 'product_uom_qty': quantity, + 'product_uom_id': by_product_move.product_uom.id, + 'qty_done': quantity, + 'workorder_id': self.id, + 'location_id': by_product_move.location_id.id, + 'location_dest_id': by_product_move.location_dest_id.id, + } + @api.multi def record_production(self): self.ensure_one() @@ -339,33 +352,37 @@ class MrpWorkorder(models.Model): # If last work order, then post lots used # TODO: should be same as checking if for every workorder something has been done? if not self.next_work_order_id: - production_moves = self.production_id.move_finished_ids.filtered(lambda x: (x.state not in ('done', 'cancel'))) - for production_move in production_moves: - if production_move.product_id.id == self.production_id.product_id.id and production_move.has_tracking != 'none': - move_line = production_move.move_line_ids.filtered(lambda x: x.lot_id.id == self.final_lot_id.id) - if move_line: - move_line.product_uom_qty += self.qty_producing - else: - move_line.create({'move_id': production_move.id, - 'product_id': production_move.product_id.id, - 'lot_id': self.final_lot_id.id, - 'product_uom_qty': self.qty_producing, - 'product_uom_id': production_move.product_uom.id, - 'qty_done': self.qty_producing, - 'workorder_id': self.id, - 'location_id': production_move.location_id.id, - 'location_dest_id': production_move.location_dest_id.id, - }) - elif production_move.unit_factor: - rounding = production_move.product_uom.rounding - production_move.quantity_done += float_round(self.qty_producing * production_move.unit_factor, precision_rounding=rounding) + production_move = self.production_id.move_finished_ids.filtered( + lambda x: (x.product_id.id == self.production_id.product_id.id) and (x.state not in ('done', 'cancel'))) + if production_move.product_id.tracking != 'none': + move_line = production_move.move_line_ids.filtered(lambda x: x.lot_id.id == self.final_lot_id.id) + if move_line: + move_line.product_uom_qty += self.qty_producing + move_line.qty_done += self.qty_producing else: - production_move.quantity_done += self.qty_producing + move_line.create({'move_id': production_move.id, + 'product_id': production_move.product_id.id, + 'lot_id': self.final_lot_id.id, + 'product_uom_qty': self.qty_producing, + 'product_uom_id': production_move.product_uom.id, + 'qty_done': self.qty_producing, + 'workorder_id': self.id, + 'location_id': production_move.location_id.id, + 'location_dest_id': production_move.location_dest_id.id, + }) + else: + production_move.quantity_done += self.qty_producing if not self.next_work_order_id: for by_product_move in self.production_id.move_finished_ids.filtered(lambda x: (x.product_id.id != self.production_id.product_id.id) and (x.state not in ('done', 'cancel'))): - if by_product_move.has_tracking == 'none': - by_product_move.quantity_done += self.qty_producing * by_product_move.unit_factor + if by_product_move.has_tracking != 'serial': + values = self._get_byproduct_move_line(by_product_move, self.qty_producing * by_product_move.unit_factor) + self.env['stock.move.line'].create(values) + elif by_product_move.has_tracking == 'serial': + qty_todo = by_product_move.product_uom._compute_quantity(self.qty_producing * by_product_move.unit_factor, by_product_move.product_id.uom_id) + for i in range(0, int(float_round(qty_todo, precision_digits=0))): + values = self._get_byproduct_move_line(by_product_move, 1) + self.env['stock.move.line'].create(values) # Update workorder quantity produced self.qty_produced += self.qty_producing @@ -395,7 +412,12 @@ class MrpWorkorder(models.Model): @api.multi def button_start(self): - # TDE CLEANME + self.ensure_one() + # As button_start is automatically called in the new view + if self.state in ('done', 'cancel'): + return True + + # Need a loss in case of the real time exceeding the expected timeline = self.env['mrp.workcenter.productivity'] if self.duration < self.duration_expected: loss_id = self.env['mrp.workcenter.productivity.loss'].search([('loss_type','=','productive')], limit=1) diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py index 00d4f048..28b8bee7 100644 --- a/addons/mrp/models/stock_move.py +++ b/addons/mrp/models/stock_move.py @@ -73,6 +73,13 @@ class StockMove(models.Model): order_finished_lot_ids = fields.Many2many('stock.production.lot', compute='_compute_order_finished_lot_ids') finished_lots_exist = fields.Boolean('Finished Lots Exist', compute='_compute_order_finished_lot_ids') + def _unreserve_initial_demand(self, new_move): + # If you were already putting stock.move.lots on the next one in the work order, transfer those to the new move + self.filtered(lambda m: m.production_id or m.raw_material_production_id)\ + .mapped('move_line_ids')\ + .filtered(lambda ml: ml.qty_done == 0.0)\ + .write({'move_id': new_move, 'product_uom_qty': 0}) + @api.depends('active_move_line_ids.qty_done', 'active_move_line_ids.product_uom_id') def _compute_done_quantity(self): super(StockMove, self)._compute_done_quantity() diff --git a/addons/mrp/models/stock_warehouse.py b/addons/mrp/models/stock_warehouse.py index 8cd714f4..e71b73b4 100644 --- a/addons/mrp/models/stock_warehouse.py +++ b/addons/mrp/models/stock_warehouse.py @@ -29,12 +29,12 @@ class StockWarehouse(models.Model): return result def _get_manufacture_route_id(self): - manufacture_route_id = self.env.ref('mrp.route_warehouse0_manufacture').id - if not manufacture_route_id: - manufacture_route_id = self.env['stock.location.route'].search([('name', 'like', _('Manufacture'))], limit=1).id - if not manufacture_route_id: + manufacture_route = self.env.ref('mrp.route_warehouse0_manufacture', raise_if_not_found=False) + if not manufacture_route: + manufacture_route = self.env['stock.location.route'].search([('name', 'like', _('Manufacture'))], limit=1) + if not manufacture_route: raise exceptions.UserError(_('Can\'t find any generic Manufacture route.')) - return manufacture_route_id + return manufacture_route.id def _get_manufacture_pull_rules_values(self, route_values): if not self.manu_type_id: diff --git a/addons/mrp/report/mrp_bom_cost_report_templates.xml b/addons/mrp/report/mrp_bom_cost_report_templates.xml index a0936d96..c1402b6f 100644 --- a/addons/mrp/report/mrp_bom_cost_report_templates.xml +++ b/addons/mrp/report/mrp_bom_cost_report_templates.xml @@ -36,7 +36,7 @@ - + diff --git a/addons/mrp/report/mrp_bom_structure_report.py b/addons/mrp/report/mrp_bom_structure_report.py index 37e3b33e..534d2d24 100644 --- a/addons/mrp/report/mrp_bom_structure_report.py +++ b/addons/mrp/report/mrp_bom_structure_report.py @@ -7,36 +7,49 @@ from flectra import api, models class BomStructureReport(models.AbstractModel): _name = 'report.mrp.mrp_bom_structure_report' - def get_children(self, object, level=0): + @api.model + def _get_child_vals(self, record, level, qty, uom): + """Get bom.line values. + + :param record: mrp.bom.line record + :param level: level of recursion + :param qty: quantity of the product + :param uom: unit of measurement of a product + """ + child = { + 'pname': record.product_id.name_get()[0][1], + 'pcode': record.product_id.default_code, + 'puom': record.product_uom_id, + 'uname': record.product_uom_id.name, + 'level': level, + 'code': record.bom_id.code, + } + qty_per_bom = record.bom_id.product_qty + if uom: + if uom != record.bom_id.product_uom_id: + qty = uom._compute_quantity(qty, record.bom_id.product_uom_id) + child['pqty'] = (record.product_qty * qty) / qty_per_bom + else: + # for the first case, the ponderation is right + child['pqty'] = (record.product_qty * qty) + return child + + def get_children(self, records, level=0): result = [] - def _get_rec(object, level, qty=1.0, uom=False): - for l in object: - res = {} - res['pname'] = l.product_id.name_get()[0][1] - res['pcode'] = l.product_id.default_code - qty_per_bom = l.bom_id.product_qty - if uom: - if uom != l.bom_id.product_uom_id: - qty = uom._compute_quantity(qty, l.bom_id.product_uom_id) - res['pqty'] = (l.product_qty *qty)/ qty_per_bom - else: - #for the first case, the ponderation is right - res['pqty'] = (l.product_qty *qty) - res['puom'] = l.product_uom_id - res['uname'] = l.product_uom_id.name - res['level'] = level - res['code'] = l.bom_id.code - result.append(res) + def _get_rec(records, level, qty=1.0, uom=False): + for l in records: + child = self._get_child_vals(l, level, qty, uom) + result.append(child) if l.child_line_ids: if level < 6: level += 1 - _get_rec(l.child_line_ids, level, qty=res['pqty'], uom=res['puom']) + _get_rec(l.child_line_ids, level, qty=child['pqty'], uom=child['puom']) if level > 0 and level < 6: level -= 1 return result - children = _get_rec(object, level) + children = _get_rec(records, level) return children diff --git a/addons/mrp/views/mrp_production_views.xml b/addons/mrp/views/mrp_production_views.xml index b5e2292e..b4e38222 100644 --- a/addons/mrp/views/mrp_production_views.xml +++ b/addons/mrp/views/mrp_production_views.xml @@ -126,7 +126,7 @@ - + diff --git a/addons/mrp/views/mrp_routing_views.xml b/addons/mrp/views/mrp_routing_views.xml index 31e67897..59d2af62 100644 --- a/addons/mrp/views/mrp_routing_views.xml +++ b/addons/mrp/views/mrp_routing_views.xml @@ -177,4 +177,4 @@ groups="group_mrp_routings" sequence="50"/> - + \ No newline at end of file diff --git a/addons/mrp/views/mrp_workorder_views.xml b/addons/mrp/views/mrp_workorder_views.xml index c40060ad..8b1c48fa 100644 --- a/addons/mrp/views/mrp_workorder_views.xml +++ b/addons/mrp/views/mrp_workorder_views.xml @@ -190,18 +190,19 @@