From b28b94821f9e9d744ea58fb87e06096d8ade3fbc Mon Sep 17 00:00:00 2001 From: Vincent Maury Date: Sat, 18 Oct 2025 11:19:31 +0200 Subject: [PATCH] =?UTF-8?q?NEW=20#35700=20:=20Throw=20an=20error=20when=20?= =?UTF-8?q?validating=20a=20propal,=20order,=20supplier=20with=20a=20produ?= =?UTF-8?q?ct=20no=20more=20in=20sale/purchase=E2=80=A6=20(#35709)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #35700 : Throw an error when validating a propal, order, supplier proposal, supplier order if some products doesn't have the good status (on sale, on buy) * Fix #35700 : Throw an error when validating a propal, order, supplier proposal, supplier order if some products doesn't have the good status (on sale, on buy) * Fix #35700 : Throw an error when validating a propal, order, supplier proposal, supplier order if some products doesn't have the good status (on sale, on buy) * Fix #35700 : Throw an error when validating a propal, order, supplier proposal, supplier order if some products doesn't have the good status (on sale, on buy) * Fix #35700 : Throw an error when validating a propal, order, supplier proposal, supplier order if some products doesn't have the good status (on sale, on buy) * Update commonobject.class.php * Refactor checkActiveProductInLines method * Fix comment formatting in commonobject.class.php * Update commonobject.class.php --------- Co-authored-by: vmaury Co-authored-by: Laurent Destailleur --- htdocs/comm/propal/class/propal.class.php | 5 +++ htdocs/commande/class/commande.class.php | 5 ++- htdocs/core/class/commonobject.class.php | 42 ++++++++++++++++++- .../class/fournisseur.commande.class.php | 4 ++ htdocs/langs/en_US/errors.lang | 1 + htdocs/langs/fr_FR/errors.lang | 1 + .../class/supplier_proposal.class.php | 5 ++- 7 files changed, 60 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index dfd0bcafc78..c2af9bc7d12 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -2102,6 +2102,11 @@ class Propal extends CommonObject return -1; } + if (!getDolGlobalBool('PROPALE_NOCHECK_ONSALE_PRODUCTS_ONVALID') && !$this->checkActiveProductInLines()) { + dol_syslog(get_class($this)."::valid checkActiveProductInLines ".$this->error, LOG_INFO); + return -1; + } + $now = dol_now(); $this->db->begin(); diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 5833b5119ba..dd070117b55 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -529,7 +529,10 @@ class Commande extends CommonOrder $this->error = 'ErrorWrongParameters'; return -1; } - + if (!getDolGlobalBool('ORDER_NOCHECK_ONSALE_PRODUCTS_ONVALID') && !$this->checkActiveProductInLines()) { + dol_syslog(get_class($this)."::valid checkActiveProductInLines ".$this->error, LOG_INFO); + return -1; + } $now = dol_now(); $this->db->begin(); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index af10c4eabeb..8a300692617 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -20,7 +20,8 @@ * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 William Mead * Copyright (C) 2025 Alexandre Janniaux - * + * Copyright (C) 2025 Vincent Maury +* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -11619,4 +11620,43 @@ abstract class CommonObject $this->db->commit(); return true; } + + /** + * Check if all products have the right status (on sale, on buy) called + * during validation of propal, order, supplier proposal, supplier order + * + * @global object $langs + * @param string $status onsale or onbuy + * @return bool + */ + public function checkActiveProductInLines($status = 'onsale') + { + global $langs; + + if (isModEnabled('product') || isModEnabled('service')) { + include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + + $ret = true; + $tmpproduct = new Product($this->db); + foreach ($this->lines as $line) { + if ($line->fk_product > 0) { + $tmpproduct->fetch($line->fk_product); + $statustotest = ($status == 'onsale' ? 'status' : 'status_buy'); + if (!$tmpproduct->$statustotest) { + $langs->load('products'); + $statuskey4lang = ($status == 'onsale' ? 'ProductStatusNotOnSell' : 'ProductStatusNotOnBuy'); + $ret = false; + $this->errors[] = $langs->trans('ProductRef').' '.$tmpproduct->ref.' '.$langs->trans($statuskey4lang); + break; + } + } + } + if (!$ret) { + $this->error = 'ErrorOneLineContainsADisactivatedProduct'; + } + return $ret; + } else { + return true; + } + } } diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 06d08eab352..b52c88733f8 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -800,6 +800,10 @@ class CommandeFournisseur extends CommonOrder || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight("fournisseur", "supplier_order_advance", "validate"))) { $this->db->begin(); + if (!getDolGlobalBool('SUPPLIER_ORDER_NOCHECK_ONBUY_PRODUCTS_ONVALID') && !$this->checkActiveProductInLines('onbuy')) { + dol_syslog(get_class($this)."::valid checkActiveProductInLines ".$this->error, LOG_INFO); + return -1; + } // Definition of supplier order numbering model name $soc = new Societe($this->db); $soc->fetch($this->fourn_id); diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 6622b68edd2..4bdde7393f5 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -364,6 +364,7 @@ ErrorIsNotInError=%s is not in error ErrorFilenameExtensionNotAllowed=File %s has a forbidden file extension ErrorNoValueForSelectListType=Error, a value for this type of field is mandatory ErrorPaymentAmountMustNotBeNull=Error, payment amount must be defined and not zero +ErrorOneLineContainsADisactivatedProduct=Error, at least one product is not or no more on sale or for purchase ErrorCalendarIsNotYetOpenOrHasBeenClosed=This calendar is not yet open or has been closed # Warnings diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index 05803f1c04d..8c711c6dc68 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -361,6 +361,7 @@ ErrorThisGroupIsAlreadyDefinedAsThisType=Les contacts avec ce groupe sont déjà ErrorIsNotInError=%s n'est pas en erreur ErrorFilenameExtensionNotAllowed=Le fichier %s a une extension interdite ErrorNoValueForSelectListType=Erreur, une valeur pour ce type de champ est obligatoire +ErrorOneLineContainsADisactivatedProduct=Erreur, au moins un produit n'a pas le bon statut # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Votre paramètre PHP upload_max_filesize (%s) est supérieur au paramètre PHP post_max_size (%s). Ceci n'est pas une configuration cohérente. diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 400cddcc3ec..22d101e5077 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -1497,7 +1497,10 @@ class SupplierProposal extends CommonObject if ($result < 0) { return -1; } - + if (!getDolGlobalBool('SUPPLIER_PROPOSAL_NOCHECK_ONBUY_PRODUCTS_ONVALID') && !$this->checkActiveProductInLines('onbuy')) { + dol_syslog(get_class($this)."::valid checkActiveProductInLines ".$this->error, LOG_INFO); + return -1; + } // Define new ref if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) { // empty should not happened, but when it occurs, the test save life $num = $this->getNextNumRef($soc);