From c7720d32f02dba77a9624eeb7b90b98f711ec63a Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Tue, 14 Jan 2020 16:36:03 +0100 Subject: [PATCH] [IMP] : black, isort --- rma/__manifest__.py | 64 +- rma/models/procurement.py | 55 +- rma/models/product.py | 11 +- rma/models/product_category.py | 21 +- rma/models/res_partner.py | 7 +- rma/models/rma_operation.py | 95 ++- rma/models/rma_order.py | 258 ++++--- rma/models/rma_order_line.py | 688 ++++++++++------- rma/models/stock.py | 18 +- rma/models/stock_warehouse.py | 301 ++++---- rma/report/rma_report.xml | 4 +- rma/security/rma.xml | 2 +- rma/tests/test_rma.py | 725 ++++++++---------- rma/views/stock_warehouse.xml | 1 - rma/wizards/rma_add_stock_move.py | 133 ++-- rma/wizards/rma_make_picking.py | 225 +++--- .../rma_order_line_make_supplier_rma.py | 218 +++--- rma/wizards/stock_config_settings.py | 38 +- 18 files changed, 1507 insertions(+), 1357 deletions(-) diff --git a/rma/__manifest__.py b/rma/__manifest__.py index d3022fd7..346fe5b4 100644 --- a/rma/__manifest__.py +++ b/rma/__manifest__.py @@ -2,36 +2,36 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) { - 'name': 'RMA (Return Merchandise Authorization)', - 'version': '12.0.2.3.0', - 'license': 'LGPL-3', - 'category': 'RMA', - 'summary': 'Introduces the return merchandise authorization (RMA) process ' - 'in odoo', - 'author': "Eficent, Odoo Community Association (OCA)", - 'website': 'https://github.com/Eficent/stock-rma', - 'depends': ['stock', 'mail', 'web'], - 'demo': ['demo/stock_demo.xml', - ], - 'data': ['security/rma.xml', - 'security/ir.model.access.csv', - 'data/rma_sequence.xml', - 'data/stock_data.xml', - 'data/rma_operation.xml', - 'report/rma_report.xml', - 'report/rma_report_templates.xml', - 'views/rma_order_view.xml', - 'views/rma_operation_view.xml', - 'views/rma_order_line_view.xml', - 'views/stock_view.xml', - 'views/stock_warehouse.xml', - 'views/product_view.xml', - 'views/res_partner_view.xml', - 'wizards/rma_make_picking_view.xml', - 'wizards/rma_add_stock_move_view.xml', - 'wizards/stock_config_settings.xml', - 'wizards/rma_order_line_make_supplier_rma_view.xml', - ], - 'installable': True, - 'auto_install': False, + "name": "RMA (Return Merchandise Authorization)", + "version": "12.0.2.3.0", + "license": "LGPL-3", + "category": "RMA", + "summary": "Introduces the return merchandise authorization (RMA) process " + "in odoo", + "author": "Eficent, Odoo Community Association (OCA)", + "website": "https://github.com/Eficent/stock-rma", + "depends": ["stock", "mail", "web"], + "demo": ["demo/stock_demo.xml"], + "data": [ + "security/rma.xml", + "security/ir.model.access.csv", + "data/rma_sequence.xml", + "data/stock_data.xml", + "data/rma_operation.xml", + "report/rma_report.xml", + "report/rma_report_templates.xml", + "views/rma_order_view.xml", + "views/rma_operation_view.xml", + "views/rma_order_line_view.xml", + "views/stock_view.xml", + "views/stock_warehouse.xml", + "views/product_view.xml", + "views/res_partner_view.xml", + "wizards/rma_make_picking_view.xml", + "wizards/rma_add_stock_move_view.xml", + "wizards/stock_config_settings.xml", + "wizards/rma_order_line_make_supplier_rma_view.xml", + ], + "installable": True, + "auto_install": False, } diff --git a/rma/models/procurement.py b/rma/models/procurement.py index 5a9a7709..5083841d 100644 --- a/rma/models/procurement.py +++ b/rma/models/procurement.py @@ -5,43 +5,52 @@ from odoo import fields, models class StockRule(models.Model): - _inherit = 'stock.rule' + _inherit = "stock.rule" rma_line_id = fields.Many2one( - comodel_name='rma.order.line', string='RMA line', - ondelete="set null", + comodel_name="rma.order.line", string="RMA line", ondelete="set null" ) - def _get_stock_move_values(self, product_id, product_qty, product_uom, - location_id, name, origin, values, group_id): - res = super(StockRule, self)._get_stock_move_values(product_id, - product_qty, - product_uom, - location_id, - name, origin, - values, group_id) - if 'rma_line_id' in values: - line = self.env['rma.order.line'].browse(values.get('rma_line_id')) - res['rma_line_id'] = line.id + def _get_stock_move_values( + self, + product_id, + product_qty, + product_uom, + location_id, + name, + origin, + values, + group_id, + ): + res = super(StockRule, self)._get_stock_move_values( + product_id, + product_qty, + product_uom, + location_id, + name, + origin, + values, + group_id, + ) + if "rma_line_id" in values: + line = self.env["rma.order.line"].browse(values.get("rma_line_id")) + res["rma_line_id"] = line.id if line.delivery_address_id: - res['partner_id'] = line.delivery_address_id.id + res["partner_id"] = line.delivery_address_id.id else: - res['partner_id'] = line.rma_id.partner_id.id - dest_loc = self.env["stock.location"].browse([ - res["location_dest_id"]])[0] + res["partner_id"] = line.rma_id.partner_id.id + dest_loc = self.env["stock.location"].browse([res["location_dest_id"]])[0] if dest_loc.usage == "internal": res["price_unit"] = line.price_unit return res class ProcurementGroup(models.Model): - _inherit = 'procurement.group' + _inherit = "procurement.group" rma_id = fields.Many2one( - comodel_name='rma.order', string='RMA', - ondelete="set null", + comodel_name="rma.order", string="RMA", ondelete="set null" ) rma_line_id = fields.Many2one( - comodel_name='rma.order.line', string='RMA line', - ondelete="set null", + comodel_name="rma.order.line", string="RMA line", ondelete="set null" ) diff --git a/rma/models/product.py b/rma/models/product.py index b1da2221..4330b3d1 100644 --- a/rma/models/product.py +++ b/rma/models/product.py @@ -5,11 +5,14 @@ from odoo import fields, models class ProductTemplate(models.Model): - _inherit = 'product.template' + _inherit = "product.template" rma_customer_operation_id = fields.Many2one( - comodel_name="rma.operation", string="Default RMA Customer Operation") + comodel_name="rma.operation", string="Default RMA Customer Operation" + ) rma_supplier_operation_id = fields.Many2one( - comodel_name="rma.operation", string="Default RMA Supplier Operation") + comodel_name="rma.operation", string="Default RMA Supplier Operation" + ) rma_approval_policy = fields.Selection( - related="categ_id.rma_approval_policy", readonly=True) + related="categ_id.rma_approval_policy", readonly=True + ) diff --git a/rma/models/product_category.py b/rma/models/product_category.py index 7bfd6100..7ac3ae1c 100644 --- a/rma/models/product_category.py +++ b/rma/models/product_category.py @@ -8,14 +8,19 @@ class ProductCategory(models.Model): _inherit = "product.category" rma_approval_policy = fields.Selection( - selection=[('one_step', 'One step'), ('two_step', 'Two steps')], - string="RMA Approval Policy", required=True, default='one_step', + selection=[("one_step", "One step"), ("two_step", "Two steps")], + string="RMA Approval Policy", + required=True, + default="one_step", help="Options: \n " - "* One step: Always auto-approve RMAs that only contain " - "products within categories with this policy.\n" - "* Two steps: A RMA containing a product within a category with " - "this policy will request the RMA manager approval.") + "* One step: Always auto-approve RMAs that only contain " + "products within categories with this policy.\n" + "* Two steps: A RMA containing a product within a category with " + "this policy will request the RMA manager approval.", + ) rma_customer_operation_id = fields.Many2one( - comodel_name="rma.operation", string="Default RMA Customer Operation") + comodel_name="rma.operation", string="Default RMA Customer Operation" + ) rma_supplier_operation_id = fields.Many2one( - comodel_name="rma.operation", string="Default RMA Supplier Operation") + comodel_name="rma.operation", string="Default RMA Supplier Operation" + ) diff --git a/rma/models/res_partner.py b/rma/models/res_partner.py index 896b03a1..9eed65ae 100644 --- a/rma/models/res_partner.py +++ b/rma/models/res_partner.py @@ -13,14 +13,13 @@ class ResPartner(models.Model): rec.rma_line_count = len(rec.rma_line_ids) rma_line_ids = fields.One2many( - comodel_name="rma.order.line", string="RMAs", - inverse_name="partner_id", + comodel_name="rma.order.line", string="RMAs", inverse_name="partner_id" ) rma_line_count = fields.Integer(compute="_compute_rma_line_count") @api.multi def action_open_partner_rma(self): - action = self.env.ref('rma.action_rma_customer_lines') + action = self.env.ref("rma.action_rma_customer_lines") result = action.read()[0] - result['context'] = {'search_default_partner_id': self.id} + result["context"] = {"search_default_partner_id": self.id} return result diff --git a/rma/models/rma_operation.py b/rma/models/rma_operation.py index 65312a23..04285d6d 100644 --- a/rma/models/rma_operation.py +++ b/rma/models/rma_operation.py @@ -5,77 +5,94 @@ from odoo import api, fields, models class RmaOperation(models.Model): - _name = 'rma.operation' - _description = 'RMA Operation' + _name = "rma.operation" + _description = "RMA Operation" @api.model def _default_warehouse_id(self): company_id = self.env.user.company_id.id - warehouse = self.env['stock.warehouse'].search( - [('company_id', '=', company_id)], limit=1) + warehouse = self.env["stock.warehouse"].search( + [("company_id", "=", company_id)], limit=1 + ) return warehouse @api.model def _default_customer_location_id(self): - return self.env.ref('stock.stock_location_customers') or False + return self.env.ref("stock.stock_location_customers") or False @api.model def _default_supplier_location_id(self): - return self.env.ref('stock.stock_location_suppliers') or False + return self.env.ref("stock.stock_location_suppliers") or False @api.model def _default_routes(self): - op_type = self.env.context.get('default_type') - if op_type == 'customer': - return self.env.ref('rma.route_rma_customer') - elif op_type == 'supplier': - return self.env.ref('rma.route_rma_supplier') + op_type = self.env.context.get("default_type") + if op_type == "customer": + return self.env.ref("rma.route_rma_customer") + elif op_type == "supplier": + return self.env.ref("rma.route_rma_supplier") - name = fields.Char('Description', required=True) - code = fields.Char('Code', required=True) - active = fields.Boolean(string='Active', default=True) - receipt_policy = fields.Selection([ - ('no', 'Not required'), ('ordered', 'Based on Ordered Quantities'), - ('delivered', 'Based on Delivered Quantities')], - string="Receipts Policy", default='no') - delivery_policy = fields.Selection([ - ('no', 'Not required'), ('ordered', 'Based on Ordered Quantities'), - ('received', 'Based on Received Quantities')], - string="Delivery Policy", default='no') + name = fields.Char("Description", required=True) + code = fields.Char("Code", required=True) + active = fields.Boolean(string="Active", default=True) + receipt_policy = fields.Selection( + [ + ("no", "Not required"), + ("ordered", "Based on Ordered Quantities"), + ("delivered", "Based on Delivered Quantities"), + ], + string="Receipts Policy", + default="no", + ) + delivery_policy = fields.Selection( + [ + ("no", "Not required"), + ("ordered", "Based on Ordered Quantities"), + ("received", "Based on Received Quantities"), + ], + string="Delivery Policy", + default="no", + ) in_route_id = fields.Many2one( - comodel_name='stock.location.route', string='Inbound Route', - domain=[('rma_selectable', '=', True)], + comodel_name="stock.location.route", + string="Inbound Route", + domain=[("rma_selectable", "=", True)], default=lambda self: self._default_routes(), ) out_route_id = fields.Many2one( - comodel_name='stock.location.route', string='Outbound Route', - domain=[('rma_selectable', '=', True)], + comodel_name="stock.location.route", + string="Outbound Route", + domain=[("rma_selectable", "=", True)], default=lambda self: self._default_routes(), ) customer_to_supplier = fields.Boolean( - string='The customer will send to the supplier', + string="The customer will send to the supplier" ) supplier_to_customer = fields.Boolean( - string='The supplier will send to the customer', + string="The supplier will send to the customer" ) in_warehouse_id = fields.Many2one( - comodel_name='stock.warehouse', string='Inbound Warehouse', + comodel_name="stock.warehouse", + string="Inbound Warehouse", default=lambda self: self._default_warehouse_id(), ) out_warehouse_id = fields.Many2one( - comodel_name='stock.warehouse', string='Outbound Warehouse', + comodel_name="stock.warehouse", + string="Outbound Warehouse", default=lambda self: self._default_warehouse_id(), ) - location_id = fields.Many2one( - 'stock.location', 'Send To This Company Location') - type = fields.Selection([ - ('customer', 'Customer'), ('supplier', 'Supplier')], - string="Used in RMA of this type", required=True) + location_id = fields.Many2one("stock.location", "Send To This Company Location") + type = fields.Selection( + [("customer", "Customer"), ("supplier", "Supplier")], + string="Used in RMA of this type", + required=True, + ) rma_line_ids = fields.One2many( - comodel_name='rma.order.line', inverse_name='operation_id', - string='RMA lines', + comodel_name="rma.order.line", inverse_name="operation_id", string="RMA lines" ) company_id = fields.Many2one( - comodel_name='res.company', string='Company', required=True, - default=lambda self: self.env.user.company_id + comodel_name="res.company", + string="Company", + required=True, + default=lambda self: self.env.user.company_id, ) diff --git a/rma/models/rma_order.py b/rma/models/rma_order.py index b3a0969d..015dc536 100644 --- a/rma/models/rma_order.py +++ b/rma/models/rma_order.py @@ -1,19 +1,20 @@ # Copyright (C) 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, fields, models, _ -from odoo.exceptions import UserError from datetime import datetime +from odoo import _, api, fields, models +from odoo.exceptions import UserError + class RmaOrder(models.Model): _name = "rma.order" - _description = 'RMA Group' - _inherit = ['mail.thread'] + _description = "RMA Group" + _inherit = ["mail.thread"] @api.model def _get_default_type(self): - if 'supplier' in self.env.context: + if "supplier" in self.env.context: return "supplier" return "customer" @@ -23,7 +24,7 @@ class RmaOrder(models.Model): picking_ids = [] for line in rec.rma_line_ids: for move in line.move_ids: - if move.location_dest_id.usage == 'internal': + if move.location_dest_id.usage == "internal": picking_ids.append(move.picking_id.id) else: if line.customer_to_supplier: @@ -37,7 +38,7 @@ class RmaOrder(models.Model): for rec in self: for line in rec.rma_line_ids: for move in line.move_ids: - if move.location_dest_id.usage in ('supplier', 'customer'): + if move.location_dest_id.usage in ("supplier", "customer"): if not line.customer_to_supplier: picking_ids.append(move.picking_id.id) shipments = list(set(picking_ids)) @@ -45,34 +46,36 @@ class RmaOrder(models.Model): @api.multi def _compute_supplier_line_count(self): - self.supplier_line_count = len(self.rma_line_ids.filtered( - lambda r: r.supplier_rma_line_ids)) + self.supplier_line_count = len( + self.rma_line_ids.filtered(lambda r: r.supplier_rma_line_ids) + ) @api.multi def _compute_line_count(self): for rec in self: rec.line_count = len(rec._get_valid_lines()) - @api.depends('rma_line_ids', 'rma_line_ids.state') + @api.depends("rma_line_ids", "rma_line_ids.state") @api.multi def _compute_state(self): for rec in self: - rma_line_done = self.env['rma.order.line'].search_count( - [('id', 'in', rec.rma_line_ids.ids), ('state', '=', 'done')]) - rma_line_approved = self.env['rma.order.line'].search_count( - [('id', 'in', rec.rma_line_ids.ids), - ('state', '=', 'approved')]) - rma_line_to_approve = self.env['rma.order.line'].search_count( - [('id', 'in', rec.rma_line_ids.ids), - ('state', '=', 'to_approve')]) + rma_line_done = self.env["rma.order.line"].search_count( + [("id", "in", rec.rma_line_ids.ids), ("state", "=", "done")] + ) + rma_line_approved = self.env["rma.order.line"].search_count( + [("id", "in", rec.rma_line_ids.ids), ("state", "=", "approved")] + ) + rma_line_to_approve = self.env["rma.order.line"].search_count( + [("id", "in", rec.rma_line_ids.ids), ("state", "=", "to_approve")] + ) if rma_line_done != 0: - state = 'done' + state = "done" elif rma_line_approved != 0: - state = 'approved' + state = "approved" elif rma_line_to_approve != 0: - state = 'to_approve' + state = "to_approve" else: - state = 'draft' + state = "draft" rec.state = state @api.model @@ -81,108 +84,114 @@ class RmaOrder(models.Model): @api.model def _default_warehouse_id(self): - warehouse = self.env['stock.warehouse'].search( - [('company_id', '=', self.env.user.company_id.id)], limit=1) + warehouse = self.env["stock.warehouse"].search( + [("company_id", "=", self.env.user.company_id.id)], limit=1 + ) return warehouse - name = fields.Char( - string='Group Number', index=True, copy=False) + name = fields.Char(string="Group Number", index=True, copy=False) type = fields.Selection( - [('customer', 'Customer'), ('supplier', 'Supplier')], - string="Type", required=True, + [("customer", "Customer"), ("supplier", "Supplier")], + string="Type", + required=True, default=lambda self: self._get_default_type(), - readonly=True + readonly=True, + ) + reference = fields.Char( + string="Partner Reference", help="The partner reference of this RMA order." + ) + comment = fields.Text("Additional Information") + date_rma = fields.Datetime( + string="Order Date", index=True, default=lambda self: self._default_date_rma() ) - reference = fields.Char(string='Partner Reference', - help="The partner reference of this RMA order.") - comment = fields.Text('Additional Information') - date_rma = fields.Datetime(string='Order Date', index=True, - default=lambda self: self._default_date_rma(),) partner_id = fields.Many2one( - comodel_name='res.partner', string='Partner', required=True) - rma_line_ids = fields.One2many('rma.order.line', 'rma_id', - string='RMA lines') - in_shipment_count = fields.Integer(compute='_compute_in_shipment_count', - string='# of Invoices') - out_shipment_count = fields.Integer(compute='_compute_out_shipment_count', - string='# of Outgoing Shipments') - line_count = fields.Integer(compute='_compute_line_count', - string='# of Outgoing Shipments') - supplier_line_count = fields.Integer( - compute='_compute_supplier_line_count', - string='# of Supplier RMAs' + comodel_name="res.partner", string="Partner", required=True + ) + rma_line_ids = fields.One2many("rma.order.line", "rma_id", string="RMA lines") + in_shipment_count = fields.Integer( + compute="_compute_in_shipment_count", string="# of Invoices" + ) + out_shipment_count = fields.Integer( + compute="_compute_out_shipment_count", string="# of Outgoing Shipments" + ) + line_count = fields.Integer( + compute="_compute_line_count", string="# of Outgoing Shipments" + ) + supplier_line_count = fields.Integer( + compute="_compute_supplier_line_count", string="# of Supplier RMAs" + ) + company_id = fields.Many2one( + "res.company", + string="Company", + required=True, + default=lambda self: self.env.user.company_id, ) - company_id = fields.Many2one('res.company', string='Company', - required=True, default=lambda self: - self.env.user.company_id) assigned_to = fields.Many2one( - comodel_name='res.users', track_visibility='onchange', + comodel_name="res.users", + track_visibility="onchange", default=lambda self: self.env.uid, ) requested_by = fields.Many2one( - comodel_name='res.users', track_visibility='onchange', + comodel_name="res.users", + track_visibility="onchange", default=lambda self: self.env.uid, ) in_warehouse_id = fields.Many2one( - comodel_name='stock.warehouse', - string='Inbound Warehouse', + comodel_name="stock.warehouse", + string="Inbound Warehouse", required=True, default=_default_warehouse_id, ) - customer_to_supplier = fields.Boolean( - 'The customer will send to the supplier', - ) - supplier_to_customer = fields.Boolean( - 'The supplier will send to the customer', - ) + customer_to_supplier = fields.Boolean("The customer will send to the supplier") + supplier_to_customer = fields.Boolean("The supplier will send to the customer") supplier_address_id = fields.Many2one( - comodel_name='res.partner', - string='Supplier Address', - help="Address of the supplier in case of Customer RMA operation " - "dropship.") + comodel_name="res.partner", + string="Supplier Address", + help="Address of the supplier in case of Customer RMA operation " "dropship.", + ) customer_address_id = fields.Many2one( - comodel_name='res.partner', - string='Customer Address', - help="Address of the customer in case of Supplier RMA operation " - "dropship.") + comodel_name="res.partner", + string="Customer Address", + help="Address of the customer in case of Supplier RMA operation " "dropship.", + ) state = fields.Selection( compute=_compute_state, - selection=[('draft', 'Draft'), - ('to_approve', 'To Approve'), - ('approved', 'Approved'), - ('done', 'Done')], - string='State', default='draft', store=True + selection=[ + ("draft", "Draft"), + ("to_approve", "To Approve"), + ("approved", "Approved"), + ("done", "Done"), + ], + string="State", + default="draft", + store=True, ) @api.constrains("partner_id", "rma_line_ids") def _check_partner_id(self): if self.rma_line_ids and self.partner_id != self.mapped( - "rma_line_ids.partner_id"): - raise UserError(_( - "Group partner and RMA's partner must be the same.")) + "rma_line_ids.partner_id" + ): + raise UserError(_("Group partner and RMA's partner must be the same.")) if len(self.mapped("rma_line_ids.partner_id")) > 1: - raise UserError(_( - "All grouped RMA's should have same partner.")) + raise UserError(_("All grouped RMA's should have same partner.")) @api.model def create(self, vals): - if (self.env.context.get('supplier') or - vals.get('type') == 'supplier'): - vals['name'] = self.env['ir.sequence'].next_by_code( - 'rma.order.supplier') + if self.env.context.get("supplier") or vals.get("type") == "supplier": + vals["name"] = self.env["ir.sequence"].next_by_code("rma.order.supplier") else: - vals['name'] = self.env['ir.sequence'].next_by_code( - 'rma.order.customer') + vals["name"] = self.env["ir.sequence"].next_by_code("rma.order.customer") return super(RmaOrder, self).create(vals) @api.multi def action_view_in_shipments(self): - action = self.env.ref('stock.action_picking_tree_all') + action = self.env.ref("stock.action_picking_tree_all") result = action.read()[0] picking_ids = [] for line in self.rma_line_ids: for move in line.move_ids: - if move.location_dest_id.usage == 'internal': + if move.location_dest_id.usage == "internal": picking_ids.append(move.picking_id.id) else: if line.customer_to_supplier: @@ -191,32 +200,32 @@ class RmaOrder(models.Model): shipments = list(set(picking_ids)) # choose the view_mode accordingly if len(shipments) > 1: - result['domain'] = [('id', 'in', shipments)] + result["domain"] = [("id", "in", shipments)] else: - res = self.env.ref('stock.view_picking_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = shipments[0] + res = self.env.ref("stock.view_picking_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = shipments[0] return result @api.multi def action_view_out_shipments(self): - action = self.env.ref('stock.action_picking_tree_all') + action = self.env.ref("stock.action_picking_tree_all") result = action.read()[0] picking_ids = [] for line in self.rma_line_ids: for move in line.move_ids: - if move.location_dest_id.usage in ('supplier', 'customer'): + if move.location_dest_id.usage in ("supplier", "customer"): if not line.customer_to_supplier: picking_ids.append(move.picking_id.id) if picking_ids: shipments = list(set(picking_ids)) # choose the view_mode accordingly if len(shipments) != 1: - result['domain'] = [('id', 'in', shipments)] + result["domain"] = [("id", "in", shipments)] else: - res = self.env.ref('stock.view_picking_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = shipments[0] + res = self.env.ref("stock.view_picking_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = shipments[0] return result @api.multi @@ -228,56 +237,65 @@ class RmaOrder(models.Model): @api.multi def action_view_lines(self): - if self.type == 'customer': - action = self.env.ref('rma.action_rma_customer_lines') - res = self.env.ref('rma.view_rma_line_form', False) + if self.type == "customer": + action = self.env.ref("rma.action_rma_customer_lines") + res = self.env.ref("rma.view_rma_line_form", False) else: - action = self.env.ref('rma.action_rma_supplier_lines') - res = self.env.ref('rma.view_rma_line_supplier_form', False) + action = self.env.ref("rma.action_rma_supplier_lines") + res = self.env.ref("rma.view_rma_line_supplier_form", False) result = action.read()[0] lines = self._get_valid_lines() # choose the view_mode accordingly if len(lines.ids) != 1: - result['domain'] = [('id', 'in', lines.ids)] + result["domain"] = [("id", "in", lines.ids)] else: - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = lines.id - result['context'] = {} + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = lines.id + result["context"] = {} return result @api.multi def action_view_supplier_lines(self): - action = self.env.ref('rma.action_rma_supplier_lines') + action = self.env.ref("rma.action_rma_supplier_lines") result = action.read()[0] lines = self.rma_line_ids for line_id in lines: related_lines = [line.id for line in line_id.supplier_rma_line_ids] # choose the view_mode accordingly if len(related_lines) != 1: - result['domain'] = [('id', 'in', related_lines)] + result["domain"] = [("id", "in", related_lines)] else: - res = self.env.ref('rma.view_rma_line_supplier_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = related_lines[0] + res = self.env.ref("rma.view_rma_line_supplier_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = related_lines[0] return result - @api.onchange('in_warehouse_id') + @api.onchange("in_warehouse_id") def _onchange_in_warehouse_id(self): if self.in_warehouse_id and self.rma_line_ids: self.rma_line_ids.write( - {'in_warehouse_id': self.in_warehouse_id.id, - 'location_id': self.in_warehouse_id.lot_rma_id.id}) + { + "in_warehouse_id": self.in_warehouse_id.id, + "location_id": self.in_warehouse_id.lot_rma_id.id, + } + ) - @api.onchange('customer_to_supplier', 'supplier_address_id') + @api.onchange("customer_to_supplier", "supplier_address_id") def _onchange_customer_to_supplier(self): - if self.type == 'customer' and self.rma_line_ids: + if self.type == "customer" and self.rma_line_ids: self.rma_line_ids.write( - {'customer_to_supplier': self.customer_to_supplier, - 'supplier_address_id': self.supplier_address_id.id}) + { + "customer_to_supplier": self.customer_to_supplier, + "supplier_address_id": self.supplier_address_id.id, + } + ) - @api.onchange('supplier_to_customer', 'customer_address_id') + @api.onchange("supplier_to_customer", "customer_address_id") def _onchange_supplier_to_customer(self): - if self.type == 'supplier' and self.rma_line_ids: + if self.type == "supplier" and self.rma_line_ids: self.rma_line_ids.write( - {'supplier_to_customer': self.supplier_to_customer, - 'customer_address_id': self.customer_address_id.id}) + { + "supplier_to_customer": self.supplier_to_customer, + "customer_address_id": self.customer_address_id.id, + } + ) diff --git a/rma/models/rma_order_line.py b/rma/models/rma_order_line.py index 33bcb493..da083544 100644 --- a/rma/models/rma_order_line.py +++ b/rma/models/rma_order_line.py @@ -1,33 +1,36 @@ # Copyright (C) 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, fields, models, _ -from odoo.exceptions import ValidationError, UserError -from odoo.addons import decimal_precision as dp import operator -ops = {'=': operator.eq, - '!=': operator.ne} + +from odoo import _, api, fields, models +from odoo.exceptions import UserError, ValidationError + +from odoo.addons import decimal_precision as dp + +ops = {"=": operator.eq, "!=": operator.ne} class RmaOrderLine(models.Model): _name = "rma.order.line" - _description = 'RMA' - _inherit = ['mail.thread'] + _description = "RMA" + _inherit = ["mail.thread"] @api.model def _get_default_type(self): - if 'supplier' in self.env.context: + if "supplier" in self.env.context: return "supplier" return "customer" @api.model def _default_warehouse_id(self): - rma_id = self.env.context.get('default_rma_id', False) - warehouse = self.env['stock.warehouse'] + rma_id = self.env.context.get("default_rma_id", False) + warehouse = self.env["stock.warehouse"] if rma_id: - rma = self.env['rma.order'].browse(rma_id) - warehouse = self.env['stock.warehouse'].search( - [('company_id', '=', rma.company_id.id)], limit=1) + rma = self.env["rma.order"].browse(rma_id) + warehouse = self.env["stock.warehouse"].search( + [("company_id", "=", rma.company_id.id)], limit=1 + ) return warehouse @api.model @@ -37,11 +40,11 @@ class RmaOrderLine(models.Model): @api.model def _default_delivery_address(self): - partner_id = self.env.context.get('partner_id', False) + partner_id = self.env.context.get("partner_id", False) if partner_id: - partner = self.env['res.partner'].browse(partner_id) - addr = partner.address_get(['delivery']) - return self.env['res.partner'].browse(addr['delivery']) + partner = self.env["res.partner"].browse(partner_id) + addr = partner.address_get(["delivery"]) + return self.env["res.partner"].browse(addr["delivery"]) return False @api.multi @@ -49,7 +52,7 @@ class RmaOrderLine(models.Model): for line in self: picking_ids = [] for move in line.move_ids: - if move.location_dest_id.usage == 'internal': + if move.location_dest_id.usage == "internal": picking_ids.append(move.picking_id.id) else: if line.customer_to_supplier: @@ -62,93 +65,113 @@ class RmaOrderLine(models.Model): picking_ids = [] for line in self: for move in line.move_ids: - if move.location_dest_id.usage in ('supplier', 'customer'): + if move.location_dest_id.usage in ("supplier", "customer"): if not line.customer_to_supplier: picking_ids.append(move.picking_id.id) shipments = list(set(picking_ids)) line.out_shipment_count = len(shipments) @api.multi - def _get_rma_move_qty(self, states, direction='in'): + def _get_rma_move_qty(self, states, direction="in"): for rec in self: - product_obj = self.env['uom.uom'] + product_obj = self.env["uom.uom"] qty = 0.0 - if direction == 'in': - op = ops['='] + if direction == "in": + op = ops["="] else: - op = ops['!='] + op = ops["!="] for move in rec.move_ids.filtered( - lambda m: m.state in states and op(m.location_id.usage, - rec.type)): - qty += product_obj._compute_quantity( - move.product_uom_qty, rec.uom_id) + lambda m: m.state in states and op(m.location_id.usage, rec.type) + ): + qty += product_obj._compute_quantity(move.product_uom_qty, rec.uom_id) return qty @api.multi - @api.depends('move_ids', 'move_ids.state', 'qty_received', - 'receipt_policy', 'product_qty', 'type') + @api.depends( + "move_ids", + "move_ids.state", + "qty_received", + "receipt_policy", + "product_qty", + "type", + ) def _compute_qty_to_receive(self): for rec in self: rec.qty_to_receive = 0.0 - if rec.receipt_policy == 'ordered': - rec.qty_to_receive = \ - rec.product_qty - rec.qty_received - elif rec.receipt_policy == 'delivered': - rec.qty_to_receive = \ - rec.qty_delivered - rec.qty_received + if rec.receipt_policy == "ordered": + rec.qty_to_receive = rec.product_qty - rec.qty_received + elif rec.receipt_policy == "delivered": + rec.qty_to_receive = rec.qty_delivered - rec.qty_received @api.multi - @api.depends('move_ids', 'move_ids.state', - 'delivery_policy', 'product_qty', 'type', 'qty_delivered', - 'qty_received') + @api.depends( + "move_ids", + "move_ids.state", + "delivery_policy", + "product_qty", + "type", + "qty_delivered", + "qty_received", + ) def _compute_qty_to_deliver(self): for rec in self: rec.qty_to_deliver = 0.0 - if rec.delivery_policy == 'ordered': + if rec.delivery_policy == "ordered": rec.qty_to_deliver = rec.product_qty - rec.qty_delivered - elif rec.delivery_policy == 'received': + elif rec.delivery_policy == "received": rec.qty_to_deliver = rec.qty_received - rec.qty_delivered @api.multi - @api.depends('move_ids', 'move_ids.state', 'type') + @api.depends("move_ids", "move_ids.state", "type") def _compute_qty_incoming(self): for rec in self: qty = rec._get_rma_move_qty( - ('draft', 'confirmed', 'assigned'), direction='in') + ("draft", "confirmed", "assigned"), direction="in" + ) rec.qty_incoming = qty @api.multi - @api.depends('move_ids', 'move_ids.state', 'type') + @api.depends("move_ids", "move_ids.state", "type") def _compute_qty_received(self): for rec in self: - qty = rec._get_rma_move_qty('done', direction='in') + qty = rec._get_rma_move_qty("done", direction="in") rec.qty_received = qty @api.multi - @api.depends('move_ids', 'move_ids.state', 'type') + @api.depends("move_ids", "move_ids.state", "type") def _compute_qty_outgoing(self): for rec in self: qty = rec._get_rma_move_qty( - ('draft', 'confirmed', 'assigned'), direction='out') + ("draft", "confirmed", "assigned"), direction="out" + ) rec.qty_outgoing = qty @api.multi - @api.depends('move_ids', 'move_ids.state', 'type') + @api.depends("move_ids", "move_ids.state", "type") def _compute_qty_delivered(self): for rec in self: - qty = rec._get_rma_move_qty('done', direction='out') + qty = rec._get_rma_move_qty("done", direction="out") rec.qty_delivered = qty @api.model def _get_supplier_rma_qty(self): - return sum(self.supplier_rma_line_ids.filtered( - lambda r: r.state != 'cancel').mapped( - 'product_qty')) + return sum( + self.supplier_rma_line_ids.filtered(lambda r: r.state != "cancel").mapped( + "product_qty" + ) + ) @api.multi - @api.depends('customer_to_supplier', 'supplier_rma_line_ids', - 'move_ids', 'move_ids.state', 'qty_received', - 'receipt_policy', 'product_qty', 'type') + @api.depends( + "customer_to_supplier", + "supplier_rma_line_ids", + "move_ids", + "move_ids.state", + "qty_received", + "receipt_policy", + "product_qty", + "type", + ) def _compute_qty_supplier_rma(self): for rec in self: if rec.customer_to_supplier: @@ -161,277 +184,366 @@ class RmaOrderLine(models.Model): @api.multi def _compute_rma_line_count(self): - for rec in self.filtered(lambda r: r.type == 'customer'): + for rec in self.filtered(lambda r: r.type == "customer"): rec.rma_line_count = len(rec.supplier_rma_line_ids) - for rec in self.filtered(lambda r: r.type == 'supplier'): + for rec in self.filtered(lambda r: r.type == "supplier"): rec.rma_line_count = len(rec.customer_rma_id) delivery_address_id = fields.Many2one( - comodel_name='res.partner', string='Partner delivery address', + comodel_name="res.partner", + string="Partner delivery address", default=lambda self: self._default_delivery_address(), - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, help="This address will be used to deliver repaired or replacement " - "products.", + "products.", ) rma_id = fields.Many2one( - comodel_name='rma.order', string='RMA Group', - track_visibility='onchange', readonly=True, + comodel_name="rma.order", + string="RMA Group", + track_visibility="onchange", + readonly=True, ) name = fields.Char( - string='Reference', required=True, default='/', - readonly=True, states={'draft': [('readonly', False)]}, - help='Add here the supplier RMA #. Otherwise an internal code is' - ' assigned.', copy=False + string="Reference", + required=True, + default="/", + readonly=True, + states={"draft": [("readonly", False)]}, + help="Add here the supplier RMA #. Otherwise an internal code is" " assigned.", + copy=False, ) - description = fields.Text(string='Description') - conditions = fields.Html(string='Terms and conditions') + description = fields.Text(string="Description") + conditions = fields.Html(string="Terms and conditions") origin = fields.Char( - string='Source Document', - readonly=True, states={'draft': [('readonly', False)]}, - help="Reference of the document that produced this rma.") + string="Source Document", + readonly=True, + states={"draft": [("readonly", False)]}, + help="Reference of the document that produced this rma.", + ) state = fields.Selection( - selection=[('draft', 'Draft'), - ('to_approve', 'To Approve'), - ('approved', 'Approved'), - ('done', 'Done')], - string='State', default='draft', - track_visibility='onchange', + selection=[ + ("draft", "Draft"), + ("to_approve", "To Approve"), + ("approved", "Approved"), + ("done", "Done"), + ], + string="State", + default="draft", + track_visibility="onchange", ) operation_id = fields.Many2one( - comodel_name="rma.operation", string="Operation", - readonly=True, states={'draft': [('readonly', False)]}, + comodel_name="rma.operation", + string="Operation", + readonly=True, + states={"draft": [("readonly", False)]}, ) assigned_to = fields.Many2one( - comodel_name='res.users', track_visibility='onchange', + comodel_name="res.users", + track_visibility="onchange", default=lambda self: self.env.uid, ) requested_by = fields.Many2one( - comodel_name='res.users', track_visibility='onchange', + comodel_name="res.users", + track_visibility="onchange", default=lambda self: self.env.uid, ) partner_id = fields.Many2one( - comodel_name='res.partner', required=True, store=True, - track_visibility='onchange', + comodel_name="res.partner", + required=True, + store=True, + track_visibility="onchange", string="Partner", - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, ) sequence = fields.Integer( - default=10, - help="Gives the sequence of this line when displaying the rma.") + default=10, help="Gives the sequence of this line when displaying the rma." + ) product_id = fields.Many2one( - comodel_name='product.product', string='Product', - ondelete='restrict', required=True, - readonly=True, states={'draft': [('readonly', False)]}, + comodel_name="product.product", + string="Product", + ondelete="restrict", + required=True, + readonly=True, + states={"draft": [("readonly", False)]}, ) product_tracking = fields.Selection(related="product_id.tracking") lot_id = fields.Many2one( - comodel_name="stock.production.lot", string="Lot/Serial Number", - readonly=True, states={"draft": [("readonly", False)]}, + comodel_name="stock.production.lot", + string="Lot/Serial Number", + readonly=True, + states={"draft": [("readonly", False)]}, ) product_qty = fields.Float( - string='Return Qty', copy=False, default=1.0, - digits=dp.get_precision('Product Unit of Measure'), - readonly=True, states={'draft': [('readonly', False)]}, + string="Return Qty", + copy=False, + default=1.0, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + states={"draft": [("readonly", False)]}, ) uom_id = fields.Many2one( - comodel_name='uom.uom', string='Unit of Measure', + comodel_name="uom.uom", + string="Unit of Measure", required=True, - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, ) price_unit = fields.Monetary( - string='Price Unit', - readonly=True, states={'draft': [('readonly', False)]}, + string="Price Unit", readonly=True, states={"draft": [("readonly", False)]} + ) + in_shipment_count = fields.Integer( + compute="_compute_in_shipment_count", string="# of Shipments" + ) + out_shipment_count = fields.Integer( + compute="_compute_out_shipment_count", string="# of Deliveries" + ) + move_ids = fields.One2many( + "stock.move", "rma_line_id", string="Stock Moves", readonly=True, copy=False ) - in_shipment_count = fields.Integer(compute='_compute_in_shipment_count', - string='# of Shipments') - out_shipment_count = fields.Integer(compute='_compute_out_shipment_count', - string='# of Deliveries') - move_ids = fields.One2many('stock.move', 'rma_line_id', - string='Stock Moves', readonly=True, - copy=False) reference_move_id = fields.Many2one( - comodel_name='stock.move', string='Originating Stock Move', + comodel_name="stock.move", + string="Originating Stock Move", copy=False, - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, ) - currency_id = fields.Many2one('res.currency', string="Currency") + currency_id = fields.Many2one("res.currency", string="Currency") company_id = fields.Many2one( - comodel_name='res.company', string='Company', required=True, - default=lambda self: self.env.user.company_id) + comodel_name="res.company", + string="Company", + required=True, + default=lambda self: self.env.user.company_id, + ) type = fields.Selection( - selection=[('customer', 'Customer'), ('supplier', 'Supplier')], - string="Type", required=True, + selection=[("customer", "Customer"), ("supplier", "Supplier")], + string="Type", + required=True, default=lambda self: self._get_default_type(), readonly=True, ) customer_to_supplier = fields.Boolean( - 'The customer will send to the supplier', - readonly=True, states={'draft': [('readonly', False)]}, + "The customer will send to the supplier", + readonly=True, + states={"draft": [("readonly", False)]}, ) supplier_to_customer = fields.Boolean( - 'The supplier will send to the customer', - readonly=True, states={'draft': [('readonly', False)]}, + "The supplier will send to the customer", + readonly=True, + states={"draft": [("readonly", False)]}, ) - receipt_policy = fields.Selection([ - ('no', 'Not required'), ('ordered', 'Based on Ordered Quantities'), - ('delivered', 'Based on Delivered Quantities')], - required=True, string="Receipts Policy", default='no', - readonly=True, states={'draft': [('readonly', False)]}, + receipt_policy = fields.Selection( + [ + ("no", "Not required"), + ("ordered", "Based on Ordered Quantities"), + ("delivered", "Based on Delivered Quantities"), + ], + required=True, + string="Receipts Policy", + default="no", + readonly=True, + states={"draft": [("readonly", False)]}, ) - delivery_policy = fields.Selection([ - ('no', 'Not required'), ('ordered', 'Based on Ordered Quantities'), - ('received', 'Based on Received Quantities')], required=True, - string="Delivery Policy", default='no', - readonly=True, states={'draft': [('readonly', False)]}, + delivery_policy = fields.Selection( + [ + ("no", "Not required"), + ("ordered", "Based on Ordered Quantities"), + ("received", "Based on Received Quantities"), + ], + required=True, + string="Delivery Policy", + default="no", + readonly=True, + states={"draft": [("readonly", False)]}, ) in_route_id = fields.Many2one( - 'stock.location.route', string='Inbound Route', + "stock.location.route", + string="Inbound Route", required=True, - domain=[('rma_selectable', '=', True)], - readonly=True, states={'draft': [('readonly', False)]}, + domain=[("rma_selectable", "=", True)], + readonly=True, + states={"draft": [("readonly", False)]}, ) out_route_id = fields.Many2one( - 'stock.location.route', string='Outbound Route', + "stock.location.route", + string="Outbound Route", required=True, - domain=[('rma_selectable', '=', True)], - readonly=True, states={'draft': [('readonly', False)]}, + domain=[("rma_selectable", "=", True)], + readonly=True, + states={"draft": [("readonly", False)]}, ) in_warehouse_id = fields.Many2one( - comodel_name='stock.warehouse', - string='Inbound Warehouse', + comodel_name="stock.warehouse", + string="Inbound Warehouse", required=True, - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, default=lambda self: self._default_warehouse_id(), ) out_warehouse_id = fields.Many2one( - comodel_name='stock.warehouse', string='Outbound Warehouse', + comodel_name="stock.warehouse", + string="Outbound Warehouse", required=True, - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, default=lambda self: self._default_warehouse_id(), ) location_id = fields.Many2one( - comodel_name='stock.location', string='Send To This Company Location', + comodel_name="stock.location", + string="Send To This Company Location", required=True, - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, default=lambda self: self._default_location_id(), ) customer_rma_id = fields.Many2one( - 'rma.order.line', string='Customer RMA line', ondelete='cascade') - supplier_rma_line_ids = fields.One2many( - 'rma.order.line', 'customer_rma_id') + "rma.order.line", string="Customer RMA line", ondelete="cascade" + ) + supplier_rma_line_ids = fields.One2many("rma.order.line", "customer_rma_id") rma_line_count = fields.Integer( - compute='_compute_rma_line_count', - string='# of RMA lines associated', + compute="_compute_rma_line_count", string="# of RMA lines associated" ) supplier_address_id = fields.Many2one( - comodel_name='res.partner', readonly=True, - states={'draft': [('readonly', False)]}, - string='Supplier Address', - help="Address of the supplier in case of Customer RMA operation " - "dropship.") + comodel_name="res.partner", + readonly=True, + states={"draft": [("readonly", False)]}, + string="Supplier Address", + help="Address of the supplier in case of Customer RMA operation " "dropship.", + ) customer_address_id = fields.Many2one( - comodel_name='res.partner', readonly=True, - states={'draft': [('readonly', False)]}, - string='Customer Address', - help="Address of the customer in case of Supplier RMA operation " - "dropship.") + comodel_name="res.partner", + readonly=True, + states={"draft": [("readonly", False)]}, + string="Customer Address", + help="Address of the customer in case of Supplier RMA operation " "dropship.", + ) qty_to_receive = fields.Float( - string='Qty To Receive', - digits=dp.get_precision('Product Unit of Measure'), - compute='_compute_qty_to_receive', store=True) + string="Qty To Receive", + digits=dp.get_precision("Product Unit of Measure"), + compute="_compute_qty_to_receive", + store=True, + ) qty_incoming = fields.Float( - string='Incoming Qty', copy=False, - readonly=True, digits=dp.get_precision('Product Unit of Measure'), - compute='_compute_qty_incoming', store=True) + string="Incoming Qty", + copy=False, + readonly=True, + digits=dp.get_precision("Product Unit of Measure"), + compute="_compute_qty_incoming", + store=True, + ) qty_received = fields.Float( - string='Qty Received', copy=False, - digits=dp.get_precision('Product Unit of Measure'), - compute='_compute_qty_received', - store=True) + string="Qty Received", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + compute="_compute_qty_received", + store=True, + ) qty_to_deliver = fields.Float( - string='Qty To Deliver', copy=False, - digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute='_compute_qty_to_deliver', - store=True) + string="Qty To Deliver", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty_to_deliver", + store=True, + ) qty_outgoing = fields.Float( - string='Outgoing Qty', copy=False, - readonly=True, digits=dp.get_precision('Product Unit of Measure'), - compute='_compute_qty_outgoing', - store=True) + string="Outgoing Qty", + copy=False, + readonly=True, + digits=dp.get_precision("Product Unit of Measure"), + compute="_compute_qty_outgoing", + store=True, + ) qty_delivered = fields.Float( - string='Qty Delivered', copy=False, - digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute='_compute_qty_delivered', - store=True) + string="Qty Delivered", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty_delivered", + store=True, + ) qty_to_supplier_rma = fields.Float( - string='Qty to send to Supplier RMA', - digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute='_compute_qty_supplier_rma', - store=True) + string="Qty to send to Supplier RMA", + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty_supplier_rma", + store=True, + ) qty_in_supplier_rma = fields.Float( - string='Qty in Supplier RMA', - digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute='_compute_qty_supplier_rma', - store=True) + string="Qty in Supplier RMA", + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty_supplier_rma", + store=True, + ) under_warranty = fields.Boolean( - string="Under Warranty?", - readonly=True, states={'draft': [('readonly', False)]}, + string="Under Warranty?", readonly=True, states={"draft": [("readonly", False)]} ) @api.multi def _prepare_rma_line_from_stock_move(self, sm, lot=False): if not self.type: self.type = self._get_default_type() - if self.type == 'customer': - operation = sm.product_id.rma_customer_operation_id or \ - sm.product_id.categ_id.rma_customer_operation_id + if self.type == "customer": + operation = ( + sm.product_id.rma_customer_operation_id + or sm.product_id.categ_id.rma_customer_operation_id + ) else: - operation = sm.product_id.rma_supplier_operation_id or \ - sm.product_id.categ_id.rma_supplier_operation_id + operation = ( + sm.product_id.rma_supplier_operation_id + or sm.product_id.categ_id.rma_supplier_operation_id + ) if not operation: - operation = self.env['rma.operation'].search( - [('type', '=', self.type)], limit=1) + operation = self.env["rma.operation"].search( + [("type", "=", self.type)], limit=1 + ) if not operation: raise ValidationError(_("Please define an operation first.")) if not operation.in_route_id or not operation.out_route_id: - route = self.env['stock.location.route'].search( - [('rma_selectable', '=', True)], limit=1) + route = self.env["stock.location.route"].search( + [("rma_selectable", "=", True)], limit=1 + ) if not route: raise ValidationError(_("Please define an RMA route.")) if not operation.in_warehouse_id or not operation.out_warehouse_id: - warehouse = self.env['stock.warehouse'].search( - [('company_id', '=', self.company_id.id), - ('lot_rma_id', '!=', False)], limit=1) + warehouse = self.env["stock.warehouse"].search( + [("company_id", "=", self.company_id.id), ("lot_rma_id", "!=", False)], + limit=1, + ) if not warehouse: raise ValidationError( - _("Please define a warehouse with a default RMA " - "location.")) + _("Please define a warehouse with a default RMA " "location.") + ) data = { - 'product_id': sm.product_id.id, - 'lot_id': lot and lot.id or False, - 'origin': sm.picking_id.name or sm.name, - 'uom_id': sm.product_uom.id, - 'product_qty': sm.product_uom_qty, - 'delivery_address_id': sm.picking_id.partner_id.id, - 'operation_id': operation.id, - 'receipt_policy': operation.receipt_policy, - 'delivery_policy': operation.delivery_policy, - 'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, - 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, - 'in_route_id': operation.in_route_id.id or route.id, - 'out_route_id': operation.out_route_id.id or route.id, - 'location_id': (operation.location_id.id or - operation.in_warehouse_id.lot_rma_id.id or - warehouse.lot_rma_id.id) + "product_id": sm.product_id.id, + "lot_id": lot and lot.id or False, + "origin": sm.picking_id.name or sm.name, + "uom_id": sm.product_uom.id, + "product_qty": sm.product_uom_qty, + "delivery_address_id": sm.picking_id.partner_id.id, + "operation_id": operation.id, + "receipt_policy": operation.receipt_policy, + "delivery_policy": operation.delivery_policy, + "in_warehouse_id": operation.in_warehouse_id.id or warehouse.id, + "out_warehouse_id": operation.out_warehouse_id.id or warehouse.id, + "in_route_id": operation.in_route_id.id or route.id, + "out_route_id": operation.out_route_id.id or route.id, + "location_id": ( + operation.location_id.id + or operation.in_warehouse_id.lot_rma_id.id + or warehouse.lot_rma_id.id + ), } return data @api.multi - @api.onchange('reference_move_id') + @api.onchange("reference_move_id") def _onchange_reference_move_id(self): self.ensure_one() sm = self.reference_move_id @@ -439,72 +551,77 @@ class RmaOrderLine(models.Model): return if sm.move_line_ids.lot_id: if len(sm.move_line_ids.lot_id) > 1: - raise UserError(_('To manage lots use RMA groups.')) + raise UserError(_("To manage lots use RMA groups.")) else: data = self._prepare_rma_line_from_stock_move( - sm, lot=sm.move_line_ids.lot_id[0]) + sm, lot=sm.move_line_ids.lot_id[0] + ) self.update(data) else: - data = self._prepare_rma_line_from_stock_move( - sm, lot=False) + data = self._prepare_rma_line_from_stock_move(sm, lot=False) self.update(data) - self._remove_other_data_origin('reference_move_id') + self._remove_other_data_origin("reference_move_id") @api.multi - @api.constrains('reference_move_id', 'partner_id') + @api.constrains("reference_move_id", "partner_id") def _check_move_partner(self): for rec in self: - if (rec.reference_move_id and - rec.reference_move_id.picking_id.partner_id != - rec.partner_id): - raise ValidationError(_( - "RMA customer and originating stock move customer " - "doesn't match.")) + if ( + rec.reference_move_id + and rec.reference_move_id.picking_id.partner_id != rec.partner_id + ): + raise ValidationError( + _( + "RMA customer and originating stock move customer " + "doesn't match." + ) + ) @api.multi def _remove_other_data_origin(self, exception): - if not exception == 'reference_move_id': + if not exception == "reference_move_id": self.reference_move_id = False return True @api.multi def action_rma_to_approve(self): - self.write({'state': 'to_approve'}) + self.write({"state": "to_approve"}) for rec in self: - if rec.product_id.rma_approval_policy == 'one_step': + if rec.product_id.rma_approval_policy == "one_step": rec.action_rma_approve() return True @api.multi def action_rma_draft(self): if self.in_shipment_count or self.out_shipment_count: - raise UserError(_( - "You cannot reset to draft a RMA with related pickings.")) - self.write({'state': 'draft'}) + raise UserError(_("You cannot reset to draft a RMA with related pickings.")) + self.write({"state": "draft"}) return True @api.multi def action_rma_approve(self): - self.write({'state': 'approved'}) + self.write({"state": "approved"}) return True @api.multi def action_rma_done(self): - self.write({'state': 'done'}) + self.write({"state": "done"}) return True @api.model def create(self, vals): - if not vals.get('name') or vals.get('name') == '/': - if self.env.context.get('supplier'): - vals['name'] = self.env['ir.sequence'].next_by_code( - 'rma.order.line.supplier') + if not vals.get("name") or vals.get("name") == "/": + if self.env.context.get("supplier"): + vals["name"] = self.env["ir.sequence"].next_by_code( + "rma.order.line.supplier" + ) else: - vals['name'] = self.env['ir.sequence'].next_by_code( - 'rma.order.line.customer') + vals["name"] = self.env["ir.sequence"].next_by_code( + "rma.order.line.customer" + ) return super(RmaOrderLine, self).create(vals) - @api.onchange('product_id') + @api.onchange("product_id") def _onchange_product_id(self): result = {} if not self.product_id: @@ -513,18 +630,21 @@ class RmaOrderLine(models.Model): self.price_unit = self.product_id.standard_price if not self.type: self.type = self._get_default_type() - if self.type == 'customer': - self.operation_id = self.product_id.rma_customer_operation_id or \ - self.product_id.categ_id.rma_customer_operation_id + if self.type == "customer": + self.operation_id = ( + self.product_id.rma_customer_operation_id + or self.product_id.categ_id.rma_customer_operation_id + ) else: - self.operation_id = self.product_id.rma_supplier_operation_id or \ - self.product_id.categ_id.rma_supplier_operation_id + self.operation_id = ( + self.product_id.rma_supplier_operation_id + or self.product_id.categ_id.rma_supplier_operation_id + ) if self.lot_id.product_id != self.product_id: self.lot_id = False - return {'domain': { - 'lot_id': [('product_id', '=', self.product_id.id)]}} + return {"domain": {"lot_id": [("product_id", "=", self.product_id.id)]}} - @api.onchange('operation_id') + @api.onchange("operation_id") def _onchange_operation_id(self): result = {} if not self.operation_id: @@ -533,20 +653,21 @@ class RmaOrderLine(models.Model): self.delivery_policy = self.operation_id.delivery_policy self.in_warehouse_id = self.operation_id.in_warehouse_id self.out_warehouse_id = self.operation_id.out_warehouse_id - self.location_id = self.operation_id.location_id or \ - self.in_warehouse_id.lot_rma_id + self.location_id = ( + self.operation_id.location_id or self.in_warehouse_id.lot_rma_id + ) self.customer_to_supplier = self.operation_id.customer_to_supplier self.supplier_to_customer = self.operation_id.supplier_to_customer self.in_route_id = self.operation_id.in_route_id self.out_route_id = self.operation_id.out_route_id return result - @api.onchange('customer_to_supplier', 'type') + @api.onchange("customer_to_supplier", "type") def _onchange_receipt_policy(self): - if self.type == 'supplier' and self.customer_to_supplier: - self.receipt_policy = 'no' - elif self.type == 'customer' and self.supplier_to_customer: - self.delivery_policy = 'no' + if self.type == "supplier" and self.customer_to_supplier: + self.receipt_policy = "no" + elif self.type == "customer" and self.supplier_to_customer: + self.delivery_policy = "no" @api.onchange("lot_id") def _onchange_lot_id(self): @@ -557,12 +678,12 @@ class RmaOrderLine(models.Model): @api.multi def action_view_in_shipments(self): - action = self.env.ref('stock.action_picking_tree_all') + action = self.env.ref("stock.action_picking_tree_all") result = action.read()[0] picking_ids = [] for line in self: for move in line.move_ids: - if move.location_dest_id.usage == 'internal': + if move.location_dest_id.usage == "internal": picking_ids.append(move.picking_id.id) else: if line.customer_to_supplier: @@ -571,60 +692,57 @@ class RmaOrderLine(models.Model): shipments = list(set(picking_ids)) # choose the view_mode accordingly if len(shipments) != 1: - result['domain'] = "[('id', 'in', " + \ - str(shipments) + ")]" + result["domain"] = "[('id', 'in', " + str(shipments) + ")]" elif len(shipments) == 1: - res = self.env.ref('stock.view_picking_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = shipments[0] + res = self.env.ref("stock.view_picking_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = shipments[0] return result @api.multi def action_view_out_shipments(self): - action = self.env.ref('stock.action_picking_tree_all') + action = self.env.ref("stock.action_picking_tree_all") result = action.read()[0] picking_ids = [] for line in self: for move in line.move_ids: - if move.location_dest_id.usage in ('supplier', 'customer'): + if move.location_dest_id.usage in ("supplier", "customer"): if not line.customer_to_supplier: picking_ids.append(move.picking_id.id) shipments = list(set(picking_ids)) # choose the view_mode accordingly if len(shipments) != 1: - result['domain'] = "[('id', 'in', " + \ - str(shipments) + ")]" + result["domain"] = "[('id', 'in', " + str(shipments) + ")]" elif len(shipments) == 1: - res = self.env.ref('stock.view_picking_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = shipments[0] + res = self.env.ref("stock.view_picking_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = shipments[0] return result @api.multi def action_view_rma_lines(self): - if self.type == 'customer': + if self.type == "customer": # from customer we link to supplier rma - action = self.env.ref( - 'rma.action_rma_supplier_lines') + action = self.env.ref("rma.action_rma_supplier_lines") rma_lines = self.supplier_rma_line_ids.ids - res = self.env.ref('rma.view_rma_line_supplier_form', False) + res = self.env.ref("rma.view_rma_line_supplier_form", False) else: # from supplier we link to customer rma - action = self.env.ref( - 'rma.action_rma_customer_lines') + action = self.env.ref("rma.action_rma_customer_lines") rma_lines = self.customer_rma_id.ids - res = self.env.ref('rma.view_rma_line_form', False) + res = self.env.ref("rma.view_rma_line_form", False) result = action.read()[0] # choose the view_mode accordingly if rma_lines and len(rma_lines) != 1: - result['domain'] = rma_lines.ids + result["domain"] = rma_lines.ids elif len(rma_lines) == 1: - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = rma_lines[0] + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = rma_lines[0] return result @api.constrains("partner_id", "rma_id") def _check_partner_id(self): if self.rma_id and self.partner_id != self.rma_id.partner_id: - raise ValidationError(_( - "Group partner and RMA's partner must be the same.")) + raise ValidationError( + _("Group partner and RMA's partner must be the same.") + ) diff --git a/rma/models/stock.py b/rma/models/stock.py index aecb0cff..38dc6243 100644 --- a/rma/models/stock.py +++ b/rma/models/stock.py @@ -15,8 +15,11 @@ class StockPicking(models.Model): res = super(StockPicking, self).action_assign() for picking in self: for move in picking.move_lines: - if (move.rma_line_id and move.state == 'confirmed' and - move.location_id.usage == 'customer'): + if ( + move.rma_line_id + and move.state == "confirmed" + and move.location_id.usage == "customer" + ): move.force_assign() return res @@ -24,15 +27,16 @@ class StockPicking(models.Model): class StockMove(models.Model): _inherit = "stock.move" - rma_line_id = fields.Many2one('rma.order.line', string='RMA line', - ondelete='restrict') + rma_line_id = fields.Many2one( + "rma.order.line", string="RMA line", ondelete="restrict" + ) @api.model def create(self, vals): - if vals.get('group_id'): - group = self.env['procurement.group'].browse(vals['group_id']) + if vals.get("group_id"): + group = self.env["procurement.group"].browse(vals["group_id"]) if group.rma_line_id: - vals['rma_line_id'] = group.rma_line_id.id + vals["rma_line_id"] = group.rma_line_id.id return super(StockMove, self).create(vals) def _action_assign(self): diff --git a/rma/models/stock_warehouse.py b/rma/models/stock_warehouse.py index 35bc9488..d69506fd 100644 --- a/rma/models/stock_warehouse.py +++ b/rma/models/stock_warehouse.py @@ -8,41 +8,37 @@ class StockWarehouse(models.Model): _inherit = "stock.warehouse" lot_rma_id = fields.Many2one( - comodel_name='stock.location', string='RMA Location', + comodel_name="stock.location", string="RMA Location" ) # not readonly to have the possibility to edit location and # propagate to rma rules (add a auto-update when writing this field?) rma_cust_out_type_id = fields.Many2one( - comodel_name='stock.picking.type', string='RMA Customer out Type', - readonly=True, + comodel_name="stock.picking.type", string="RMA Customer out Type", readonly=True ) rma_sup_out_type_id = fields.Many2one( - comodel_name='stock.picking.type', string='RMA Supplier out Type', - readonly=True, + comodel_name="stock.picking.type", string="RMA Supplier out Type", readonly=True ) rma_cust_in_type_id = fields.Many2one( - comodel_name='stock.picking.type', string='RMA Customer in Type', - readonly=True, + comodel_name="stock.picking.type", string="RMA Customer in Type", readonly=True ) rma_sup_in_type_id = fields.Many2one( - comodel_name='stock.picking.type', string='RMA Supplier in Type', - readonly=True, + comodel_name="stock.picking.type", string="RMA Supplier in Type", readonly=True ) rma_in_this_wh = fields.Boolean( - string='RMA in this Warehouse', + string="RMA in this Warehouse", help="If set, it will create RMA location, picking types and routes " - "for this warehouse.", + "for this warehouse.", ) rma_customer_in_pull_id = fields.Many2one( - comodel_name='stock.rule', string="RMA Customer In Rule", + comodel_name="stock.rule", string="RMA Customer In Rule" ) rma_customer_out_pull_id = fields.Many2one( - comodel_name='stock.rule', string="RMA Customer Out Rule", + comodel_name="stock.rule", string="RMA Customer Out Rule" ) rma_supplier_in_pull_id = fields.Many2one( - comodel_name='stock.rule', string="RMA Supplier In Rule", + comodel_name="stock.rule", string="RMA Supplier In Rule" ) rma_supplier_out_pull_id = fields.Many2one( - comodel_name='stock.rule', string="RMA Supplier Out Rule", + comodel_name="stock.rule", string="RMA Supplier Out Rule" ) @api.multi @@ -51,7 +47,8 @@ class StockWarehouse(models.Model): self.rma_cust_out_type_id, self.rma_sup_out_type_id, self.rma_cust_in_type_id, - self.rma_sup_in_type_id] + self.rma_sup_in_type_id, + ] @api.multi def _rma_types_available(self): @@ -64,17 +61,19 @@ class StockWarehouse(models.Model): @api.multi def write(self, vals): - if 'rma_in_this_wh' in vals: + if "rma_in_this_wh" in vals: if vals.get("rma_in_this_wh"): for wh in self: # RMA location: if not wh.lot_rma_id: - wh.lot_rma_id = self.env['stock.location'].create({ - 'name': 'RMA', - 'usage': 'internal', - 'location_id': wh.lot_stock_id.id, - 'company_id': wh.company_id.id, - }) + wh.lot_rma_id = self.env["stock.location"].create( + { + "name": "RMA", + "usage": "internal", + "location_id": wh.lot_stock_id.id, + "company_id": wh.company_id.id, + } + ) # RMA types if not wh._rma_types_available(): wh._create_rma_picking_types() @@ -90,83 +89,89 @@ class StockWarehouse(models.Model): if type: type.active = False # Unlink rules: - self.mapped('rma_customer_in_pull_id').unlink() - self.mapped('rma_customer_out_pull_id').unlink() - self.mapped('rma_supplier_in_pull_id').unlink() - self.mapped('rma_supplier_out_pull_id').unlink() + self.mapped("rma_customer_in_pull_id").unlink() + self.mapped("rma_customer_out_pull_id").unlink() + self.mapped("rma_supplier_in_pull_id").unlink() + self.mapped("rma_supplier_out_pull_id").unlink() return super(StockWarehouse, self).write(vals) def _create_rma_picking_types(self): - picking_type_obj = self.env['stock.picking.type'] + picking_type_obj = self.env["stock.picking.type"] customer_loc, supplier_loc = self._get_partner_locations() for wh in self: other_pick_type = picking_type_obj.search( - [('warehouse_id', '=', wh.id)], order='sequence desc', - limit=1) + [("warehouse_id", "=", wh.id)], order="sequence desc", limit=1 + ) color = other_pick_type.color if other_pick_type else 0 max_sequence = other_pick_type and other_pick_type.sequence or 0 # create rma_cust_out_type_id: - rma_cust_out_type_id = picking_type_obj.create({ - 'name': _('Customer RMA Deliveries'), - 'warehouse_id': wh.id, - 'code': 'outgoing', - 'use_create_lots': True, - 'use_existing_lots': False, - 'sequence_id': self.env.ref( - 'rma.seq_picking_type_rma_cust_out').id, - 'default_location_src_id': wh.lot_rma_id.id, - 'default_location_dest_id': customer_loc.id, - 'sequence': max_sequence, - 'color': color, - }) + rma_cust_out_type_id = picking_type_obj.create( + { + "name": _("Customer RMA Deliveries"), + "warehouse_id": wh.id, + "code": "outgoing", + "use_create_lots": True, + "use_existing_lots": False, + "sequence_id": self.env.ref("rma.seq_picking_type_rma_cust_out").id, + "default_location_src_id": wh.lot_rma_id.id, + "default_location_dest_id": customer_loc.id, + "sequence": max_sequence, + "color": color, + } + ) # create rma_sup_out_type_id: - rma_sup_out_type_id = picking_type_obj.create({ - 'name': _('Supplier RMA Deliveries'), - 'warehouse_id': wh.id, - 'code': 'outgoing', - 'use_create_lots': True, - 'use_existing_lots': False, - 'sequence_id': self.env.ref( - 'rma.seq_picking_type_rma_sup_out').id, - 'default_location_src_id': wh.lot_rma_id.id, - 'default_location_dest_id': supplier_loc.id, - 'sequence': max_sequence, - 'color': color, - }) + rma_sup_out_type_id = picking_type_obj.create( + { + "name": _("Supplier RMA Deliveries"), + "warehouse_id": wh.id, + "code": "outgoing", + "use_create_lots": True, + "use_existing_lots": False, + "sequence_id": self.env.ref("rma.seq_picking_type_rma_sup_out").id, + "default_location_src_id": wh.lot_rma_id.id, + "default_location_dest_id": supplier_loc.id, + "sequence": max_sequence, + "color": color, + } + ) # create rma_cust_in_type_id: - rma_cust_in_type_id = picking_type_obj.create({ - 'name': _('Customer RMA Receipts'), - 'warehouse_id': wh.id, - 'code': 'incoming', - 'use_create_lots': True, - 'use_existing_lots': False, - 'sequence_id': self.env.ref( - 'rma.seq_picking_type_rma_cust_in').id, - 'default_location_src_id': customer_loc.id, - 'default_location_dest_id': wh.lot_rma_id.id, - 'sequence': max_sequence, - 'color': color, - }) + rma_cust_in_type_id = picking_type_obj.create( + { + "name": _("Customer RMA Receipts"), + "warehouse_id": wh.id, + "code": "incoming", + "use_create_lots": True, + "use_existing_lots": False, + "sequence_id": self.env.ref("rma.seq_picking_type_rma_cust_in").id, + "default_location_src_id": customer_loc.id, + "default_location_dest_id": wh.lot_rma_id.id, + "sequence": max_sequence, + "color": color, + } + ) # create rma_sup_in_type_id: - rma_sup_in_type_id = picking_type_obj.create({ - 'name': _('Supplier RMA Receipts'), - 'warehouse_id': wh.id, - 'code': 'incoming', - 'use_create_lots': True, - 'use_existing_lots': False, - 'sequence_id': self.env.ref( - 'rma.seq_picking_type_rma_sup_in').id, - 'default_location_src_id': supplier_loc.id, - 'default_location_dest_id': wh.lot_rma_id.id, - 'sequence': max_sequence, - 'color': color, - }) - wh.write({ - 'rma_cust_out_type_id': rma_cust_out_type_id.id, - 'rma_sup_out_type_id': rma_sup_out_type_id.id, - 'rma_cust_in_type_id': rma_cust_in_type_id.id, - 'rma_sup_in_type_id': rma_sup_in_type_id.id, - }) + rma_sup_in_type_id = picking_type_obj.create( + { + "name": _("Supplier RMA Receipts"), + "warehouse_id": wh.id, + "code": "incoming", + "use_create_lots": True, + "use_existing_lots": False, + "sequence_id": self.env.ref("rma.seq_picking_type_rma_sup_in").id, + "default_location_src_id": supplier_loc.id, + "default_location_dest_id": wh.lot_rma_id.id, + "sequence": max_sequence, + "color": color, + } + ) + wh.write( + { + "rma_cust_out_type_id": rma_cust_out_type_id.id, + "rma_sup_out_type_id": rma_sup_out_type_id.id, + "rma_cust_in_type_id": rma_cust_in_type_id.id, + "rma_sup_in_type_id": rma_sup_in_type_id.id, + } + ) return True @api.multi @@ -174,93 +179,87 @@ class StockWarehouse(models.Model): self.ensure_one() rma_rules = dict() customer_loc, supplier_loc = self._get_partner_locations() - rma_rules['rma_customer_in'] = { - 'name': self._format_rulename(self, - customer_loc, - self.lot_rma_id.name), - 'action': 'pull', - 'warehouse_id': self.id, - 'company_id': self.company_id.id, - 'location_src_id': customer_loc.id, - 'location_id': self.lot_rma_id.id, - 'procure_method': 'make_to_stock', - 'route_id': self.env.ref('rma.route_rma_customer').id, - 'picking_type_id': self.rma_cust_in_type_id.id, - 'active': True, + rma_rules["rma_customer_in"] = { + "name": self._format_rulename(self, customer_loc, self.lot_rma_id.name), + "action": "pull", + "warehouse_id": self.id, + "company_id": self.company_id.id, + "location_src_id": customer_loc.id, + "location_id": self.lot_rma_id.id, + "procure_method": "make_to_stock", + "route_id": self.env.ref("rma.route_rma_customer").id, + "picking_type_id": self.rma_cust_in_type_id.id, + "active": True, } - rma_rules['rma_customer_out'] = { - 'name': self._format_rulename(self, - self.lot_rma_id, - customer_loc.name), - 'action': 'pull', - 'warehouse_id': self.id, - 'company_id': self.company_id.id, - 'location_src_id': self.lot_rma_id.id, - 'location_id': customer_loc.id, - 'procure_method': 'make_to_stock', - 'route_id': self.env.ref('rma.route_rma_customer').id, - 'picking_type_id': self.rma_cust_out_type_id.id, - 'active': True, + rma_rules["rma_customer_out"] = { + "name": self._format_rulename(self, self.lot_rma_id, customer_loc.name), + "action": "pull", + "warehouse_id": self.id, + "company_id": self.company_id.id, + "location_src_id": self.lot_rma_id.id, + "location_id": customer_loc.id, + "procure_method": "make_to_stock", + "route_id": self.env.ref("rma.route_rma_customer").id, + "picking_type_id": self.rma_cust_out_type_id.id, + "active": True, } - rma_rules['rma_supplier_in'] = { - 'name': self._format_rulename(self, - supplier_loc, - self.lot_rma_id.name), - 'action': 'pull', - 'warehouse_id': self.id, - 'company_id': self.company_id.id, - 'location_src_id': supplier_loc.id, - 'location_id': self.lot_rma_id.id, - 'procure_method': 'make_to_stock', - 'route_id': self.env.ref('rma.route_rma_supplier').id, - 'picking_type_id': self.rma_sup_in_type_id.id, - 'active': True, + rma_rules["rma_supplier_in"] = { + "name": self._format_rulename(self, supplier_loc, self.lot_rma_id.name), + "action": "pull", + "warehouse_id": self.id, + "company_id": self.company_id.id, + "location_src_id": supplier_loc.id, + "location_id": self.lot_rma_id.id, + "procure_method": "make_to_stock", + "route_id": self.env.ref("rma.route_rma_supplier").id, + "picking_type_id": self.rma_sup_in_type_id.id, + "active": True, } - rma_rules['rma_supplier_out'] = { - 'name': self._format_rulename(self, - self.lot_rma_id, - supplier_loc.name), - 'action': 'pull', - 'warehouse_id': self.id, - 'company_id': self.company_id.id, - 'location_src_id': self.lot_rma_id.id, - 'location_id': supplier_loc.id, - 'procure_method': 'make_to_stock', - 'route_id': self.env.ref('rma.route_rma_supplier').id, - 'picking_type_id': self.rma_sup_out_type_id.id, - 'active': True, + rma_rules["rma_supplier_out"] = { + "name": self._format_rulename(self, self.lot_rma_id, supplier_loc.name), + "action": "pull", + "warehouse_id": self.id, + "company_id": self.company_id.id, + "location_src_id": self.lot_rma_id.id, + "location_id": supplier_loc.id, + "procure_method": "make_to_stock", + "route_id": self.env.ref("rma.route_rma_supplier").id, + "picking_type_id": self.rma_sup_out_type_id.id, + "active": True, } return rma_rules def _create_or_update_rma_pull(self): - rule_obj = self.env['stock.rule'] + rule_obj = self.env["stock.rule"] for wh in self: rules_dict = wh.get_rma_rules_dict() if wh.rma_customer_in_pull_id: - wh.rma_customer_in_pull_id.write(rules_dict['rma_customer_in']) + wh.rma_customer_in_pull_id.write(rules_dict["rma_customer_in"]) else: wh.rma_customer_in_pull_id = rule_obj.create( - rules_dict['rma_customer_in']) + rules_dict["rma_customer_in"] + ) if wh.rma_customer_out_pull_id: - wh.rma_customer_out_pull_id.write( - rules_dict['rma_customer_out']) + wh.rma_customer_out_pull_id.write(rules_dict["rma_customer_out"]) else: wh.rma_customer_out_pull_id = rule_obj.create( - rules_dict['rma_customer_out']) + rules_dict["rma_customer_out"] + ) if wh.rma_supplier_in_pull_id: - wh.rma_supplier_in_pull_id.write(rules_dict['rma_supplier_in']) + wh.rma_supplier_in_pull_id.write(rules_dict["rma_supplier_in"]) else: wh.rma_supplier_in_pull_id = rule_obj.create( - rules_dict['rma_supplier_in']) + rules_dict["rma_supplier_in"] + ) if wh.rma_supplier_out_pull_id: - wh.rma_supplier_out_pull_id.write( - rules_dict['rma_supplier_out']) + wh.rma_supplier_out_pull_id.write(rules_dict["rma_supplier_out"]) else: wh.rma_supplier_out_pull_id = rule_obj.create( - rules_dict['rma_supplier_out']) + rules_dict["rma_supplier_out"] + ) return True diff --git a/rma/report/rma_report.xml b/rma/report/rma_report.xml index 1d18f831..b2222392 100644 --- a/rma/report/rma_report.xml +++ b/rma/report/rma_report.xml @@ -1,7 +1,7 @@ - - - + rma order multi-company diff --git a/rma/tests/test_rma.py b/rma/tests/test_rma.py index e415edb4..27e5d827 100644 --- a/rma/tests/test_rma.py +++ b/rma/tests/test_rma.py @@ -1,8 +1,8 @@ # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo.tests import common from odoo.exceptions import ValidationError +from odoo.tests import common class TestRma(common.SavepointCase): @@ -12,153 +12,181 @@ class TestRma(common.SavepointCase): def setUpClass(cls): super(TestRma, cls).setUpClass() - cls.rma_make_picking = cls.env['rma_make_picking.wizard'] + cls.rma_make_picking = cls.env["rma_make_picking.wizard"] cls.make_supplier_rma = cls.env["rma.order.line.make.supplier.rma"] - cls.rma_add_stock_move = cls.env['rma_add_stock_move'] - cls.stockpicking = cls.env['stock.picking'] - cls.rma = cls.env['rma.order'] - cls.rma_line = cls.env['rma.order.line'] - cls.rma_op = cls.env['rma.operation'] - cls.rma_cust_replace_op_id = cls.env.ref( - 'rma.rma_operation_customer_replace') - cls.rma_sup_replace_op_id = cls.env.ref( - 'rma.rma_operation_supplier_replace') - cls.rma_ds_replace_op_id = cls.env.ref( - 'rma.rma_operation_ds_replace') - cls.product_id = cls.env.ref('product.product_product_4') - cls.product_1 = cls.env.ref('product.product_product_25') - cls.product_2 = cls.env.ref('product.product_product_22') - cls.product_3 = cls.env.ref('product.product_product_20') - cls.uom_unit = cls.env.ref('uom.product_uom_unit') + cls.rma_add_stock_move = cls.env["rma_add_stock_move"] + cls.stockpicking = cls.env["stock.picking"] + cls.rma = cls.env["rma.order"] + cls.rma_line = cls.env["rma.order.line"] + cls.rma_op = cls.env["rma.operation"] + cls.rma_cust_replace_op_id = cls.env.ref("rma.rma_operation_customer_replace") + cls.rma_sup_replace_op_id = cls.env.ref("rma.rma_operation_supplier_replace") + cls.rma_ds_replace_op_id = cls.env.ref("rma.rma_operation_ds_replace") + cls.product_id = cls.env.ref("product.product_product_4") + cls.product_1 = cls.env.ref("product.product_product_25") + cls.product_2 = cls.env.ref("product.product_product_22") + cls.product_3 = cls.env.ref("product.product_product_20") + cls.uom_unit = cls.env.ref("uom.product_uom_unit") # assign an operation cls.product_1.write( - {'rma_customer_operation_id': cls.rma_cust_replace_op_id.id, - 'rma_supplier_operation_id': cls.rma_sup_replace_op_id.id}) + { + "rma_customer_operation_id": cls.rma_cust_replace_op_id.id, + "rma_supplier_operation_id": cls.rma_sup_replace_op_id.id, + } + ) cls.product_2.write( - {'rma_customer_operation_id': cls.rma_cust_replace_op_id.id, - 'rma_supplier_operation_id': cls.rma_sup_replace_op_id.id}) + { + "rma_customer_operation_id": cls.rma_cust_replace_op_id.id, + "rma_supplier_operation_id": cls.rma_sup_replace_op_id.id, + } + ) cls.product_3.write( - {'rma_customer_operation_id': cls.rma_cust_replace_op_id.id, - 'rma_supplier_operation_id': cls.rma_sup_replace_op_id.id}) - cls.partner_id = cls.env.ref('base.res_partner_2') - cls.stock_location = cls.env.ref('stock.stock_location_stock') - wh = cls.env.ref('stock.warehouse0') + { + "rma_customer_operation_id": cls.rma_cust_replace_op_id.id, + "rma_supplier_operation_id": cls.rma_sup_replace_op_id.id, + } + ) + cls.partner_id = cls.env.ref("base.res_partner_2") + cls.stock_location = cls.env.ref("stock.stock_location_stock") + wh = cls.env.ref("stock.warehouse0") cls.stock_rma_location = wh.lot_rma_id - cls.customer_location = cls.env.ref( - 'stock.stock_location_customers') - cls.supplier_location = cls.env.ref( - 'stock.stock_location_suppliers') - cls.product_uom_id = cls.env.ref('uom.product_uom_unit') + cls.customer_location = cls.env.ref("stock.stock_location_customers") + cls.supplier_location = cls.env.ref("stock.stock_location_suppliers") + cls.product_uom_id = cls.env.ref("uom.product_uom_unit") # Customer RMA: - products2move = [(cls.product_1, 3), (cls.product_2, 5), - (cls.product_3, 2)] + products2move = [(cls.product_1, 3), (cls.product_2, 5), (cls.product_3, 2)] cls.rma_customer_id = cls._create_rma_from_move( - products2move, 'customer', cls.env.ref('base.res_partner_2'), - dropship=False) + products2move, "customer", cls.env.ref("base.res_partner_2"), dropship=False + ) # Dropship: cls.rma_droship_id = cls._create_rma_from_move( - products2move, 'customer', cls.env.ref('base.res_partner_2'), + products2move, + "customer", + cls.env.ref("base.res_partner_2"), dropship=True, - supplier_address_id=cls.env.ref('base.res_partner_3')) + supplier_address_id=cls.env.ref("base.res_partner_3"), + ) # Supplier RMA: cls.rma_supplier_id = cls._create_rma_from_move( - products2move, 'supplier', cls.env.ref('base.res_partner_2'), - dropship=False) + products2move, "supplier", cls.env.ref("base.res_partner_2"), dropship=False + ) @classmethod def _create_picking(cls, partner): - return cls.stockpicking.create({ - 'partner_id': partner.id, - 'picking_type_id': cls.env.ref('stock.picking_type_in').id, - 'location_id': cls.stock_location.id, - 'location_dest_id': cls.supplier_location.id - }) + return cls.stockpicking.create( + { + "partner_id": partner.id, + "picking_type_id": cls.env.ref("stock.picking_type_in").id, + "location_id": cls.stock_location.id, + "location_dest_id": cls.supplier_location.id, + } + ) @classmethod - def _create_rma_from_move(cls, products2move, type, partner, dropship, - supplier_address_id=None): + def _create_rma_from_move( + cls, products2move, type, partner, dropship, supplier_address_id=None + ): picking_in = cls._create_picking(partner) moves = [] - if type == 'customer': + if type == "customer": for item in products2move: move_values = cls._prepare_move( - item[0], item[1], cls.stock_location, - cls.customer_location, picking_in) - moves.append(cls.env['stock.move'].create(move_values)) + item[0], + item[1], + cls.stock_location, + cls.customer_location, + picking_in, + ) + moves.append(cls.env["stock.move"].create(move_values)) else: for item in products2move: move_values = cls._prepare_move( - item[0], item[1], cls.supplier_location, - cls.stock_rma_location, picking_in) - moves.append(cls.env['stock.move'].create(move_values)) + item[0], + item[1], + cls.supplier_location, + cls.stock_rma_location, + picking_in, + ) + moves.append(cls.env["stock.move"].create(move_values)) # Create the RMA from the stock_move rma_id = cls.rma.create( { - 'reference': '0001', - 'type': type, - 'partner_id': partner.id, - 'company_id': cls.env.ref('base.main_company').id - }) + "reference": "0001", + "type": type, + "partner_id": partner.id, + "company_id": cls.env.ref("base.main_company").id, + } + ) for move in moves: - if type == 'customer': + if type == "customer": wizard = cls.rma_add_stock_move.new( - {'stock_move_id': move.id, 'customer': True, - 'active_ids': rma_id.id, - 'rma_id': rma_id.id, - 'partner_id': move.partner_id.id, - 'active_model': 'rma.order', - } + { + "stock_move_id": move.id, + "customer": True, + "active_ids": rma_id.id, + "rma_id": rma_id.id, + "partner_id": move.partner_id.id, + "active_model": "rma.order", + } ) - wizard.with_context({ - 'stock_move_id': move.id, 'customer': True, - 'active_ids': rma_id.id, - 'partner_id': move.partner_id.id, - 'active_model': 'rma.order', - }).default_get([str(move.id), - str(cls.partner_id.id)]) - data = wizard.with_context(customer=1).\ - _prepare_rma_line_from_stock_move(move) + wizard.with_context( + { + "stock_move_id": move.id, + "customer": True, + "active_ids": rma_id.id, + "partner_id": move.partner_id.id, + "active_model": "rma.order", + } + ).default_get([str(move.id), str(cls.partner_id.id)]) + data = wizard.with_context( + customer=1 + )._prepare_rma_line_from_stock_move(move) wizard.add_lines() if move.product_id.rma_customer_operation_id: - move.product_id.rma_customer_operation_id.in_route_id = \ - False + move.product_id.rma_customer_operation_id.in_route_id = False move.product_id.categ_id.rma_customer_operation_id = False move.product_id.rma_customer_operation_id = False wizard._prepare_rma_line_from_stock_move(move) else: wizard = cls.rma_add_stock_move.new( - {'stock_move_id': move.id, 'supplier': True, - 'active_ids': rma_id.id, - 'rma_id': rma_id.id, - 'partner_id': move.partner_id.id, - 'active_model': 'rma.order', - } + { + "stock_move_id": move.id, + "supplier": True, + "active_ids": rma_id.id, + "rma_id": rma_id.id, + "partner_id": move.partner_id.id, + "active_model": "rma.order", + } ) - wizard.with_context({ - 'stock_move_id': move.id, 'supplier': True, - 'active_ids': rma_id.id, - 'partner_id': move.partner_id.id, - 'active_model': 'rma.order', - }).default_get([str(move.id), - str(cls.partner_id.id)]) - data = wizard.with_context(customer=1).\ - _prepare_rma_line_from_stock_move(move) + wizard.with_context( + { + "stock_move_id": move.id, + "supplier": True, + "active_ids": rma_id.id, + "partner_id": move.partner_id.id, + "active_model": "rma.order", + } + ).default_get([str(move.id), str(cls.partner_id.id)]) + data = wizard.with_context( + customer=1 + )._prepare_rma_line_from_stock_move(move) wizard.add_lines() if move.product_id.rma_customer_operation_id: - move.product_id.rma_customer_operation_id.in_route_id = \ - False + move.product_id.rma_customer_operation_id.in_route_id = False move.product_id.categ_id.rma_supplier_operation_id = False move.product_id.rma_supplier_operation_id = False wizard._prepare_rma_line_from_stock_move(move) if dropship: - data.update(customer_to_supplier=dropship, - operation_id=cls.rma_ds_replace_op_id.id, - supplier_address_id=supplier_address_id.id) + data.update( + customer_to_supplier=dropship, + operation_id=cls.rma_ds_replace_op_id.id, + supplier_address_id=supplier_address_id.id, + ) cls.line = cls.rma_line.create(data) cls.line.action_rma_to_approve() cls.line.action_rma_approve() @@ -178,68 +206,71 @@ class TestRma(common.SavepointCase): @classmethod def _prepare_move(cls, product, qty, src, dest, picking_in): res = { - 'partner_id': cls.partner_id.id, - 'product_id': product.id, - 'name': product.partner_ref, - 'state': 'confirmed', - 'product_uom': cls.product_uom_id.id or product.uom_id.id, - 'product_uom_qty': qty, - 'origin': 'Test RMA', - 'location_id': src.id, - 'location_dest_id': dest.id, - 'picking_id': picking_in.id + "partner_id": cls.partner_id.id, + "product_id": product.id, + "name": product.partner_ref, + "state": "confirmed", + "product_uom": cls.product_uom_id.id or product.uom_id.id, + "product_uom_qty": qty, + "origin": "Test RMA", + "location_id": src.id, + "location_dest_id": dest.id, + "picking_id": picking_in.id, } return res def test_01_rma_order_line(self): for line in self.rma_customer_id.rma_line_ids: - line.with_context({'default_rma_id': line.rma_id.id - })._default_warehouse_id() + line.with_context( + {"default_rma_id": line.rma_id.id} + )._default_warehouse_id() line._default_location_id() - line.with_context({'partner_id': line.rma_id.partner_id.id - })._default_delivery_address() + line.with_context( + {"partner_id": line.rma_id.partner_id.id} + )._default_delivery_address() line._compute_in_shipment_count() line._compute_out_shipment_count() - data = {'reference_move_id': line.reference_move_id.id} + data = {"reference_move_id": line.reference_move_id.id} new_line = self.rma_line.new(data) new_line._onchange_reference_move_id() # check assert if call reference_move_id onchange - self.assertEquals(new_line.product_id, - line.reference_move_id.product_id) - self.assertEquals(new_line.product_qty, - line.reference_move_id.product_uom_qty) - self.assertEquals(new_line.location_id.location_id, - line.reference_move_id.location_id) - self.assertEquals(new_line.origin, - line.reference_move_id.picking_id.name) - self.assertEquals(new_line.delivery_address_id, - line.reference_move_id.picking_partner_id) - self.assertEquals(new_line.qty_to_receive, - line.reference_move_id.product_uom_qty) + self.assertEquals(new_line.product_id, line.reference_move_id.product_id) + self.assertEquals( + new_line.product_qty, line.reference_move_id.product_uom_qty + ) + self.assertEquals( + new_line.location_id.location_id, line.reference_move_id.location_id + ) + self.assertEquals(new_line.origin, line.reference_move_id.picking_id.name) + self.assertEquals( + new_line.delivery_address_id, line.reference_move_id.picking_partner_id + ) + self.assertEquals( + new_line.qty_to_receive, line.reference_move_id.product_uom_qty + ) line.action_rma_to_approve() line.action_rma_draft() line.action_rma_done() - data = {'product_id': line.product_id.id} + data = {"product_id": line.product_id.id} new_line = self.rma_line.new(data) new_line._onchange_product_id() - data = {'operation_id': line.operation_id.id} + data = {"operation_id": line.operation_id.id} new_line = self.rma_line.new(data) new_line._onchange_operation_id() # check assert if call operation_id onchange - self.assertEquals(new_line.operation_id.receipt_policy, - line.receipt_policy) + self.assertEquals(new_line.operation_id.receipt_policy, line.receipt_policy) - data = {'customer_to_supplier': line.customer_to_supplier} + data = {"customer_to_supplier": line.customer_to_supplier} new_line = self.rma_line.new(data) new_line._onchange_receipt_policy() - data = {'lot_id': line.lot_id.id} + data = {"lot_id": line.lot_id.id} new_line = self.rma_line.new(data) new_line._onchange_lot_id() @@ -248,155 +279,112 @@ class TestRma(common.SavepointCase): self.rma_customer_id.action_view_supplier_lines() with self.assertRaises(ValidationError): line.rma_id.partner_id = self.partner_id.id - self.rma_customer_id.rma_line_ids[0].\ - partner_id = self.env.ref('base.res_partner_3').id + self.rma_customer_id.rma_line_ids[0].partner_id = self.env.ref( + "base.res_partner_3" + ).id self.rma_customer_id.action_view_supplier_lines() def test_02_customer_rma(self): - wizard = self.rma_make_picking.with_context({ - 'active_ids': self.rma_customer_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'picking_type': 'incoming', - 'active_id': 1 - }).create({}) + wizard = self.rma_make_picking.with_context( + { + "active_ids": self.rma_customer_id.rma_line_ids.ids, + "active_model": "rma.order.line", + "picking_type": "incoming", + "active_id": 1, + } + ).create({}) wizard._create_picking() res = self.rma_customer_id.rma_line_ids.action_view_in_shipments() - self.assertTrue('res_id' in res, - "Incorrect number of pickings created") - picking = self.env['stock.picking'].browse(res['res_id']) - self.assertEquals(len(picking), 1, - "Incorrect number of pickings created") + self.assertTrue("res_id" in res, "Incorrect number of pickings created") + picking = self.env["stock.picking"].browse(res["res_id"]) + self.assertEquals(len(picking), 1, "Incorrect number of pickings created") moves = picking.move_lines - self.assertEquals(len(moves), 3, - "Incorrect number of moves created") + self.assertEquals(len(moves), 3, "Incorrect number of moves created") for line in self.rma_customer_id.rma_line_ids: # common qtys for all products - self.assertEquals(line.qty_received, 0, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 0, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 0, - "Wrong qty outgoing") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") + self.assertEquals(line.qty_received, 0, "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 0, "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 0, "Wrong qty outgoing") + self.assertEquals(line.qty_delivered, 0, "Wrong qty delivered") # product specific if line.product_id == self.product_1: - self.assertEquals(line.qty_to_receive, 3, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 3, - "Wrong qty incoming") + self.assertEquals(line.qty_to_receive, 3, "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 3, "Wrong qty incoming") if line.product_id == self.product_2: - self.assertEquals(line.qty_to_receive, 5, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 5, - "Wrong qty incoming") + self.assertEquals(line.qty_to_receive, 5, "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 5, "Wrong qty incoming") if line.product_id == self.product_3: - self.assertEquals(line.qty_to_receive, 2, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 2, - "Wrong qty incoming") + self.assertEquals(line.qty_to_receive, 2, "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 2, "Wrong qty incoming") picking.action_assign() for mv in picking.move_lines: mv.quantity_done = mv.product_uom_qty picking.action_done() for line in self.rma_customer_id.rma_line_ids: - self.assertEquals(line.qty_to_receive, 0, - "Wrong qty to_receive") - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_outgoing, 0, - "Wrong qty outgoing") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") + self.assertEquals(line.qty_to_receive, 0, "Wrong qty to_receive") + self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") + self.assertEquals(line.qty_outgoing, 0, "Wrong qty outgoing") + self.assertEquals(line.qty_delivered, 0, "Wrong qty delivered") if line.product_id == self.product_1: - self.assertEquals(line.qty_received, 3, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 3, - "Wrong qty to_deliver") + self.assertEquals(line.qty_received, 3, "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 3, "Wrong qty to_deliver") if line.product_id == self.product_2: - self.assertEquals(line.qty_received, 5, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 5, - "Wrong qty to_deliver") + self.assertEquals(line.qty_received, 5, "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 5, "Wrong qty to_deliver") if line.product_id == self.product_3: - self.assertEquals(line.qty_received, 2, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 2, - "Wrong qty to_deliver") + self.assertEquals(line.qty_received, 2, "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 2, "Wrong qty to_deliver") - wizard = self.rma_make_picking.with_context({ - 'active_id': 1, - 'active_ids': self.rma_customer_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'picking_type': 'outgoing', - }).create({}) + wizard = self.rma_make_picking.with_context( + { + "active_id": 1, + "active_ids": self.rma_customer_id.rma_line_ids.ids, + "active_model": "rma.order.line", + "picking_type": "outgoing", + } + ).create({}) wizard._create_picking() res = self.rma_customer_id.rma_line_ids.action_view_out_shipments() - self.assertTrue('res_id' in res, - "Incorrect number of pickings created") - picking = self.env['stock.picking'].browse(res['res_id']) + self.assertTrue("res_id" in res, "Incorrect number of pickings created") + picking = self.env["stock.picking"].browse(res["res_id"]) moves = picking.move_lines - self.assertEquals(len(moves), 3, - "Incorrect number of moves created") + self.assertEquals(len(moves), 3, "Incorrect number of moves created") for line in self.rma_customer_id.rma_line_ids: - self.assertEquals(line.qty_to_receive, 0, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") + self.assertEquals(line.qty_to_receive, 0, "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 0, "Wrong qty delivered") if line.product_id == self.product_1: - self.assertEquals(line.qty_to_deliver, 3, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 3, - "Wrong qty outgoing") - self.assertEquals(line.qty_received, 3, - "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 3, "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 3, "Wrong qty outgoing") + self.assertEquals(line.qty_received, 3, "Wrong qty received") if line.product_id == self.product_2: - self.assertEquals(line.qty_received, 5, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 5, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 5, - "Wrong qty outgoing") + self.assertEquals(line.qty_received, 5, "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 5, "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 5, "Wrong qty outgoing") if line.product_id == self.product_3: - self.assertEquals(line.qty_received, 2, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 2, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 2, - "Wrong qty outgoing") + self.assertEquals(line.qty_received, 2, "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 2, "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 2, "Wrong qty outgoing") picking.action_assign() for mv in picking.move_lines: mv.quantity_done = mv.product_uom_qty picking.action_done() for line in self.rma_customer_id.rma_line_ids: - self.assertEquals(line.qty_to_receive, 0, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_to_deliver, 0, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 0, - "Wrong qty outgoing") + self.assertEquals(line.qty_to_receive, 0, "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") + self.assertEquals(line.qty_to_deliver, 0, "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 0, "Wrong qty outgoing") if line.product_id == self.product_1: - self.assertEquals(line.qty_received, 3, - "Wrong qty received") - self.assertEquals(line.qty_delivered, 3, - "Wrong qty delivered") + self.assertEquals(line.qty_received, 3, "Wrong qty received") + self.assertEquals(line.qty_delivered, 3, "Wrong qty delivered") if line.product_id == self.product_2: - self.assertEquals(line.qty_received, 5, - "Wrong qty received") - self.assertEquals(line.qty_delivered, 5, - "Wrong qty delivered") + self.assertEquals(line.qty_received, 5, "Wrong qty received") + self.assertEquals(line.qty_delivered, 5, "Wrong qty delivered") if line.product_id == self.product_3: - self.assertEquals(line.qty_received, 2, - "Wrong qty received") - self.assertEquals(line.qty_delivered, 2, - "Wrong qty delivered") + self.assertEquals(line.qty_received, 2, "Wrong qty received") + self.assertEquals(line.qty_delivered, 2, "Wrong qty delivered") self.line.action_rma_done() - self.assertEquals(self.line.state, 'done', - "Wrong State") + self.assertEquals(self.line.state, "done", "Wrong State") self.rma_customer_id.action_view_in_shipments() self.rma_customer_id.action_view_out_shipments() self.rma_customer_id.action_view_lines() @@ -407,204 +395,165 @@ class TestRma(common.SavepointCase): line.action_rma_to_approve() line.action_rma_approve() line._onchange_operation_id() - wizard = self.rma_make_picking.with_context({ - 'active_id': 1, - 'active_ids': self.rma_droship_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'picking_type': 'incoming', - }).create({}) + wizard = self.rma_make_picking.with_context( + { + "active_id": 1, + "active_ids": self.rma_droship_id.rma_line_ids.ids, + "active_model": "rma.order.line", + "picking_type": "incoming", + } + ).create({}) wizard._create_picking() res = self.rma_droship_id.rma_line_ids.action_view_in_shipments() - self.assertTrue('res_id' in res, - "Incorrect number of pickings created") - picking = self.env['stock.picking'].browse(res['res_id']) - self.assertEquals(len(picking), 1, - "Incorrect number of pickings created") + self.assertTrue("res_id" in res, "Incorrect number of pickings created") + picking = self.env["stock.picking"].browse(res["res_id"]) + self.assertEquals(len(picking), 1, "Incorrect number of pickings created") moves = picking.move_lines - self.assertEquals(len(moves), 3, - "Incorrect number of moves created") - wizard = self.make_supplier_rma.with_context({ - 'active_ids': self.rma_droship_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'active_id': 1 - }).create({}) + self.assertEquals(len(moves), 3, "Incorrect number of moves created") + wizard = self.make_supplier_rma.with_context( + { + "active_ids": self.rma_droship_id.rma_line_ids.ids, + "active_model": "rma.order.line", + "active_id": 1, + } + ).create({}) res = wizard.make_supplier_rma() - supplier_rma = self.rma.browse(res['res_id']) + supplier_rma = self.rma.browse(res["res_id"]) for line in supplier_rma.rma_line_ids: # common qtys for all products - self.assertEquals(line.qty_received, 0, - "Wrong qty received") - self.assertEquals(line.qty_outgoing, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") + self.assertEquals(line.qty_received, 0, "Wrong qty received") + self.assertEquals(line.qty_outgoing, 0, "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 0, "Wrong qty delivered") # product specific if line.product_id == self.product_1: - self.assertEquals(line.qty_to_deliver, 3, - "Wrong qty to deliver") + self.assertEquals(line.qty_to_deliver, 3, "Wrong qty to deliver") if line.product_id == self.product_2: - self.assertEquals(line.qty_to_deliver, 5, - "Wrong qty to deliver") + self.assertEquals(line.qty_to_deliver, 5, "Wrong qty to deliver") if line.product_id == self.product_3: - self.assertEquals(line.qty_to_deliver, 2, - "Wrong qty to deliver") + self.assertEquals(line.qty_to_deliver, 2, "Wrong qty to deliver") for line in self.rma_droship_id.rma_line_ids: if line.product_id == self.product_1: - self.assertEquals(line.qty_to_supplier_rma, 0, - "Wrong qty to supplier rma") - self.assertEquals(line.qty_in_supplier_rma, 3, - "Wrong qty in supplier rma") + self.assertEquals( + line.qty_to_supplier_rma, 0, "Wrong qty to supplier rma" + ) + self.assertEquals( + line.qty_in_supplier_rma, 3, "Wrong qty in supplier rma" + ) if line.product_id == self.product_2: - self.assertEquals(line.qty_to_supplier_rma, 0, - "Wrong qty to supplier rma") - self.assertEquals(line.qty_in_supplier_rma, 5, - "Wrong qty in supplier rma") + self.assertEquals( + line.qty_to_supplier_rma, 0, "Wrong qty to supplier rma" + ) + self.assertEquals( + line.qty_in_supplier_rma, 5, "Wrong qty in supplier rma" + ) if line.product_id == self.product_3: - self.assertEquals(line.qty_to_supplier_rma, 0, - "Wrong qty to supplier rma") - self.assertEquals(line.qty_in_supplier_rma, 2, - "Wrong qty in supplier rma") + self.assertEquals( + line.qty_to_supplier_rma, 0, "Wrong qty to supplier rma" + ) + self.assertEquals( + line.qty_in_supplier_rma, 2, "Wrong qty in supplier rma" + ) for line in self.rma_droship_id.rma_line_ids: line.action_rma_done() - self.assertEquals(line.state, 'done', - "Wrong State") + self.assertEquals(line.state, "done", "Wrong State") # Supplier RMA def test_04_supplier_rma(self): - wizard = self.rma_make_picking.with_context({ - 'active_ids': self.rma_supplier_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'picking_type': 'outgoing', - 'active_id': 1 - }).create({}) + wizard = self.rma_make_picking.with_context( + { + "active_ids": self.rma_supplier_id.rma_line_ids.ids, + "active_model": "rma.order.line", + "picking_type": "outgoing", + "active_id": 1, + } + ).create({}) wizard._create_picking() res = self.rma_supplier_id.rma_line_ids.action_view_out_shipments() - self.assertTrue('res_id' in res, - "Incorrect number of pickings created") - picking = self.env['stock.picking'].browse(res['res_id']) + self.assertTrue("res_id" in res, "Incorrect number of pickings created") + picking = self.env["stock.picking"].browse(res["res_id"]) moves = picking.move_lines - self.assertEquals(len(moves), 3, - "Incorrect number of moves created") + self.assertEquals(len(moves), 3, "Incorrect number of moves created") for line in self.rma_supplier_id.rma_line_ids: # common qtys for all products - self.assertEquals(line.qty_received, 0, - "Wrong qty received") - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") + self.assertEquals(line.qty_received, 0, "Wrong qty received") + self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 0, "Wrong qty delivered") # product specific if line.product_id == self.product_1: - self.assertEquals(line.qty_to_receive, 3, - "Wrong qty to receive") - self.assertEquals(line.qty_to_deliver, 3, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 3, - "Wrong qty outgoing") + self.assertEquals(line.qty_to_receive, 3, "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 3, "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 3, "Wrong qty outgoing") if line.product_id == self.product_2: - self.assertEquals(line.qty_to_receive, 5, - "Wrong qty to receive") - self.assertEquals(line.qty_to_deliver, 5, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 5, - "Wrong qty outgoing") + self.assertEquals(line.qty_to_receive, 5, "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 5, "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 5, "Wrong qty outgoing") if line.product_id == self.product_3: - self.assertEquals(line.qty_to_receive, 2, - "Wrong qty to receive") - self.assertEquals(line.qty_to_deliver, 2, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 2, - "Wrong qty outgoing") + self.assertEquals(line.qty_to_receive, 2, "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 2, "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 2, "Wrong qty outgoing") picking.action_assign() for mv in picking.move_lines: mv.quantity_done = mv.product_uom_qty picking.action_done() for line in self.rma_supplier_id.rma_line_ids: - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_received, 0, - "Wrong qty received") + self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") + self.assertEquals(line.qty_received, 0, "Wrong qty received") if line.product_id == self.product_1: - self.assertEquals(line.qty_delivered, 3, - "Wrong qty delivered") - self.assertEquals(line.qty_to_receive, 3, - "Wrong qty to receive") + self.assertEquals(line.qty_delivered, 3, "Wrong qty delivered") + self.assertEquals(line.qty_to_receive, 3, "Wrong qty to receive") if line.product_id == self.product_2: - self.assertEquals(line.qty_delivered, 5, - "Wrong qty delivered") - self.assertEquals(line.qty_to_receive, 5, - "Wrong qty to receive") + self.assertEquals(line.qty_delivered, 5, "Wrong qty delivered") + self.assertEquals(line.qty_to_receive, 5, "Wrong qty to receive") if line.product_id == self.product_3: - self.assertEquals(line.qty_delivered, 2, - "Wrong qty delivered") - self.assertEquals(line.qty_to_receive, 2, - "Wrong qty to receive") - wizard = self.rma_make_picking.with_context({ - 'active_id': 1, - 'active_ids': self.rma_supplier_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'picking_type': 'incoming', - }).create({}) + self.assertEquals(line.qty_delivered, 2, "Wrong qty delivered") + self.assertEquals(line.qty_to_receive, 2, "Wrong qty to receive") + wizard = self.rma_make_picking.with_context( + { + "active_id": 1, + "active_ids": self.rma_supplier_id.rma_line_ids.ids, + "active_model": "rma.order.line", + "picking_type": "incoming", + } + ).create({}) wizard._create_picking() res = self.rma_supplier_id.rma_line_ids.action_view_in_shipments() - self.assertTrue('res_id' in res, - "Incorrect number of pickings created") - pickings = self.env['stock.picking'].browse(res['res_id']) - self.assertEquals(len(pickings), 1, - "Incorrect number of pickings created") + self.assertTrue("res_id" in res, "Incorrect number of pickings created") + pickings = self.env["stock.picking"].browse(res["res_id"]) + self.assertEquals(len(pickings), 1, "Incorrect number of pickings created") picking_out = pickings[0] moves = picking_out.move_lines - self.assertEquals(len(moves), 3, - "Incorrect number of moves created") + self.assertEquals(len(moves), 3, "Incorrect number of moves created") for line in self.rma_supplier_id.rma_line_ids: - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_received, 0, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 0, - "Wrong qty to deliver") + self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") + self.assertEquals(line.qty_received, 0, "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 0, "Wrong qty to deliver") if line.product_id == self.product_1: - self.assertEquals(line.qty_to_receive, 3, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") + self.assertEquals(line.qty_to_receive, 3, "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") if line.product_id == self.product_2: - self.assertEquals(line.qty_to_receive, 5, - "Wrong qty to receive") + self.assertEquals(line.qty_to_receive, 5, "Wrong qty to receive") if line.product_id == self.product_3: - self.assertEquals(line.qty_to_receive, 2, - "Wrong qty to receive") + self.assertEquals(line.qty_to_receive, 2, "Wrong qty to receive") picking_out.action_assign() for mv in picking.move_lines: mv.quantity_done = mv.product_uom_qty picking_out.action_done() for line in self.rma_supplier_id.rma_line_ids[0]: - self.assertEquals(line.qty_to_receive, 3, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_to_deliver, 0, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 3, - "Wrong qty outgoing") + self.assertEquals(line.qty_to_receive, 3, "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") + self.assertEquals(line.qty_to_deliver, 0, "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 3, "Wrong qty outgoing") if line.product_id == self.product_1: - self.assertEquals(line.qty_received, 0, - "Wrong qty received") - self.assertEquals(line.qty_delivered, 3, - "Wrong qty delivered") + self.assertEquals(line.qty_received, 0, "Wrong qty received") + self.assertEquals(line.qty_delivered, 3, "Wrong qty delivered") if line.product_id == self.product_2: - self.assertEquals(line.qty_received, 0, - "Wrong qty received") - self.assertEquals(line.qty_delivered, 5, - "Wrong qty delivered") + self.assertEquals(line.qty_received, 0, "Wrong qty received") + self.assertEquals(line.qty_delivered, 5, "Wrong qty delivered") if line.product_id == self.product_3: - self.assertEquals(line.qty_received, 2, - "Wrong qty received") - self.assertEquals(line.qty_delivered, 2, - "Wrong qty delivered") + self.assertEquals(line.qty_received, 2, "Wrong qty received") + self.assertEquals(line.qty_delivered, 2, "Wrong qty delivered") for line in self.rma_supplier_id.rma_line_ids: line.action_rma_done() - self.assertEquals(line.state, 'done', - "Wrong State") + self.assertEquals(line.state, "done", "Wrong State") diff --git a/rma/views/stock_warehouse.xml b/rma/views/stock_warehouse.xml index 4b1cc6c4..617e2cab 100755 --- a/rma/views/stock_warehouse.xml +++ b/rma/views/stock_warehouse.xml @@ -20,4 +20,3 @@ - diff --git a/rma/wizards/rma_add_stock_move.py b/rma/wizards/rma_add_stock_move.py index 3ba80672..810a8bdb 100644 --- a/rma/wizards/rma_add_stock_move.py +++ b/rma/wizards/rma_add_stock_move.py @@ -1,89 +1,101 @@ # Copyright (C) 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, fields, models, _ +from odoo import _, api, fields, models from odoo.exceptions import ValidationError class RmaAddStockMove(models.TransientModel): - _name = 'rma_add_stock_move' - _description = 'Wizard to add rma lines from pickings' + _name = "rma_add_stock_move" + _description = "Wizard to add rma lines from pickings" @api.model def default_get(self, fields_list): res = super(RmaAddStockMove, self).default_get(fields_list) - rma_obj = self.env['rma.order'] - rma_id = self.env.context['active_ids'] or [] - active_model = self.env.context['active_model'] + rma_obj = self.env["rma.order"] + rma_id = self.env.context["active_ids"] or [] + active_model = self.env.context["active_model"] if not rma_id: return res - assert active_model == 'rma.order', 'Bad context propagation' + assert active_model == "rma.order", "Bad context propagation" rma = rma_obj.browse(rma_id) - res['rma_id'] = rma.id - res['partner_id'] = rma.partner_id.id - res['move_ids'] = False + res["rma_id"] = rma.id + res["partner_id"] = rma.partner_id.id + res["move_ids"] = False return res rma_id = fields.Many2one( - comodel_name='rma.order', string='RMA Order', - readonly=True, ondelete='cascade', + comodel_name="rma.order", string="RMA Order", readonly=True, ondelete="cascade" ) partner_id = fields.Many2one( - comodel_name='res.partner', string='Partner', - readonly=True, + comodel_name="res.partner", string="Partner", readonly=True ) move_ids = fields.Many2many( - comodel_name='stock.move', string='Stock Moves', + comodel_name="stock.move", + string="Stock Moves", domain="[('state', '=', 'done')]", ) def _prepare_rma_line_from_stock_move(self, sm, lot=False): - if self.env.context.get('customer'): - operation = sm.product_id.rma_customer_operation_id or \ - sm.product_id.categ_id.rma_customer_operation_id + if self.env.context.get("customer"): + operation = ( + sm.product_id.rma_customer_operation_id + or sm.product_id.categ_id.rma_customer_operation_id + ) else: - operation = sm.product_id.rma_supplier_operation_id or \ - sm.product_id.categ_id.rma_supplier_operation_id + operation = ( + sm.product_id.rma_supplier_operation_id + or sm.product_id.categ_id.rma_supplier_operation_id + ) if not operation: - operation = self.env['rma.operation'].search( - [('type', '=', self.rma_id.type)], limit=1) + operation = self.env["rma.operation"].search( + [("type", "=", self.rma_id.type)], limit=1 + ) if not operation: raise ValidationError(_("Please define an operation first")) if not operation.in_route_id or not operation.out_route_id: - route = self.env['stock.location.route'].search( - [('rma_selectable', '=', True)], limit=1) + route = self.env["stock.location.route"].search( + [("rma_selectable", "=", True)], limit=1 + ) if not route: raise ValidationError(_("Please define an RMA route")) if not operation.in_warehouse_id or not operation.out_warehouse_id: - warehouse = self.env['stock.warehouse'].search( - [('company_id', '=', self.rma_id.company_id.id), - ('lot_rma_id', '!=', False)], limit=1) + warehouse = self.env["stock.warehouse"].search( + [ + ("company_id", "=", self.rma_id.company_id.id), + ("lot_rma_id", "!=", False), + ], + limit=1, + ) if not warehouse: - raise ValidationError(_( - "Please define a warehouse with a default RMA location")) + raise ValidationError( + _("Please define a warehouse with a default RMA location") + ) data = { - 'partner_id': self.partner_id.id, - 'reference_move_id': sm.id, - 'product_id': sm.product_id.id, - 'lot_id': lot and lot.id or False, - 'origin': sm.picking_id.name or sm.name, - 'uom_id': sm.product_uom.id, - 'operation_id': operation.id, - 'product_qty': sm.product_uom_qty, - 'delivery_address_id': sm.picking_id.partner_id.id, - 'rma_id': self.rma_id.id, - 'receipt_policy': operation.receipt_policy, - 'delivery_policy': operation.delivery_policy, - 'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, - 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, - 'in_route_id': operation.in_route_id.id or route.id, - 'out_route_id': operation.out_route_id.id or route.id, - 'location_id': (operation.location_id.id or - operation.in_warehouse_id.lot_rma_id.id or - warehouse.lot_rma_id.id) + "partner_id": self.partner_id.id, + "reference_move_id": sm.id, + "product_id": sm.product_id.id, + "lot_id": lot and lot.id or False, + "origin": sm.picking_id.name or sm.name, + "uom_id": sm.product_uom.id, + "operation_id": operation.id, + "product_qty": sm.product_uom_qty, + "delivery_address_id": sm.picking_id.partner_id.id, + "rma_id": self.rma_id.id, + "receipt_policy": operation.receipt_policy, + "delivery_policy": operation.delivery_policy, + "in_warehouse_id": operation.in_warehouse_id.id or warehouse.id, + "out_warehouse_id": operation.out_warehouse_id.id or warehouse.id, + "in_route_id": operation.in_route_id.id or route.id, + "out_route_id": operation.out_route_id.id or route.id, + "location_id": ( + operation.location_id.id + or operation.in_warehouse_id.lot_rma_id.id + or warehouse.lot_rma_id.id + ), } return data @@ -96,20 +108,19 @@ class RmaAddStockMove(models.TransientModel): @api.multi def add_lines(self): - rma_line_obj = self.env['rma.order.line'] + rma_line_obj = self.env["rma.order.line"] existing_stock_moves = self._get_existing_stock_moves() for sm in self.move_ids: if sm not in existing_stock_moves: - if sm.product_id.tracking == 'none': - data = self._prepare_rma_line_from_stock_move(sm, - lot=False) - rma_line_obj.with_context( - default_rma_id=self.rma_id.id).create(data) + if sm.product_id.tracking == "none": + data = self._prepare_rma_line_from_stock_move(sm, lot=False) + rma_line_obj.with_context(default_rma_id=self.rma_id.id).create( + data + ) else: - lot_ids = [x.lot_id.id for x in sm.move_line_ids if - x.lot_id] - data = self._prepare_rma_line_from_stock_move( - sm, lot=lot_ids[0]) - rma_line_obj.with_context( - default_rma_id=self.rma_id.id).create(data) - return {'type': 'ir.actions.act_window_close'} + lot_ids = [x.lot_id.id for x in sm.move_line_ids if x.lot_id] + data = self._prepare_rma_line_from_stock_move(sm, lot=lot_ids[0]) + rma_line_obj.with_context(default_rma_id=self.rma_id.id).create( + data + ) + return {"type": "ir.actions.act_window_close"} diff --git a/rma/wizards/rma_make_picking.py b/rma/wizards/rma_make_picking.py index 8e5170b5..0d53cb7c 100644 --- a/rma/wizards/rma_make_picking.py +++ b/rma/wizards/rma_make_picking.py @@ -2,27 +2,30 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) import time -from odoo import models, fields, api, _ + +from odoo import _, api, fields, models from odoo.exceptions import UserError, ValidationError from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT as DT_FORMAT + import odoo.addons.decimal_precision as dp class RmaMakePicking(models.TransientModel): - _name = 'rma_make_picking.wizard' - _description = 'Wizard to create pickings from rma lines' + _name = "rma_make_picking.wizard" + _description = "Wizard to create pickings from rma lines" - @api.returns('rma.order.line') + @api.returns("rma.order.line") def _prepare_item(self, line): - values = {'product_id': line.product_id.id, - 'product_qty': line.product_qty, - 'uom_id': line.uom_id.id, - 'qty_to_receive': line.qty_to_receive, - 'qty_to_deliver': line.qty_to_deliver, - 'line_id': line.id, - 'rma_id': line.rma_id and line.rma_id.id or False, - 'wiz_id': self.env.context['active_id'], - } + values = { + "product_id": line.product_id.id, + "product_qty": line.product_qty, + "uom_id": line.uom_id.id, + "qty_to_receive": line.qty_to_receive, + "qty_to_deliver": line.qty_to_deliver, + "line_id": line.id, + "rma_id": line.rma_id and line.rma_id.id or False, + "wiz_id": self.env.context["active_id"], + } return values @api.model @@ -33,46 +36,47 @@ class RmaMakePicking(models.TransientModel): """ context = self._context.copy() res = super(RmaMakePicking, self).default_get(fields_list) - rma_line_obj = self.env['rma.order.line'] - rma_line_ids = self.env.context['active_ids'] or [] - active_model = self.env.context['active_model'] + rma_line_obj = self.env["rma.order.line"] + rma_line_ids = self.env.context["active_ids"] or [] + active_model = self.env.context["active_model"] if not rma_line_ids: return res - assert active_model == 'rma.order.line', \ - 'Bad context propagation' + assert active_model == "rma.order.line", "Bad context propagation" items = [] lines = rma_line_obj.browse(rma_line_ids) - if len(lines.mapped('partner_id')) > 1: + if len(lines.mapped("partner_id")) > 1: raise ValidationError( - _('Only RMA lines from the same partner can be processed at ' - 'the same time')) + _( + "Only RMA lines from the same partner can be processed at " + "the same time" + ) + ) for line in lines: items.append([0, 0, self._prepare_item(line)]) - res['item_ids'] = items - context.update({'items_ids': items}) + res["item_ids"] = items + context.update({"items_ids": items}) return res - item_ids = fields.One2many( - 'rma_make_picking.wizard.item', - 'wiz_id', string='Items') + item_ids = fields.One2many("rma_make_picking.wizard.item", "wiz_id", string="Items") def find_procurement_group(self, item): if item.line_id.rma_id: - return self.env['procurement.group'].search([ - ('rma_id', '=', item.line_id.rma_id.id)]) + return self.env["procurement.group"].search( + [("rma_id", "=", item.line_id.rma_id.id)] + ) else: - return self.env['procurement.group'].search([ - ('rma_line_id', '=', item.line_id.id)]) + return self.env["procurement.group"].search( + [("rma_line_id", "=", item.line_id.id)] + ) def _get_procurement_group_data(self, item): group_data = { - 'partner_id': item.line_id.partner_id.id, - 'name': item.line_id.rma_id.name or item.line_id.name, - 'rma_id': item.line_id.rma_id and item.line_id.rma_id.id or False, - 'rma_line_id': item.line_id.id if not item.line_id.rma_id else - False, + "partner_id": item.line_id.partner_id.id, + "name": item.line_id.rma_id.name or item.line_id.name, + "rma_id": item.line_id.rma_id and item.line_id.rma_id.id or False, + "rma_line_id": item.line_id.id if not item.line_id.rma_id else False, } return group_data @@ -87,34 +91,31 @@ class RmaMakePicking(models.TransientModel): elif item.line_id.partner_id: delivery_address = item.line_id.partner_id else: - raise ValidationError(_('Unknown delivery address')) + raise ValidationError(_("Unknown delivery address")) return delivery_address @api.model def _get_address_location(self, delivery_address_id, type): - if type == 'supplier': + if type == "supplier": return delivery_address_id.property_stock_supplier - elif type == 'customer': + elif type == "customer": return delivery_address_id.property_stock_customer @api.model def _get_procurement_data(self, item, group, qty, picking_type): line = item.line_id delivery_address_id = self._get_address(item) - if picking_type == 'incoming': + if picking_type == "incoming": if line.customer_to_supplier: - location = self._get_address_location( - delivery_address_id, 'supplier') + location = self._get_address_location(delivery_address_id, "supplier") elif line.supplier_to_customer: - location = self._get_address_location( - delivery_address_id, 'customer') + location = self._get_address_location(delivery_address_id, "customer") else: location = line.location_id warehouse = line.in_warehouse_id route = line.in_route_id else: - location = self._get_address_location( - delivery_address_id, line.type) + location = self._get_address_location(delivery_address_id, line.type) warehouse = line.out_warehouse_id route = line.out_route_id if not route: @@ -122,18 +123,18 @@ class RmaMakePicking(models.TransientModel): if not warehouse: raise ValidationError(_("No warehouse specified")) procurement_data = { - 'name': line.rma_id and line.rma_id.name or line.name, - 'group_id': group, - 'origin': line.name, - 'warehouse_id': warehouse, - 'date_planned': time.strftime(DT_FORMAT), - 'product_id': item.product_id, - 'product_qty': qty, - 'partner_id': delivery_address_id.id, - 'product_uom': line.product_id.product_tmpl_id.uom_id.id, - 'location_id': location, - 'rma_line_id': line.id, - 'route_ids': route + "name": line.rma_id and line.rma_id.name or line.name, + "group_id": group, + "origin": line.name, + "warehouse_id": warehouse, + "date_planned": time.strftime(DT_FORMAT), + "product_id": item.product_id, + "product_qty": qty, + "partner_id": delivery_address_id.id, + "product_uom": line.product_id.product_tmpl_id.uom_id.id, + "location_id": location, + "rma_line_id": line.id, + "route_ids": route, } return procurement_data @@ -143,47 +144,41 @@ class RmaMakePicking(models.TransientModel): group = self.find_procurement_group(item) if not group: pg_data = self._get_procurement_group_data(item) - group = self.env['procurement.group'].create(pg_data) - if picking_type == 'incoming': + group = self.env["procurement.group"].create(pg_data) + if picking_type == "incoming": qty = item.qty_to_receive else: qty = item.qty_to_deliver values = self._get_procurement_data(item, group, qty, picking_type) # create picking try: - self.env['procurement.group'].run( + self.env["procurement.group"].run( item.line_id.product_id, qty, item.line_id.product_id.product_tmpl_id.uom_id, - values.get('location_id'), - values.get('origin'), - values.get('origin'), - values + values.get("location_id"), + values.get("origin"), + values.get("origin"), + values, ) except UserError as error: - errors.append(error.name) + errors.append(error.name) if errors: - raise UserError('\n'.join(errors)) - return values.get('origin') + raise UserError("\n".join(errors)) + return values.get("origin") @api.multi def _create_picking(self): """Method called when the user clicks on create picking""" - picking_type = self.env.context.get('picking_type') + picking_type = self.env.context.get("picking_type") for item in self.item_ids: line = item.line_id - if line.state != 'approved': - raise ValidationError( - _('RMA %s is not approved') % - line.name) - if line.receipt_policy == 'no' and picking_type == \ - 'incoming': - raise ValidationError( - _('No shipments needed for this operation')) - if line.delivery_policy == 'no' and picking_type == \ - 'outgoing': - raise ValidationError( - _('No deliveries needed for this operation')) + if line.state != "approved": + raise ValidationError(_("RMA %s is not approved") % line.name) + if line.receipt_policy == "no" and picking_type == "incoming": + raise ValidationError(_("No shipments needed for this operation")) + if line.delivery_policy == "no" and picking_type == "outgoing": + raise ValidationError(_("No deliveries needed for this operation")) procurement = self._create_procurement(item, picking_type) return procurement @@ -192,67 +187,63 @@ class RmaMakePicking(models.TransientModel): if pickings and procurements: action = procurements.do_view_pickings() else: - action = self.env.ref( - 'procurement.procurement_order_action_exceptions') + action = self.env.ref("procurement.procurement_order_action_exceptions") action = action.read()[0] if procurements: # choose the view_mode accordingly if len(procurements.ids) <= 1: - res = self.env.ref('procurement.procurement_form_view', - False) - action['views'] = [(res and res.id or False, 'form')] - action['res_id'] = procurements.ids[0] + res = self.env.ref("procurement.procurement_form_view", False) + action["views"] = [(res and res.id or False, "form")] + action["res_id"] = procurements.ids[0] else: - action['domain'] = [('id', 'in', procurements.ids)] + action["domain"] = [("id", "in", procurements.ids)] return action @api.multi def action_create_picking(self): procurement = self._create_picking() - action = self.env.ref('stock.do_view_pickings') + action = self.env.ref("stock.do_view_pickings") action = action.read()[0] if procurement: - pickings = self.env['stock.picking'].search( - [('origin', '=', procurement)]).ids + pickings = ( + self.env["stock.picking"].search([("origin", "=", procurement)]).ids + ) if len(pickings) > 1: - action['domain'] = [('id', 'in', pickings)] + action["domain"] = [("id", "in", pickings)] else: - form = self.env.ref('stock.view_picking_form', False) - action['views'] = [(form and form.id or False, 'form')] - action['res_id'] = pickings and pickings[0] + form = self.env.ref("stock.view_picking_form", False) + action["views"] = [(form and form.id or False, "form")] + action["res_id"] = pickings and pickings[0] return action @api.multi def action_cancel(self): - return {'type': 'ir.actions.act_window_close'} + return {"type": "ir.actions.act_window_close"} class RmaMakePickingItem(models.TransientModel): _name = "rma_make_picking.wizard.item" _description = "Items to receive" - wiz_id = fields.Many2one( - 'rma_make_picking.wizard', - string='Wizard', required=True) - line_id = fields.Many2one('rma.order.line', - string='RMA order Line', - readonly=True, - ondelete='cascade') - rma_id = fields.Many2one('rma.order', - related='line_id.rma_id', - string='RMA Group', - readonly=True) - product_id = fields.Many2one('product.product', string='Product', - readonly=True) + wiz_id = fields.Many2one("rma_make_picking.wizard", string="Wizard", required=True) + line_id = fields.Many2one( + "rma.order.line", string="RMA order Line", readonly=True, ondelete="cascade" + ) + rma_id = fields.Many2one( + "rma.order", related="line_id.rma_id", string="RMA Group", readonly=True + ) + product_id = fields.Many2one("product.product", string="Product", readonly=True) product_qty = fields.Float( - related='line_id.product_qty', - string='Quantity Ordered', copy=False, - digits=dp.get_precision('Product Unit of Measure'), readonly=True) + related="line_id.product_qty", + string="Quantity Ordered", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + ) qty_to_receive = fields.Float( - string='Quantity to Receive', - digits=dp.get_precision('Product Unit of Measure')) + string="Quantity to Receive", digits=dp.get_precision("Product Unit of Measure") + ) qty_to_deliver = fields.Float( - string='Quantity To Deliver', - digits=dp.get_precision('Product Unit of Measure')) - uom_id = fields.Many2one('uom.uom', string='Unit of Measure', - readonly=True) + string="Quantity To Deliver", digits=dp.get_precision("Product Unit of Measure") + ) + uom_id = fields.Many2one("uom.uom", string="Unit of Measure", readonly=True) diff --git a/rma/wizards/rma_order_line_make_supplier_rma.py b/rma/wizards/rma_order_line_make_supplier_rma.py index e8d976c9..7ecc2877 100644 --- a/rma/wizards/rma_order_line_make_supplier_rma.py +++ b/rma/wizards/rma_order_line_make_supplier_rma.py @@ -1,86 +1,94 @@ # Copyright 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -import odoo.addons.decimal_precision as dp from odoo import _, api, fields, models from odoo.exceptions import ValidationError +import odoo.addons.decimal_precision as dp + class RmaLineMakeSupplierRma(models.TransientModel): _name = "rma.order.line.make.supplier.rma" _description = "RMA Line Make Supplier RMA" partner_id = fields.Many2one( - comodel_name='res.partner', string='Supplier', - domain=[('supplier', '=', True)], required=True, + comodel_name="res.partner", + string="Supplier", + domain=[("supplier", "=", True)], + required=True, ) item_ids = fields.One2many( - comodel_name='rma.order.line.make.supplier.rma.item', - inverse_name='wiz_id', string='Items', + comodel_name="rma.order.line.make.supplier.rma.item", + inverse_name="wiz_id", + string="Items", ) supplier_rma_id = fields.Many2one( - comodel_name='rma.order', string='Supplier RMA Order Group', + comodel_name="rma.order", string="Supplier RMA Order Group" ) @api.model def _get_default_operation(self): """Dropshipping is the most common use case of this wizard, thus trying to default to a dropshipping operation first.""" - operation = self.env['rma.operation'].search([ - ('type', '=', 'supplier'), - ('supplier_to_customer', '=', True)], limit=1) + operation = self.env["rma.operation"].search( + [("type", "=", "supplier"), ("supplier_to_customer", "=", True)], limit=1 + ) if not operation: - operation = self.env['rma.operation'].search( - [('type', '=', 'supplier')], limit=1) + operation = self.env["rma.operation"].search( + [("type", "=", "supplier")], limit=1 + ) return operation @api.model def _prepare_item(self, line): operation = self._get_default_operation() return { - 'line_id': line.id, - 'product_id': line.product_id.id, - 'name': line.name, - 'product_qty': line.qty_to_supplier_rma, - 'uom_id': line.uom_id.id, - 'operation_id': operation.id if operation else False, + "line_id": line.id, + "product_id": line.product_id.id, + "name": line.name, + "product_qty": line.qty_to_supplier_rma, + "uom_id": line.uom_id.id, + "operation_id": operation.id if operation else False, } @api.model def default_get(self, fields_list): - res = super(RmaLineMakeSupplierRma, self).default_get( - fields_list) - rma_line_obj = self.env['rma.order.line'] - rma_line_ids = self.env.context['active_ids'] or [] - active_model = self.env.context['active_model'] + res = super(RmaLineMakeSupplierRma, self).default_get(fields_list) + rma_line_obj = self.env["rma.order.line"] + rma_line_ids = self.env.context["active_ids"] or [] + active_model = self.env.context["active_model"] if not rma_line_ids: return res - assert active_model == 'rma.order.line', 'Bad context propagation' + assert active_model == "rma.order.line", "Bad context propagation" items = [] lines = rma_line_obj.browse(rma_line_ids) for line in lines: items.append([0, 0, self._prepare_item(line)]) suppliers = lines.mapped( - lambda r: r.supplier_address_id.parent_id or r.supplier_address_id) + lambda r: r.supplier_address_id.parent_id or r.supplier_address_id + ) if len(suppliers) > 1: raise ValidationError( - _('Only RMA lines from the same supplier can be ' - 'processed at the same time')) - res['partner_id'] = suppliers.id - res['item_ids'] = items + _( + "Only RMA lines from the same supplier can be " + "processed at the same time" + ) + ) + res["partner_id"] = suppliers.id + res["item_ids"] = items return res @api.model def _prepare_supplier_rma(self, company): if not self.partner_id: - raise ValidationError(_('Enter a supplier.')) + raise ValidationError(_("Enter a supplier.")) return { - 'partner_id': self.partner_id.id, - 'delivery_address_id': self.partner_id.id, - 'type': 'supplier', - 'company_id': company.id, + "partner_id": self.partner_id.id, + "delivery_address_id": self.partner_id.id, + "type": "supplier", + "company_id": company.id, } @api.model @@ -90,55 +98,61 @@ class RmaLineMakeSupplierRma(models.TransientModel): else: operation = self._get_default_operation() if not operation.in_route_id or not operation.out_route_id: - route = self.env['stock.location.route'].search( - [('rma_selectable', '=', True)], limit=1) + route = self.env["stock.location.route"].search( + [("rma_selectable", "=", True)], limit=1 + ) if not route: raise ValidationError(_("Please define an RMA route")) if not operation.in_warehouse_id or not operation.out_warehouse_id: - warehouse = self.env['stock.warehouse'].search( - [('company_id', '=', self.rma_id.company_id.id), - ('lot_rma_id', '!=', False)], limit=1) + warehouse = self.env["stock.warehouse"].search( + [ + ("company_id", "=", self.rma_id.company_id.id), + ("lot_rma_id", "!=", False), + ], + limit=1, + ) if not warehouse: raise ValidationError( - _("Please define a warehouse with a default RMA location")) + _("Please define a warehouse with a default RMA location") + ) data = { - 'partner_id': self.partner_id.id, - 'type': 'supplier', - 'origin': item.line_id.rma_id.name, - 'customer_address_id': - item.line_id.delivery_address_id.id or - item.line_id.partner_id.id, - 'product_id': item.line_id.product_id.id, - 'customer_rma_id': item.line_id.id, - 'product_qty': item.product_qty, - 'rma_id': rma.id if rma else False, - 'uom_id': item.line_id.uom_id.id, - 'operation_id': operation.id, - 'receipt_policy': operation.receipt_policy, - 'delivery_policy': operation.delivery_policy, - 'supplier_to_customer': operation.supplier_to_customer, - 'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, - 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, - 'in_route_id': operation.in_route_id.id or route.id, - 'out_route_id': operation.out_route_id.id or route.id, - 'location_id': (operation.location_id.id or - operation.in_warehouse_id.lot_rma_id.id or - warehouse.lot_rma_id.id) + "partner_id": self.partner_id.id, + "type": "supplier", + "origin": item.line_id.rma_id.name, + "customer_address_id": item.line_id.delivery_address_id.id + or item.line_id.partner_id.id, + "product_id": item.line_id.product_id.id, + "customer_rma_id": item.line_id.id, + "product_qty": item.product_qty, + "rma_id": rma.id if rma else False, + "uom_id": item.line_id.uom_id.id, + "operation_id": operation.id, + "receipt_policy": operation.receipt_policy, + "delivery_policy": operation.delivery_policy, + "supplier_to_customer": operation.supplier_to_customer, + "in_warehouse_id": operation.in_warehouse_id.id or warehouse.id, + "out_warehouse_id": operation.out_warehouse_id.id or warehouse.id, + "in_route_id": operation.in_route_id.id or route.id, + "out_route_id": operation.out_route_id.id or route.id, + "location_id": ( + operation.location_id.id + or operation.in_warehouse_id.lot_rma_id.id + or warehouse.lot_rma_id.id + ), } return data @api.multi def make_supplier_rma(self): self = self.with_context(supplier=True, customer=False) - rma_obj = self.env['rma.order'] - rma_line_obj = self.env['rma.order.line'] + rma_obj = self.env["rma.order"] + rma_line_obj = self.env["rma.order.line"] rma = False for item in self.item_ids: line = item.line_id if item.product_qty <= 0.0: - raise ValidationError( - _('Enter a positive quantity.')) + raise ValidationError(_("Enter a positive quantity.")) if self.supplier_rma_id: rma = self.supplier_rma_id @@ -150,25 +164,25 @@ class RmaLineMakeSupplierRma(models.TransientModel): rma_line = rma_line_obj.create(rma_line_data) if rma: return { - 'name': _('Supplier RMA'), - 'view_type': 'form', - 'view_mode': 'form', - 'res_model': 'rma.order', - 'view_id': False, - 'res_id': rma.id, - 'context': {'supplier': True, 'customer': False}, - 'type': 'ir.actions.act_window' + "name": _("Supplier RMA"), + "view_type": "form", + "view_mode": "form", + "res_model": "rma.order", + "view_id": False, + "res_id": rma.id, + "context": {"supplier": True, "customer": False}, + "type": "ir.actions.act_window", } else: return { - 'name': _('Supplier RMA Line'), - 'view_type': 'form', - 'view_mode': 'form', - 'res_model': 'rma.order.line', - 'view_id': False, - 'res_id': rma_line.id, - 'context': {'supplier': True, 'customer': False}, - 'type': 'ir.actions.act_window' + "name": _("Supplier RMA Line"), + "view_type": "form", + "view_mode": "form", + "res_model": "rma.order.line", + "view_id": False, + "res_id": rma_line.id, + "context": {"supplier": True, "customer": False}, + "type": "ir.actions.act_window", } @@ -177,22 +191,28 @@ class RmaLineMakeRmaOrderItem(models.TransientModel): _description = "RMA Line Make Supplier RMA Item" wiz_id = fields.Many2one( - 'rma.order.line.make.supplier.rma', - string='Wizard', required=True, ondelete='cascade', - readonly=True) - line_id = fields.Many2one('rma.order.line', - string='RMA Line', - required=True, - ondelete='cascade') - rma_id = fields.Many2one('rma.order', related='line_id.rma_id', - string='RMA Order', readonly=True) - product_id = fields.Many2one('product.product', - related='line_id.product_id', readony=True) - name = fields.Char(related='line_id.name', readonly=True) - uom_id = fields.Many2one('uom.uom', string='UoM', readonly=True) - product_qty = fields.Float(string='Quantity', - digits=dp.get_precision('Product UoS')) - operation_id = fields.Many2one( - comodel_name="rma.operation", string="Operation", - domain=[('type', '=', 'supplier')], + "rma.order.line.make.supplier.rma", + string="Wizard", + required=True, + ondelete="cascade", + readonly=True, + ) + line_id = fields.Many2one( + "rma.order.line", string="RMA Line", required=True, ondelete="cascade" + ) + rma_id = fields.Many2one( + "rma.order", related="line_id.rma_id", string="RMA Order", readonly=True + ) + product_id = fields.Many2one( + "product.product", related="line_id.product_id", readony=True + ) + name = fields.Char(related="line_id.name", readonly=True) + uom_id = fields.Many2one("uom.uom", string="UoM", readonly=True) + product_qty = fields.Float( + string="Quantity", digits=dp.get_precision("Product UoS") + ) + operation_id = fields.Many2one( + comodel_name="rma.operation", + string="Operation", + domain=[("type", "=", "supplier")], ) diff --git a/rma/wizards/stock_config_settings.py b/rma/wizards/stock_config_settings.py index a598ae2c..5c6654aa 100644 --- a/rma/wizards/stock_config_settings.py +++ b/rma/wizards/stock_config_settings.py @@ -1,23 +1,31 @@ # Copyright (C) 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import models, fields +from odoo import fields, models class StockConfigSettings(models.TransientModel): - _inherit = 'res.config.settings' + _inherit = "res.config.settings" - group_rma_delivery_address = fields.Selection([ - (0, "Invoicing and shipping addresses are always the same " - "(Example: services companies)"), - (1, 'Display 3 fields on rma: partner, invoice address, delivery ' - 'address') - ], "Addresses", - implied_group='rma.group_rma_delivery_invoice_address') + group_rma_delivery_address = fields.Selection( + [ + ( + 0, + "Invoicing and shipping addresses are always the same " + "(Example: services companies)", + ), + ( + 1, + "Display 3 fields on rma: partner, invoice address, delivery " + "address", + ), + ], + "Addresses", + implied_group="rma.group_rma_delivery_invoice_address", + ) - group_rma_lines = fields.Selection([ - (0, "Do not group RMA lines"), - (1, 'Group RMA lines in one RMA group') - ], "Grouping", - implied_group='rma.group_rma_groups', - ) + group_rma_lines = fields.Selection( + [(0, "Do not group RMA lines"), (1, "Group RMA lines in one RMA group")], + "Grouping", + implied_group="rma.group_rma_groups", + )