From 7f18319f2a3d6f47548605c7175aa96e4e7d02b7 Mon Sep 17 00:00:00 2001 From: Nicolas Pierre Date: Wed, 17 Feb 2021 09:58:46 +0000 Subject: [PATCH] [IMP] repair: updates to repairs workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The purpose of this commit is to improve the repairs module general workflow, to make it more intuitive and more flexible. 1. Change in the way the Repair Reference is created. It is now always autogenerated. A new Repair Description can be used. 2. Make the 'Parts' and 'Operations' tabs editable up until (and including) the stage 'Under Repair'. 3. Make the 'Lot/Serial Number' Field non mandatory for tracked products, up to and including to the stage 'Under Repair'. If the user forgot to specify the serial number and clicks on 'End Repair', shows the exisiting error message. 4. Add product moves related to the repair order in a smart button at the top right of repair, just like for a finished manufacturing order. 5. Add a Sale Order field in the repair form to make it easier to perform return if needed. 6. When a component is not tracked by serial/lot number, leaves lot/serial number read only. 7. Separationo of notes and internal notes into 2 seperate tabs. 8. Lot/serial field always visible but readonly when no tracking. Task ID-2424420 closes odoo/odoo#66496 Related: odoo/upgrade#2327 Signed-off-by: Rémy Voet --- addons/repair/__manifest__.py | 1 + addons/repair/data/ir_sequence_data.xml | 2 +- addons/repair/models/repair.py | 43 ++++++++++++------------ addons/repair/views/repair_views.xml | 27 ++++++++++----- addons/repair/views/stock_move_views.xml | 12 +++++++ 5 files changed, 53 insertions(+), 32 deletions(-) create mode 100644 addons/repair/views/stock_move_views.xml diff --git a/addons/repair/__manifest__.py b/addons/repair/__manifest__.py index 86ca0cf3fa4..edd5204d7f1 100644 --- a/addons/repair/__manifest__.py +++ b/addons/repair/__manifest__.py @@ -27,6 +27,7 @@ The following topics are covered by this module: 'security/repair_security.xml', 'wizard/repair_make_invoice_views.xml', 'wizard/stock_warn_insufficient_qty_views.xml', + 'views/stock_move_views.xml', 'views/repair_views.xml', 'report/repair_reports.xml', 'report/repair_templates_repair_order.xml', diff --git a/addons/repair/data/ir_sequence_data.xml b/addons/repair/data/ir_sequence_data.xml index fe0c00de9ca..86c21acd619 100644 --- a/addons/repair/data/ir_sequence_data.xml +++ b/addons/repair/data/ir_sequence_data.xml @@ -4,7 +4,7 @@ Repair Order repair.order - RMA/ + RO/ 5 diff --git a/addons/repair/models/repair.py b/addons/repair/models/repair.py index 3fd0f179165..379df962ccc 100644 --- a/addons/repair/models/repair.py +++ b/addons/repair/models/repair.py @@ -22,9 +22,10 @@ class Repair(models.Model): name = fields.Char( 'Repair Reference', - default='/', + default='New', copy=False, required=True, - states={'confirmed': [('readonly', True)]}) + readonly=True) + description = fields.Char('Repair Description') product_id = fields.Many2one( 'product.product', string='Product to Repair', domain="[('type', 'in', ['product', 'consu']), '|', ('company_id', '=', company_id), ('company_id', '=', False)]", @@ -49,16 +50,16 @@ class Repair(models.Model): state = fields.Selection([ ('draft', 'Quotation'), ('confirmed', 'Confirmed'), - ('under_repair', 'Under Repair'), ('ready', 'Ready to Repair'), + ('under_repair', 'Under Repair'), ('2binvoiced', 'To be Invoiced'), - ('invoice_except', 'Invoice Exception'), ('done', 'Repaired'), ('cancel', 'Cancelled')], string='Status', copy=False, default='draft', readonly=True, tracking=True, help="* The \'Draft\' status is used when a user is encoding a new and unconfirmed repair order.\n" "* The \'Confirmed\' status is used when a user confirms the repair order.\n" "* The \'Ready to Repair\' status is used to start to repairing, user can start repairing only after repair order is confirmed.\n" + "* The \'Under Repair\' status is used when the repair is ongoing.\n" "* The \'To be Invoiced\' status is used to generate the invoice before or after repairing done.\n" "* The \'Done\' status is set when repairing is completed.\n" "* The \'Cancelled\' status is used when user cancel repair order.") @@ -74,7 +75,7 @@ class Repair(models.Model): guarantee_limit = fields.Date('Warranty Expiration', states={'confirmed': [('readonly', True)]}) operations = fields.One2many( 'repair.line', 'repair_id', 'Parts', - copy=True, readonly=True, states={'draft': [('readonly', False)]}) + copy=True) pricelist_id = fields.Many2one( 'product.pricelist', 'Pricelist', default=lambda self: self.env['product.pricelist'].search([('company_id', 'in', [self.env.company.id, False])], limit=1).id, @@ -98,7 +99,7 @@ class Repair(models.Model): help="Move created by the repair order") fees_lines = fields.One2many( 'repair.fee', 'repair_id', 'Operations', - copy=True, readonly=True, states={'draft': [('readonly', False)]}) + copy=True, readonly=False) internal_notes = fields.Text('Internal Notes') quotation_notes = fields.Text('Quotation Notes') user_id = fields.Many2one('res.users', string="Responsible", default=lambda self: self.env.user, check_company=True) @@ -106,6 +107,7 @@ class Repair(models.Model): 'res.company', 'Company', readonly=True, required=True, index=True, default=lambda self: self.env.company) + sale_order_id = fields.Many2one('sale.order', 'Sale Order', copy=False, help="Sale Order from which the product to be repaired comes from.") tag_ids = fields.Many2many('repair.tags', string="Tags") invoiced = fields.Boolean('Invoiced', copy=False, readonly=True) repaired = fields.Boolean('Repaired', copy=False, readonly=True) @@ -206,12 +208,8 @@ class Repair(models.Model): @api.model def create(self, vals): - # To avoid consuming a sequence number when clicking on 'Create', we preprend it if the - # the name starts with '/'. - vals['name'] = vals.get('name') or '/' - if vals['name'].startswith('/'): - vals['name'] = (self.env['ir.sequence'].next_by_code('repair.order') or '/') + vals['name'] - vals['name'] = vals['name'][:-1] if vals['name'].endswith('/') and vals['name'] != '/' else vals['name'] + # We generate a standard reference + vals['name'] = self.env['ir.sequence'].next_by_code('repair.order') or '/' return super(Repair, self).create(vals) def button_dummy(self): @@ -495,6 +493,7 @@ class Repair(models.Model): """ if self.filtered(lambda repair: repair.state != 'under_repair'): raise UserError(_("Repair must be under repair in order to end reparation.")) + self._check_product_tracking() for repair in self: repair.write({'repaired': True}) vals = {'state': 'done'} @@ -595,6 +594,15 @@ class Repair(models.Model): res[repair.id] = move.id return res + def _check_product_tracking(self): + invalid_lines = self.operations.filtered(lambda x: x.tracking != 'none' and not x.lot_id) + if invalid_lines: + products = invalid_lines.product_id + raise ValidationError(_( + "Serial number is required for operation lines with products: %s", + ", ".join(products.mapped('display_name')), + )) + class RepairLine(models.Model): _name = 'repair.line' @@ -649,16 +657,7 @@ class RepairLine(models.Model): ('cancel', 'Cancelled')], 'Status', default='draft', copy=False, readonly=True, required=True, help='The status of a repair line is set automatically to the one of the linked repair order.') - - @api.constrains('lot_id', 'product_id') - def _check_product_tracking(self): - invalid_lines = self.filtered(lambda x: x.product_id.tracking != 'none' and not x.lot_id) - if invalid_lines: - products = invalid_lines.product_id - raise ValidationError(_( - "Serial number is required for operation lines with products: %s", - ", ".join(products.mapped('name')), - )) + tracking = fields.Selection(string='Product Tracking', related="product_id.tracking") @api.depends('price_unit', 'repair_id', 'product_uom_qty', 'product_id', 'repair_id.invoice_method') def _compute_price_subtotal(self): diff --git a/addons/repair/views/repair_views.xml b/addons/repair/views/repair_views.xml index d98b5e62d9c..76f2bb99222 100644 --- a/addons/repair/views/repair_views.xml +++ b/addons/repair/views/repair_views.xml @@ -8,6 +8,7 @@ + @@ -44,6 +45,7 @@
+
-