From c3ca8a1ccc1dd4d57b6dc11e2cf281a9394e05d0 Mon Sep 17 00:00:00 2001 From: Juany Davila Date: Tue, 8 Nov 2022 13:17:02 -0500 Subject: [PATCH] [IMP] fp-303: add changes from 14.0 --- rma_account/models/account_move.py | 174 ++++++++++++++++++------ rma_account/models/procurement.py | 8 +- rma_account/tests/test_rma_account.py | 28 +++- rma_account/views/account_move_view.xml | 31 ++--- rma_purchase/__manifest__.py | 2 +- rma_purchase/models/__init__.py | 1 + rma_purchase/models/account_move.py | 13 ++ 7 files changed, 189 insertions(+), 68 deletions(-) create mode 100644 rma_purchase/models/account_move.py diff --git a/rma_account/models/account_move.py b/rma_account/models/account_move.py index d543fc74..602bba60 100644 --- a/rma_account/models/account_move.py +++ b/rma_account/models/account_move.py @@ -1,4 +1,4 @@ -# Copyright 2017 ForgeFlow S.L. +# Copyright 2017-22 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from odoo import api, fields, models @@ -14,29 +14,36 @@ class AccountMove(models.Model): rmas = self.mapped("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: + def _prepare_invoice_line_from_rma_line(self, rma_line): + sequence = max(self.line_ids.mapped("sequence")) + 1 if self.line_ids else 10 + qty = rma_line.qty_to_refund + if float_compare(qty, 0.0, precision_rounding=rma_line.uom_id.rounding) <= 0: qty = 0.0 # Todo fill taxes from somewhere - invoice_line = self.env["account.move.line"] data = { - "purchase_line_id": line.id, - "name": line.name + ": " + line.name, - "product_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( + "move_id": self.id, + "product_uom_id": rma_line.uom_id.id, + "product_id": rma_line.product_id.id, + "price_unit": rma_line.company_id.currency_id.with_context( date=self.date - ).compute(line.price_unit, self.currency_id, round=False), + ).compute(rma_line.price_unit, self.currency_id, round=False), "quantity": qty, "discount": 0.0, - "rma_line_ids": [(4, line.id)], + "rma_line_ids": [(4, rma_line.id)], + "sequence": sequence + 1, } return data + def _post_process_invoice_line_from_rma_line(self, new_line, rma_line): + new_line.name = "%s: %s" % ( + self.add_rma_line_id.name, + new_line._get_computed_name(), + ) + new_line.account_id = new_line._get_computed_account() + new_line._onchange_price_subtotal() + new_line._onchange_mark_recompute_taxes() + return True + @api.onchange("add_rma_line_id") def on_change_add_rma_line_id(self): if not self.add_rma_line_id: @@ -48,10 +55,18 @@ class AccountMove(models.Model): if self.add_rma_line_id not in (self.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.line_ids += new_line + self._post_process_invoice_line_from_rma_line( + new_line, self.add_rma_line_id + ) + line = new_line._convert_to_write( + {name: new_line[name] for name in new_line._cache} + ) + # Compute invoice_origin. + origins = set(self.line_ids.mapped("rma_line_id.name")) + self.invoice_origin = ",".join(list(origins)) self.add_rma_line_id = False - return {} + self._onchange_currency() + return line rma_count = fields.Integer(compute="_compute_rma_count", string="# of RMA") @@ -62,32 +77,24 @@ class AccountMove(models.Model): help="Create a refund in based on an existing rma_line", ) - def action_view_rma_supplier(self): - action = self.env.ref("rma.action_rma_supplier_lines") + def action_view_rma(self): + if self.move_type in ["in_invoice", "in_refund"]: + action = self.env.ref("rma.action_rma_supplier_lines") + form_view = self.env.ref("rma.view_rma_line_supplier_form", False) + else: + action = self.env.ref("rma.action_rma_customer_lines") + form_view = self.env.ref("rma.view_rma_line_form", False) result = action.sudo().read()[0] rma_ids = self.mapped("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)] - 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] - return result - - def action_view_rma_customer(self): - action = self.env.ref("rma.action_rma_customer_lines") - result = action.sudo().read()[0] - rma_ids = self.mapped("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)] - 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] + # choose the view_mode accordingly + if not rma_ids: + result["domain"] = [("id", "in", [])] + elif len(rma_ids) > 1: + result["domain"] = [("id", "in", rma_ids)] + else: + res = form_view + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = rma_ids and rma_ids[0] or False return result def _stock_account_prepare_anglo_saxon_out_lines_vals(self): @@ -113,3 +120,86 @@ class AccountMove(models.Model): if len(find_with_label_rma) == 1: line.update({"rma_line_id": find_with_label_rma.id}) return res + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + @api.model + 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([("move_id.name", operator, name)] + args, limit=limit) + res = lines.name_get() + if limit: + limit_rest = limit - len(lines) + else: + # limit can be 0 or None representing infinite + limit_rest = limit + if limit_rest or not limit: + args += [("id", "not in", lines.ids)] + res += super(AccountMoveLine, self).name_search( + name, args=args, operator=operator, limit=limit_rest + ) + return res + + def name_get(self): + res = [] + if self.env.context.get("rma"): + for inv in self: + if inv.move_id.ref: + res.append( + ( + inv.id, + "INV:%s | REF:%s | ORIG:%s | PART:%s | QTY:%s" + % ( + inv.move_id.name or "", + inv.move_id.invoice_origin or "", + inv.move_id.ref or "", + inv.product_id.name, + inv.quantity, + ), + ) + ) + elif inv.move_id.name: + res.append( + ( + inv.id, + "INV:%s | ORIG:%s | PART:%s | QTY:%s" + % ( + inv.move_id.name or "", + inv.move_id.invoice_origin or "", + inv.product_id.name, + inv.quantity, + ), + ) + ) + else: + res.append(super(AccountMoveLine, inv).name_get()[0]) + return res + else: + return super(AccountMoveLine, self).name_get() + + def _compute_rma_count(self): + for invl in self: + 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_ids = fields.One2many( + comodel_name="rma.order.line", + inverse_name="account_move_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", + string="RMA line", + ondelete="set null", + 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 index 517cda76..7a3ae703 100644 --- a/rma_account/models/procurement.py +++ b/rma_account/models/procurement.py @@ -33,12 +33,8 @@ class StockRule(models.Model): line = self.env["rma.order.line"].browse([line]) move = line.reference_move_id if move and move.stock_valuation_layer_ids: - layers = move.stock_valuation_layer_ids - price_unit = sum(layers.mapped("value")) / sum( - layers.mapped("quantity") - ) - - res["price_unit"] = price_unit + cost = move.stock_valuation_layer_ids[-1].unit_cost + res["price_unit"] = cost return res diff --git a/rma_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py index bbeed9af..b05ef925 100644 --- a/rma_account/tests/test_rma_account.py +++ b/rma_account/tests/test_rma_account.py @@ -231,7 +231,7 @@ class TestRmaAccount(common.SingleTransactionCase): self.assertEqual(rma.qty_refunded, 2.0) def test_05_fill_rma_from_inv_line(self): - """Test filling a RMA (line) from a invoice line.""" + """Test filling a RMA (line) from an invoice line.""" rma = self.rma_line_obj.new( { "partner_id": self.inv_customer.partner_id.id, @@ -271,3 +271,29 @@ class TestRmaAccount(common.SingleTransactionCase): self.assertEqual( self.operation_1.refund_journal_id, rma.refund_line_ids.journal_id ) + + def test_07_add_lines_from_rma(self): + """Test adding line from rma to supplier refund""" + add_inv = self.rma_add_invoice_wiz.with_context( + **{ + "supplier": True, + "active_ids": self.rma_group_supplier.id, + "active_model": "rma.order", + } + ).create({"line_ids": [(6, 0, self.inv_supplier.line_ids.ids)]}) + add_inv.add_lines() + rma_1 = self.rma_group_supplier.rma_line_ids.filtered( + lambda r: r.product_id == self.product_1 + ) + inv = self.inv_obj.with_context( + **{ + "default_move_type": "in_refund", + "default_partner_id": self.inv_supplier.partner_id, + } + ).create({"add_rma_line_id": rma_1}) + line = inv.on_change_add_rma_line_id() + inv.invoice_line_ids = [(0, 0, line)] + inv_product = inv.invoice_line_ids.filtered( + lambda x: x.product_id == self.product_1 + ).mapped("product_id") + self.assertEqual(rma_1.product_id.id, inv_product.id) diff --git a/rma_account/views/account_move_view.xml b/rma_account/views/account_move_view.xml index 247e7167..2153188a 100644 --- a/rma_account/views/account_move_view.xml +++ b/rma_account/views/account_move_view.xml @@ -5,22 +5,17 @@ account.move - -
+ -
-
+ + + @@ -55,10 +50,10 @@ diff --git a/rma_purchase/__manifest__.py b/rma_purchase/__manifest__.py index bd5ec669..153e14d6 100644 --- a/rma_purchase/__manifest__.py +++ b/rma_purchase/__manifest__.py @@ -6,7 +6,7 @@ "category": "RMA", "summary": "RMA from PO", "license": "LGPL-3", - "author": "ForgeFlow", + "author": "ForgeFlow, Odoo Community Association (OCA)", "website": "https://github.com/ForgeFlow/stock-rma", "depends": ["rma_account", "purchase"], "data": [ diff --git a/rma_purchase/models/__init__.py b/rma_purchase/models/__init__.py index 5edaa9af..39c02682 100644 --- a/rma_purchase/models/__init__.py +++ b/rma_purchase/models/__init__.py @@ -4,3 +4,4 @@ from . import purchase_order from . import purchase_order_line from . import rma_operation from . import procurement +from . import account_move diff --git a/rma_purchase/models/account_move.py b/rma_purchase/models/account_move.py new file mode 100644 index 00000000..e43c6a15 --- /dev/null +++ b/rma_purchase/models/account_move.py @@ -0,0 +1,13 @@ +# Copyright 2017-22 ForgeFlow S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from odoo import models + + +class AccountMove(models.Model): + _inherit = "account.move" + + def _prepare_invoice_line_from_rma_line(self, line): + data = super(AccountMove, self)._prepare_invoice_line_from_rma_line(line) + data["purchase_line_id"]: line.id + return data