diff options
| author | William Henrotin <whe@odoo.com> | 2020-04-27 11:56:02 +0200 |
|---|---|---|
| committer | Simon Lejeune <sle@openerp.com> | 2020-06-15 16:59:41 +0200 |
| commit | 0e2765f5fd0ca0079f1f024ec3a1448b6d2ea3db (patch) | |
| tree | 90ea03d1aca1bf87a080775e7db07977b645c5cc /addons/mrp_subcontracting | |
| parent | 1b6421285c6bc4c61be3242cea30c2813251cbc7 (diff) | |
[REF] mrp: no more produce wizard
Use a view similar as the pickings one.
task-2241471
Diffstat (limited to 'addons/mrp_subcontracting')
| -rw-r--r-- | addons/mrp_subcontracting/models/stock_move.py | 25 | ||||
| -rw-r--r-- | addons/mrp_subcontracting/models/stock_picking.py | 34 | ||||
| -rw-r--r-- | addons/mrp_subcontracting/tests/test_subcontracting.py | 97 | ||||
| -rw-r--r-- | addons/mrp_subcontracting/views/stock_move_views.xml | 31 | ||||
| -rw-r--r-- | addons/mrp_subcontracting/wizard/mrp_product_produce.py | 80 |
5 files changed, 127 insertions, 140 deletions
diff --git a/addons/mrp_subcontracting/models/stock_move.py b/addons/mrp_subcontracting/models/stock_move.py index 72f50c9374e..e33f5377c0b 100644 --- a/addons/mrp_subcontracting/models/stock_move.py +++ b/addons/mrp_subcontracting/models/stock_move.py @@ -126,12 +126,21 @@ class StockMove(models.Model): return res def _action_record_components(self): - action = self.env.ref('mrp.act_mrp_product_produce').read()[0] - action['context'] = dict( - default_production_id=self.move_orig_ids.production_id.id, - default_subcontract_move_id=self.id - ) - return action + self.ensure_one() + production = self.move_orig_ids.production_id + view = self.env.ref('mrp.mrp_production_form_view') + return { + 'name': _('Subcontract'), + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_model': 'mrp.production', + 'views': [(view.id, 'form')], + 'view_id': view.id, + 'target': 'new', + 'res_id': production.id, + 'context': dict(self.env.context, subcontract_move_id=self.id), + } + def _check_overprocessed_subcontract_qty(self): """ If a subcontracted move use tracked components. Do not allow to add @@ -147,8 +156,8 @@ class StockMove(models.Model): if not move._has_tracked_subcontract_components(): continue rounding = move.product_uom.rounding - if float_compare(move.quantity_done, move.move_orig_ids.production_id.qty_produced, precision_rounding=rounding) > 0: - overprocessed_moves |= move +# if float_compare(move.quantity_done, move.move_orig_ids.production_id.qty_produced, precision_rounding=rounding) > 0: +# overprocessed_moves |= move if overprocessed_moves: raise UserError(_(""" You have to use 'Records Components' button in order to register quantity for a diff --git a/addons/mrp_subcontracting/models/stock_picking.py b/addons/mrp_subcontracting/models/stock_picking.py index 29c44aec51b..0ab1655a6dc 100644 --- a/addons/mrp_subcontracting/models/stock_picking.py +++ b/addons/mrp_subcontracting/models/stock_picking.py @@ -4,6 +4,7 @@ from datetime import timedelta from odoo import api, fields, models +from odoo.tools import float_is_zero class StockPicking(models.Model): @@ -43,7 +44,9 @@ class StockPicking(models.Model): for move in picking.move_lines: if not move.is_subcontract: continue - production = move.move_orig_ids.production_id + production = move.move_orig_ids.production_id.filtered(lambda p: p.state not in ('done', 'cancel')) + if len(production) > 1: + production = production[-1] if move._has_tracked_subcontract_components(): move.move_orig_ids.filtered(lambda m: m.state not in ('done', 'cancel')).move_line_ids.unlink() move_finished_ids = move.move_orig_ids.filtered(lambda m: m.state not in ('done', 'cancel')) @@ -58,16 +61,25 @@ class StockPicking(models.Model): 'location_dest_id': move_finished_ids.location_dest_id.id, }) else: - for move_line in move.move_line_ids: - produce = self.env['mrp.product.produce'].with_context(default_production_id=production.id).create({ - 'production_id': production.id, - 'qty_producing': move_line.qty_done, - 'product_uom_id': move_line.product_uom_id.id, - 'finished_lot_id': move_line.lot_id.id, - 'consumption': 'strict', - }) - produce._generate_produce_lines() - produce._record_production() + if not move.move_line_ids.lot_id: + qty_done_production_uom = move.product_uom._compute_quantity(move.quantity_done, production.product_uom_id) + production.qty_producing += qty_done_production_uom + for move in (production.move_raw_ids | production.move_finished_ids.filtered(lambda m: m.product_id != production.product_id)): + if move.state in ('done', 'cancel'): + continue + if float_is_zero(move.product_uom_qty, precision_rounding=move.product_uom.rounding): + continue + new_qty = production.product_uom_id._compute_quantity( + (production.qty_producing - production.qty_produced) * move.unit_factor, production.product_uom_id, + rounding_method='HALF-UP') + move.move_line_ids.filtered(lambda ml: ml.state not in ('done', 'cancel')).qty_done = 0 + vals = move._set_quantity_done_prepare_vals(new_qty) + if vals['to_create']: + for res in vals['to_create']: + move.move_line_ids.create(res) + if vals['to_write']: + for move_line, res in vals['to_write']: + move_line.write(res) productions |= production for subcontracted_production in productions: if subcontracted_production.state == 'progress': diff --git a/addons/mrp_subcontracting/tests/test_subcontracting.py b/addons/mrp_subcontracting/tests/test_subcontracting.py index 281e32c96ea..c282950ee97 100644 --- a/addons/mrp_subcontracting/tests/test_subcontracting.py +++ b/addons/mrp_subcontracting/tests/test_subcontracting.py @@ -415,7 +415,7 @@ class TestSubcontractingFlows(TestMrpSubcontractingCommon): picking_form.partner_id = self.subcontractor_partner1 with picking_form.move_ids_without_package.new() as move: move.product_id = self.finished - move.product_uom_qty = 5 + move.product_uom_qty = 3 # FIXME sle: need to handle the backorder in subcontract picking_receipt = picking_form.save() picking_receipt.action_confirm() mo = picking_receipt.move_lines.move_orig_ids.production_id @@ -442,39 +442,26 @@ class TestSubcontractingFlows(TestMrpSubcontractingCommon): 'product_id': self.finished.id, 'company_id': self.env.company.id, }) + mo_form = Form(picking_receipt._get_subcontracted_productions().with_context(subcontract_move_id=picking_receipt.move_lines.id)) + mo_form.qty_producing = 3 + mo_form.lot_producing_id = lot_f1 + mo = mo_form.save() + details_operation_form = Form(mo.move_raw_ids[0], view=self.env.ref('stock.view_stock_move_operations')) + with details_operation_form.move_line_ids.new() as ml: + ml.lot_id = lot_c1 + ml.qty_done = 3 + details_operation_form.save() + details_operation_form = Form(mo.move_raw_ids[1], view=self.env.ref('stock.view_stock_move_operations')) + with details_operation_form.move_line_ids.new() as ml: + ml.lot_id = lot_c2 + ml.qty_done = 3 + details_operation_form.save() - register_form = Form(self.env['mrp.product.produce'].with_context( - active_id=picking_receipt._get_subcontracted_productions().id, - default_subcontract_move_id=picking_receipt.move_lines.id - )) - register_form.qty_producing = 3.0 - self.assertEqual(len(register_form._values['raw_workorder_line_ids']), 2, - 'Register Components Form should contains one line per component.') - self.assertTrue(all(p[2]['product_id'] in (self.comp1 | self.comp2).ids for p in register_form._values['raw_workorder_line_ids']), - 'Register Components Form should contains component.') - with register_form.raw_workorder_line_ids.edit(0) as pl: - pl.lot_id = lot_c1 - with register_form.raw_workorder_line_ids.edit(1) as pl: - pl.lot_id = lot_c2 - register_form.finished_lot_id = lot_f1 - register_wizard = register_form.save() - action = register_wizard.continue_production() - register_form = Form(self.env['mrp.product.produce'].with_context( - **action['context'] - )) - with register_form.raw_workorder_line_ids.edit(0) as pl: - pl.lot_id = lot_c1 - with register_form.raw_workorder_line_ids.edit(1) as pl: - pl.lot_id = lot_c2 - register_form.finished_lot_id = lot_f1 - register_wizard = register_form.save() - register_wizard.do_produce() - - self.assertEqual(move_comp1.quantity_done, 5.0) + self.assertEqual(move_comp1.quantity_done, 3) self.assertEqual(move_comp1.move_line_ids.filtered(lambda ml: not ml.product_uom_qty).lot_id.name, 'LOT C1') - self.assertEqual(move_comp2.quantity_done, 5.0) + self.assertEqual(move_comp2.quantity_done, 3) self.assertEqual(move_comp2.move_line_ids.filtered(lambda ml: not ml.product_uom_qty).lot_id.name, 'LOT C2') - self.assertEqual(move_finished.quantity_done, 5.0) + self.assertEqual(move_finished.quantity_done, 3) self.assertEqual(move_finished.move_line_ids.filtered(lambda ml: ml.product_uom_qty).lot_id.name, 'LOT F1') corrected_final_lot = self.env['stock.production.lot'].create({ @@ -484,31 +471,17 @@ class TestSubcontractingFlows(TestMrpSubcontractingCommon): }) details_operation_form = Form(picking_receipt.move_lines, view=self.env.ref('stock.view_stock_move_operations')) - for i in range(len(details_operation_form._values['move_line_ids'])): - with details_operation_form.move_line_ids.edit(i) as ml: - if ml._values['qty_done']: - ml.lot_id = corrected_final_lot + with details_operation_form.move_line_ids.edit(0) as ml: + ml.lot_id = corrected_final_lot details_operation_form.save() move_raw_comp_1 = picking_receipt.move_lines.move_orig_ids.production_id.move_raw_ids.filtered(lambda m: m.product_id == self.comp1) move_raw_comp_2 = picking_receipt.move_lines.move_orig_ids.production_id.move_raw_ids.filtered(lambda m: m.product_id == self.comp2) - details_subcontract_moves_form = Form(move_raw_comp_1, view=self.env.ref('mrp_subcontracting.mrp_subcontracting_move_form_view')) - for i in range(len(details_subcontract_moves_form._values['move_line_ids'])): - with details_subcontract_moves_form.move_line_ids.edit(i) as sc: - if sc._values['qty_done']: - sc.lot_produced_ids.remove(index=0) - sc.lot_produced_ids.add(corrected_final_lot) - details_subcontract_moves_form.save() - details_subcontract_moves_form = Form(move_raw_comp_2, view=self.env.ref('mrp_subcontracting.mrp_subcontracting_move_form_view')) - for i in range(len(details_subcontract_moves_form._values['move_line_ids'])): - with details_subcontract_moves_form.move_line_ids.edit(i) as sc: - if sc._values['qty_done']: - sc.lot_produced_ids.remove(index=0) - sc.lot_produced_ids.add(corrected_final_lot) - details_subcontract_moves_form.save() - - self.assertEqual(move_comp1.move_line_ids.filtered(lambda ml: not ml.product_uom_qty).lot_produced_ids.name, 'LOT F2') - self.assertEqual(move_comp2.move_line_ids.filtered(lambda ml: not ml.product_uom_qty).lot_produced_ids.name, 'LOT F2') + picking_receipt.move_lines.move_orig_ids.production_id.lot_producing_id = corrected_final_lot + picking_receipt.move_lines.move_orig_ids.production_id.button_mark_done() + + self.assertEqual(move_comp1.move_line_ids.filtered(lambda ml: not ml.product_uom_qty).produce_line_ids.lot_id.name, 'LOT F2') + self.assertEqual(move_comp2.move_line_ids.filtered(lambda ml: not ml.product_uom_qty).produce_line_ids.lot_id.name, 'LOT F2') def test_flow_8(self): resupply_sub_on_order_route = self.env['stock.location.route'].search([('name', '=', 'Resupply Subcontractor on Order')]) @@ -693,20 +666,20 @@ class TestSubcontractingTracking(TransactionCase): 'product_id': self.comp1_sn.id, 'company_id': self.env.company.id, }) - produce_form = Form(self.env['mrp.product.produce'].with_context({ - 'active_id': mo.id, - 'active_ids': [mo.id], - })) - produce_form.finished_lot_id = lot_id - produce_form.raw_workorder_line_ids._records[0]['lot_id'] = serial_id.id - wiz_produce = produce_form.save() - wiz_produce.do_produce() + + mo_form = Form(mo.with_context(subcontract_move_id=picking_receipt.move_lines.id)) + mo_form.qty_producing = 1 + mo_form.lot_producing_id = lot_id + mo = mo_form.save() + details_operation_form = Form(mo.move_raw_ids[0], view=self.env.ref('stock.view_stock_move_operations')) + with details_operation_form.move_line_ids.new() as ml: + ml.qty_done = 1 + ml.lot_id = serial_id + details_operation_form.save() # We should not be able to call the 'record_components' button self.assertFalse(picking_receipt.display_action_record_components) - picking_receipt.move_lines.quantity_done = 1 - picking_receipt.move_lines.move_line_ids.lot_id = lot_id.id picking_receipt.button_validate() self.assertEqual(mo.state, 'done') diff --git a/addons/mrp_subcontracting/views/stock_move_views.xml b/addons/mrp_subcontracting/views/stock_move_views.xml index 63ccc1c0a62..58159cc81c9 100644 --- a/addons/mrp_subcontracting/views/stock_move_views.xml +++ b/addons/mrp_subcontracting/views/stock_move_views.xml @@ -17,11 +17,6 @@ <field name="state" invisible="1"/> <field name="tracking" invisible="1"/> <field name="product_id" readonly="1"/> - <field name="lot_produced_ids" - widget="many2many_tags" - context="{'default_product_id': parent.product_id}" - attrs="{'column_invisible': [('parent.finished_lots_exist', '!=', True)]}" - /> <field name="qty_done"/> <field name="lot_id" context="{'default_product_id': product_id}"/> </tree> @@ -30,17 +25,17 @@ </form> </field> </record> - <record id="mrp_subcontracting_move_tree_view" model="ir.ui.view"> - <field name="name">mrp.subcontracting.move.tree.view</field> - <field name="model">stock.move</field> - <field name="priority">1000</field> - <field name="mode">primary</field> - <field name="inherit_id" ref="mrp.view_stock_move_raw_tree"/> - <field name="arch" type="xml"> - <xpath expr="//tree" position="attributes"> - <attribute name="create">0</attribute> - <attribute name="delete">0</attribute> - </xpath> - </field> - </record> + <!-- <record id="mrp_subcontracting_move_tree_view" model="ir.ui.view"> --> + <!-- <field name="name">mrp.subcontracting.move.tree.view</field> --> + <!-- <field name="model">stock.move</field> --> + <!-- <field name="priority">1000</field> --> + <!-- <field name="mode">primary</field> --> + <!-- <field name="inherit_id" ref="mrp.view_stock_move_raw_tree"/> --> + <!-- <field name="arch" type="xml"> --> + <!-- <xpath expr="//tree" position="attributes"> --> + <!-- <attribute name="create">0</attribute> --> + <!-- <attribute name="delete">0</attribute> --> + <!-- </xpath> --> + <!-- </field> --> + <!-- </record> --> </odoo> diff --git a/addons/mrp_subcontracting/wizard/mrp_product_produce.py b/addons/mrp_subcontracting/wizard/mrp_product_produce.py index ceb803858e0..0dd804ad9f4 100644 --- a/addons/mrp_subcontracting/wizard/mrp_product_produce.py +++ b/addons/mrp_subcontracting/wizard/mrp_product_produce.py @@ -2,42 +2,36 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import fields, models -from odoo.tools.float_utils import float_is_zero, float_compare +from odoo.tools.float_utils import float_compare, float_is_zero -class MrpProductProduce(models.TransientModel): - _inherit = 'mrp.product.produce' - subcontract_move_id = fields.Many2one('stock.move', 'stock move from the subcontract picking', check_company=True) +class MrpProduction(models.Model): + _inherit = 'mrp.production' - def continue_production(self): - action = super(MrpProductProduce, self).continue_production() - action['context'] = dict(action['context'], default_subcontract_move_id=self.subcontract_move_id.id) - return action + def write(self, vals): + res = super().write(vals) + if self.env.context.get('subcontract_move_id'): + for production in self: + if production.state not in ('cancel', 'done') and \ + ('lot_producing_id' in vals or 'qty_producing' in vals): + production._update_finished_move() - def _generate_produce_lines(self): - """ When the wizard is called in backend, the onchange that create the - produce lines is not trigger. This method generate them and is used with - _record_production to appropriately set the lot_produced_id and - appropriately create raw stock move lines. - """ - self.ensure_one() - moves = (self.move_raw_ids | self.move_finished_ids).filtered( - lambda move: move.state not in ('done', 'cancel') - ) - for move in moves: - qty_to_consume = self._prepare_component_quantity(move, self.qty_producing) - line_values = self._generate_lines_values(move, qty_to_consume) - self.env['mrp.product.produce.line'].create(line_values) + def _pre_button_mark_done(self): + if self.env.context.get('subcontract_move_id'): + return True + return super()._pre_button_mark_done() def _update_finished_move(self): """ After producing, set the move line on the subcontract picking. """ - res = super(MrpProductProduce, self)._update_finished_move() - if self.subcontract_move_id: + subcontract_move_id = self.env.context.get('subcontract_move_id') + res = None + if subcontract_move_id: + subcontract_move_id = self.env['stock.move'].browse(subcontract_move_id) quantity = self.qty_producing - if self.finished_lot_id: - move_lines = self.subcontract_move_id.move_line_ids.filtered(lambda ml: ml.lot_id == self.finished_lot_id or not ml.lot_id) + if self.lot_producing_id: + move_lines = subcontract_move_id.move_line_ids.filtered(lambda ml: ml.lot_id == self.lot_producing_id or not ml.lot_id) else: - move_lines = self.subcontract_move_id.move_line_ids.filtered(lambda ml: not ml.lot_id) + move_lines = subcontract_move_id.move_line_ids.filtered(lambda ml: not ml.lot_id) # Update reservation and quantity done for ml in move_lines: rounding = ml.product_uom_id.rounding @@ -52,16 +46,14 @@ class MrpProductProduce(models.TransientModel): if float_compare(new_quantity_done, ml.product_uom_qty, precision_rounding=rounding) >= 0: ml.write({ 'qty_done': new_quantity_done, - 'lot_id': self.finished_lot_id and self.finished_lot_id.id, - 'lot_name': self.finished_lot_id and self.finished_lot_id.name, + 'lot_id': self.lot_producing_id and self.lot_producing_id.id, }) else: new_qty_reserved = ml.product_uom_qty - new_quantity_done default = { 'product_uom_qty': new_quantity_done, 'qty_done': new_quantity_done, - 'lot_id': self.finished_lot_id and self.finished_lot_id.id, - 'lot_name': self.finished_lot_id and self.finished_lot_id.name, + 'lot_id': self.lot_producing_id and self.lot_producing_id.id, } ml.copy(default=default) ml.with_context(bypass_reservation_update=True).write({ @@ -71,24 +63,30 @@ class MrpProductProduce(models.TransientModel): if float_compare(quantity, 0, precision_rounding=self.product_uom_id.rounding) > 0: self.env['stock.move.line'].create({ - 'move_id': self.subcontract_move_id.id, - 'picking_id': self.subcontract_move_id.picking_id.id, + 'move_id': subcontract_move_id.id, + 'picking_id': subcontract_move_id.picking_id.id, 'product_id': self.product_id.id, - 'location_id': self.subcontract_move_id.location_id.id, - 'location_dest_id': self.subcontract_move_id.location_dest_id.id, + 'location_id': subcontract_move_id.location_id.id, + 'location_dest_id': subcontract_move_id.location_dest_id.id, 'product_uom_qty': 0, 'product_uom_id': self.product_uom_id.id, 'qty_done': quantity, - 'lot_id': self.finished_lot_id and self.finished_lot_id.id, - 'lot_name': self.finished_lot_id and self.finished_lot_id.name, + 'lot_id': self.lot_producing_id and self.lot_producing_id.id, }) - if not self._get_todo(self.production_id): - ml_reserved = self.subcontract_move_id.move_line_ids.filtered(lambda ml: + if not self._get_todo(): + ml_reserved = subcontract_move_id.move_line_ids.filtered(lambda ml: float_is_zero(ml.qty_done, precision_rounding=ml.product_uom_id.rounding) and not float_is_zero(ml.product_uom_qty, precision_rounding=ml.product_uom_id.rounding)) ml_reserved.unlink() - for ml in self.subcontract_move_id.move_line_ids: + for ml in subcontract_move_id.move_line_ids: ml.product_uom_qty = ml.qty_done - self.subcontract_move_id._recompute_state() + subcontract_move_id._recompute_state() return res + + def _get_todo(self): + """ This method will return remaining todo quantity of production. """ + main_product_moves = self.move_finished_ids.filtered(lambda x: x.product_id.id == self.product_id.id) + todo_quantity = self.product_qty - sum(main_product_moves.mapped('quantity_done')) + todo_quantity = todo_quantity if (todo_quantity > 0) else 0 + return todo_quantity |
