details:   https://code.tryton.org/tryton/commit/84761faccad4
branch:    default
user:      Cédric Krier <[email protected]>
date:      Thu Sep 10 14:22:34 2026 +0200
description:
        Replace typing of stock move origin by sale and purchase Function field

        The origin may not always be a sale or purchase line like with product 
kit.
        So such test must be extendable by other modules implicitly. This can be
        achieved by using the Function fields.

        Closes #15084
diffstat:

 modules/incoterm/stock.py             |  12 ++++--------
 modules/purchase/stock.py             |   8 ++------
 modules/sale/stock.py                 |   8 ++------
 modules/sale_advance_payment/stock.py |   9 ++++-----
 4 files changed, 12 insertions(+), 25 deletions(-)

diffs (113 lines):

diff -r d8089f958e22 -r 84761faccad4 modules/incoterm/stock.py
--- a/modules/incoterm/stock.py Thu Sep 17 17:10:34 2026 +0200
+++ b/modules/incoterm/stock.py Thu Sep 10 14:22:34 2026 +0200
@@ -46,13 +46,11 @@
     def receive(cls, shipments):
         pool = Pool()
         Warning = pool.get('res.user.warning')
-        PurchaseLine = pool.get('purchase.line')
         for shipment in shipments:
             if shipment.incoterm:
                 incoterms = {
-                    move.origin.purchase.incoterm for move in shipment.moves
-                    if isinstance(move.origin, PurchaseLine)
-                    and move.state != 'cancelled'}
+                    move.purchase.incoterm for move in shipment.moves
+                    if move.state != 'cancelled' and move.purchase}
                 if {shipment.incoterm} != incoterms:
                     incoterms.discard(shipment.incoterm)
                     origin_incoterms = ', '.join(
@@ -99,13 +97,11 @@
     def wait(cls, shipments, moves=None):
         pool = Pool()
         Warning = pool.get('res.user.warning')
-        SaleLine = pool.get('sale.line')
         for shipment in shipments:
             if shipment.incoterm:
                 incoterms = {
-                    move.origin.sale.incoterm for move in shipment.moves
-                    if isinstance(move.origin, SaleLine)
-                    and move.state != 'cancelled'}
+                    move.sale.incoterm for move in shipment.moves
+                    if move.state != 'cancelled' and move.sale}
                 if {shipment.incoterm} != incoterms:
                     incoterms.discard(shipment.incoterm)
                     origin_incoterms = ', '.join(
diff -r d8089f958e22 -r 84761faccad4 modules/purchase/stock.py
--- a/modules/purchase/stock.py Thu Sep 17 17:10:34 2026 +0200
+++ b/modules/purchase/stock.py Thu Sep 10 14:22:34 2026 +0200
@@ -54,11 +54,9 @@
     @ModelView.button
     @Workflow.transition('draft')
     def draft(cls, shipments):
-        PurchaseLine = Pool().get('purchase.line')
         for shipment in shipments:
             for move in shipment.incoming_moves:
-                if (move.state == 'cancelled'
-                        and isinstance(move.origin, PurchaseLine)):
+                if move.state == 'cancelled' and move.purchase:
                     raise AccessError(
                         gettext('purchase.msg_purchase_move_reset_draft',
                             move=move.rec_name))
@@ -93,11 +91,9 @@
     @ModelView.button
     @Workflow.transition('draft')
     def draft(cls, shipments):
-        PurchaseLine = Pool().get('purchase.line')
         for shipment in shipments:
             for move in shipment.moves:
-                if (move.state == 'cancelled'
-                        and isinstance(move.origin, PurchaseLine)):
+                if move.state == 'cancelled' and move.purchase:
                     raise AccessError(
                         gettext('purchase.msg_purchase_move_reset_draft',
                             move=move.rec_name))
diff -r d8089f958e22 -r 84761faccad4 modules/sale/stock.py
--- a/modules/sale/stock.py     Thu Sep 17 17:10:34 2026 +0200
+++ b/modules/sale/stock.py     Thu Sep 10 14:22:34 2026 +0200
@@ -39,11 +39,9 @@
     @ModelView.button
     @Workflow.transition('draft')
     def draft(cls, shipments):
-        SaleLine = Pool().get('sale.line')
         for shipment in shipments:
             for move in shipment.outgoing_moves:
-                if (move.state == 'cancelled'
-                        and isinstance(move.origin, SaleLine)):
+                if move.state == 'cancelled' and move.sale:
                     raise AccessError(
                         gettext('sale.msg_sale_move_reset_draft',
                             move=move.rec_name))
@@ -79,11 +77,9 @@
     @ModelView.button
     @Workflow.transition('draft')
     def draft(cls, shipments):
-        SaleLine = Pool().get('sale.line')
         for shipment in shipments:
             for move in shipment.incoming_moves:
-                if (move.state == 'cancelled'
-                        and isinstance(move.origin, SaleLine)):
+                if move.state == 'cancelled' and move.sale:
                     raise AccessError(
                         gettext('sale.msg_sale_move_reset_draft',
                             move=move.rec_name))
diff -r d8089f958e22 -r 84761faccad4 modules/sale_advance_payment/stock.py
--- a/modules/sale_advance_payment/stock.py     Thu Sep 17 17:10:34 2026 +0200
+++ b/modules/sale_advance_payment/stock.py     Thu Sep 10 14:22:34 2026 +0200
@@ -17,12 +17,11 @@
     def pack(cls, shipments):
         pool = Pool()
         Sale = pool.get('sale.sale')
-        SaleLine = pool.get('sale.line')
 
-        sales = {move.origin.sale
-            for shipment in shipments for move in shipment.moves
-            if isinstance(move.origin, SaleLine)}
-        for sale in Sale.browse([s.id for s in sales]):
+        sales = {
+            move.sale for shipment in shipments for move in shipment.moves
+            if move.sale}
+        for sale in Sale.browse(sales):
             if sale.shipping_blocked:
                 raise ShippingBlocked(
                     gettext('sale_advance_payment.msg_shipping_blocked',

Reply via email to