From 58de28682ca152e6966f878ab47f2bf79e88e9a2 Mon Sep 17 00:00:00 2001 From: JordiMForgeFlow Date: Tue, 24 Feb 2026 13:56:17 +0100 Subject: [PATCH 1/2] [IMP] purchase_last_price_info: improve field name for last purchase currency rate --- .../models/product_product.py | 26 ++++++++++++------- .../models/product_template.py | 12 ++++++--- .../tests/test_purchase_last_price_info.py | 4 +-- .../views/product_views.xml | 22 ++++++++++------ 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/purchase_last_price_info/models/product_product.py b/purchase_last_price_info/models/product_product.py index a1573b43807..ef835fb21db 100644 --- a/purchase_last_price_info/models/product_product.py +++ b/purchase_last_price_info/models/product_product.py @@ -36,11 +36,17 @@ class ProductProduct(models.Model): string="Last Purchase Currency", ) show_last_purchase_price_currency = fields.Boolean( - compute="_compute_show_last_purchase_price_currency", + related="show_last_purchase_price_currency_rate" + ) + show_last_purchase_price_currency_rate = fields.Boolean( + compute="_compute_show_last_purchase_price_currency_rate", ) last_purchase_price_currency = fields.Float( - string="Last currency purchase price", - compute="_compute_last_purchase_price_currency", + related="last_purchase_price_currency_rate" + ) + last_purchase_price_currency_rate = fields.Float( + string="Last Purchase Currency Rate", + compute="_compute_last_purchase_price_currency_rate", digits=0, ) @@ -66,10 +72,10 @@ def _compute_last_purchase_line_id_info(self): item.last_purchase_currency_id = item.last_purchase_line_id.currency_id @api.depends("last_purchase_line_id", "last_purchase_currency_id") - def _compute_show_last_purchase_price_currency(self): + def _compute_show_last_purchase_price_currency_rate(self): for item in self: last_line = item.last_purchase_line_id - item.show_last_purchase_price_currency = ( + item.show_last_purchase_price_currency_rate = ( last_line and item.last_purchase_currency_id and item.last_purchase_currency_id != last_line.company_id.currency_id @@ -77,18 +83,18 @@ def _compute_show_last_purchase_price_currency(self): @api.depends( "last_purchase_line_id", - "show_last_purchase_price_currency", + "show_last_purchase_price_currency_rate", "last_purchase_currency_id", "last_purchase_date", ) - def _compute_last_purchase_price_currency(self): + def _compute_last_purchase_price_currency_rate(self): for item in self: - if item.show_last_purchase_price_currency: + if item.show_last_purchase_price_currency_rate: rates = item.last_purchase_currency_id._get_rates( item.last_purchase_line_id.company_id, item.last_purchase_date ) - item.last_purchase_price_currency = rates.get( + item.last_purchase_price_currency_rate = rates.get( item.last_purchase_currency_id.id ) else: - item.last_purchase_price_currency = 1 + item.last_purchase_price_currency_rate = 1 diff --git a/purchase_last_price_info/models/product_template.py b/purchase_last_price_info/models/product_template.py index 177ae507ee4..1ce5e32e9d2 100644 --- a/purchase_last_price_info/models/product_template.py +++ b/purchase_last_price_info/models/product_template.py @@ -36,11 +36,17 @@ class ProductTemplate(models.Model): string="Last Purchase Currency", ) show_last_purchase_price_currency = fields.Boolean( - related="product_variant_ids.show_last_purchase_price_currency", + related="show_last_purchase_price_currency_rate", + ) + show_last_purchase_price_currency_rate = fields.Boolean( + related="product_variant_ids.show_last_purchase_price_currency_rate", ) last_purchase_price_currency = fields.Float( - string="Last currency purchase price", - related="product_variant_ids.last_purchase_price_currency", + related="last_purchase_price_currency_rate" + ) + last_purchase_price_currency_rate = fields.Float( + string="Last Purchase Currency Rate", + related="product_variant_ids.last_purchase_price_currency_rate", digits=0, ) diff --git a/purchase_last_price_info/tests/test_purchase_last_price_info.py b/purchase_last_price_info/tests/test_purchase_last_price_info.py index dbe7fbd5637..a681eb60c2e 100644 --- a/purchase_last_price_info/tests/test_purchase_last_price_info.py +++ b/purchase_last_price_info/tests/test_purchase_last_price_info.py @@ -54,7 +54,7 @@ def test_purchase_last_price_info_demo(self): first_purchase_line.currency_id, self.product.last_purchase_currency_id ) self.assertEqual(self.product.last_purchase_currency_id, self.currency) - self.assertEqual(self.product.last_purchase_price_currency, 1.0) + self.assertEqual(self.product.last_purchase_price_currency_rate, 1.0) def test_purchase_last_price_info_new_order(self): purchase_order = self.purchase_model.create( @@ -90,7 +90,7 @@ def test_purchase_last_price_info_new_order(self): self.product.last_purchase_currency_id, ) self.assertEqual(self.product.last_purchase_currency_id, self.currency_extra) - self.assertEqual(self.product.last_purchase_price_currency, 2.0) + self.assertEqual(self.product.last_purchase_price_currency_rate, 2.0) self.assertEqual(self.partner, self.product.last_purchase_supplier_id) purchase_order.button_cancel() self.assertEqual(purchase_order.state, "cancel") diff --git a/purchase_last_price_info/views/product_views.xml b/purchase_last_price_info/views/product_views.xml index 0ec3d30688e..12c0b1da9ee 100644 --- a/purchase_last_price_info/views/product_views.xml +++ b/purchase_last_price_info/views/product_views.xml @@ -14,16 +14,19 @@ - + @@ -43,16 +46,19 @@ - + From 168ee14b577516fc0d0704126c9fa2cb21ce8e7a Mon Sep 17 00:00:00 2001 From: david-s73 Date: Mon, 22 Sep 2025 08:53:54 +0200 Subject: [PATCH 2/2] [FIX] purchase_last_price_info: filter last purchase A change has been made to how the last purchase date was filtered, as in some cases it was not taking the last date but the first, so I have modified how the date is filtered. --- .../models/product_product.py | 22 +++-- .../models/product_template.py | 20 +++-- .../tests/test_purchase_last_price_info.py | 88 +++++++++++++++---- 3 files changed, 96 insertions(+), 34 deletions(-) diff --git a/purchase_last_price_info/models/product_product.py b/purchase_last_price_info/models/product_product.py index ef835fb21db..c0f6785f8bc 100644 --- a/purchase_last_price_info/models/product_product.py +++ b/purchase_last_price_info/models/product_product.py @@ -36,13 +36,15 @@ class ProductProduct(models.Model): string="Last Purchase Currency", ) show_last_purchase_price_currency = fields.Boolean( - related="show_last_purchase_price_currency_rate" + related="show_last_purchase_price_currency_rate", + string="Show Last Purchase Price Currency (Old)", ) show_last_purchase_price_currency_rate = fields.Boolean( compute="_compute_show_last_purchase_price_currency_rate", ) last_purchase_price_currency = fields.Float( - related="last_purchase_price_currency_rate" + related="last_purchase_price_currency_rate", + string="Last Purchase Currency Rate (Old)", ) last_purchase_price_currency_rate = fields.Float( string="Last Purchase Currency Rate", @@ -54,14 +56,16 @@ class ProductProduct(models.Model): @api.depends("last_purchase_line_ids.state") def _compute_last_purchase_line_id(self): for item in self: - item.last_purchase_line_id = fields.first( - item.last_purchase_line_ids.sudo().filtered_domain( - [ - ("state", "in", ["purchase", "done"]), - ("company_id", "in", self.env.companies.ids), - ] - ) + candidate_lines = item.last_purchase_line_ids.sudo().filtered_domain( + [ + ("state", "in", ["purchase", "done"]), + ("company_id", "in", self.env.companies.ids), + ] + ) + sorted_lines = candidate_lines.sorted( + key=lambda r: (r.date_order, r.id), reverse=True ) + item.last_purchase_line_id = fields.first(sorted_lines) @api.depends("last_purchase_line_id") def _compute_last_purchase_line_id_info(self): diff --git a/purchase_last_price_info/models/product_template.py b/purchase_last_price_info/models/product_template.py index 1ce5e32e9d2..78191edadae 100644 --- a/purchase_last_price_info/models/product_template.py +++ b/purchase_last_price_info/models/product_template.py @@ -37,12 +37,14 @@ class ProductTemplate(models.Model): ) show_last_purchase_price_currency = fields.Boolean( related="show_last_purchase_price_currency_rate", + string="Show Last Purchase Price Currency (Old)", ) show_last_purchase_price_currency_rate = fields.Boolean( related="product_variant_ids.show_last_purchase_price_currency_rate", ) last_purchase_price_currency = fields.Float( - related="last_purchase_price_currency_rate" + related="last_purchase_price_currency_rate", + string="Last Purchase Currency Rate (Old)", ) last_purchase_price_currency_rate = fields.Float( string="Last Purchase Currency Rate", @@ -54,14 +56,16 @@ class ProductTemplate(models.Model): @api.depends("last_purchase_line_ids.state") def _compute_last_purchase_line_id(self): for item in self: - item.last_purchase_line_id = fields.first( - item.last_purchase_line_ids.sudo().filtered_domain( - [ - ("state", "in", ["purchase", "done"]), - ("company_id", "in", self.env.companies.ids), - ] - ) + candidate_lines = item.last_purchase_line_ids.sudo().filtered_domain( + [ + ("state", "in", ["purchase", "done"]), + ("company_id", "in", self.env.companies.ids), + ] ) + sorted_lines = candidate_lines.sorted( + key=lambda r: (r.date_order, r.id), reverse=True + ) + item.last_purchase_line_id = fields.first(sorted_lines) @api.depends("last_purchase_line_id") def _compute_last_purchase_line_id_info(self): diff --git a/purchase_last_price_info/tests/test_purchase_last_price_info.py b/purchase_last_price_info/tests/test_purchase_last_price_info.py index a681eb60c2e..f50d0696e9d 100644 --- a/purchase_last_price_info/tests/test_purchase_last_price_info.py +++ b/purchase_last_price_info/tests/test_purchase_last_price_info.py @@ -2,6 +2,8 @@ # Copyright 2021 Tecnativa - Víctor Martínez # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import datetime + import odoo.tests.common as common from odoo import fields @@ -16,6 +18,16 @@ def setUp(self): self.purchase_model = self.env["purchase.order"] self.purchase_line_model = self.env["purchase.order.line"] self.product = self.env.ref("product.consu_delivery_01") + self.product1 = self.env["product.product"].create( + { + "name": "Test product", + "type": "consu", + "standard_price": 10.0, + "list_price": 20.0, + "uom_id": self.env.ref("uom.product_uom_unit").id, + "uom_po_id": self.env.ref("uom.product_uom_unit").id, + } + ) self.partner = self.env.ref("base.res_partner_1") # Create custom rates to currency + currency_extra self._create_currency_rate(self.currency, "2000-01-01", 1.0) @@ -57,7 +69,7 @@ def test_purchase_last_price_info_demo(self): self.assertEqual(self.product.last_purchase_price_currency_rate, 1.0) def test_purchase_last_price_info_new_order(self): - purchase_order = self.purchase_model.create( + purchase_order1 = self.purchase_model.create( { "date_order": "2000-01-01", "currency_id": self.currency_extra.id, @@ -67,30 +79,72 @@ def test_purchase_last_price_info_new_order(self): 0, 0, { - "product_id": self.product.id, - "product_uom": self.product.uom_id.id, - "price_unit": self.product.standard_price, - "name": self.product.name, + "product_id": self.product1.id, + "product_uom": self.product1.uom_id.id, + "price_unit": self.product1.standard_price, + "name": self.product1.name, "date_planned": fields.Datetime.now(), "product_qty": 1, + "sequence": 1, }, ) ], } ) - purchase_order.button_confirm() + purchase_order2 = self.purchase_model.create( + { + "date_order": "2001-01-01", + "currency_id": self.currency_extra.id, + "partner_id": self.partner.id, + "order_line": [ + ( + 0, + 0, + { + "product_id": self.product1.id, + "product_uom": self.product1.uom_id.id, + "price_unit": self.product1.standard_price, + "name": self.product1.name, + "date_planned": fields.Datetime.now(), + "product_qty": 1, + "sequence": 9999, + }, + ) + ], + } + ) + purchase_order1.button_confirm() + purchase_order2.button_confirm() self.assertEqual( - fields.Datetime.from_string(purchase_order.date_order).date(), - fields.Datetime.from_string(self.product.last_purchase_date).date(), + purchase_order2.date_order, + self.product1.last_purchase_date, + ) + first_order_line = fields.first( + self.product1.last_purchase_line_ids.sudo().filtered_domain( + [ + ("state", "in", ["purchase", "done"]), + ("company_id", "in", self.env.companies.ids), + ] + ) + ) + self.assertNotEqual( + first_order_line.date_order, + self.product1.last_purchase_date, + ) + expected_date = datetime.datetime(2001, 1, 1, 0, 0) + self.assertEqual( + expected_date, + self.product1.last_purchase_date, ) - first_order_line = fields.first(purchase_order.order_line) - self.assertEqual(first_order_line.price_unit, self.product.last_purchase_price) + expected_price = 10.0 + self.assertEqual(expected_price, self.product1.last_purchase_price) + expected_currency = self.currency_extra self.assertEqual( - first_order_line.currency_id, - self.product.last_purchase_currency_id, + expected_currency, + self.product1.last_purchase_currency_id, ) - self.assertEqual(self.product.last_purchase_currency_id, self.currency_extra) - self.assertEqual(self.product.last_purchase_price_currency_rate, 2.0) - self.assertEqual(self.partner, self.product.last_purchase_supplier_id) - purchase_order.button_cancel() - self.assertEqual(purchase_order.state, "cancel") + self.assertEqual(self.product1.last_purchase_currency_id, self.currency_extra) + self.assertEqual(self.product1.last_purchase_price_currency, 2.0) + self.assertEqual(self.partner, self.product1.last_purchase_supplier_id) + purchase_order2.button_cancel() + self.assertEqual(purchase_order2.state, "cancel")