details:   https://code.tryton.org/tryton/commit/21cb53f6b5ba
branch:    default
user:      Cédric Krier <[email protected]>
date:      Tue Nov 11 18:04:50 2025 +0100
description:
        Use the fastest product supplier when anyone can supply on time

        Closes #12806
diffstat:

 modules/purchase_request/CHANGELOG            |   1 +
 modules/purchase_request/purchase_request.py  |   4 +
 modules/purchase_request/tests/test_module.py |  63 ++++++++++++++++++++++++++-
 3 files changed, 67 insertions(+), 1 deletions(-)

diffs (107 lines):

diff -r e0d1ee7e0c9f -r 21cb53f6b5ba modules/purchase_request/CHANGELOG
--- a/modules/purchase_request/CHANGELOG        Tue Oct 21 12:07:40 2025 +0200
+++ b/modules/purchase_request/CHANGELOG        Tue Nov 11 18:04:50 2025 +0100
@@ -1,3 +1,4 @@
+* Use the fastest product supplier when anyone can supply on time
 
 Version 7.6.0 - 2025-04-28
 --------------------------
diff -r e0d1ee7e0c9f -r 21cb53f6b5ba 
modules/purchase_request/purchase_request.py
--- a/modules/purchase_request/purchase_request.py      Tue Oct 21 12:07:40 
2025 +0200
+++ b/modules/purchase_request/purchase_request.py      Tue Nov 11 18:04:50 
2025 +0100
@@ -298,6 +298,7 @@
         Date = pool.get('ir.date')
         with Transaction().set_context(context=product._context):
             today = Date.today()
+        earlier_date, fastest = datetime.date.max, None
         for product_supplier in product.product_suppliers_used(**pattern):
             if date is None:
                 return product_supplier
@@ -305,6 +306,9 @@
             timedelta = date - supply_date
             if timedelta >= datetime.timedelta(0):
                 return product_supplier
+            if supply_date < earlier_date or earlier_date is datetime.date.max:
+                earlier_date, fastest = supply_date, product_supplier
+        return fastest
 
     @classmethod
     def find_best_supplier(cls, product, date, **pattern):
diff -r e0d1ee7e0c9f -r 21cb53f6b5ba 
modules/purchase_request/tests/test_module.py
--- a/modules/purchase_request/tests/test_module.py     Tue Oct 21 12:07:40 
2025 +0200
+++ b/modules/purchase_request/tests/test_module.py     Tue Nov 11 18:04:50 
2025 +0100
@@ -1,12 +1,73 @@
 # This file is part of Tryton.  The COPYRIGHT file at the top level of
 # this repository contains the full copyright notices and license terms.
 
-from trytond.tests.test_tryton import ModuleTestCase
+import datetime as dt
+
+from trytond.modules.company.tests import create_company, set_company
+from trytond.pool import Pool
+from trytond.tests.test_tryton import ModuleTestCase, with_transaction
 
 
 class PurchaseRequestTestCase(ModuleTestCase):
     'Test Purchase Request module'
     module = 'purchase_request'
 
+    @with_transaction()
+    def test_find_best_product_supplier(self):
+        "Test finding best product supplier"
+        pool = Pool()
+        ProductTemplate = pool.get('product.template')
+        Product = pool.get('product.product')
+        ProductSupplier = pool.get('purchase.product_supplier')
+        Party = pool.get('party.party')
+        UoM = pool.get('product.uom')
+        PurchaseRequest = pool.get('purchase.request')
+        Date = pool.get('ir.date')
+
+        supplier = Party(name="Supplier")
+        supplier.save()
+
+        company = create_company()
+        with set_company(company):
+            unit, = UoM.search([('name', '=', "Unit")])
+            template = ProductTemplate(name="Product")
+            template.purchasable = True
+            template.default_uom = unit
+            template.purchase_uom = unit
+            template.save()
+            product = Product(template=template)
+            product.save()
+
+            product_supplier1 = ProductSupplier(
+                template=template, party=supplier,
+                lead_time=dt.timedelta(days=5))
+            product_supplier1.save()
+            product_supplier2 = ProductSupplier(
+                template=template, party=supplier,
+                lead_time=dt.timedelta(days=2))
+            product_supplier2.save()
+            product_supplier3 = ProductSupplier(
+                template=template, party=supplier,
+                lead_time=dt.timedelta(days=3))
+            product_supplier3.save()
+
+            today = Date.today()
+            for date, product_supplier in [
+                    (None, product_supplier1),
+                    (today, product_supplier2),
+                    (today + dt.timedelta(days=1), product_supplier2),
+                    (today + dt.timedelta(days=2), product_supplier2),
+                    (today + dt.timedelta(days=3), product_supplier2),
+                    (today + dt.timedelta(days=4), product_supplier2),
+                    (today + dt.timedelta(days=5), product_supplier1),
+                    (dt.date.max, product_supplier1),
+                    (dt.date.min, product_supplier2),
+                    ]:
+                with self.subTest(date=date):
+                    self.assertEqual(
+                        PurchaseRequest.find_best_product_supplier(
+                            product, date),
+                        product_supplier)
+
 
 del ModuleTestCase

Reply via email to