From f48e298bd89ccea9a2c2c8c3be90bb2fa7afa0a0 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Date: Wed, 2 Mar 2022 11:35:08 +0100 Subject: [PATCH] [IMP] rma: Refactor all rma modules in order to consider using the correct price unit in moves Otherwise the inventory accounting will be completely wrong. --- rma_account/models/__init__.py | 4 +-- rma_account/models/account_move.py | 4 +-- rma_account/models/procurement.py | 48 +++++++++++++++++++++++++++ rma_account/models/rma_order.py | 4 ++- rma_account/models/rma_order_line.py | 23 ++++++++----- rma_account/tests/test_rma_account.py | 6 ++-- rma_account/wizards/rma_refund.py | 17 ++++------ 7 files changed, 79 insertions(+), 27 deletions(-) create mode 100644 rma_account/models/procurement.py diff --git a/rma_account/models/__init__.py b/rma_account/models/__init__.py index 09afbe77..a5c03656 100644 --- a/rma_account/models/__init__.py +++ b/rma_account/models/__init__.py @@ -1,7 +1,5 @@ -# Copyright 2017 ForgeFlow S.L. -# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) - from . import rma_order from . import rma_order_line from . import rma_operation from . import account_move +from . import procurement diff --git a/rma_account/models/account_move.py b/rma_account/models/account_move.py index 4afe1ac9..d4f5deac 100644 --- a/rma_account/models/account_move.py +++ b/rma_account/models/account_move.py @@ -168,7 +168,7 @@ class AccountMoveLine(models.Model): rma_line_id = fields.Many2one( comodel_name="rma.order.line", - string="RMA line refund", + string="RMA line", ondelete="set null", - help="This will contain the rma line that originated the refund line", + help="This will contain the rma line that originated this line", ) diff --git a/rma_account/models/procurement.py b/rma_account/models/procurement.py new file mode 100644 index 00000000..9404d1c2 --- /dev/null +++ b/rma_account/models/procurement.py @@ -0,0 +1,48 @@ +# Copyright 2017-2022 ForgeFlow S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from odoo import fields, models + + +class StockRule(models.Model): + _inherit = "stock.rule" + + def _get_stock_move_values( + self, + product_id, + product_qty, + product_uom, + location_id, + name, + origin, + company_id, + values, + ): + res = super(StockRule, self)._get_stock_move_values( + product_id, + product_qty, + product_uom, + location_id, + name, + origin, + company_id, + values, + ) + if "rma_line_id" in values: + line = values.get("rma_line_id") + move = line.reference_move_id + if move and move.stock_valuation_layer_ids: + cost = move.stock_valuation_layer_ids[-1].unit_cost + res["price_unit"] = cost + return res + + +class ProcurementGroup(models.Model): + _inherit = "procurement.group" + + rma_id = fields.Many2one( + 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" + ) diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index 747316c2..370630d2 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/models/rma_order.py @@ -9,7 +9,9 @@ class RmaOrder(models.Model): def _compute_invoice_refund_count(self): for rec in self: - invoices = rec.mapped("rma_line_ids.refund_line_ids.move_id") + invoices = rec.mapped("rma_line_ids.move_line_ids.move_id").filtered( + lambda m: m.move_type in ["in_refund", "out_refund"] + ) rec.invoice_refund_count = len(invoices) def _compute_invoice_count(self): diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 0e0a78b1..02ee3157 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -16,19 +16,20 @@ class RmaOrderLine(models.Model): return self.env["res.partner"] @api.depends( - "refund_line_ids", "refund_line_ids.move_id.state", "refund_policy", "type" + "move_line_ids", "move_line_ids.move_id.state", "refund_policy", "type" ) def _compute_qty_refunded(self): for rec in self: rec.qty_refunded = sum( - rec.refund_line_ids.filtered( + rec.move_line_ids.filtered( lambda i: i.move_id.state in ("posted") + and i.move_id.move_type in ["out_refund", "in_refund"] ).mapped("quantity") ) @api.depends( - "refund_line_ids", - "refund_line_ids.move_id.state", + "move_line_ids", + "move_line_ids.move_id.state", "refund_policy", "move_ids", "move_ids.state", @@ -47,7 +48,11 @@ class RmaOrderLine(models.Model): def _compute_refund_count(self): for rec in self: - rec.refund_count = len(rec.refund_line_ids.mapped("move_id")) + rec.refund_count = len( + rec.move_line_ids.mapped("move_id").filtered( + lambda m: m.move_type in ["out_refund", "in_refund"] + ) + ) invoice_address_id = fields.Many2one( "res.partner", @@ -68,7 +73,7 @@ class RmaOrderLine(models.Model): readonly=True, states={"draft": [("readonly", False)]}, ) - refund_line_ids = fields.One2many( + move_line_ids = fields.One2many( comodel_name="account.move.line", inverse_name="rma_line_id", string="Refund Lines", @@ -269,12 +274,14 @@ class RmaOrderLine(models.Model): } def action_view_refunds(self): - move_ids = self.mapped("refund_line_ids.move_id").ids + moves = self.mapped("move_line_ids.move_id").filtered( + lambda m: m.move_type in ["out_refund", "in_refund"] + ) form_view_ref = self.env.ref("account.view_move_form", False) tree_view_ref = self.env.ref("account.view_move_tree", False) return { - "domain": [("id", "in", move_ids)], + "domain": [("id", "in", moves.ids)], "name": "Refunds", "res_model": "account.move", "type": "ir.actions.act_window", diff --git a/rma_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py index 6d07bf3a..7f169e7a 100644 --- a/rma_account/tests/test_rma_account.py +++ b/rma_account/tests/test_rma_account.py @@ -224,7 +224,7 @@ class TestRmaAccount(common.SingleTransactionCase): } ).create({"description": "Test refund"}) make_refund.invoice_refund() - rma.refund_line_ids.move_id.action_post() + rma.move_line_ids.move_id.action_post() rma._compute_refund_count() self.assertEqual(rma.refund_count, 1) self.assertEqual(rma.qty_to_refund, 0.0) @@ -266,8 +266,8 @@ class TestRmaAccount(common.SingleTransactionCase): } ).create({"description": "Test refund"}) make_refund.invoice_refund() - rma.refund_line_ids.move_id.action_post() + rma.move_line_ids.move_id.action_post() rma._compute_refund_count() self.assertEqual( - self.operation_1.refund_journal_id, rma.refund_line_ids.journal_id + self.operation_1.refund_journal_id, rma.move_line_ids.journal_id ) diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index 264ddb60..7c2b878b 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -80,7 +80,13 @@ 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.move"].create(values) + default_move_type = ( + "in_refund" if first.line_id.type == "supplier" else "out_refund", + ) + account_move_model = self.env["account.move"].with_context( + default_move_type=default_move_type + ) + new_refund = account_move_model.create(values) return new_refund def invoice_refund(self): @@ -106,17 +112,8 @@ class RmaRefund(models.TransientModel): @api.model def prepare_refund_line(self, item): - accounts = item.product.product_tmpl_id._get_product_accounts() - if item.line_id.type == "customer": - account = accounts["income"] - else: - account = accounts["expense"] - if not account: - raise ValidationError(_("Accounts are not configured for this product.")) - values = { "name": item.line_id.name or item.rma_id.name, - "account_id": account.id, "price_unit": item.line_id.price_unit, "product_uom_id": item.line_id.uom_id.id, "product_id": item.product.id,