From 9328d47d738444a3743fcf0615ea6e9743c308b4 Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Wed, 22 Jan 2020 11:18:04 +0100 Subject: [PATCH] [IMP] : black, isort --- rma_account/__manifest__.py | 38 +-- rma_account/models/invoice.py | 144 +++++---- rma_account/models/rma_operation.py | 17 +- rma_account/models/rma_order.py | 96 +++--- rma_account/models/rma_order_line.py | 298 ++++++++++------- rma_account/tests/test_rma_account.py | 299 +++++++++--------- rma_account/wizards/rma_add_invoice.py | 134 ++++---- .../rma_order_line_make_supplier_rma.py | 9 +- rma_account/wizards/rma_refund.py | 246 +++++++------- 9 files changed, 698 insertions(+), 583 deletions(-) diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index 47ddd0b0..7ba3aebe 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -2,24 +2,24 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) { - 'name': 'RMA Account', - 'version': '12.0.1.0.0', - 'license': 'LGPL-3', - 'category': 'RMA', - 'summary': 'Integrates RMA with Invoice Processing', - 'author': "Eficent, Odoo Community Association (OCA)", - 'website': 'https://github.com/Eficent/stock-rma', - 'depends': ['stock_account', 'rma'], - 'demo': ['data/rma_operation.xml'], - 'data': [ - 'security/ir.model.access.csv', - 'views/rma_order_view.xml', - 'views/rma_operation_view.xml', - 'views/rma_order_line_view.xml', - 'views/invoice_view.xml', - 'views/rma_account_menu.xml', - 'wizards/rma_add_invoice.xml', - 'wizards/rma_refund.xml', + "name": "RMA Account", + "version": "12.0.1.0.0", + "license": "LGPL-3", + "category": "RMA", + "summary": "Integrates RMA with Invoice Processing", + "author": "Eficent, Odoo Community Association (OCA)", + "website": "https://github.com/Eficent/stock-rma", + "depends": ["stock_account", "rma"], + "demo": ["data/rma_operation.xml"], + "data": [ + "security/ir.model.access.csv", + "views/rma_order_view.xml", + "views/rma_operation_view.xml", + "views/rma_order_line_view.xml", + "views/invoice_view.xml", + "views/rma_account_menu.xml", + "wizards/rma_add_invoice.xml", + "wizards/rma_refund.xml", ], - 'installable': True, + "installable": True, } diff --git a/rma_account/models/invoice.py b/rma_account/models/invoice.py index 1b8b9fa9..3fadd0b4 100644 --- a/rma_account/models/invoice.py +++ b/rma_account/models/invoice.py @@ -8,92 +8,89 @@ from odoo.tools.float_utils import float_compare class AccountInvoice(models.Model): _inherit = "account.invoice" - @api.depends('invoice_line_ids.rma_line_ids') + @api.depends("invoice_line_ids.rma_line_ids") def _compute_rma_count(self): for inv in self: - rmas = self.mapped('invoice_line_ids.rma_line_ids') + rmas = self.mapped("invoice_line_ids.rma_line_ids") inv.rma_count = len(rmas) def _prepare_invoice_line_from_rma_line(self, line): qty = line.qty_to_refund - if float_compare( - qty, 0.0, precision_rounding=line.uom_id.rounding) <= 0: + if float_compare(qty, 0.0, precision_rounding=line.uom_id.rounding) <= 0: qty = 0.0 # Todo fill taxes from somewhere - invoice_line = self.env['account.invoice.line'] + invoice_line = self.env["account.invoice.line"] data = { - 'purchase_line_id': line.id, - 'name': line.name + ': '+line.name, - 'origin': line.origin, - 'uom_id': line.uom_id.id, - 'product_id': line.product_id.id, - 'account_id': invoice_line.with_context( - {'journal_id': self.journal_id.id, - 'type': 'in_invoice'})._default_account(), - 'price_unit': line.company_id.currency_id.with_context( - date=self.date_invoice).compute( - line.price_unit, self.currency_id, round=False), - 'quantity': qty, - 'discount': 0.0, - 'rma_line_ids': [(4, line.id)], + "purchase_line_id": line.id, + "name": line.name + ": " + line.name, + "origin": line.origin, + "uom_id": line.uom_id.id, + "product_id": line.product_id.id, + "account_id": invoice_line.with_context( + {"journal_id": self.journal_id.id, "type": "in_invoice"} + )._default_account(), + "price_unit": line.company_id.currency_id.with_context( + date=self.date_invoice + ).compute(line.price_unit, self.currency_id, round=False), + "quantity": qty, + "discount": 0.0, + "rma_line_ids": [(4, line.id)], } return data - @api.onchange('add_rma_line_id') + @api.onchange("add_rma_line_id") def on_change_add_rma_line_id(self): if not self.add_rma_line_id: return {} if not self.partner_id: self.partner_id = self.add_rma_line_id.partner_id.id - new_line = self.env['account.invoice.line'] - if self.add_rma_line_id not in ( - self.invoice_line_ids.mapped('rma_line_id')): - data = self._prepare_invoice_line_from_rma_line( - self.add_rma_line_id) + new_line = self.env["account.invoice.line"] + if self.add_rma_line_id not in (self.invoice_line_ids.mapped("rma_line_id")): + data = self._prepare_invoice_line_from_rma_line(self.add_rma_line_id) new_line = new_line.new(data) new_line._set_additional_fields(self) self.invoice_line_ids += new_line self.add_rma_line_id = False return {} - rma_count = fields.Integer( - compute='_compute_rma_count', string='# of RMA') + rma_count = fields.Integer(compute="_compute_rma_count", string="# of RMA") add_rma_line_id = fields.Many2one( - comodel_name='rma.order.line', + comodel_name="rma.order.line", string="Add from RMA line", ondelete="set null", - help="Create a refund in based on an existing rma_line") + help="Create a refund in based on an existing rma_line", + ) @api.multi def action_view_rma_supplier(self): - action = self.env.ref('rma.action_rma_supplier_lines') + action = self.env.ref("rma.action_rma_supplier_lines") result = action.read()[0] - rma_ids = self.mapped('invoice_line_ids.rma_line_ids').ids + rma_ids = self.mapped("invoice_line_ids.rma_line_ids").ids if rma_ids: # choose the view_mode accordingly if len(rma_ids) > 1: - result['domain'] = [('id', 'in', rma_ids)] + result["domain"] = [("id", "in", rma_ids)] else: - res = self.env.ref('rma.view_rma_line_supplier_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = rma_ids[0] + res = self.env.ref("rma.view_rma_line_supplier_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = rma_ids[0] return result @api.multi def action_view_rma_customer(self): - action = self.env.ref('rma.action_rma_customer_lines') + action = self.env.ref("rma.action_rma_customer_lines") result = action.read()[0] - rma_ids = self.mapped('invoice_line_ids.rma_line_ids').ids + rma_ids = self.mapped("invoice_line_ids.rma_line_ids").ids if rma_ids: # choose the view_mode accordingly if len(rma_ids) > 1: - result['domain'] = [('id', 'in', rma_ids)] + result["domain"] = [("id", "in", rma_ids)] else: - res = self.env.ref('rma.view_rma_line_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = rma_ids[0] + res = self.env.ref("rma.view_rma_line_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = rma_ids[0] return result @@ -101,15 +98,13 @@ class AccountInvoiceLine(models.Model): _inherit = "account.invoice.line" @api.model - def name_search(self, name, args=None, operator='ilike', limit=100): + def name_search(self, name, args=None, operator="ilike", limit=100): """Allows to search by Invoice number. This has to be done this way, as Odoo adds extra args to name_search on _name_search method that will make impossible to get the desired result.""" if not args: args = [] - lines = self.search( - [('invoice_id.number', operator, name)] + args, limit=limit, - ) + lines = self.search([("invoice_id.number", operator, name)] + args, limit=limit) res = lines.name_get() if limit: limit_rest = limit - len(lines) @@ -117,32 +112,44 @@ class AccountInvoiceLine(models.Model): # limit can be 0 or None representing infinite limit_rest = limit if limit_rest or not limit: - args += [('id', 'not in', lines.ids)] + args += [("id", "not in", lines.ids)] res += super(AccountInvoiceLine, self).name_search( - name, args=args, operator=operator, limit=limit_rest, + name, args=args, operator=operator, limit=limit_rest ) return res @api.multi def name_get(self): res = [] - if self.env.context.get('rma'): + if self.env.context.get("rma"): for inv in self: if inv.invoice_id.reference: res.append( - (inv.id, - "INV:%s | REF:%s | ORIG:%s | PART:%s | QTY:%s" % ( - inv.invoice_id.number or '', - inv.origin or '', - inv.invoice_id.reference or "", - inv.product_id.name, inv.quantity))) + ( + inv.id, + "INV:%s | REF:%s | ORIG:%s | PART:%s | QTY:%s" + % ( + inv.invoice_id.number or "", + inv.origin or "", + inv.invoice_id.reference or "", + inv.product_id.name, + inv.quantity, + ), + ) + ) elif inv.invoice_id.number: res.append( - (inv.id, - "INV:%s | ORIG:%s | PART:%s | QTY:%s" % ( - inv.invoice_id.number or '', - inv.origin or '', - inv.product_id.name, inv.quantity))) + ( + inv.id, + "INV:%s | ORIG:%s | PART:%s | QTY:%s" + % ( + inv.invoice_id.number or "", + inv.origin or "", + inv.product_id.name, + inv.quantity, + ), + ) + ) else: res.append(super(AccountInvoiceLine, inv).name_get()[0]) return res @@ -152,18 +159,21 @@ class AccountInvoiceLine(models.Model): @api.multi def _compute_rma_count(self): for invl in self: - rma_lines = invl.mapped('rma_line_ids') + rma_lines = invl.mapped("rma_line_ids") invl.rma_line_count = len(rma_lines) - rma_line_count = fields.Integer( - compute='_compute_rma_count', string='# of RMA') + rma_line_count = fields.Integer(compute="_compute_rma_count", string="# of RMA") rma_line_ids = fields.One2many( - comodel_name='rma.order.line', inverse_name='invoice_line_id', - string="RMA", readonly=True, - help="This will contain the RMA lines for the invoice line") + comodel_name="rma.order.line", + inverse_name="invoice_line_id", + string="RMA", + readonly=True, + help="This will contain the RMA lines for the invoice line", + ) rma_line_id = fields.Many2one( - comodel_name='rma.order.line', + comodel_name="rma.order.line", string="RMA line refund", ondelete="set null", - help="This will contain the rma line that originated the refund line") + help="This will contain the rma line that originated the refund line", + ) diff --git a/rma_account/models/rma_operation.py b/rma_account/models/rma_operation.py index 88085d85..53ce4ed3 100644 --- a/rma_account/models/rma_operation.py +++ b/rma_account/models/rma_operation.py @@ -5,10 +5,15 @@ from odoo import fields, models class RmaOperation(models.Model): - _inherit = 'rma.operation' + _inherit = "rma.operation" - refund_policy = fields.Selection([ - ('no', 'No refund'), ('ordered', 'Based on Ordered Quantities'), - ('delivered', 'Based on Delivered Quantities'), - ('received', 'Based on Received Quantities')], string="Refund Policy", - default='no') + refund_policy = fields.Selection( + [ + ("no", "No refund"), + ("ordered", "Based on Ordered Quantities"), + ("delivered", "Based on Delivered Quantities"), + ("received", "Based on Received Quantities"), + ], + string="Refund Policy", + default="no", + ) diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index 82a4591b..240ca011 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/models/rma_order.py @@ -10,58 +10,64 @@ class RmaOrder(models.Model): @api.multi def _compute_invoice_refund_count(self): for rec in self: - invoices = rec.mapped( - 'rma_line_ids.refund_line_ids.invoice_id') + invoices = rec.mapped("rma_line_ids.refund_line_ids.invoice_id") rec.invoice_refund_count = len(invoices) @api.multi def _compute_invoice_count(self): for rec in self: - invoices = rec.mapped('rma_line_ids.invoice_id') + invoices = rec.mapped("rma_line_ids.invoice_id") rec.invoice_count = len(invoices) add_invoice_id = fields.Many2one( - comodel_name='account.invoice', string='Add Invoice', - ondelete='set null', readonly=True, + comodel_name="account.invoice", + string="Add Invoice", + ondelete="set null", + readonly=True, ) invoice_refund_count = fields.Integer( - compute='_compute_invoice_refund_count', string='# of Refunds') + compute="_compute_invoice_refund_count", string="# of Refunds" + ) invoice_count = fields.Integer( - compute='_compute_invoice_count', string='# of Invoices') + compute="_compute_invoice_count", string="# of Invoices" + ) def _prepare_rma_line_from_inv_line(self, line): - if self.type == 'customer': - operation =\ - self.rma_line_ids.product_id.rma_customer_operation_id or \ - self.rma_line_ids.product_id.categ_id.rma_customer_operation_id + if self.type == "customer": + operation = ( + self.rma_line_ids.product_id.rma_customer_operation_id + or self.rma_line_ids.product_id.categ_id.rma_customer_operation_id + ) else: - operation =\ - self.rma_line_ids.product_id.rma_supplier_operation_id or \ - self.rma_line_ids.product_id.categ_id.rma_supplier_operation_id + operation = ( + self.rma_line_ids.product_id.rma_supplier_operation_id + or self.rma_line_ids.product_id.categ_id.rma_supplier_operation_id + ) data = { - 'invoice_line_id': line.id, - 'product_id': line.product_id.id, - 'name': line.name, - 'origin': line.invoice_id.number, - 'uom_id': line.uom_id.id, - 'operation_id': operation, - 'product_qty': line.quantity, - 'price_unit': line.invoice_id.currency_id.compute( - line.price_unit, line.currency_id, round=False), - 'rma_id': self.id + "invoice_line_id": line.id, + "product_id": line.product_id.id, + "name": line.name, + "origin": line.invoice_id.number, + "uom_id": line.uom_id.id, + "operation_id": operation, + "product_qty": line.quantity, + "price_unit": line.invoice_id.currency_id.compute( + line.price_unit, line.currency_id, round=False + ), + "rma_id": self.id, } return data - @api.onchange('add_invoice_id') + @api.onchange("add_invoice_id") def on_change_invoice(self): if not self.add_invoice_id: return {} if not self.partner_id: self.partner_id = self.add_invoice_id.partner_id.id - new_lines = self.env['rma.order.line'] + new_lines = self.env["rma.order.line"] for line in self.add_invoice_id.invoice_line_ids: # Load a PO line only once - if line in self.rma_line_ids.mapped('invoice_line_id'): + if line in self.rma_line_ids.mapped("invoice_line_id"): continue data = self._prepare_rma_line_from_inv_line(line) new_line = new_lines.new(data) @@ -76,48 +82,46 @@ class RmaOrder(models.Model): @api.model def prepare_rma_line(self, origin_rma, rma_id, line): - line_values = super(RmaOrder, self).prepare_rma_line( - origin_rma, rma_id, line) - line_values['invoice_address_id'] = line.invoice_address_id.id + line_values = super(RmaOrder, self).prepare_rma_line(origin_rma, rma_id, line) + line_values["invoice_address_id"] = line.invoice_address_id.id return line_values @api.model def _prepare_rma_data(self, partner, origin_rma): res = super(RmaOrder, self)._prepare_rma_data(partner, origin_rma) - res['invoice_address_id'] = partner.id + res["invoice_address_id"] = partner.id return res @api.multi def action_view_invoice_refund(self): - action = self.env.ref('account.action_invoice_tree2') + action = self.env.ref("account.action_invoice_tree2") result = action.read()[0] - invoice_ids = self.mapped( - 'rma_line_ids.refund_line_ids.invoice_id').ids + invoice_ids = self.mapped("rma_line_ids.refund_line_ids.invoice_id").ids if invoice_ids: # choose the view_mode accordingly if len(invoice_ids) > 1: - result['domain'] = [('id', 'in', invoice_ids)] + result["domain"] = [("id", "in", invoice_ids)] else: - res = self.env.ref('account.invoice_supplier_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids[0] + res = self.env.ref("account.invoice_supplier_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = invoice_ids[0] return result @api.multi def action_view_invoice(self): if self.type == "supplier": - action = self.env.ref('account.action_invoice_tree2') - res = self.env.ref('account.invoice_supplier_form', False) + action = self.env.ref("account.action_invoice_tree2") + res = self.env.ref("account.invoice_supplier_form", False) else: - action = self.env.ref('account.action_invoice_tree') - res = self.env.ref('account.invoice_form', False) + action = self.env.ref("account.action_invoice_tree") + res = self.env.ref("account.invoice_form", False) result = action.read()[0] - invoice_ids = self.mapped('rma_line_ids.invoice_id').ids + invoice_ids = self.mapped("rma_line_ids.invoice_id").ids if invoice_ids: # choose the view_mode accordingly if len(invoice_ids) > 1: - result['domain'] = [('id', 'in', invoice_ids)] + result["domain"] = [("id", "in", invoice_ids)] else: - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids[0] + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = invoice_ids[0] return result diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 61e7a5fb..c6dd50ab 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -1,8 +1,9 @@ # © 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 import _, api, fields, models +from odoo.exceptions import UserError, ValidationError + from odoo.addons import decimal_precision as dp @@ -11,90 +12,125 @@ class RmaOrderLine(models.Model): @api.model def _default_invoice_address(self): - partner_id = self.env.context.get('partner_id') + partner_id = self.env.context.get("partner_id") if partner_id: - return self.env['res.partner'].browse(partner_id) - return self.env['res.partner'] + return self.env["res.partner"].browse(partner_id) + return self.env["res.partner"] @api.multi - @api.depends('refund_line_ids', 'refund_line_ids.invoice_id.state', - 'refund_policy', 'type') + @api.depends( + "refund_line_ids", "refund_line_ids.invoice_id.state", "refund_policy", "type" + ) def _compute_qty_refunded(self): for rec in self: - rec.qty_refunded = sum(rec.refund_line_ids.filtered( - lambda i: i.invoice_id.state in ('open', 'paid')).mapped( - 'quantity')) + rec.qty_refunded = sum( + rec.refund_line_ids.filtered( + lambda i: i.invoice_id.state in ("open", "paid") + ).mapped("quantity") + ) - @api.depends('refund_line_ids', 'refund_line_ids.invoice_id.state', - 'refund_policy', 'move_ids', 'move_ids.state', 'type') + @api.depends( + "refund_line_ids", + "refund_line_ids.invoice_id.state", + "refund_policy", + "move_ids", + "move_ids.state", + "type", + ) def _compute_qty_to_refund(self): qty = 0.0 for res in self: - if res.refund_policy == 'ordered': + if res.refund_policy == "ordered": qty = res.product_qty - res.qty_refunded - elif res.refund_policy == 'received': + elif res.refund_policy == "received": qty = res.qty_received - res.qty_refunded - elif res.refund_policy == 'delivered': + elif res.refund_policy == "delivered": qty = res.qty_delivered - res.qty_refunded res.qty_to_refund = qty @api.multi def _compute_refund_count(self): for rec in self: - rec.refund_count = len(rec.refund_line_ids.mapped('invoice_id')) + rec.refund_count = len(rec.refund_line_ids.mapped("invoice_id")) invoice_address_id = fields.Many2one( - 'res.partner', string='Partner invoice address', + "res.partner", + string="Partner invoice address", default=lambda self: self._default_invoice_address(), - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, help="Invoice address for current rma order.", ) refund_count = fields.Integer( - compute='_compute_refund_count', string='# of Refunds', default=0) + compute="_compute_refund_count", string="# of Refunds", default=0 + ) invoice_line_id = fields.Many2one( - comodel_name='account.invoice.line', - string='Originating Invoice Line', - ondelete='restrict', + comodel_name="account.invoice.line", + string="Originating Invoice Line", + ondelete="restrict", index=True, - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, ) refund_line_ids = fields.One2many( - comodel_name='account.invoice.line', - inverse_name='rma_line_id', string='Refund Lines', - copy=False, index=True, readonly=True, + comodel_name="account.invoice.line", + inverse_name="rma_line_id", + string="Refund Lines", + copy=False, + index=True, + readonly=True, ) - invoice_id = fields.Many2one('account.invoice', string='Source', - related='invoice_line_id.invoice_id', - index=True, readonly=True) - refund_policy = fields.Selection([ - ('no', 'No refund'), ('ordered', 'Based on Ordered Quantities'), - ('delivered', 'Based on Delivered Quantities'), - ('received', 'Based on Received Quantities')], string="Refund Policy", - required=True, default='no', - readonly=True, states={'draft': [('readonly', False)]}, + invoice_id = fields.Many2one( + "account.invoice", + string="Source", + related="invoice_line_id.invoice_id", + index=True, + readonly=True, + ) + refund_policy = fields.Selection( + [ + ("no", "No refund"), + ("ordered", "Based on Ordered Quantities"), + ("delivered", "Based on Delivered Quantities"), + ("received", "Based on Received Quantities"), + ], + string="Refund Policy", + required=True, + default="no", + readonly=True, + states={"draft": [("readonly", False)]}, ) qty_to_refund = fields.Float( - string='Qty To Refund', copy=False, - digits=dp.get_precision('Product Unit of Measure'), readonly=True, - compute='_compute_qty_to_refund', store=True) + string="Qty To Refund", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty_to_refund", + store=True, + ) qty_refunded = fields.Float( - string='Qty Refunded', copy=False, - digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute='_compute_qty_refunded', store=True) + string="Qty Refunded", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty_refunded", + store=True, + ) - @api.onchange('product_id', 'partner_id') + @api.onchange("product_id", "partner_id") def _onchange_product_id(self): """Domain for sale_line_id is computed here to make it dynamic.""" res = super(RmaOrderLine, self)._onchange_product_id() - if not res.get('domain'): - res['domain'] = {} + if not res.get("domain"): + res["domain"] = {} domain = [ - '|', - ('invoice_id.partner_id', '=', self.partner_id.id), - ('invoice_id.partner_id', 'child_of', self.partner_id.id)] + "|", + ("invoice_id.partner_id", "=", self.partner_id.id), + ("invoice_id.partner_id", "child_of", self.partner_id.id), + ] if self.product_id: - domain.append(('product_id', '=', self.product_id.id)) - res['domain']['invoice_line_id'] = domain + domain.append(("product_id", "=", self.product_id.id)) + res["domain"]["invoice_line_id"] = domain return res @api.multi @@ -102,137 +138,157 @@ class RmaOrderLine(models.Model): self.ensure_one() if not self.type: self.type = self._get_default_type() - if self.type == 'customer': - operation = line.product_id.rma_customer_operation_id or \ - line.product_id.categ_id.rma_customer_operation_id + if self.type == "customer": + operation = ( + line.product_id.rma_customer_operation_id + or line.product_id.categ_id.rma_customer_operation_id + ) else: - operation = line.product_id.rma_supplier_operation_id or \ - line.product_id.categ_id.rma_supplier_operation_id + operation = ( + line.product_id.rma_supplier_operation_id + or line.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")) + raise ValidationError( + _("Please define a warehouse with a" " default rma location") + ) data = { - 'product_id': line.product_id.id, - 'origin': line.invoice_id.number, - 'uom_id': line.uom_id.id, - 'operation_id': operation.id, - 'product_qty': line.quantity, - 'price_unit': line.invoice_id.currency_id.compute( - line.price_unit, line.currency_id, round=False), - 'delivery_address_id': line.invoice_id.partner_id.id, - 'invoice_address_id': line.invoice_id.partner_id.id, - 'receipt_policy': operation.receipt_policy, - 'refund_policy': operation.refund_policy, - 'delivery_policy': operation.delivery_policy, - 'currency_id': line.currency_id.id, - '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": line.product_id.id, + "origin": line.invoice_id.number, + "uom_id": line.uom_id.id, + "operation_id": operation.id, + "product_qty": line.quantity, + "price_unit": line.invoice_id.currency_id.compute( + line.price_unit, line.currency_id, round=False + ), + "delivery_address_id": line.invoice_id.partner_id.id, + "invoice_address_id": line.invoice_id.partner_id.id, + "receipt_policy": operation.receipt_policy, + "refund_policy": operation.refund_policy, + "delivery_policy": operation.delivery_policy, + "currency_id": line.currency_id.id, + "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.onchange('invoice_line_id') + @api.onchange("invoice_line_id") def _onchange_invoice_line_id(self): if not self.invoice_line_id: return - data = self._prepare_rma_line_from_inv_line( - self.invoice_line_id) + data = self._prepare_rma_line_from_inv_line(self.invoice_line_id) self.update(data) - self._remove_other_data_origin('invoice_line_id') + self._remove_other_data_origin("invoice_line_id") @api.multi - @api.constrains('invoice_line_id', 'partner_id') + @api.constrains("invoice_line_id", "partner_id") def _check_invoice_partner(self): for rec in self: - if (rec.invoice_line_id and - rec.invoice_line_id.invoice_id.partner_id != - rec.partner_id): - raise ValidationError(_( - "RMA customer and originating invoice line customer " - "doesn't match.")) + if ( + rec.invoice_line_id + and rec.invoice_line_id.invoice_id.partner_id != rec.partner_id + ): + raise ValidationError( + _( + "RMA customer and originating invoice line customer " + "doesn't match." + ) + ) @api.multi def _remove_other_data_origin(self, exception): res = super(RmaOrderLine, self)._remove_other_data_origin(exception) - if not exception == 'invoice_line_id': + if not exception == "invoice_line_id": self.invoice_line_id = False return res - @api.onchange('operation_id') + @api.onchange("operation_id") def _onchange_operation_id(self): result = super(RmaOrderLine, self)._onchange_operation_id() if self.operation_id: - self.refund_policy = self.operation_id.refund_policy or 'no' + self.refund_policy = self.operation_id.refund_policy or "no" return result @api.multi - @api.constrains('invoice_line_id') + @api.constrains("invoice_line_id") def _check_duplicated_lines(self): for line in self: - matching_inv_lines = self.env['account.invoice.line'].search([( - 'id', '=', line.invoice_line_id.id)]) + matching_inv_lines = self.env["account.invoice.line"].search( + [("id", "=", line.invoice_line_id.id)] + ) if len(matching_inv_lines) > 1: - raise UserError( - _("There's an rma for the invoice line %s " - "and invoice %s" % - (line.invoice_line_id, - line.invoice_line_id.invoice_id))) + raise UserError( + _( + "There's an rma for the invoice line %s " + "and invoice %s" + % (line.invoice_line_id, line.invoice_line_id.invoice_id) + ) + ) return {} @api.multi def action_view_invoice(self): - action = self.env.ref('account.action_invoice_tree') + action = self.env.ref("account.action_invoice_tree") result = action.read()[0] - res = self.env.ref('account.invoice_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['view_id'] = res and res.id or False - result['res_id'] = self.invoice_line_id.invoice_id.id + res = self.env.ref("account.invoice_form", False) + result["views"] = [(res and res.id or False, "form")] + result["view_id"] = res and res.id or False + result["res_id"] = self.invoice_line_id.invoice_id.id return result @api.multi def action_view_refunds(self): - action = self.env.ref('account.action_invoice_tree2') + action = self.env.ref("account.action_invoice_tree2") result = action.read()[0] - invoice_ids = self.mapped('refund_line_ids.invoice_id').ids + invoice_ids = self.mapped("refund_line_ids.invoice_id").ids if invoice_ids: # choose the view_mode accordingly if len(invoice_ids) > 1: - result['domain'] = [('id', 'in', invoice_ids)] + result["domain"] = [("id", "in", invoice_ids)] else: - res = self.env.ref('account.invoice_supplier_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids[0] + res = self.env.ref("account.invoice_supplier_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = invoice_ids[0] return result @api.multi def name_get(self): res = [] - if self.env.context.get('rma'): + if self.env.context.get("rma"): for rma in self: - res.append((rma.id, "%s %s qty:%s" % ( - rma.name, - rma.product_id.name, - rma.product_qty))) + res.append( + ( + rma.id, + "%s %s qty:%s" + % (rma.name, rma.product_id.name, rma.product_qty), + ) + ) return res else: return super(RmaOrderLine, self).name_get() diff --git a/rma_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py index 4da5c8cb..53c164fd 100644 --- a/rma_account/tests/test_rma_account.py +++ b/rma_account/tests/test_rma_account.py @@ -5,193 +5,206 @@ from odoo.tests import common class TestRmaAccount(common.SingleTransactionCase): - @classmethod def setUpClass(cls): super(TestRmaAccount, cls).setUpClass() - cls.rma_obj = cls.env['rma.order'] - cls.rma_line_obj = cls.env['rma.order.line'] - cls.rma_op_obj = cls.env['rma.operation'] - cls.rma_add_invoice_wiz = cls.env['rma_add_invoice'] - cls.rma_refund_wiz = cls.env['rma.refund'] - cls.acc_obj = cls.env['account.account'] - cls.inv_obj = cls.env['account.invoice'] - cls.invl_obj = cls.env['account.invoice.line'] - cls.product_obj = cls.env['product.product'] - cls.partner_obj = cls.env['res.partner'] + cls.rma_obj = cls.env["rma.order"] + cls.rma_line_obj = cls.env["rma.order.line"] + cls.rma_op_obj = cls.env["rma.operation"] + cls.rma_add_invoice_wiz = cls.env["rma_add_invoice"] + cls.rma_refund_wiz = cls.env["rma.refund"] + cls.acc_obj = cls.env["account.account"] + cls.inv_obj = cls.env["account.invoice"] + cls.invl_obj = cls.env["account.invoice.line"] + cls.product_obj = cls.env["product.product"] + cls.partner_obj = cls.env["res.partner"] - cls.rma_route_cust = cls.env.ref('rma.route_rma_customer') - receivable_type = cls.env.ref('account.data_account_type_receivable') - payable_type = cls.env.ref('account.data_account_type_payable') - cls.cust_refund_op = cls.env.ref( - 'rma_account.rma_operation_customer_refund') + cls.rma_route_cust = cls.env.ref("rma.route_rma_customer") + receivable_type = cls.env.ref("account.data_account_type_receivable") + payable_type = cls.env.ref("account.data_account_type_payable") + cls.cust_refund_op = cls.env.ref("rma_account.rma_operation_customer_refund") # Create partners - customer1 = cls.partner_obj.create({'name': 'Customer 1'}) - supplier1 = cls.partner_obj.create({'name': 'Supplier 1'}) + customer1 = cls.partner_obj.create({"name": "Customer 1"}) + supplier1 = cls.partner_obj.create({"name": "Supplier 1"}) # Create RMA group and operation: - cls.rma_group_customer = cls.rma_obj.create({ - 'partner_id': customer1.id, - 'type': 'customer', - }) - cls.rma_group_supplier = cls.rma_obj.create({ - 'partner_id': supplier1.id, - 'type': 'supplier', - }) - cls.operation_1 = cls.rma_op_obj.create({ - 'code': 'TEST', - 'name': 'Refund and receive', - 'type': 'customer', - 'receipt_policy': 'ordered', - 'refund_policy': 'ordered', - 'in_route_id': cls.rma_route_cust.id, - 'out_route_id': cls.rma_route_cust.id, - }) + cls.rma_group_customer = cls.rma_obj.create( + {"partner_id": customer1.id, "type": "customer"} + ) + cls.rma_group_supplier = cls.rma_obj.create( + {"partner_id": supplier1.id, "type": "supplier"} + ) + cls.operation_1 = cls.rma_op_obj.create( + { + "code": "TEST", + "name": "Refund and receive", + "type": "customer", + "receipt_policy": "ordered", + "refund_policy": "ordered", + "in_route_id": cls.rma_route_cust.id, + "out_route_id": cls.rma_route_cust.id, + } + ) # Create products - cls.product_1 = cls.product_obj.create({ - 'name': 'Test Product 1', - 'type': 'product', - 'list_price': 100.0, - 'rma_customer_operation_id': cls.cust_refund_op.id, - }) - cls.product_2 = cls.product_obj.create({ - 'name': 'Test Product 2', - 'type': 'product', - 'list_price': 150.0, - 'rma_customer_operation_id': cls.operation_1.id, - }) - cls.product_3 = cls.product_obj.create({ - 'name': 'Test Product 3', - 'type': 'product', - }) - cls.product_4 = cls.product_obj.create({ - 'name': 'Test Product 4', - 'type': 'product', - }) + cls.product_1 = cls.product_obj.create( + { + "name": "Test Product 1", + "type": "product", + "list_price": 100.0, + "rma_customer_operation_id": cls.cust_refund_op.id, + } + ) + cls.product_2 = cls.product_obj.create( + { + "name": "Test Product 2", + "type": "product", + "list_price": 150.0, + "rma_customer_operation_id": cls.operation_1.id, + } + ) + cls.product_3 = cls.product_obj.create( + {"name": "Test Product 3", "type": "product"} + ) + cls.product_4 = cls.product_obj.create( + {"name": "Test Product 4", "type": "product"} + ) # Create Invoices: - customer_account = cls.acc_obj. search( - [('user_type_id', '=', receivable_type.id)], limit=1).id - cls.inv_customer = cls.inv_obj.create({ - 'partner_id': customer1.id, - 'account_id': customer_account, - 'type': 'out_invoice', - }) - cls.inv_line_1 = cls.invl_obj.create({ - 'name': cls.product_1.name, - 'product_id': cls.product_1.id, - 'quantity': 12.0, - 'price_unit': 100.0, - 'invoice_id': cls.inv_customer.id, - 'uom_id': cls.product_1.uom_id.id, - 'account_id': customer_account, - }) - cls.inv_line_2 = cls.invl_obj.create({ - 'name': cls.product_2.name, - 'product_id': cls.product_2.id, - 'quantity': 15.0, - 'price_unit': 150.0, - 'invoice_id': cls.inv_customer.id, - 'uom_id': cls.product_2.uom_id.id, - 'account_id': customer_account, - }) + customer_account = cls.acc_obj.search( + [("user_type_id", "=", receivable_type.id)], limit=1 + ).id + cls.inv_customer = cls.inv_obj.create( + { + "partner_id": customer1.id, + "account_id": customer_account, + "type": "out_invoice", + } + ) + cls.inv_line_1 = cls.invl_obj.create( + { + "name": cls.product_1.name, + "product_id": cls.product_1.id, + "quantity": 12.0, + "price_unit": 100.0, + "invoice_id": cls.inv_customer.id, + "uom_id": cls.product_1.uom_id.id, + "account_id": customer_account, + } + ) + cls.inv_line_2 = cls.invl_obj.create( + { + "name": cls.product_2.name, + "product_id": cls.product_2.id, + "quantity": 15.0, + "price_unit": 150.0, + "invoice_id": cls.inv_customer.id, + "uom_id": cls.product_2.uom_id.id, + "account_id": customer_account, + } + ) supplier_account = cls.acc_obj.search( - [('user_type_id', '=', payable_type.id)], limit=1).id - cls.inv_supplier = cls.inv_obj.create({ - 'partner_id': supplier1.id, - 'account_id': supplier_account, - 'type': 'in_invoice', - }) - cls.inv_line_3 = cls.invl_obj.create({ - 'name': cls.product_3.name, - 'product_id': cls.product_3.id, - 'quantity': 17.0, - 'price_unit': 250.0, - 'invoice_id': cls.inv_supplier.id, - 'uom_id': cls.product_3.uom_id.id, - 'account_id': supplier_account, - }) - cls.inv_line_4 = cls.invl_obj.create({ - 'name': cls.product_4.name, - 'product_id': cls.product_4.id, - 'quantity': 9.0, - 'price_unit': 300.0, - 'invoice_id': cls.inv_supplier.id, - 'uom_id': cls.product_4.uom_id.id, - 'account_id': supplier_account, - }) + [("user_type_id", "=", payable_type.id)], limit=1 + ).id + cls.inv_supplier = cls.inv_obj.create( + { + "partner_id": supplier1.id, + "account_id": supplier_account, + "type": "in_invoice", + } + ) + cls.inv_line_3 = cls.invl_obj.create( + { + "name": cls.product_3.name, + "product_id": cls.product_3.id, + "quantity": 17.0, + "price_unit": 250.0, + "invoice_id": cls.inv_supplier.id, + "uom_id": cls.product_3.uom_id.id, + "account_id": supplier_account, + } + ) + cls.inv_line_4 = cls.invl_obj.create( + { + "name": cls.product_4.name, + "product_id": cls.product_4.id, + "quantity": 9.0, + "price_unit": 300.0, + "invoice_id": cls.inv_supplier.id, + "uom_id": cls.product_4.uom_id.id, + "account_id": supplier_account, + } + ) def test_01_add_from_invoice_customer(self): """Test wizard to create RMA from a customer invoice.""" - add_inv = self.rma_add_invoice_wiz.with_context({ - 'customer': True, - 'active_ids': self.rma_group_customer.id, - 'active_model': 'rma.order', - }).create({ - 'invoice_line_ids': - [(6, 0, self.inv_customer.invoice_line_ids.ids)], - }) + add_inv = self.rma_add_invoice_wiz.with_context( + { + "customer": True, + "active_ids": self.rma_group_customer.id, + "active_model": "rma.order", + } + ).create({"invoice_line_ids": [(6, 0, self.inv_customer.invoice_line_ids.ids)]}) add_inv.add_lines() self.assertEqual(len(self.rma_group_customer.rma_line_ids), 2) - for t in self.rma_group_supplier.rma_line_ids.mapped('type'): - self.assertEqual(t, 'customer') + for t in self.rma_group_supplier.rma_line_ids.mapped("type"): + self.assertEqual(t, "customer") rma_1 = self.rma_group_customer.rma_line_ids.filtered( - lambda r: r.product_id == self.product_1) + lambda r: r.product_id == self.product_1 + ) self.assertEqual(rma_1.operation_id, self.cust_refund_op) rma_2 = self.rma_group_customer.rma_line_ids.filtered( - lambda r: r.product_id == self.product_2) + lambda r: r.product_id == self.product_2 + ) self.assertEqual(rma_2.operation_id, self.operation_1) def test_02_add_from_invoice_supplier(self): """Test wizard to create RMA from a vendor bill.""" - add_inv = self.rma_add_invoice_wiz.with_context({ - 'supplier': True, - 'active_ids': self.rma_group_supplier.id, - 'active_model': 'rma.order', - }).create({ - 'invoice_line_ids': - [(6, 0, self.inv_supplier.invoice_line_ids.ids)], - }) + add_inv = self.rma_add_invoice_wiz.with_context( + { + "supplier": True, + "active_ids": self.rma_group_supplier.id, + "active_model": "rma.order", + } + ).create({"invoice_line_ids": [(6, 0, self.inv_supplier.invoice_line_ids.ids)]}) add_inv.add_lines() self.assertEqual(len(self.rma_group_supplier.rma_line_ids), 2) - for t in self.rma_group_supplier.rma_line_ids.mapped('type'): - self.assertEqual(t, 'supplier') + for t in self.rma_group_supplier.rma_line_ids.mapped("type"): + self.assertEqual(t, "supplier") def test_03_rma_refund_operation(self): """Test RMA quantities using refund operations.""" # Received refund_policy: rma_1 = self.rma_group_customer.rma_line_ids.filtered( - lambda r: r.product_id == self.product_1) - self.assertEqual(rma_1.refund_policy, 'received') + lambda r: r.product_id == self.product_1 + ) + self.assertEqual(rma_1.refund_policy, "received") self.assertEqual(rma_1.qty_to_refund, 0.0) # TODO: receive and check qty_to_refund is 12.0 # Ordered refund_policy: rma_2 = self.rma_group_customer.rma_line_ids.filtered( - lambda r: r.product_id == self.product_2) + lambda r: r.product_id == self.product_2 + ) rma_2._onchange_operation_id() - self.assertEqual(rma_2.refund_policy, 'ordered') + self.assertEqual(rma_2.refund_policy, "ordered") self.assertEqual(rma_2.qty_to_refund, 15.0) def test_04_rma_create_refund(self): """Generate a Refund from a customer RMA.""" rma = self.rma_group_customer.rma_line_ids.filtered( - lambda r: r.product_id == self.product_2) + lambda r: r.product_id == self.product_2 + ) rma.action_rma_to_approve() rma.action_rma_approve() self.assertEqual(rma.refund_count, 0) self.assertEqual(rma.qty_to_refund, 15.0) self.assertEqual(rma.qty_refunded, 0.0) - make_refund = self.rma_refund_wiz.with_context({ - 'customer': True, - 'active_ids': rma.ids, - 'active_model': 'rma.order.line', - }).create({ - 'description': 'Test refund', - }) + make_refund = self.rma_refund_wiz.with_context( + {"customer": True, "active_ids": rma.ids, "active_model": "rma.order.line"} + ).create({"description": "Test refund"}) make_refund.invoice_refund() rma.refund_line_ids.invoice_id.action_invoice_open() rma._compute_refund_count() @@ -201,10 +214,12 @@ class TestRmaAccount(common.SingleTransactionCase): def test_05_fill_rma_from_inv_line(self): """Test filling a RMA (line) from a invoice line.""" - rma = self.rma_line_obj.new({ - 'partner_id': self.inv_customer.partner_id.id, - 'invoice_line_id': self.inv_line_1.id, - }) + rma = self.rma_line_obj.new( + { + "partner_id": self.inv_customer.partner_id.id, + "invoice_line_id": self.inv_line_1.id, + } + ) self.assertFalse(rma.product_id) rma._onchange_invoice_line_id() self.assertEqual(rma.product_id, self.product_1) diff --git a/rma_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_invoice.py index f766b6f6..a97e37f6 100644 --- a/rma_account/wizards/rma_add_invoice.py +++ b/rma_account/wizards/rma_add_invoice.py @@ -6,90 +6,106 @@ from odoo.exceptions import ValidationError class RmaAddInvoice(models.TransientModel): - _name = 'rma_add_invoice' - _description = 'Wizard to add rma lines' + _name = "rma_add_invoice" + _description = "Wizard to add rma lines" @api.model def default_get(self, fields_list): res = super(RmaAddInvoice, 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['invoice_line_ids'] = False + res["rma_id"] = rma.id + res["partner_id"] = rma.partner_id.id + res["invoice_line_ids"] = False return res - rma_id = fields.Many2one('rma.order', string='RMA Order', readonly=True, - ondelete='cascade') - partner_id = fields.Many2one(comodel_name='res.partner', string='Partner', - readonly=True) - invoice_line_ids = fields.Many2many('account.invoice.line', - 'rma_add_invoice_add_line_rel', - 'invoice_line_id', - 'rma_add_invoice_id', - string='Invoice Lines') + rma_id = fields.Many2one( + "rma.order", string="RMA Order", readonly=True, ondelete="cascade" + ) + partner_id = fields.Many2one( + comodel_name="res.partner", string="Partner", readonly=True + ) + invoice_line_ids = fields.Many2many( + "account.invoice.line", + "rma_add_invoice_add_line_rel", + "invoice_line_id", + "rma_add_invoice_id", + string="Invoice Lines", + ) def _prepare_rma_line_from_inv_line(self, line): - if self.env.context.get('customer'): - operation = line.product_id.rma_customer_operation_id or \ - line.product_id.categ_id.rma_customer_operation_id + if self.env.context.get("customer"): + operation = ( + line.product_id.rma_customer_operation_id + or line.product_id.categ_id.rma_customer_operation_id + ) else: - operation = line.product_id.rma_supplier_operation_id or \ - line.product_id.categ_id.rma_supplier_operation_id + operation = ( + line.product_id.rma_supplier_operation_id + or line.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, - 'invoice_line_id': line.id, - 'product_id': line.product_id.id, - 'origin': line.invoice_id.number, - 'uom_id': line.uom_id.id, - 'operation_id': operation.id, - 'product_qty': line.quantity, - 'price_unit': line.invoice_id.currency_id.compute( - line.price_unit, line.currency_id, round=False), - 'delivery_address_id': line.invoice_id.partner_id.id, - 'invoice_address_id': line.invoice_id.partner_id.id, - 'rma_id': self.rma_id.id, - 'receipt_policy': operation.receipt_policy, - 'refund_policy': operation.refund_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, + "invoice_line_id": line.id, + "product_id": line.product_id.id, + "origin": line.invoice_id.number, + "uom_id": line.uom_id.id, + "operation_id": operation.id, + "product_qty": line.quantity, + "price_unit": line.invoice_id.currency_id.compute( + line.price_unit, line.currency_id, round=False + ), + "delivery_address_id": line.invoice_id.partner_id.id, + "invoice_address_id": line.invoice_id.partner_id.id, + "rma_id": self.rma_id.id, + "receipt_policy": operation.receipt_policy, + "refund_policy": operation.refund_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.model def _get_rma_data(self): - data = { - 'date_rma': fields.Datetime.now(), - } + data = {"date_rma": fields.Datetime.now()} return data @api.model @@ -101,7 +117,7 @@ class RmaAddInvoice(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_invoice_lines = self._get_existing_invoice_lines() for line in self.invoice_line_ids: # Load a PO line only once @@ -111,4 +127,4 @@ class RmaAddInvoice(models.TransientModel): rma = self.rma_id data_rma = self._get_rma_data() rma.write(data_rma) - return {'type': 'ir.actions.act_window_close'} + return {"type": "ir.actions.act_window_close"} diff --git a/rma_account/wizards/rma_order_line_make_supplier_rma.py b/rma_account/wizards/rma_order_line_make_supplier_rma.py index bbd94cd1..e1c3fc78 100644 --- a/rma_account/wizards/rma_order_line_make_supplier_rma.py +++ b/rma_account/wizards/rma_order_line_make_supplier_rma.py @@ -9,9 +9,8 @@ class RmaLineMakeSupplierRma(models.TransientModel): @api.model def _prepare_supplier_rma_line(self, rma, item): - res = super(RmaLineMakeSupplierRma, self)._prepare_supplier_rma_line( - rma, item) - if res['operation_id']: - operation = self.env['rma.operation'].browse(res['operation_id']) - res['refund_policy'] = operation.refund_policy + res = super(RmaLineMakeSupplierRma, self)._prepare_supplier_rma_line(rma, item) + if res["operation_id"]: + operation = self.env["rma.operation"].browse(res["operation_id"]) + res["refund_policy"] = operation.refund_policy return res diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index 0e06ee16..d86a754c 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -3,6 +3,7 @@ from odoo import _, api, fields, models from odoo.exceptions import ValidationError + import odoo.addons.decimal_precision as dp @@ -12,22 +13,21 @@ class RmaRefund(models.TransientModel): @api.model def _get_reason(self): - active_ids = self.env.context.get('active_ids', False) - return self.env['rma.order.line'].browse( - active_ids[0]).rma_id.name or '' + active_ids = self.env.context.get("active_ids", False) + return self.env["rma.order.line"].browse(active_ids[0]).rma_id.name or "" - @api.returns('rma.order.line') + @api.returns("rma.order.line") def _prepare_item(self, line): values = { - 'product_id': line.product_id.id, - 'name': line.name, - 'product_qty': line.product_qty, - 'uom_id': line.uom_id.id, - 'qty_to_refund': line.qty_to_refund, - 'refund_policy': line.refund_policy, - 'invoice_address_id': line.invoice_address_id.id, - 'line_id': line.id, - 'rma_id': line.rma_id.id, + "product_id": line.product_id.id, + "name": line.name, + "product_qty": line.product_qty, + "uom_id": line.uom_id.id, + "qty_to_refund": line.qty_to_refund, + "refund_policy": line.refund_policy, + "invoice_address_id": line.invoice_address_id.id, + "line_id": line.id, + "rma_id": line.rma_id.id, } return values @@ -39,37 +39,37 @@ class RmaRefund(models.TransientModel): """ context = self._context.copy() res = super(RmaRefund, 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 RMAs from the same partner can be processed at " - "the same time.")) + _( + "Only RMAs 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 date_invoice = fields.Date( - string='Refund Date', - default=fields.Date.context_today, required=True, + string="Refund Date", default=fields.Date.context_today, required=True ) - date = fields.Date(string='Accounting Date') + date = fields.Date(string="Accounting Date") description = fields.Char( - string='Reason', required=True, - default=lambda self: self._get_reason(), + string="Reason", required=True, default=lambda self: self._get_reason() ) item_ids = fields.One2many( - comodel_name='rma.refund.item', - inverse_name='wiz_id', string='Items', + comodel_name="rma.refund.item", inverse_name="wiz_id", string="Items" ) @api.multi @@ -77,102 +77,107 @@ class RmaRefund(models.TransientModel): for wizard in self: first = self.item_ids[0] values = self._prepare_refund(wizard, first.line_id) - new_refund = self.env['account.invoice'].create(values) + new_refund = self.env["account.invoice"].create(values) for item in self.item_ids: refund_line_values = self.prepare_refund_line(item, new_refund) - self.env['account.invoice.line'].create( - refund_line_values) + self.env["account.invoice.line"].create(refund_line_values) return new_refund @api.multi def invoice_refund(self): - rma_line_ids = self.env['rma.order.line'].browse( - self.env.context['active_ids']) + rma_line_ids = self.env["rma.order.line"].browse(self.env.context["active_ids"]) for line in rma_line_ids: - if line.refund_policy == 'no': + if line.refund_policy == "no": raise ValidationError( - _('The operation is not refund for at least one line')) - if line.state != 'approved': - raise ValidationError( - _('RMA %s is not approved') % line.name) + _("The operation is not refund for at least one line") + ) + if line.state != "approved": + raise ValidationError(_("RMA %s is not approved") % line.name) new_invoice = self.compute_refund() - action = 'action_invoice_tree1' if ( - new_invoice.type in ['out_refund', 'out_invoice']) \ - else 'action_invoice_in_refund' - result = self.env.ref('account.%s' % action).read()[0] - form_view = self.env.ref('account.invoice_supplier_form', False) - result['views'] = [(form_view and form_view.id or False, 'form')] - result['res_id'] = new_invoice.id + action = ( + "action_invoice_tree1" + if (new_invoice.type in ["out_refund", "out_invoice"]) + else "action_invoice_in_refund" + ) + result = self.env.ref("account.%s" % action).read()[0] + form_view = self.env.ref("account.invoice_supplier_form", False) + result["views"] = [(form_view and form_view.id or False, "form")] + result["res_id"] = new_invoice.id return result @api.model def prepare_refund_line(self, item, refund): accounts = item.product_id.product_tmpl_id._get_product_accounts() - if item.line_id.type == 'customer': - account = accounts['stock_output'] + if item.line_id.type == "customer": + account = accounts["stock_output"] else: - account = accounts['stock_input'] + account = accounts["stock_input"] if not account: - raise ValidationError(_( - "Accounts are not configured for this product.")) + raise ValidationError(_("Accounts are not configured for this product.")) values = { - 'name': item.line_id.name or item.rma_id.name, - 'origin': item.line_id.name or item.rma_id.name, - 'account_id': account.id, - 'price_unit': item.line_id.price_unit, - 'uom_id': item.line_id.uom_id.id, - 'product_id': item.product_id.id, - 'rma_line_id': item.line_id.id, - 'quantity': item.qty_to_refund, - 'invoice_id': refund.id + "name": item.line_id.name or item.rma_id.name, + "origin": item.line_id.name or item.rma_id.name, + "account_id": account.id, + "price_unit": item.line_id.price_unit, + "uom_id": item.line_id.uom_id.id, + "product_id": item.product_id.id, + "rma_line_id": item.line_id.id, + "quantity": item.qty_to_refund, + "invoice_id": refund.id, } return values @api.model def _prepare_refund(self, wizard, rma_line): # origin_invoices = self._get_invoice(rma_line) - if rma_line.type == 'customer': - journal = self.env['account.journal'].search( - [('type', '=', 'sale')], limit=1) + if rma_line.type == "customer": + journal = self.env["account.journal"].search( + [("type", "=", "sale")], limit=1 + ) else: - journal = self.env['account.journal'].search( - [('type', '=', 'purchase')], limit=1) + journal = self.env["account.journal"].search( + [("type", "=", "purchase")], limit=1 + ) values = { - 'name': rma_line.rma_id.name or rma_line.name, - 'origin': rma_line.rma_id.name or rma_line.name, - 'reference': False, + "name": rma_line.rma_id.name or rma_line.name, + "origin": rma_line.rma_id.name or rma_line.name, + "reference": False, # 'account_id': account.id, - 'journal_id': journal.id, - 'currency_id': rma_line.partner_id.company_id.currency_id.id, - 'payment_term_id': False, - 'fiscal_position_id': - rma_line.partner_id.property_account_position_id.id, - 'state': 'draft', - 'number': False, - 'date': wizard.date, - 'date_invoice': wizard.date_invoice, - 'partner_id': rma_line.invoice_address_id.id or - rma_line.partner_id.id, + "journal_id": journal.id, + "currency_id": rma_line.partner_id.company_id.currency_id.id, + "payment_term_id": False, + "fiscal_position_id": rma_line.partner_id.property_account_position_id.id, + "state": "draft", + "number": False, + "date": wizard.date, + "date_invoice": wizard.date_invoice, + "partner_id": rma_line.invoice_address_id.id or rma_line.partner_id.id, } - if self.env.registry.models.get('crm.team', False): - team_ids = self.env['crm.team'].search( - ['|', ('user_id', '=', self.env.uid), - ('member_ids', '=', self.env.uid)], limit=1) + if self.env.registry.models.get("crm.team", False): + team_ids = self.env["crm.team"].search( + [ + "|", + ("user_id", "=", self.env.uid), + ("member_ids", "=", self.env.uid), + ], + limit=1, + ) team_id = team_ids[0] if team_ids else False if team_id: - values['team_id'] = team_id.id - if rma_line.type == 'customer': - values['type'] = 'out_refund' + values["team_id"] = team_id.id + if rma_line.type == "customer": + values["type"] = "out_refund" else: - values['type'] = 'in_refund' + values["type"] = "in_refund" return values - @api.constrains('item_ids') + @api.constrains("item_ids") def check_unique_invoice_address_id(self): - addresses = self.item_ids.mapped('invoice_address_id') + addresses = self.item_ids.mapped("invoice_address_id") if len(addresses) > 1: - raise ValidationError(_( - "The invoice address must be the same for all the lines.")) + raise ValidationError( + _("The invoice address must be the same for all the lines.") + ) return True @@ -180,33 +185,38 @@ class RmaRefundItem(models.TransientModel): _name = "rma.refund.item" _description = "RMA Lines to refund" - wiz_id = fields.Many2one( - comodel_name='rma.refund', string='Wizard', required=True) - line_id = fields.Many2one('rma.order.line', - string='RMA order Line', - required=True, - readonly=True, - ondelete='cascade') - rma_id = fields.Many2one('rma.order', - related='line_id.rma_id', - string='RMA', - readonly=True) - product_id = fields.Many2one('product.product', string='Product') - product = fields.Many2one('product.product', string='Product', - readonly=True) - name = fields.Char(string='Description', required=True) + wiz_id = fields.Many2one(comodel_name="rma.refund", string="Wizard", required=True) + line_id = fields.Many2one( + "rma.order.line", + string="RMA order Line", + required=True, + readonly=True, + ondelete="cascade", + ) + rma_id = fields.Many2one( + "rma.order", related="line_id.rma_id", string="RMA", readonly=True + ) + product_id = fields.Many2one("product.product", string="Product") + product = fields.Many2one("product.product", string="Product", readonly=True) + name = fields.Char(string="Description", required=True) product_qty = fields.Float( - string='Quantity Ordered', copy=False, - digits=dp.get_precision('Product Unit of Measure'), - readonly=True) + string="Quantity Ordered", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + ) invoice_address_id = fields.Many2one( - comodel_name='res.partner', string='Invoice Address') + comodel_name="res.partner", string="Invoice Address" + ) qty_to_refund = fields.Float( - string='Quantity To Refund', - digits=dp.get_precision('Product Unit of Measure')) - uom_id = fields.Many2one('uom.uom', string='Unit of Measure', - readonly=True) - refund_policy = fields.Selection(selection=[ - ('no', 'Not required'), ('ordered', 'Based on Ordered Quantities'), - ('received', 'Based on Received Quantities')], - string="Refund Policy") + string="Quantity To Refund", digits=dp.get_precision("Product Unit of Measure") + ) + uom_id = fields.Many2one("uom.uom", string="Unit of Measure", readonly=True) + refund_policy = fields.Selection( + selection=[ + ("no", "Not required"), + ("ordered", "Based on Ordered Quantities"), + ("received", "Based on Received Quantities"), + ], + string="Refund Policy", + )