From e2bfab1c83c3400ffb45712578af8766a812a907 Mon Sep 17 00:00:00 2001 From: david Date: Mon, 16 Nov 2020 17:26:06 +0100 Subject: [PATCH] [IMP] rma_sale: prepare kits integration When a sale line has a phantom product (mrp kits) the RMA would not be possible as the wizard couldn't pair the components moves with the product in the line. With this approach, we can at least return the spare components of the original kit line. We also need some hooks to intervine in the main methods, like in invoicing. --- rma_sale/controllers/sale_portal.py | 2 +- rma_sale/models/rma.py | 22 ++++++++++++++ rma_sale/models/sale.py | 39 ++++++++++++++++--------- rma_sale/views/sale_portal_template.xml | 14 +++++---- 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/rma_sale/controllers/sale_portal.py b/rma_sale/controllers/sale_portal.py index 70403a80..7ea70a3a 100644 --- a/rma_sale/controllers/sale_portal.py +++ b/rma_sale/controllers/sale_portal.py @@ -40,7 +40,7 @@ class CustomerPortal(CustomerPortal): wizard = wizard_obj.with_context(active_id=order_id).create( {"line_ids": line_vals, "location_id": location_id} ) - rma = wizard.sudo().create_rma() + rma = wizard.sudo().create_rma(from_portal=True) for rec in rma: rec.origin += _(" (Portal)") # Add the user as follower of the created RMAs so they can diff --git a/rma_sale/models/rma.py b/rma_sale/models/rma.py index 4fc540c1..70c0dfcd 100644 --- a/rma_sale/models/rma.py +++ b/rma_sale/models/rma.py @@ -25,6 +25,7 @@ class Rma(models.Model): comodel_name="sale.order.line", compute="_compute_allowed_move_ids", ) move_id = fields.Many2one(domain="[('id', 'in', allowed_move_ids)]") + sale_line_id = fields.Many2one(related="move_id.sale_line_id",) allowed_product_ids = fields.Many2many( comodel_name="product.product", compute="_compute_allowed_product_ids", ) @@ -83,3 +84,24 @@ class Rma(models.Model): if self.order_id: invoice_form.invoice_user_id = self.order_id.user_id return res + + def _get_refund_line_price_unit(self): + """Get the sale order price unit""" + if self.sale_line_id: + return self.sale_line_id.price_unit + return super()._get_refund_line_price_unit() + + def _get_refund_line_product(self): + """To be overriden in a third module with the proper origin values + in case a kit is linked with the rma """ + if not self.sale_line_id: + return super()._get_refund_line_product() + return self.sale_line_id.product_id + + def _prepare_refund_line(self, line_form): + """Add line data""" + super()._prepare_refund_line(line_form) + line = self.sale_line_id + if line: + line_form.discount = line.discount + line_form.sequence = line.sequence diff --git a/rma_sale/models/sale.py b/rma_sale/models/sale.py index bfc14243..fa91e86c 100644 --- a/rma_sale/models/sale.py +++ b/rma_sale/models/sale.py @@ -1,7 +1,7 @@ # Copyright 2020 Tecnativa - Ernesto Tejeda # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import _, fields, models +from odoo import _, api, fields, models from odoo.exceptions import ValidationError @@ -22,6 +22,16 @@ class SaleOrder(models.Model): for record in self: record.rma_count = mapped_data.get(record.id, 0) + def _prepare_rma_wizard_line_vals(self, data): + """So we can extend the wizard easily""" + return { + "product_id": data["product"].id, + "quantity": data["quantity"], + "sale_line_id": data["sale_line_id"].id, + "uom_id": data["uom"].id, + "picking_id": data["picking"] and data["picking"].id, + } + def action_create_rma(self): self.ensure_one() if self.state not in ["sale", "done"]: @@ -30,17 +40,7 @@ class SaleOrder(models.Model): ) wizard_obj = self.env["sale.order.rma.wizard"] line_vals = [ - ( - 0, - 0, - { - "product_id": data["product"].id, - "quantity": data["quantity"], - "sale_line_id": data["sale_line_id"].id, - "uom_id": data["uom"].id, - "picking_id": data["picking"] and data["picking"].id, - }, - ) + (0, 0, self._prepare_rma_wizard_line_vals(data)) for data in self.get_delivery_rma_data() ] wizard = wizard_obj.with_context(active_id=self.id).create( @@ -76,6 +76,19 @@ class SaleOrder(models.Model): data += line.prepare_sale_rma_data() return data + @api.depends("rma_ids.refund_id") + def _get_invoiced(self): + """Search for possible RMA refunds and link them to the order. We + don't want to link their sale lines as that would unbalance the + qtys to invoice wich isn't correct for this case""" + super()._get_invoiced() + for order in self: + refunds = order.sudo().rma_ids.mapped("refund_id") + if not refunds: + continue + order.invoice_ids += refunds + order.invoice_count = len(order.invoice_ids) + class SaleOrderLine(models.Model): _inherit = "sale.order.line" @@ -98,7 +111,7 @@ class SaleOrderLine(models.Model): def prepare_sale_rma_data(self): self.ensure_one() product = self.product_id - if self.product_id.type != "product": + if self.product_id.type not in ["product", "consu"]: return {} moves = self.get_delivery_move() data = [] diff --git a/rma_sale/views/sale_portal_template.xml b/rma_sale/views/sale_portal_template.xml index c61f1e4f..b1ee9ef7 100644 --- a/rma_sale/views/sale_portal_template.xml +++ b/rma_sale/views/sale_portal_template.xml @@ -131,12 +131,14 @@ - - - - + +