diff --git a/repair_refurbish/__manifest__.py b/repair_refurbish/__manifest__.py index 7342048ff..329e64345 100644 --- a/repair_refurbish/__manifest__.py +++ b/repair_refurbish/__manifest__.py @@ -10,9 +10,7 @@ "license": "AGPL-3", "application": False, "installable": True, - "depends": [ - 'repair', - ], + "depends": ["repair",], "data": [ "views/repair_view.xml", "data/stock_data.xml", diff --git a/repair_refurbish/data/stock_data.xml b/repair_refurbish/data/stock_data.xml index 479c57699..2c45818a1 100644 --- a/repair_refurbish/data/stock_data.xml +++ b/repair_refurbish/data/stock_data.xml @@ -1,27 +1,24 @@ - + - Refurbish - + production - + - - - - + property_stock_refurbish - - + + - diff --git a/repair_refurbish/models/product_product.py b/repair_refurbish/models/product_product.py index 4ab246863..83dd31572 100644 --- a/repair_refurbish/models/product_product.py +++ b/repair_refurbish/models/product_product.py @@ -5,8 +5,10 @@ from odoo import fields, models class ProductProduct(models.Model): - _inherit = 'product.product' + _inherit = "product.product" refurbish_product_id = fields.Many2one( - comodel_name='product.product', string='Refurbished Product', - domain="[('type', '=', 'product')]") + comodel_name="product.product", + string="Refurbished Product", + domain="[('type', '=', 'product')]", + ) diff --git a/repair_refurbish/models/product_template.py b/repair_refurbish/models/product_template.py index 3b6935e72..91d69cece 100644 --- a/repair_refurbish/models/product_template.py +++ b/repair_refurbish/models/product_template.py @@ -5,40 +5,46 @@ from odoo import api, fields, models class ProductTemplate(models.Model): - _inherit = 'product.template' + _inherit = "product.template" refurbish_product_id = fields.Many2one( - comodel_name='product.product', string='Refurbished Product', - compute='_compute_refurbish_product', - inverse='_inverse_refurbish_product', - search='_search_refurbish_product', - domain="[('type', '=', 'product')]") + comodel_name="product.product", + string="Refurbished Product", + compute="_compute_refurbish_product", + inverse="_inverse_refurbish_product", + search="_search_refurbish_product", + domain="[('type', '=', 'product')]", + ) property_stock_refurbish = fields.Many2one( - comodel_name='stock.location', string="Refurbish Location", - company_dependent=True, domain=[('usage', 'like', 'production')], + comodel_name="stock.location", + string="Refurbish Location", + company_dependent=True, + domain=[("usage", "like", "production")], help="This stock location will be used, instead of the " - "default one, as the source location for " - "stock moves generated by repair orders when refurbishing takes " - "place.") + "default one, as the source location for " + "stock moves generated by repair orders when refurbishing takes " + "place.", + ) - @api.depends('product_variant_ids', - 'product_variant_ids.refurbish_product_id') + @api.depends("product_variant_ids", "product_variant_ids.refurbish_product_id") def _compute_refurbish_product(self): - unique_variants = self.filtered(lambda template: - len(template.product_variant_ids) == 1) + unique_variants = self.filtered( + lambda template: len(template.product_variant_ids) == 1 + ) for template in unique_variants: - template.refurbish_product_id = \ + template.refurbish_product_id = ( template.product_variant_ids.refurbish_product_id + ) @api.multi def _inverse_refurbish_product(self): for rec in self: if len(rec.product_variant_ids) == 1: - rec.product_variant_ids.refurbish_product_id = \ - rec.refurbish_product_id + rec.product_variant_ids.refurbish_product_id = rec.refurbish_product_id def _search_refurbish_product(self, operator, value): - products = self.env['product.product'].search([ - ('refurbish_product_id', operator, value)], limit=None) - return [('id', 'in', products.mapped('product_tmpl_id').ids)] + products = self.env["product.product"].search( + [("refurbish_product_id", operator, value)], limit=None + ) + return [("id", "in", products.mapped("product_tmpl_id").ids)] diff --git a/repair_refurbish/models/repair.py b/repair_refurbish/models/repair.py index 8168ac32e..6d3e5a5e2 100644 --- a/repair_refurbish/models/repair.py +++ b/repair_refurbish/models/repair.py @@ -5,28 +5,32 @@ from odoo import api, fields, models class RepairOrder(models.Model): - _inherit = 'repair.order' + _inherit = "repair.order" to_refurbish = fields.Boolean() location_dest_id = fields.Many2one( - string='Delivery Location', comodel_name='stock.location') + string="Delivery Location", comodel_name="stock.location" + ) refurbish_location_dest_id = fields.Many2one( - string='Refurbished Delivery Location', comodel_name='stock.location') + string="Refurbished Delivery Location", comodel_name="stock.location" + ) refurbish_product_id = fields.Many2one( - string='Refurbished product', comodel_name='product.product') + string="Refurbished product", comodel_name="product.product" + ) refurbish_lot_id = fields.Many2one( - string='Refurbished Lot', comodel_name='stock.production.lot') + string="Refurbished Lot", comodel_name="stock.production.lot" + ) refurbish_move_id = fields.Many2one( - string='Refurbished Inventory Move', comodel_name='stock.move') + string="Refurbished Inventory Move", comodel_name="stock.move" + ) - @api.onchange('product_id') + @api.onchange("product_id") def onchange_product_id(self): res = super().onchange_product_id() - self.to_refurbish = True if \ - self.product_id.refurbish_product_id else False + self.to_refurbish = True if self.product_id.refurbish_product_id else False return res - @api.onchange('to_refurbish', 'product_id') + @api.onchange("to_refurbish", "product_id") def _onchange_to_refurbish(self): if self.to_refurbish: self.refurbish_product_id = self.product_id.refurbish_product_id @@ -40,37 +44,47 @@ class RepairOrder(models.Model): @api.multi def _get_refurbish_stock_move_dict(self): return { - 'name': self.name, - 'product_id': self.refurbish_product_id.id, - 'product_uom': self.product_uom.id or - self.refurbish_product_id.uom_id.id, - 'product_uom_qty': self.product_qty, - 'partner_id': self.address_id and - self.address_id.id or False, - 'location_id': self.location_dest_id.id, - 'location_dest_id': self.refurbish_location_dest_id.id, - 'move_line_ids': [(0, 0, { - 'product_id': self.refurbish_product_id.id, - 'lot_id': self.refurbish_lot_id.id, - 'product_uom_qty': self.product_qty, - 'product_uom_id': self.product_uom.id or - self.refurbish_product_id.uom_id.id, - 'qty_done': self.product_qty, - 'package_id': False, - 'result_package_id': False, - 'location_id': self.location_dest_id.id, - 'location_dest_id': self.refurbish_location_dest_id.id})]} + "name": self.name, + "product_id": self.refurbish_product_id.id, + "product_uom": self.product_uom.id or self.refurbish_product_id.uom_id.id, + "product_uom_qty": self.product_qty, + "partner_id": self.address_id and self.address_id.id or False, + "location_id": self.location_dest_id.id, + "location_dest_id": self.refurbish_location_dest_id.id, + "move_line_ids": [ + ( + 0, + 0, + { + "product_id": self.refurbish_product_id.id, + "lot_id": self.refurbish_lot_id.id, + "product_uom_qty": self.product_qty, + "product_uom_id": self.product_uom.id + or self.refurbish_product_id.uom_id.id, + "qty_done": self.product_qty, + "package_id": False, + "result_package_id": False, + "location_id": self.location_dest_id.id, + "location_dest_id": self.refurbish_location_dest_id.id, + }, + ) + ], + } @api.multi def action_repair_done(self): - res = super(RepairOrder, self.with_context( - force_refurbish_location_dest_id=self.location_dest_id.id, - to_refurbish=self.to_refurbish, - )).action_repair_done() + res = super( + RepairOrder, + self.with_context( + force_refurbish_location_dest_id=self.location_dest_id.id, + to_refurbish=self.to_refurbish, + ), + ).action_repair_done() for repair in self: if repair.to_refurbish: - move = self.env['stock.move'].create( - repair._get_refurbish_stock_move_dict()) + move = self.env["stock.move"].create( + repair._get_refurbish_stock_move_dict() + ) move.quantity_done = repair.product_qty move._action_done() repair.refurbish_move_id = move.id @@ -78,18 +92,21 @@ class RepairOrder(models.Model): class RepairLine(models.Model): - _inherit = 'repair.line' + _inherit = "repair.line" - @api.onchange('type', 'repair_id') + @api.onchange("type", "repair_id") def onchange_operation_type(self): res = super(RepairLine, self).onchange_operation_type() context = self.env.context - if (self.type == 'add' and 'to_refurbish' in context and - context['to_refurbish']): - self.location_dest_id = context['refurbish_location_dest_id'] - elif (self.type == 'add' and 'to_refurbish' in context and not - context['to_refurbish']): - scrap_location_id = self.env['stock.location'].search([ - ('usage', '=', 'customer')], limit=1) + if self.type == "add" and "to_refurbish" in context and context["to_refurbish"]: + self.location_dest_id = context["refurbish_location_dest_id"] + elif ( + self.type == "add" + and "to_refurbish" in context + and not context["to_refurbish"] + ): + scrap_location_id = self.env["stock.location"].search( + [("usage", "=", "customer")], limit=1 + ) self.location_dest_id = scrap_location_id return res diff --git a/repair_refurbish/models/stock_move.py b/repair_refurbish/models/stock_move.py index db617fdbc..703fab567 100644 --- a/repair_refurbish/models/stock_move.py +++ b/repair_refurbish/models/stock_move.py @@ -1,33 +1,33 @@ # Copyright 2019 Camptocamp SA # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -from odoo import models, api +from odoo import api, models class StockMove(models.Model): - _inherit = 'stock.move' + _inherit = "stock.move" @api.model_create_multi def create(self, vals_list): - if 'to_refurbish' in self.env.context and \ - self.env.context['to_refurbish']: - if 'force_refurbish_location_dest_id' in self.env.context: + if "to_refurbish" in self.env.context and self.env.context["to_refurbish"]: + if "force_refurbish_location_dest_id" in self.env.context: for vals in vals_list: - vals['location_dest_id'] = self.env.context[ - 'force_refurbish_location_dest_id'] + vals["location_dest_id"] = self.env.context[ + "force_refurbish_location_dest_id" + ] return super().create(vals_list) class StockMoveLine(models.Model): - _inherit = 'stock.move.line' + _inherit = "stock.move.line" @api.model_create_multi def create(self, vals_list): - if 'to_refurbish' in self.env.context and \ - self.env.context['to_refurbish']: - if 'force_refurbish_location_dest_id' in self.env.context: + if "to_refurbish" in self.env.context and self.env.context["to_refurbish"]: + if "force_refurbish_location_dest_id" in self.env.context: for vals in vals_list: - vals['location_dest_id'] = self.env.context[ - 'force_refurbish_location_dest_id'] + vals["location_dest_id"] = self.env.context[ + "force_refurbish_location_dest_id" + ] return super().create(vals_list) diff --git a/repair_refurbish/tests/test_repair_refurbish.py b/repair_refurbish/tests/test_repair_refurbish.py index c5b52e0d4..0095c66ac 100644 --- a/repair_refurbish/tests/test_repair_refurbish.py +++ b/repair_refurbish/tests/test_repair_refurbish.py @@ -5,74 +5,73 @@ from odoo.tests.common import TransactionCase class TestMrpMtoWithStock(TransactionCase): - def setUp(self, *args, **kwargs): super(TestMrpMtoWithStock, self).setUp(*args, **kwargs) - self.repair_obj = self.env['repair.order'] - self.repair_line_obj = self.env['repair.line'] - self.product_obj = self.env['product.product'] - self.move_obj = self.env['stock.move'] + self.repair_obj = self.env["repair.order"] + self.repair_line_obj = self.env["repair.line"] + self.product_obj = self.env["product.product"] + self.move_obj = self.env["stock.move"] - self.stock_location_stock = self.env.ref('stock.stock_location_stock') - self.customer_location = self.env.ref('stock.stock_location_customers') - self.refurbish_loc = self.env.ref( - 'repair_refurbish.stock_location_refurbish') + self.stock_location_stock = self.env.ref("stock.stock_location_stock") + self.customer_location = self.env.ref("stock.stock_location_customers") + self.refurbish_loc = self.env.ref("repair_refurbish.stock_location_refurbish") - self.refurbish_product = self.product_obj.create({ - 'name': 'Refurbished Awesome Screen', - 'type': 'product', - }) - self.product = self.product_obj.create({ - 'name': 'Awesome Screen', - 'type': 'product', - 'refurbish_product_id': self.refurbish_product.id, - }) - self.material = self.product_obj.create({ - 'name': 'Materials', - 'type': 'consu', - }) - self.material2 = self.product_obj.create({ - 'name': 'Materials', - 'type': 'product', - }) + self.refurbish_product = self.product_obj.create( + {"name": "Refurbished Awesome Screen", "type": "product",} + ) + self.product = self.product_obj.create( + { + "name": "Awesome Screen", + "type": "product", + "refurbish_product_id": self.refurbish_product.id, + } + ) + self.material = self.product_obj.create({"name": "Materials", "type": "consu",}) + self.material2 = self.product_obj.create( + {"name": "Materials", "type": "product",} + ) self._update_product_qty(self.product, self.stock_location_stock, 10.0) def _update_product_qty(self, product, location, quantity): - product_qty = self.env['stock.change.product.qty'].create({ - 'location_id': location.id, - 'product_id': product.id, - 'new_quantity': quantity, - }) + product_qty = self.env["stock.change.product.qty"].create( + { + "location_id": location.id, + "product_id": product.id, + "new_quantity": quantity, + } + ) product_qty.change_product_qty() return product_qty def test_01_repair_refurbish(self): """Tests that locations are properly set with a product to refurbish, then complete repair.""" - repair = self.repair_obj.create({ - 'product_id': self.product.id, - 'product_qty': 3.0, - 'product_uom': self.product.uom_id.id, - 'location_dest_id': self.customer_location.id, - }) + repair = self.repair_obj.create( + { + "product_id": self.product.id, + "product_qty": 3.0, + "product_uom": self.product.uom_id.id, + "location_dest_id": self.customer_location.id, + } + ) repair.onchange_product_id() self.assertTrue(repair.to_refurbish) repair._onchange_to_refurbish() - self.assertEqual(repair.refurbish_location_dest_id, - self.customer_location) - self.assertEqual(repair.location_dest_id, - self.product.property_stock_refurbish) + self.assertEqual(repair.refurbish_location_dest_id, self.customer_location) + self.assertEqual(repair.location_dest_id, self.product.property_stock_refurbish) line = self.repair_line_obj.with_context( to_refurbish=repair.to_refurbish, refurbish_location_dest_id=repair.refurbish_location_dest_id, - ).new({ - 'name': 'consume stuff to repair', - 'repair_id': repair.id, - 'type': 'add', - 'product_id': self.material.id, - 'product_uom': self.material.uom_id.id, - 'product_uom_qty': 1.0, - }) + ).new( + { + "name": "consume stuff to repair", + "repair_id": repair.id, + "type": "add", + "product_id": self.material.id, + "product_uom": self.material.uom_id.id, + "product_uom_qty": 1.0, + } + ) line.onchange_product_id() line.onchange_operation_type() self.assertEqual(line.location_id, repair.location_id) @@ -81,59 +80,67 @@ class TestMrpMtoWithStock(TransactionCase): repair.action_validate() repair.action_repair_start() repair.action_repair_end() - moves = self.move_obj.search([('reference', '=', repair.name)]) + moves = self.move_obj.search([("reference", "=", repair.name)]) self.assertEqual(len(moves), 2) for m in moves: - self.assertEqual(m.state, 'done') + self.assertEqual(m.state, "done") if m.product_id == self.product: self.assertEqual(m.location_id, self.stock_location_stock) self.assertEqual(m.location_dest_id, self.refurbish_loc) - self.assertEqual(m.mapped('move_line_ids.location_id'), - self.stock_location_stock) - self.assertEqual(m.mapped('move_line_ids.location_dest_id'), - self.refurbish_loc) + self.assertEqual( + m.mapped("move_line_ids.location_id"), self.stock_location_stock + ) + self.assertEqual( + m.mapped("move_line_ids.location_dest_id"), self.refurbish_loc + ) elif m.product_id == self.refurbish_product: self.assertEqual(m.location_id, self.refurbish_loc) self.assertEqual(m.location_dest_id, self.customer_location) - self.assertEqual(m.mapped('move_line_ids.location_id'), - self.refurbish_loc) - self.assertEqual(m.mapped('move_line_ids.location_dest_id'), - self.customer_location) + self.assertEqual( + m.mapped("move_line_ids.location_id"), self.refurbish_loc + ) + self.assertEqual( + m.mapped("move_line_ids.location_dest_id"), self.customer_location + ) else: self.assertTrue(False, "Unexpected move.") def test_02_repair_no_refurbish(self): """Tests normal repairs does not fail and normal location for consumed material""" - repair = self.repair_obj.create({ - 'product_id': self.product.id, - 'product_qty': 3.0, - 'product_uom': self.product.uom_id.id, - 'location_dest_id': self.customer_location.id, - 'to_refurbish': False - }) + repair = self.repair_obj.create( + { + "product_id": self.product.id, + "product_qty": 3.0, + "product_uom": self.product.uom_id.id, + "location_dest_id": self.customer_location.id, + "to_refurbish": False, + } + ) line = self.repair_line_obj.with_context( to_refurbish=repair.to_refurbish, refurbish_location_dest_id=repair.refurbish_location_dest_id, - ).create({ - 'name': 'consume stuff to repair', - 'repair_id': repair.id, - 'type': 'add', - 'product_id': self.material2.id, - 'product_uom': self.material2.uom_id.id, - 'product_uom_qty': 1.0, - 'price_unit': 50.0, - 'location_id': self.stock_location_stock.id, - 'location_dest_id': self.customer_location.id - }) + ).create( + { + "name": "consume stuff to repair", + "repair_id": repair.id, + "type": "add", + "product_id": self.material2.id, + "product_uom": self.material2.uom_id.id, + "product_uom_qty": 1.0, + "price_unit": 50.0, + "location_id": self.stock_location_stock.id, + "location_dest_id": self.customer_location.id, + } + ) line.onchange_product_id() line.onchange_operation_type() # Complete repair: repair.action_validate() repair.action_repair_start() repair.action_repair_end() - move = self.move_obj.search([ - ('product_id', '=', self.material2.id)], - order='create_date desc', limit=1)[0] + move = self.move_obj.search( + [("product_id", "=", self.material2.id)], order="create_date desc", limit=1 + )[0] self.assertEqual(move.location_dest_id, self.customer_location) diff --git a/repair_refurbish/views/product_product_view.xml b/repair_refurbish/views/product_product_view.xml index f418118fe..8565366f9 100644 --- a/repair_refurbish/views/product_product_view.xml +++ b/repair_refurbish/views/product_product_view.xml @@ -1,17 +1,15 @@ - + - product.product.form product.product - + - + - diff --git a/repair_refurbish/views/product_template_view.xml b/repair_refurbish/views/product_template_view.xml index cafa2730b..9bfd93552 100644 --- a/repair_refurbish/views/product_template_view.xml +++ b/repair_refurbish/views/product_template_view.xml @@ -1,31 +1,32 @@ - + - product.template.product.form product.template - + - - + + - product.template.stock.property.form.inherit product.template - + - - - + + - diff --git a/repair_refurbish/views/repair_view.xml b/repair_refurbish/views/repair_view.xml index f47ce2524..9ec14e56f 100644 --- a/repair_refurbish/views/repair_view.xml +++ b/repair_refurbish/views/repair_view.xml @@ -1,57 +1,63 @@ - + - repair.order.tree repair.order - + - + - repair.order.form repair.order - + - + - + - - - + + + - - {'default_product_uom_qty': product_qty, 'to_refurbish': to_refurbish, 'refurbish_location_dest_id': location_dest_id} + + {'default_product_uom_qty': product_qty, 'to_refurbish': to_refurbish, 'refurbish_location_dest_id': location_dest_id} - - repair.order.select - repair.order - - - - - - - + repair.order.select + repair.order + + + + + + + -