From 6c172d6441c97368f8baa1e72d987247894f5313 Mon Sep 17 00:00:00 2001 From: lvessiller Date: Thu, 3 Mar 2022 11:58:29 +0100 Subject: [PATCH 1/3] NEW option update prices on proposal cloning --- htdocs/comm/propal/card.php | 6 +-- htdocs/comm/propal/class/propal.class.php | 54 ++++++++++++++++++++++- htdocs/langs/en_US/products.lang | 1 + htdocs/langs/fr_FR/products.lang | 1 + 4 files changed, 57 insertions(+), 5 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 61ecb966359..e30adc2f860 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -220,7 +220,7 @@ if (empty($reshook)) { } } - $result = $object->createFromClone($user, $socid, (GETPOSTISSET('entity') ? GETPOST('entity', 'int') : null)); + $result = $object->createFromClone($user, $socid, (GETPOSTISSET('entity') ? GETPOST('entity', 'int') : null), GETPOSTISSET('update_prices')); if ($result > 0) { header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); exit(); @@ -1914,8 +1914,8 @@ if ($action == 'create') { $formquestion = array( // 'text' => $langs->trans("ConfirmClone"), // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')) + array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')), + array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans('PuttingPricesUpToDate'), 'value' => 1), ); if (!empty($conf->global->PROPAL_CLONE_DATE_DELIVERY) && !empty($object->delivery_date)) { $formquestion[] = array('type' => 'date', 'name' => 'date_delivery', 'label' => $langs->trans("DeliveryDate"), 'value' => $object->delivery_date); diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 6a6031c3a99..0f711432eb9 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1324,11 +1324,12 @@ class Propal extends CommonObject * @param User $user User making the clone * @param int $socid Id of thirdparty * @param int $forceentity Entity id to force + * @param bool $update_prices [=false] Update prices if true * @return int New id of clone */ - public function createFromClone(User $user, $socid = 0, $forceentity = null) + public function createFromClone(User $user, $socid = 0, $forceentity = null, $update_prices = false) { - global $conf, $hookmanager; + global $conf, $hookmanager, $mysoc; dol_include_once('/projet/class/project.class.php'); @@ -1375,6 +1376,55 @@ class Propal extends CommonObject $objsoc->fetch($object->socid); } + // update prices + if ($update_prices === true) { + if ($objsoc->id > 0 && !empty($object->lines)) { + if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { + // If price per customer + require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + } + + foreach ($object->lines as $line) { + if ($line->fk_product > 0) { + $prod = new Product($this->db); + $res = $prod->fetch($line->fk_product); + if ($res > 0) { + $pu_ht = $prod->price; + $tva_tx = get_default_tva($mysoc, $objsoc, $prod->id); + $remise_percent = $objsoc->remise_percent; + + if (!empty($conf->global->PRODUIT_MULTIPRICES) && $objsoc->price_level > 0) { + $pu_ht = $prod->multiprices[$objsoc->price_level]; + if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) { // using this option is a bug. kept for backward compatibility + if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) { + $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level]; + } + } + } elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { + $prodcustprice = new Productcustomerprice($this->db); + $filter = array('t.fk_product' => $prod->id, 't.fk_soc' => $objsoc->id); + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + if ($result) { + // If there is some prices specific to the customer + if (count($prodcustprice->lines) > 0) { + $pu_ht = price($prodcustprice->lines[0]->price); + $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.' ('.$prodcustprice->lines[0]->default_vat_code.' )' : $prodcustprice->lines[0]->tva_tx); + if ($prodcustprice->lines[0]->default_vat_code && !preg_match('/\(.*\)/', $tva_tx)) { + $tva_tx .= ' ('.$prodcustprice->lines[0]->default_vat_code.')'; + } + } + } + } + + $line->subprice = $pu_ht; + $line->tva_tx = $tva_tx; + $line->remise_percent = $remise_percent; + } + } + } + } + } + $object->id = 0; $object->ref = ''; $object->entity = (!empty($forceentity) ? $forceentity : $object->entity); diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 960bf02eb46..b6e41c1f9d5 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -412,3 +412,4 @@ SwitchOnSaleStatus=Switch on sale status SwitchOnPurchaseStatus=Switch on purchase status StockMouvementExtraFields= Extra Fields (stock mouvement) InventoryExtraFields= Extra Fields (inventory) +PuttingPricesUpToDate=Update prices diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index a9ae791ec8d..c99f15a4613 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -411,3 +411,4 @@ Rank=Classement SwitchOnSaleStatus=Basculer le statut En vente SwitchOnPurchaseStatus=Basculer le statut En achat StockMouvementExtraFields= Champs supplémentaires (mouvement de stock) +PuttingPricesUpToDate=Mettre à jour les tarifs From 2561fcbb85abd89c6ec21fc37c7463242d834fb2 Mon Sep 17 00:00:00 2001 From: lvessiller Date: Tue, 8 Mar 2022 10:06:57 +0100 Subject: [PATCH 2/3] FIX translate update prices and add const in proposal setup --- htdocs/admin/propal.php | 51 ++++++++++++++++++++++++++++++++ htdocs/comm/propal/card.php | 4 +-- htdocs/langs/en_US/products.lang | 2 +- htdocs/langs/en_US/propal.lang | 1 + htdocs/langs/fr_FR/products.lang | 2 +- htdocs/langs/fr_FR/propal.lang | 1 + 6 files changed, 57 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php index 6384c561967..f0996b02f75 100644 --- a/htdocs/admin/propal.php +++ b/htdocs/admin/propal.php @@ -198,6 +198,37 @@ if ($action == 'updateMask') { // par appel methode canBeActivated dolibarr_set_const($db, "PROPALE_ADDON", $value, 'chaine', 0, '', $conf->entity); +} elseif (preg_match('/set_(.*)/',$action,$reg)) { + $code = $reg[1]; + $value=(GETPOST($code) ? GETPOST($code) : 1); + + $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + + if ($error) { + setEventMessages($langs->trans('Error'), null, 'errors'); + } else { + setEventMessages($langs->trans('SetupSaved'), null, 'mesgs'); + header("Location: " . $_SERVER["PHP_SELF"]); + exit(); + } +} elseif (preg_match('/del_(.*)/',$action,$reg)) { + $code = $reg[1]; + $res = dolibarr_del_const($db, $code, $conf->entity); + + if (!($res > 0)) { + $error++; + } + + if ($error) { + setEventMessages($langs->trans('Error'), null, 'errors'); + } else { + setEventMessages($langs->trans('SetupSaved'), null, 'mesgs'); + header("Location: " . $_SERVER["PHP_SELF"]); + exit(); + } } @@ -593,6 +624,26 @@ print ''; +print ''; +print ''; +print '' . $langs->trans('DefaultPuttingPricesUpToDate').''; +print ''; +print ''; +if (!empty($conf->use_javascript_ajax)) { + print ajax_constantonoff('PROPOSAL_CLONE_UPDATE_PRICES', array(), $conf->entity, 0, 0, 1, 0); +} else { + if (empty($conf->global->PROPOSAL_CLONE_UPDATE_PRICES)) { + print '' . img_picto($langs->trans('Disabled'), 'switch_off') . ''; + } else { + print '' . img_picto($langs->trans('Enabled'), 'switch_on') . ''; + } +} +print ''; +print ''; +print ''; + /* print '
'; print ''; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index e30adc2f860..3267b7b8b67 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -220,7 +220,7 @@ if (empty($reshook)) { } } - $result = $object->createFromClone($user, $socid, (GETPOSTISSET('entity') ? GETPOST('entity', 'int') : null), GETPOSTISSET('update_prices')); + $result = $object->createFromClone($user, $socid, (GETPOSTISSET('entity') ? GETPOST('entity', 'int') : null), (GETPOST('update_prices', 'aZ') ? true : false)); if ($result > 0) { header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); exit(); @@ -1915,7 +1915,7 @@ if ($action == 'create') { // 'text' => $langs->trans("ConfirmClone"), // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')), - array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans('PuttingPricesUpToDate'), 'value' => 1), + array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans('PuttingPricesUpToDate'), 'value' => (!empty($conf->global->PROPOSAL_CLONE_UPDATE_PRICES) ? 1 : 0)), ); if (!empty($conf->global->PROPAL_CLONE_DATE_DELIVERY) && !empty($object->delivery_date)) { $formquestion[] = array('type' => 'date', 'name' => 'date_delivery', 'label' => $langs->trans("DeliveryDate"), 'value' => $object->delivery_date); diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index b6e41c1f9d5..eb890560d36 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -412,4 +412,4 @@ SwitchOnSaleStatus=Switch on sale status SwitchOnPurchaseStatus=Switch on purchase status StockMouvementExtraFields= Extra Fields (stock mouvement) InventoryExtraFields= Extra Fields (inventory) -PuttingPricesUpToDate=Update prices +PuttingPricesUpToDate=Update prices with current known prices diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index db7b559a8a7..f12832129a8 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -54,6 +54,7 @@ NoDraftProposals=No draft proposals CopyPropalFrom=Create commercial proposal by copying existing proposal CreateEmptyPropal=Create empty commercial proposal or from list of products/services DefaultProposalDurationValidity=Default commercial proposal validity duration (in days) +DefaultPuttingPricesUpToDate=By default update prices with current known prices on cloning a proposal UseCustomerContactAsPropalRecipientIfExist=Use contact/address with type 'Contact following-up proposal' if defined instead of third party address as proposal recipient address ConfirmClonePropal=Are you sure you want to clone the commercial proposal %s? ConfirmReOpenProp=Are you sure you want to open back the commercial proposal %s? diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index c99f15a4613..97443fa3f64 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -411,4 +411,4 @@ Rank=Classement SwitchOnSaleStatus=Basculer le statut En vente SwitchOnPurchaseStatus=Basculer le statut En achat StockMouvementExtraFields= Champs supplémentaires (mouvement de stock) -PuttingPricesUpToDate=Mettre à jour les tarifs +PuttingPricesUpToDate=Mettre à jour les prix diff --git a/htdocs/langs/fr_FR/propal.lang b/htdocs/langs/fr_FR/propal.lang index c32edfad8c1..54723a5747f 100644 --- a/htdocs/langs/fr_FR/propal.lang +++ b/htdocs/langs/fr_FR/propal.lang @@ -54,6 +54,7 @@ NoDraftProposals=Pas de propositions brouillons CopyPropalFrom=Créer proposition/devis par recopie d'un proposition existante CreateEmptyPropal=Créer proposition/devis vierge ou avec la liste des produits/services DefaultProposalDurationValidity=Délai de validité par défaut (en jours) +DefaultPuttingPricesUpToDate=Par défaut, mettre à jour les prix lors de clonage d'une proposition commerciale UseCustomerContactAsPropalRecipientIfExist=Utiliser l'adresse de 'contact suivi client' si définie plutôt que l'adresse du tiers comme destinataire des propositions ConfirmClonePropal=Êtes-vous sûr de vouloir cloner la proposition commerciale %s ? ConfirmReOpenProp=Êtes-vous sûr de vouloir réouvrir la proposition commerciale %s ? From bbe3cfffb187e84491c265057015043afc27d289 Mon Sep 17 00:00:00 2001 From: lvessiller Date: Tue, 8 Mar 2022 10:17:47 +0100 Subject: [PATCH 3/3] FIX stickler-ci --- htdocs/admin/propal.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php index f0996b02f75..da886630ac9 100644 --- a/htdocs/admin/propal.php +++ b/htdocs/admin/propal.php @@ -198,9 +198,9 @@ if ($action == 'updateMask') { // par appel methode canBeActivated dolibarr_set_const($db, "PROPALE_ADDON", $value, 'chaine', 0, '', $conf->entity); -} elseif (preg_match('/set_(.*)/',$action,$reg)) { +} elseif (preg_match('/set_(.*)/', $action, $reg)) { $code = $reg[1]; - $value=(GETPOST($code) ? GETPOST($code) : 1); + $value = (GETPOST($code) ? GETPOST($code) : 1); $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { @@ -214,7 +214,7 @@ if ($action == 'updateMask') { header("Location: " . $_SERVER["PHP_SELF"]); exit(); } -} elseif (preg_match('/del_(.*)/',$action,$reg)) { +} elseif (preg_match('/del_(.*)/', $action, $reg)) { $code = $reg[1]; $res = dolibarr_del_const($db, $code, $conf->entity);