From b38389bfe2ac2178fdf560bbc467b0ce726354aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 16 Jul 2026 15:58:16 +0200 Subject: [PATCH] Warn when resetting to draft or cancelling production with pending purchase lines --- modules/production_outsourcing/message.xml | 6 +++ modules/production_outsourcing/production.py | 44 ++++++++++++++++++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/modules/production_outsourcing/message.xml b/modules/production_outsourcing/message.xml index 964db10ac0..f625a8f9da 100644 --- a/modules/production_outsourcing/message.xml +++ b/modules/production_outsourcing/message.xml @@ -3,6 +3,12 @@ this repository contains the full copyright notices and license terms. --> + + The productions "%(productions)s" cannot be reset to draft as they have pending purchases. + + + The productions "%(productions)s" cannot be cancelled as they have pending purchases. + The productions "%(productions)s" cannot be processed as they have pending purchases. diff --git a/modules/production_outsourcing/production.py b/modules/production_outsourcing/production.py index 58ea988f50..a8f837f7b3 100644 --- a/modules/production_outsourcing/production.py +++ b/modules/production_outsourcing/production.py @@ -130,9 +130,27 @@ class Production(metaclass=PoolMeta): def draft(cls, productions): pool = Pool() PurchaseLine = pool.get('purchase.line') + Warning = pool.get('res.user.warning') super().draft(productions) - PurchaseLine.delete([l for p in productions for l in p.purchase_lines - if l.purchase_state in {'draft', 'cancelled'}]) + to_delete, pendings = [], set() + for production in productions: + for line in production.purchase_lines: + if line.purchase_state in {'draft', 'cancelled'}: + to_delete.append(line) + else: + pendings.add(production) + if pendings: + names = ', '.join(p.rec_name for p in pendings[:5]) + if len(pendings) > 5: + names += '...' + warning_name = Warning.format('pending_purchase.draft', pendings) + if Warning.check(warning_name): + raise PurchaseWarning( + warning_name, + gettext( + 'production_outsourcing.msg_pending_purchase_draft', + productions=names)) + PurchaseLine.delete(to_delete) @classmethod @ModelView.button @@ -140,9 +158,27 @@ class Production(metaclass=PoolMeta): def cancel(cls, productions): pool = Pool() PurchaseLine = pool.get('purchase.line') + Warning = pool.get('res.user.warning') super().cancel(productions) - PurchaseLine.delete([l for p in productions for l in p.purchase_lines - if l.purchase_state in {'draft', 'cancelled'}]) + to_delete, pendings = [], set() + for production in productions: + for line in production.purchase_lines: + if line.purchase_state in {'draft', 'cancelled'}: + to_delete.append(line) + else: + pendings.add(production) + if pendings: + names = ', '.join(p.rec_name for p in pendings[:5]) + if len(pendings) > 5: + names += '...' + warning_name = Warning.format('pending_purchase.cancel', pendings) + if Warning.check(warning_name): + raise PurchaseWarning( + warning_name, + gettext( + 'production_outsourcing.msg_pending_purchase_cancel', + productions=names)) + PurchaseLine.delete(to_delete) @classmethod @ModelView.button