From 275b5d1f77fef674ae6c8a87d5506e2bcce38963 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Tue, 11 Feb 2020 07:32:29 +0100 Subject: [PATCH 01/38] FIX #10309 --- htdocs/core/lib/security.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 71d52f1bd9d..dc739220c07 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -122,7 +122,7 @@ function dol_hash($chain, $type = '0') } // Salt value - if (! empty($conf->global->MAIN_SECURITY_SALT)) $chain=$conf->global->MAIN_SECURITY_SALT.$chain; + if (! empty($conf->global->MAIN_SECURITY_SALT) && ( ! $type == '4' || ! $type == 'md5openldap')) $chain=$conf->global->MAIN_SECURITY_SALT.$chain; if ($type == '1' || $type == 'sha1') return sha1($chain); elseif ($type == '2' || $type == 'sha1md5') return sha1(md5($chain)); From f19f706c386e8dc4f123bea2b6e9453eeccb29d6 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 13 Feb 2020 07:55:52 +0100 Subject: [PATCH 02/38] FIX better check --- htdocs/core/lib/security.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index dc739220c07..483567aa3d0 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -122,7 +122,7 @@ function dol_hash($chain, $type = '0') } // Salt value - if (! empty($conf->global->MAIN_SECURITY_SALT) && ( ! $type == '4' || ! $type == 'md5openldap')) $chain=$conf->global->MAIN_SECURITY_SALT.$chain; + if (! empty($conf->global->MAIN_SECURITY_SALT) && ($type !== '4' || $type !== 'md5openldap')) $chain = $conf->global->MAIN_SECURITY_SALT.$chain; if ($type == '1' || $type == 'sha1') return sha1($chain); elseif ($type == '2' || $type == 'sha1md5') return sha1(md5($chain)); From 52506ddd05b3d73efec8b447aad32700b6c13186 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 13 Feb 2020 09:25:36 +0100 Subject: [PATCH 03/38] FIX can be a string or integer --- htdocs/core/lib/security.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 483567aa3d0..481339916a3 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -122,7 +122,7 @@ function dol_hash($chain, $type = '0') } // Salt value - if (! empty($conf->global->MAIN_SECURITY_SALT) && ($type !== '4' || $type !== 'md5openldap')) $chain = $conf->global->MAIN_SECURITY_SALT.$chain; + if (! empty($conf->global->MAIN_SECURITY_SALT) && ($type != '4' || $type !== 'md5openldap')) $chain = $conf->global->MAIN_SECURITY_SALT.$chain; if ($type == '1' || $type == 'sha1') return sha1($chain); elseif ($type == '2' || $type == 'sha1md5') return sha1(md5($chain)); From 0ab0bb2e7de4049e17d7f801e63545f8acfb003c Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 14 Feb 2020 19:26:28 +0100 Subject: [PATCH 04/38] FIX wrong test --- htdocs/core/lib/security.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 481339916a3..1a8045df014 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -122,7 +122,7 @@ function dol_hash($chain, $type = '0') } // Salt value - if (! empty($conf->global->MAIN_SECURITY_SALT) && ($type != '4' || $type !== 'md5openldap')) $chain = $conf->global->MAIN_SECURITY_SALT.$chain; + if (! empty($conf->global->MAIN_SECURITY_SALT) && $type != '4' && $type !== 'md5openldap') $chain = $conf->global->MAIN_SECURITY_SALT.$chain; if ($type == '1' || $type == 'sha1') return sha1($chain); elseif ($type == '2' || $type == 'sha1md5') return sha1(md5($chain)); From a7ca7dfbb639521bcb3d7bf6615c1b35364d4e72 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Thu, 20 Feb 2020 06:00:17 +0100 Subject: [PATCH 05/38] FIX: z-index for moretabsList with constant MAIN_MAXTABS_IN_CARD --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 9208ebb9a6e..ed50e236ffe 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1226,7 +1226,7 @@ function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab $tabsname=str_replace("@", "", $picto); $out.='
'; $out.=''.$langs->trans("More").'... ('.$nbintab.')'; - $out.='
'; + $out.='
'; $out.=$outmore; $out.='
'; $out.='
'; From 9ff424e23b63ef50ce3b52e67b33154dbe423aed Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Thu, 20 Feb 2020 11:45:46 +0100 Subject: [PATCH 06/38] FIX: Visualization rights correction on last modified contacts box --- htdocs/core/boxes/box_contacts.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php index 2d9d7e9461b..ebe7f8f9be0 100644 --- a/htdocs/core/boxes/box_contacts.php +++ b/htdocs/core/boxes/box_contacts.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2015 Frederic France * Copyright (C) 2018 Josep Lluís Amador + * Copyright (C) 2020 Ferran Marcet * * 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 @@ -90,7 +91,7 @@ class box_contacts extends ModeleBoxes $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON sp.fk_soc = s.rowid"; if (! $user->rights->societe->client->voir && ! $user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE sp.entity IN (".getEntity('socpeople').")"; - if (! $user->rights->societe->client->voir && ! $user->societe_id) $sql.= " AND sp.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + if (! $user->rights->societe->client->voir && ! $user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; if ($user->societe_id) $sql.= " AND sp.fk_soc = ".$user->societe_id; $sql.= " ORDER BY sp.tms DESC"; $sql.= $db->plimit($max, 0); From 71c9b94b223a5ee8b3418313d90b78cd6829fe71 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Fri, 21 Feb 2020 11:08:34 +0100 Subject: [PATCH 07/38] NEW add const CASHDESK_FORCE_DECREASE_STOCK to force batch decrementation --- htdocs/compta/facture/class/facture.class.php | 105 +++++++++++++++++- htdocs/langs/en_US/admin.lang | 2 + htdocs/langs/en_US/errors.lang | 2 + htdocs/langs/fr_FR/admin.lang | 2 + htdocs/langs/fr_FR/errors.lang | 2 + htdocs/product/class/productbatch.class.php | 66 +++++++++++ htdocs/takepos/admin/terminal.php | 9 +- htdocs/takepos/invoice.php | 7 +- 8 files changed, 187 insertions(+), 8 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index cb2bf087652..800dbc66b63 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2410,12 +2410,23 @@ class Facture extends CommonInvoice * @param string $force_number Reference to force on invoice * @param int $idwarehouse Id of warehouse to use for stock decrease if option to decreasenon stock is on (0=no decrease) * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @param int $batch_rule [=0] 0 not decrement batch, else batch rule to use + * 1=take in batches ordered by sellby and eatby dates * @return int <0 if KO, 0=Nothing done because invoice is not a draft, >0 if OK */ - public function validate($user, $force_number = '', $idwarehouse = 0, $notrigger = 0) + public function validate($user, $force_number = '', $idwarehouse = 0, $notrigger = 0, $batch_rule = 0) { global $conf, $langs; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $productStatic = null; + $warehouseStatic = null; + if ($batch_rule > 0) { + require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + require_once DOL_DOCUMENT_ROOT . '/product/class/productbatch.class.php'; + require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php'; + $productStatic = new Product($this->db); + $warehouseStatic = new Entrepot($this->db); + } $now = dol_now(); @@ -2557,11 +2568,93 @@ class Facture extends CommonInvoice $mouvP = new MouvementStock($this->db); $mouvP->origin = &$this; // We decrease stock for product - if ($this->type == self::TYPE_CREDIT_NOTE) $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceValidatedInDolibarr", $num)); - else $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr", $num)); - if ($result < 0) { - $error++; - $this->error = $mouvP->error; + if ($this->type == self::TYPE_CREDIT_NOTE) { + $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceValidatedInDolibarr", $num)); + if ($result < 0) { + $error++; + $this->error = $mouvP->error; + } + } else { + $is_batch_line = false; + if ($batch_rule > 0) { + $productStatic->fetch($this->lines[$i]->fk_product); + if ($productStatic->hasbatch()) { + $is_batch_line = true; + $product_qty_remain = $this->lines[$i]->qty; + + $sortfield = null; + $sortorder = null; + // find all batch order by sellby (DLC) and eatby dates (DLUO) first + if ($batch_rule == Productbatch::BATCH_RULE_SELLBY_EATBY_DATES_FIRST) { + $sortfield = 'pl.sellby,pl.eatby,pb.qty,pl.rowid'; + $sortorder = 'ASC,ASC,ASC,ASC'; + } + + $resBatchList = Productbatch::findAllForProduct($this->db, $productStatic->id, $idwarehouse, (!empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) ? null : 0), $sortfield, $sortorder); + if (!is_array($resBatchList)) { + $error++; + $this->error = $this->db->lasterror(); + } else { + $batchList = $resBatchList; + if (empty($batchList)) { + $error++; + $langs->load('errors'); + $warehouseStatic->fetch($idwarehouse); + $this->error = $langs->trans('ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref); + dol_syslog(__METHOD__ . ' Error: ' . $langs->transnoentitiesnoconv('ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR); + } else { + foreach ($batchList as $batch) { + if ($batch->qty <= 0) continue; // try to decrement only batches have positive quantity first + + // enough quantity in this batch + if ($batch->qty >= $product_qty_remain) { + $product_batch_qty = $product_qty_remain; + } + // not enough (take all in batch) + else { + $product_batch_qty = $batch->qty; + } + $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_batch_qty, $this->lines[$i]->subprice, $langs->trans('InvoiceValidatedInDolibarr', $num), '', '', '', $batch->batch); + if ($result < 0) { + $error++; + $this->error = $mouvP->error; + break; + } + + $product_qty_remain -= $product_batch_qty; + // all product quantity was decremented + if ($product_qty_remain <= 0) break; + } + + if (!$error && $product_qty_remain>0) { + if ($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) { + // take in the first batch + $batch = $batchList[0]; + $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_qty_remain, $this->lines[$i]->subprice, $langs->trans('InvoiceValidatedInDolibarr', $num), '', '', '', $batch->batch); + if ($result < 0) { + $error++; + $this->error = $mouvP->error; + } + } else { + $error++; + $langs->load('errors'); + $warehouseStatic->fetch($idwarehouse); + $this->error = $langs->trans('ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref); + dol_syslog(__METHOD__ . ' Error: ' . $langs->transnoentitiesnoconv('ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR); + } + } + } + } + } + } + + if (!$is_batch_line) { + $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr", $num)); + if ($result < 0) { + $error++; + $this->error = $mouvP->error; + } + } } } } diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index ee025ede17f..0f10ac291ff 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1686,6 +1686,8 @@ CashDeskIdWareHouse=Force and restrict warehouse to use for stock decrease StockDecreaseForPointOfSaleDisabled=Stock decrease from Point of Sale disabled StockDecreaseForPointOfSaleDisabledbyBatch=Stock decrease in POS is not compatible with module Serial/Lot management (currently active) so stock decrease is disabled. CashDeskYouDidNotDisableStockDecease=You did not disable stock decrease when making a sale from Point of Sale. Hence a warehouse is required. +CashDeskForceDecreaseStockLabel=Stock decrease for batch products was forced. +CashDeskForceDecreaseStockDesc=Decrease first by the oldest eatby and sellby dates. ##### Bookmark ##### BookmarkSetup=Bookmark module setup BookmarkDesc=This module allows you to manage bookmarks. You can also add shortcuts to any Dolibarr pages or external web sites on your left menu. diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 525131b2a61..2de7b74e82a 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -228,6 +228,8 @@ ErrorFieldRequiredForProduct=Field '%s' is required for product %s ProblemIsInSetupOfTerminal=Problem is in setup of terminal %s. ErrorAddAtLeastOneLineFirst=Add at least one line first ErrorRecordAlreadyInAccountingDeletionNotPossible=Error, record is already transferred in accounting, deletion is not possible. +ErrorBatchNoFoundForProductInWarehouse=No batch found for prorduct "%s" in warehouse "%s". +ErrorBatchNoFoundEnoughQuantityForProductInWarehouse=No enough quantity in batches for product "%s" in warehouse "%s". # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 052f77a365e..221d5032bfb 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -1683,6 +1683,8 @@ CashDeskIdWareHouse=Forcer et restreindre l'emplacement/entrepôt à utiliser po StockDecreaseForPointOfSaleDisabled=Réduction de stock lors de l'utilisation du Point de Vente désactivée StockDecreaseForPointOfSaleDisabledbyBatch=La décrémentation de stock depuis ce module Point de Vente n'est pas encore compatible avec la gestion des numéros de lots/série. CashDeskYouDidNotDisableStockDecease=Vous n'avez pas désactivé la réduction de stock lors d'une vente depuis le Point de vente. Par conséquent, un entrepôt est nécessaire. +CashDeskForceDecreaseStockLabel=Décrémentation des stocks pour les lots a été forcé. +CashDeskForceDecreaseStockDesc=Décrémentation des lots par DLC et DLUO les plus anciennes. ##### Bookmark ##### BookmarkSetup=Configuration du module Marque-pages BookmarkDesc=Ce module vous permet de gérer des liens et raccourcis. Il permet aussi d'ajouter n'importe quelle page de Dolibarr ou lien web dans le menu d'accès rapide sur la gauche. diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index 1142524115c..f7ffea8ed10 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -227,6 +227,8 @@ ErrorNoFieldWithAttributeShowoncombobox=Aucun champ n'a la propriété 'showonco ErrorFieldRequiredForProduct=Le champ '%s' est obligatoire pour le produit %s ProblemIsInSetupOfTerminal=Le problème est dans la configuration du terminal %s. ErrorAddAtLeastOneLineFirst=Ajouter d'abord au moins une ligne +ErrorBatchNoFoundForProductInWarehouse=Aucun lot trouvé pour le produit "%s" dans l'entrepôt "%s". +ErrorBatchNoFoundEnoughQuantityForProductInWarehouse=Quantité insuffisante dans les lots pour le produit "%s" dans l'entepôt "%s". # 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. WarningPasswordSetWithNoAccount=Un mot de passe a été fixé pour cet adhérent. Cependant, aucun compte d'utilisateur n'a été créé. Donc, ce mot de passe est stocké, mais ne peut être utilisé pour accéder à Dolibarr. Il peut être utilisé par un module/interface externe, mais si vous n'avez pas besoin de définir ni login ni mot de passe pour un adhérent, vous pouvez désactiver l'option «Gérer un login pour chaque adhérent" depuis la configuration du module Adhérents. Si vous avez besoin de gérer un login, mais pas de mot de passe, vous pouvez laisser ce champ vide pour éviter cet avertissement. Remarque: L'email peut également être utilisé comme login si l'adhérent est lié à un utilisateur. diff --git a/htdocs/product/class/productbatch.class.php b/htdocs/product/class/productbatch.class.php index a0a85bbec94..843bf2aa139 100644 --- a/htdocs/product/class/productbatch.class.php +++ b/htdocs/product/class/productbatch.class.php @@ -30,6 +30,11 @@ require_once DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php"; */ class Productbatch extends CommonObject { + /** + * Batches rules + */ + const BATCH_RULE_SELLBY_EATBY_DATES_FIRST = 1; + /** * @var string ID to identify managed object */ @@ -540,4 +545,65 @@ class Productbatch extends CommonObject return -1; } } + + /** + * Return all batch for a product and a warehouse + * + * @param DoliDB $db Database object + * @param int $fk_product Id of product + * @param int $fk_warehouse Id of warehouse + * @param int $qty_min [=NULL] Minimum quantity + * @param string $sortfield [=NULL] List of sort fields, separated by comma. Example: 't1.fielda,t2.fieldb' + * @param string $sortorder [=NULL] Sort order, separated by comma. Example: 'ASC,DESC'; + * @return int|array <0 if KO, array of batch + * + * @throws Exception + */ + public static function findAllForProduct($db, $fk_product, $fk_warehouse = 0, $qty_min = null, $sortfield = null, $sortorder = null) + { + $productBatchList = array(); + + dol_syslog(__METHOD__ . ' fk_product=' . $fk_product . ', fk_warehouse=' . $fk_warehouse . ', qty_min=' . $qty_min . ', sortfield=' . $sortfield . ', sortorder=' . $sortorder, LOG_DEBUG); + + $sql = "SELECT"; + $sql .= " pl.rowid"; + $sql .= ", pl.fk_product"; + $sql .= ", pl.batch"; + $sql .= ", pl.sellby"; + $sql .= ", pl.eatby"; + $sql .= ", pb.qty"; + $sql .= " FROM " . MAIN_DB_PREFIX . "product_lot as pl"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = pl.fk_product"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_batch AS pb ON pl.batch = pb.batch"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_stock AS ps ON ps.rowid = pb.fk_product_stock"; + $sql .= " WHERE p.entity IN (" . getEntity('product') . ")"; + $sql .= " AND pl.fk_product = " . $fk_product; + if ($fk_warehouse > 0) { + $sql .= " AND ps.fk_entrepot = " . $fk_warehouse; + } + if ($qty_min !== null) { + $sql .= " AND pb.qty > " . $qty_min; + } + $sql .= $db->order($sortfield, $sortorder); + + $resql = $db->query($sql); + if ($resql) { + while ($obj = $db->fetch_object($resql)) { + $productBatch = new self($db); + $productBatch->id = $obj->rowid; + $productBatch->fk_product = $obj->fk_product; + $productBatch->batch = $obj->batch; + $productBatch->eatby = $db->jdate($obj->eatby); + $productBatch->sellby = $db->jdate($obj->sellby); + $productBatch->qty = $obj->qty; + $productBatchList[] = $productBatch; + } + $db->free($resql); + + return $productBatchList; + } else { + dol_syslog(__METHOD__ . ' Error: ' . $db->lasterror(), LOG_ERR); + return -1; + } + } } diff --git a/htdocs/takepos/admin/terminal.php b/htdocs/takepos/admin/terminal.php index b30cb4e7032..9ffc691ac46 100644 --- a/htdocs/takepos/admin/terminal.php +++ b/htdocs/takepos/admin/terminal.php @@ -179,7 +179,7 @@ if (!empty($conf->stock->enabled)) { print ''.$langs->trans("CashDeskDoNotDecreaseStock").''; // Force warehouse (this is not a default value) print ''; - if (empty($conf->productbatch->enabled)) { + if (empty($conf->productbatch->enabled) || !empty($conf->global->CASHDESK_FORCE_DECREASE_STOCK)) { print $form->selectyesno('CASHDESK_NO_DECREASE_STOCK'.$terminal, $conf->global->{'CASHDESK_NO_DECREASE_STOCK'.$terminal}, 1); } else @@ -207,6 +207,13 @@ if (!empty($conf->stock->enabled)) print ''.$langs->trans("StockDecreaseForPointOfSaleDisabled").''; } print ''; + + if (!empty($conf->productbatch->enabled) && !empty($conf->global->CASHDESK_FORCE_DECREASE_STOCK) && !$conf->global->{'CASHDESK_NO_DECREASE_STOCK'.$terminal}) { + print '' . $langs->trans('CashDeskForceDecreaseStockLabel') . ''; + print ''; + print '' . $langs->trans('CashDeskForceDecreaseStockDesc') . ''; + print ''; + } } if ($conf->receiptprinter->enabled) { diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 77c59b090ca..c9739b2c414 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -190,7 +190,12 @@ if ($action == 'valid' && $user->rights->facture->creer) $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"]; dol_syslog("Validate invoice with stock change into warehouse defined into constant ".$constantforkey." = ".$conf->global->$constantforkey); - $res = $invoice->validate($user, '', $conf->global->$constantforkey); + $batch_rule = 0; + if (!empty($conf->productbatch->enabled) && !empty($conf->global->CASHDESK_FORCE_DECREASE_STOCK)) { + require_once DOL_DOCUMENT_ROOT . '/product/class/productbatch.class.php'; + $batch_rule = Productbatch::BATCH_RULE_SELLBY_EATBY_DATES_FIRST; + } + $res = $invoice->validate($user, '', $conf->global->$constantforkey, 0, $batch_rule); $conf->global->STOCK_CALCULATE_ON_BILL = $savconst; } From ec19b2feefbf405a634af735178f2cd743c6612f Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Fri, 21 Feb 2020 12:00:16 +0100 Subject: [PATCH 08/38] FIX phpcs nestling too high level --- htdocs/compta/facture/class/facture.class.php | 73 ++++++++++--------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 800dbc66b63..e6fa9b68350 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2594,7 +2594,9 @@ class Facture extends CommonInvoice if (!is_array($resBatchList)) { $error++; $this->error = $this->db->lasterror(); - } else { + } + + if (!$error) { $batchList = $resBatchList; if (empty($batchList)) { $error++; @@ -2602,46 +2604,45 @@ class Facture extends CommonInvoice $warehouseStatic->fetch($idwarehouse); $this->error = $langs->trans('ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref); dol_syslog(__METHOD__ . ' Error: ' . $langs->transnoentitiesnoconv('ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR); - } else { - foreach ($batchList as $batch) { - if ($batch->qty <= 0) continue; // try to decrement only batches have positive quantity first + } - // enough quantity in this batch - if ($batch->qty >= $product_qty_remain) { - $product_batch_qty = $product_qty_remain; - } - // not enough (take all in batch) - else { - $product_batch_qty = $batch->qty; - } - $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_batch_qty, $this->lines[$i]->subprice, $langs->trans('InvoiceValidatedInDolibarr', $num), '', '', '', $batch->batch); + foreach ($batchList as $batch) { + if ($batch->qty <= 0) continue; // try to decrement only batches have positive quantity first + + // enough quantity in this batch + if ($batch->qty >= $product_qty_remain) { + $product_batch_qty = $product_qty_remain; + } // not enough (take all in batch) + else { + $product_batch_qty = $batch->qty; + } + $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_batch_qty, $this->lines[$i]->subprice, $langs->trans('InvoiceValidatedInDolibarr', $num), '', '', '', $batch->batch); + if ($result < 0) { + $error++; + $this->error = $mouvP->error; + break; + } + + $product_qty_remain -= $product_batch_qty; + // all product quantity was decremented + if ($product_qty_remain <= 0) break; + } + + if (!$error && $product_qty_remain > 0) { + if ($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) { + // take in the first batch + $batch = $batchList[0]; + $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_qty_remain, $this->lines[$i]->subprice, $langs->trans('InvoiceValidatedInDolibarr', $num), '', '', '', $batch->batch); if ($result < 0) { $error++; $this->error = $mouvP->error; - break; - } - - $product_qty_remain -= $product_batch_qty; - // all product quantity was decremented - if ($product_qty_remain <= 0) break; - } - - if (!$error && $product_qty_remain>0) { - if ($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) { - // take in the first batch - $batch = $batchList[0]; - $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_qty_remain, $this->lines[$i]->subprice, $langs->trans('InvoiceValidatedInDolibarr', $num), '', '', '', $batch->batch); - if ($result < 0) { - $error++; - $this->error = $mouvP->error; - } - } else { - $error++; - $langs->load('errors'); - $warehouseStatic->fetch($idwarehouse); - $this->error = $langs->trans('ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref); - dol_syslog(__METHOD__ . ' Error: ' . $langs->transnoentitiesnoconv('ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR); } + } else { + $error++; + $langs->load('errors'); + $warehouseStatic->fetch($idwarehouse); + $this->error = $langs->trans('ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref); + dol_syslog(__METHOD__ . ' Error: ' . $langs->transnoentitiesnoconv('ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR); } } } From f6eba3657505539fcab6f026effb23b7935c85d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 20 Feb 2020 09:45:17 +0100 Subject: [PATCH 09/38] fix CATEGORY_ADD_DESC_INTO_DOC $cate->add_category doesn't exists --- htdocs/core/lib/pdf.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index a5ba08bb139..59035258c74 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1401,7 +1401,7 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, foreach ($tblcateg as $cate) { // Adding the descriptions if they are filled - $desccateg = $cate->add_description; + $desccateg = $cate->description; if ($desccateg) $libelleproduitservice .= '__N__'.$desccateg; } From 327b827fb45e6a693b3cc208d1fc1f0e0c9bda7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 21 Feb 2020 09:24:24 +0100 Subject: [PATCH 10/38] avoid warning if not an array Conflicts: htdocs/projet/element.php --- htdocs/projet/element.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 46cf12356c5..ffd083d2359 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -606,7 +606,7 @@ foreach ($listofreferent as $key => $value) $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field)?$project_field:'fk_projet'); - if (count($elementarray)>0 && is_array($elementarray)) + if (is_array($elementarray) && count($elementarray) > 0) { $total_ht = 0; $total_ttc = 0; From 8d507c4f3269456255507f788c4c1070f0e20b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 20 Feb 2020 15:11:31 +0100 Subject: [PATCH 11/38] fix workflow with multicurrency --- htdocs/compta/facture/class/facture.class.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index d4a7efd3cf4..99cc638c36f 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1156,6 +1156,14 @@ class Facture extends CommonInvoice $line->date_start = $object->lines[$i]->date_start; $line->date_end = $object->lines[$i]->date_end; + // Multicurrency + $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency; + $line->multicurrency_code = $object->lines[$i]->multicurrency_code; + $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice; + $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht; + $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva; + $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc; + $line->fk_fournprice = $object->lines[$i]->fk_fournprice; $marginInfos = getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht); $line->pa_ht = $marginInfos[0]; @@ -1170,6 +1178,7 @@ class Facture extends CommonInvoice $this->socid = $object->socid; $this->fk_project = $object->fk_project; + $this->fk_account = $object->fk_account; $this->cond_reglement_id = $object->cond_reglement_id; $this->mode_reglement_id = $object->mode_reglement_id; $this->availability_id = $object->availability_id; From 6264f78e398cb97fb856090988c33bd4a3e0399e Mon Sep 17 00:00:00 2001 From: gmilad <61253440+gmilad@users.noreply.github.com> Date: Fri, 21 Feb 2020 23:01:16 +0100 Subject: [PATCH 12/38] Update note.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bonsoir, Correction pour l'issue #13168 Cordialement, Gaëtan. --- htdocs/adherents/note.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/adherents/note.php b/htdocs/adherents/note.php index e232539491b..7e8175793fd 100644 --- a/htdocs/adherents/note.php +++ b/htdocs/adherents/note.php @@ -75,7 +75,7 @@ if ($id) $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'rowid', $linkback); + dol_banner_tab($object, 'id', $linkback); print '
'; From 16b4e680f7a1decf24100258f1c5f1d6d1f1a7a3 Mon Sep 17 00:00:00 2001 From: futurehousestore Date: Sat, 22 Feb 2020 02:45:58 +0000 Subject: [PATCH 13/38] Add Products/Services by popularity in Orders --- htdocs/langs/en_US/other.lang | 6 +- htdocs/product/popucom.php | 217 ++++++++++++++++++++++++++++++++++ htdocs/product/popuprop.php | 9 +- htdocs/product/stats/card.php | 7 +- 4 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 htdocs/product/popucom.php diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 59950289236..b32dd7ed07e 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -31,7 +31,7 @@ NextYearOfInvoice=Following year of invoice date DateNextInvoiceBeforeGen=Date of next invoice (before generation) DateNextInvoiceAfterGen=Date of next invoice (after generation) GraphInBarsAreLimitedTo3Measures=Grapics are limited to 3 measures in 'Bars' mode. The mode 'Lines' was automatically selected instead. -OnlyOneFieldForXAxisIsPossible=Only 1 field is currently possible as X-Axis. Only the first selected field has been selected. +OnlyOneFieldForXAxisIsPossible=Only 1 field is currently possible as X-Axis. Only the first selected field has been selected. AtLeastOneMeasureIsRequired=At least 1 field for measure is required AtLeastOneXAxisIsRequired=At least 1 field for X-Axis is required @@ -278,3 +278,7 @@ LinesToImport=Lines to import MemoryUsage=Memory usage RequestDuration=Duration of request +PopuProp=Products/Services by popularity in Proposals +PopuCom=Products/Services by popularity in Orders +ProductStatistics=Products/Services Statistics +NbOfQtyInOrders=Qty in orders diff --git a/htdocs/product/popucom.php b/htdocs/product/popucom.php new file mode 100644 index 00000000000..41f14e25176 --- /dev/null +++ b/htdocs/product/popucom.php @@ -0,0 +1,217 @@ + + * Copyright (C) 2004-2005 Laurent Destailleur + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2014 Marcos García + * Copyright (C) 2015 Jean-François Ferry + * + * 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 + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/product/popucom.php + * \ingroup commande, produit + * \brief Liste des produits/services par popularite + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + +// Load translation files required by the page +//Required to translate NbOfCommande +$langs->load('commande'); + +$type=GETPOST("type", "int"); + +// Security check +if (! empty($user->socid)) $socid=$user->socid; +$result=restrictedArea($user, 'produit|service'); + +$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); +$page = GETPOST("page", 'int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +if (! $sortfield) $sortfield="c"; +if (! $sortorder) $sortorder="DESC"; +$offset = $limit * $page ; +$pageprev = $page - 1; +$pagenext = $page + 1; + + +$staticproduct=new Product($db); + + +/* + * View + */ + +$helpurl=''; +if ($type == '0') +{ + $helpurl='EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos'; +} +elseif ($type == '1') +{ + $helpurl='EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios'; +} +else +{ + $helpurl='EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios'; +} +$title=$langs->trans("Statistics"); + + +llxHeader('', $title, $helpurl); + +print load_fiche_titre($title, $mesg, 'products'); + + +$param = ''; +$title = $langs->trans("ListProductServiceByPopularity"); +if ((string) $type == '1') { + $title = $langs->trans("ListServiceByPopularity"); +} +if ((string) $type == '0') { + $title = $langs->trans("ListProductByPopularity"); +} + +if ($type != '') $param .= '&type='.$type; + + +$h=0; +$head = array(); + +$head[$h][0] = DOL_URL_ROOT.'/product/stats/card.php?id=all'; +$head[$h][1] = $langs->trans("Chart"); +$head[$h][2] = 'chart'; +$h++; + +$head[$h][0] = DOL_URL_ROOT.'/product/popuprop.php'; +$head[$h][1] = $langs->trans("PopuProp"); +$head[$h][2] = 'popularityprop'; +$h++; + +$head[$h][0] = DOL_URL_ROOT.'/product/popucom.php'; +$head[$h][1] = $langs->trans("PopuCom"); +$head[$h][2] = 'popularitycommande'; +$h++; + +dol_fiche_head($head, 'popularitycommande', $langs->trans("Statistics"), -1); + + +// Array of liens to show +$infoprod=array(); + + +// Add lines for commande +$sql = "SELECT p.rowid, p.label, p.ref, p.fk_product_type as type, SUM(pd.qty) as c"; +$sql.= " FROM ".MAIN_DB_PREFIX."commandedet as pd"; +$sql.= ", ".MAIN_DB_PREFIX."product as p"; +$sql.= ' WHERE p.entity IN ('.getEntity('product').')'; +$sql.= " AND p.rowid = pd.fk_product"; +if ($type !== '') { + $sql.= " AND fk_product_type = ".$type; +} +$sql.= " GROUP BY p.rowid, p.label, p.ref, p.fk_product_type"; + +$result=$db->query($sql); +if ($result) +{ + $totalnboflines = $db->num_rows($result); +} + +$sql.= $db->order($sortfield, $sortorder); +$sql.= $db->plimit($limit+1, $offset); + +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + $i = 0; + + while ($i < $num) + { + $objp = $db->fetch_object($resql); + + $infoprod[$objp->rowid]=array('type'=>$objp->type, 'ref'=>$objp->ref, 'label'=>$objp->label); + $infoprod[$objp->rowid]['nblinecommande']=$objp->c; + + $i++; + } + $db->free($resql); +} +else +{ + dol_print_error($db); +} +//var_dump($infoprod); + + +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, "", $num, $totalnboflines, ''); + +print ''; + +print ""; +print_liste_field_titre('Ref', $_SERVER["PHP_SELF"], 'p.ref', '', $param, '', $sortfield, $sortorder); +print_liste_field_titre('Type', $_SERVER["PHP_SELF"], 'p.fk_product_type', '', $param, '', $sortfield, $sortorder); +print_liste_field_titre('Label', $_SERVER["PHP_SELF"], 'p.label', '', $param, '', $sortfield, $sortorder); +print_liste_field_titre('NbOfQtyInOrders', $_SERVER["PHP_SELF"], 'c', '', $param, '', $sortfield, $sortorder, 'right '); +print "\n"; + +foreach($infoprod as $prodid => $vals) +{ + // Multilangs + if (! empty($conf->global->MAIN_MULTILANGS)) // si l'option est active + { + $sql = "SELECT label"; + $sql.= " FROM ".MAIN_DB_PREFIX."product_lang"; + $sql.= " WHERE fk_product=".$prodid; + $sql.= " AND lang='". $langs->getDefaultLang() ."'"; + $sql.= " LIMIT 1"; + + $resultp = $db->query($sql); + if ($resultp) + { + $objtp = $db->fetch_object($resultp); + if (! empty($objtp->label)) $vals['label'] = $objtp->label; + } + } + + print ""; + print ''; + print ''; + print ''; + print ''; + print "\n"; + $i++; +} + +print "
'; + if ($vals['type'] == 1) print img_object($langs->trans("ShowService"), "service"); + else print img_object($langs->trans("ShowProduct"), "product"); + print " "; + print $vals['ref'].''; + if ($vals['type'] == 1) print $langs->trans("Service"); + else print $langs->trans("Product"); + print ''.$vals['label'].''.$vals['nblinecommande'].'
"; + + + +dol_fiche_end(); + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/product/popuprop.php b/htdocs/product/popuprop.php index 95bf2b965a2..4df11c7d755 100644 --- a/htdocs/product/popuprop.php +++ b/htdocs/product/popuprop.php @@ -99,11 +99,16 @@ $head[$h][1] = $langs->trans("Chart"); $head[$h][2] = 'chart'; $h++; -$head[$h][0] = $_SERVER['PHP_SELF']; -$head[$h][1] = $title; +$head[$h][0] = DOL_URL_ROOT.'/product/popuprop.php'; +$head[$h][1] = $langs->trans("PopuProp"); $head[$h][2] = 'popularityprop'; $h++; +$head[$h][0] = DOL_URL_ROOT.'/product/popucom.php'; +$head[$h][1] = $langs->trans("PopuCom"); +$head[$h][2] = 'popularitycommande'; +$h++; + dol_fiche_head($head, 'popularityprop', $langs->trans("Statistics"), -1); diff --git a/htdocs/product/stats/card.php b/htdocs/product/stats/card.php index 24387ef8b73..c35d8401a8a 100644 --- a/htdocs/product/stats/card.php +++ b/htdocs/product/stats/card.php @@ -161,10 +161,15 @@ if (empty($id) & empty($ref)) } $head[$h][0] = DOL_URL_ROOT.'/product/popuprop.php'.($type != '' ? '?type='.$type : ''); - $head[$h][1] = $title; + $head[$h][1] = $langs->trans("PopuProp"); $head[$h][2] = 'popularityprop'; $h++; + $head[$h][0] = DOL_URL_ROOT.'/product/popucom.php'.($type != '' ? '?type='.$type : ''); + $head[$h][1] = $langs->trans("PopuCom"); + $head[$h][2] = 'popularitycommande'; + $h++; + dol_fiche_head($head, 'chart', $langs->trans("Statistics"), -1); } From fddcc844fff7024936b3738cca8c025f6c682454 Mon Sep 17 00:00:00 2001 From: javierybar Date: Sat, 22 Feb 2020 11:30:48 +0100 Subject: [PATCH 14/38] Add orders to Receipt Printers module --- htdocs/core/class/dolreceiptprinter.class.php | 26 +++++++++++++++++++ htdocs/takepos/invoice.php | 24 ++++++++++++++--- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index 9fa42a8cce8..d241c2a8c5a 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -49,6 +49,8 @@ * Print object total tax * Print object local tax * Print object total + * Print order lines for Printer1 + * Print order lines for Printer2 * Print payment method * * Code which can be placed everywhere @@ -188,6 +190,8 @@ class dolReceiptPrinter extends Printer 'dol_print_object_local_tax', 'dol_print_object_total', 'dol_print_object_number', + 'dol_print_order_lines_printer1', + 'dol_print_order_lines_printer2', 'dol_value_customer_firstname', 'dol_value_customer_lastname', 'dol_value_customer_mail', @@ -720,6 +724,28 @@ class dolReceiptPrinter extends Printer case 'DOL_BEEP': $this->printer->getPrintConnector() -> write("\x1e"); break; + case 'DOL_PRINT_ORDER_LINES_PRINTER1': + foreach ($object->lines as $line) { + if ($line->special_code==1) + { + $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - 10 - 1; + $spaces = str_repeat(' ', $spacestoadd); + $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text(strip_tags(htmlspecialchars_decode($line->desc))."\n"); + } + } + break; + case 'DOL_PRINT_ORDER_LINES_PRINTER2': + foreach ($object->lines as $line) { + if ($line->special_code==2) + { + $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - 10 - 1; + $spaces = str_repeat(' ', $spacestoadd); + $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text(strip_tags(htmlspecialchars_decode($line->desc))."\n"); + } + } + break; default: $this->printer->text($vals[$tplline]['tag']); $this->printer->text($vals[$tplline]['value']); diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index a01cc04d416..1a6b5801f2b 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -441,6 +441,10 @@ if ($action == "updatereduction") if ($action == "order" and $placeid != 0) { include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + if ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter"){ + require_once DOL_DOCUMENT_ROOT.'/core/class/dolreceiptprinter.class.php'; + $printer = new dolReceiptPrinter($db); + } $headerorder = '
'.$langs->trans('Place').' '.$place.'
'; $footerorder = '
'.$langs->trans("Label").''.$langs->trans("Qty").'
'.dol_print_date(dol_now(), 'dayhour').'
'; @@ -458,13 +462,20 @@ if ($action == "order" and $placeid != 0) $result = array_intersect($catsprinter1, $existing); $count = count($result); if ($count > 0) { - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where rowid=".$line->id; + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='1' where rowid=".$line->id; //Set to print on printer 1 $db->query($sql); $order_receipt_printer1 .= ''.$line->product_label.''.$line->qty; if (!empty($line->array_options['options_order_notes'])) $order_receipt_printer1 .= "
(".$line->array_options['options_order_notes'].")"; $order_receipt_printer1 .= ''; } } + if ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter"){ + $invoice->fetch($placeid); //Reload object before send to printer + $ret = $printer->sendToPrinter($invoice, $conf->global->{'TAKEPOS_TEMPLATE_TO_USE_FOR_ORDERS'.$_SESSION["takeposterminal"]}, $conf->global->{'TAKEPOS_PRINTER_TO_USE'.$_SESSION["takeposterminal"]}); // PRINT TO PRINTER 1 + } + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='1' and fk_facture=".$invoice->id; // Set as printed + $db->query($sql); + $invoice->fetch($placeid); //Reload object after set lines as printed foreach ($invoice->lines as $line) { @@ -476,15 +487,20 @@ if ($action == "order" and $placeid != 0) $result = array_intersect($catsprinter2, $existing); $count = count($result); if ($count > 0) { - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where rowid=".$line->id; + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='2' where rowid=".$line->id; //Set to print on printer 2 $db->query($sql); $order_receipt_printer2 .= ''.$line->product_label.''.$line->qty; if (!empty($line->array_options['options_order_notes'])) $order_receipt_printer2 .= "
(".$line->array_options['options_order_notes'].")"; $order_receipt_printer2 .= ''; } } - - $invoice->fetch($placeid); + if ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter"){ + $invoice->fetch($placeid); //Reload object before send to printer + $ret = $printer->sendToPrinter($invoice, $conf->global->{'TAKEPOS_TEMPLATE_TO_USE_FOR_ORDERS'.$_SESSION["takeposterminal"]}, $conf->global->{'TAKEPOS_PRINTER_TO_USE'.$_SESSION["takeposterminal"]}); // PRINT TO PRINTER 2 + } + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='2' and fk_facture=".$invoice->id; // Set as printed + $db->query($sql); + $invoice->fetch($placeid); //Reload object after set lines as printed } $sectionwithinvoicelink = ''; From aa77d96f239ad4ec928ff6fbb369172eaee14792 Mon Sep 17 00:00:00 2001 From: ATM john Date: Sat, 22 Feb 2020 12:06:21 +0100 Subject: [PATCH 15/38] remove IDE warnings --- .../modules/facture/doc/pdf_sponge.modules.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 4fb6a55362e..a2d103f5531 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -126,10 +126,11 @@ class pdf_sponge extends ModelePDFFactures */ public $situationinvoice; + /** - * @var float X position for the situation progress column + * @var array of document table collumns */ - public $posxprogress; + public $cols; /** @@ -407,6 +408,8 @@ class pdf_sponge extends ModelePDFFactures $tab_height_newpage = 150; if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift; + $nexY = $tab_top - 1; + // Incoterm $height_incoterms = 0; if ($conf->incoterm->enabled) @@ -632,8 +635,6 @@ class pdf_sponge extends ModelePDFFactures if ($pageposafter > $pageposbefore) // There is a pagebreak { $pdf->rollbackTransaction(true); - $pageposafter = $pageposbefore; - //print $pageposafter.'-'.$pageposbefore;exit; $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); @@ -1052,7 +1053,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param PDF $pdf Object PDF + * @param tcpdf $pdf Object PDF * @param Object $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -1223,7 +1224,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDI $pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Amount already paid (in the currency of invoice) * @param int $posy Position depart @@ -1789,7 +1790,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param tcpdf $pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1849,7 +1850,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param Tcpdf $pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output From 1d34ef213c74a5cc6c5c48216dd314eefe291495 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 22 Feb 2020 12:19:46 +0100 Subject: [PATCH 16/38] Fix error management --- htdocs/compta/accounting-files.php | 269 +++++++++++++++-------------- htdocs/langs/en_US/errors.lang | 2 +- 2 files changed, 136 insertions(+), 135 deletions(-) diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 18a7eef7b6a..3f7c24c5070 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -118,10 +118,10 @@ if (($action == "searchfiles" || $action == "dl")) { $error++; } - $sql = ''; - if (!$error) { + $sql = ''; + $wheretail = " '".$db->idate($date_start)."' AND '".$db->idate($date_stop)."'"; // Customer invoices @@ -178,152 +178,153 @@ if (($action == "searchfiles" || $action == "dl")) { $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; //$sql.=" AND fk_statut <> ".ChargeSociales::STATUS_DRAFT; } - } - if ($sql) { - $sql .= $db->order($sortfield, $sortorder); - //print $sql; + if ($sql) { + $sql .= $db->order($sortfield, $sortorder); + //print $sql; - $resd = $db->query($sql); - $files = array(); - $link = ''; + $resd = $db->query($sql); + $files = array(); + $link = ''; - if ($resd) - { - $numd = $db->num_rows($resd); + if ($resd) + { + $numd = $db->num_rows($resd); - $tmpinvoice = new Facture($db); - $tmpinvoicesupplier = new FactureFournisseur($db); - $tmpdonation = new Don($db); + $tmpinvoice = new Facture($db); + $tmpinvoicesupplier = new FactureFournisseur($db); + $tmpdonation = new Don($db); - $upload_dir = ''; - $i = 0; - while ($i < $numd) - { - $objd = $db->fetch_object($resd); + $upload_dir = ''; + $i = 0; + while ($i < $numd) + { + $objd = $db->fetch_object($resd); - switch ($objd->item) - { - case "Invoice": - $subdir = ''; - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); - $upload_dir = $conf->facture->dir_output.'/'.$subdir; - $link = "document.php?modulepart=facture&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - case "SupplierInvoice": - $tmpinvoicesupplier->fetch($objd->id); - $subdir = get_exdir($tmpinvoicesupplier->id, 2, 0, 1, $tmpinvoicesupplier, 'invoice_supplier'); // TODO Use first file - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); - $upload_dir = $conf->fournisseur->facture->dir_output.'/'.$subdir; - $link = "document.php?modulepart=facture_fournisseur&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - case "ExpenseReport": - $subdir = ''; - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); - $upload_dir = $conf->expensereport->dir_output.'/'.$subdir; - $link = "document.php?modulepart=expensereport&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - case "SalaryPayment": - $subdir = ''; - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); - $upload_dir = $conf->salaries->dir_output.'/'.$subdir; - $link = "document.php?modulepart=salaries&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - case "Donation": - $tmpdonation->fetch($objp->id); - $subdir = get_exdir(0, 0, 0, 0, $tmpdonation, 'donation'); - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); - $upload_dir = $conf->don->dir_output.'/'.$subdir; - $link = "document.php?modulepart=don&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - case "SocialContributions": - $subdir = ''; - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); - $upload_dir = $conf->tax->dir_output.'/'.$subdir; - $link = "document.php?modulepart=tax&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - default: - $subdir = ''; - $upload_dir = ''; - $link = ''; - break; - } + switch ($objd->item) + { + case "Invoice": + $subdir = ''; + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); + $upload_dir = $conf->facture->dir_output.'/'.$subdir; + $link = "document.php?modulepart=facture&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + case "SupplierInvoice": + $tmpinvoicesupplier->fetch($objd->id); + $subdir = get_exdir($tmpinvoicesupplier->id, 2, 0, 1, $tmpinvoicesupplier, 'invoice_supplier'); // TODO Use first file + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); + $upload_dir = $conf->fournisseur->facture->dir_output.'/'.$subdir; + $link = "document.php?modulepart=facture_fournisseur&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + case "ExpenseReport": + $subdir = ''; + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); + $upload_dir = $conf->expensereport->dir_output.'/'.$subdir; + $link = "document.php?modulepart=expensereport&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + case "SalaryPayment": + $subdir = ''; + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); + $upload_dir = $conf->salaries->dir_output.'/'.$subdir; + $link = "document.php?modulepart=salaries&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + case "Donation": + $tmpdonation->fetch($objp->id); + $subdir = get_exdir(0, 0, 0, 0, $tmpdonation, 'donation'); + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); + $upload_dir = $conf->don->dir_output.'/'.$subdir; + $link = "document.php?modulepart=don&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + case "SocialContributions": + $subdir = ''; + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); + $upload_dir = $conf->tax->dir_output.'/'.$subdir; + $link = "document.php?modulepart=tax&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + default: + $subdir = ''; + $upload_dir = ''; + $link = ''; + break; + } - if (!empty($upload_dir)) - { - $result = true; + if (!empty($upload_dir)) + { + $result = true; - $files = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview\.png)$', '', SORT_ASC, 1); - //var_dump($upload_dir); - //var_dump($files); - if (count($files) < 1) - { - $nofile = array(); - $nofile['id'] = $objd->id; - $nofile['entity'] = $objd->entity; - $nofile['date'] = $db->idate($objd->date); - $nofile['paid'] = $objd->paid; - $nofile['amount_ht'] = $objd->total_ht; - $nofile['amount_ttc'] = $objd->total_ttc; - $nofile['amount_vat'] = $objd->total_vat; - $nofile['ref'] = ($objd->ref ? $objd->ref : $objd->id); - $nofile['fk'] = $objd->fk_soc; - $nofile['item'] = $objd->item; - $nofile['thirdparty_name'] = $objd->thirdparty_name; - $nofile['thirdparty_code'] = $objd->thirdparty_code; - $nofile['country_code'] = $objd->country_code; - $nofile['vatnum'] = $objd->vatnum; + $files = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview\.png)$', '', SORT_ASC, 1); + //var_dump($upload_dir); + //var_dump($files); + if (count($files) < 1) + { + $nofile = array(); + $nofile['id'] = $objd->id; + $nofile['entity'] = $objd->entity; + $nofile['date'] = $db->idate($objd->date); + $nofile['paid'] = $objd->paid; + $nofile['amount_ht'] = $objd->total_ht; + $nofile['amount_ttc'] = $objd->total_ttc; + $nofile['amount_vat'] = $objd->total_vat; + $nofile['ref'] = ($objd->ref ? $objd->ref : $objd->id); + $nofile['fk'] = $objd->fk_soc; + $nofile['item'] = $objd->item; + $nofile['thirdparty_name'] = $objd->thirdparty_name; + $nofile['thirdparty_code'] = $objd->thirdparty_code; + $nofile['country_code'] = $objd->country_code; + $nofile['vatnum'] = $objd->vatnum; - $filesarray[$nofile['item'].'_'.$nofile['id']] = $nofile; - } - else - { - foreach ($files as $key => $file) - { - $file['id'] = $objd->id; - $file['entity'] = $objd->entity; - $file['date'] = $db->idate($objd->date); - $file['paid'] = $objd->paid; - $file['amount_ht'] = $objd->total_ht; - $file['amount_ttc'] = $objd->total_ttc; - $file['amount_vat'] = $objd->total_vat; - $file['ref'] = ($objd->ref ? $objd->ref : $objd->id); - $file['fk'] = $objd->fk_soc; - $file['item'] = $objd->item; + $filesarray[$nofile['item'].'_'.$nofile['id']] = $nofile; + } + else + { + foreach ($files as $key => $file) + { + $file['id'] = $objd->id; + $file['entity'] = $objd->entity; + $file['date'] = $db->idate($objd->date); + $file['paid'] = $objd->paid; + $file['amount_ht'] = $objd->total_ht; + $file['amount_ttc'] = $objd->total_ttc; + $file['amount_vat'] = $objd->total_vat; + $file['ref'] = ($objd->ref ? $objd->ref : $objd->id); + $file['fk'] = $objd->fk_soc; + $file['item'] = $objd->item; - $file['thirdparty_name'] = $objd->thirdparty_name; - $file['thirdparty_code'] = $objd->thirdparty_code; - $file['country_code'] = $objd->country_code; - $file['vatnum'] = $objd->vatnum; + $file['thirdparty_name'] = $objd->thirdparty_name; + $file['thirdparty_code'] = $objd->thirdparty_code; + $file['country_code'] = $objd->country_code; + $file['vatnum'] = $objd->vatnum; - // Save record into array (only the first time it is found) - if (empty($filesarray[$file['item'].'_'.$file['id']])) { - $filesarray[$file['item'].'_'.$file['id']] = $file; - } + // Save record into array (only the first time it is found) + if (empty($filesarray[$file['item'].'_'.$file['id']])) { + $filesarray[$file['item'].'_'.$file['id']] = $file; + } - // Add or concat file - if (empty($filesarray[$file['item'].'_'.$file['id']]['files'])) { - $filesarray[$file['item'].'_'.$file['id']]['files'] = array(); - } - $filesarray[$file['item'].'_'.$file['id']]['files'][] = array('link' => $link.$file['name'], 'name'=>$file['name'], 'ref'=>$file['ref'], 'fullname' => $file['fullname'], 'relpathnamelang' => $langs->trans($file['item']).'/'.$file['name']); - //var_dump($file['item'].'_'.$file['id']); - //var_dump($filesarray[$file['item'].'_'.$file['id']]['files']); - } - } - } + // Add or concat file + if (empty($filesarray[$file['item'].'_'.$file['id']]['files'])) { + $filesarray[$file['item'].'_'.$file['id']]['files'] = array(); + } + $filesarray[$file['item'].'_'.$file['id']]['files'][] = array('link' => $link.$file['name'], 'name'=>$file['name'], 'ref'=>$file['ref'], 'fullname' => $file['fullname'], 'relpathnamelang' => $langs->trans($file['item']).'/'.$file['name']); + //var_dump($file['item'].'_'.$file['id']); + //var_dump($filesarray[$file['item'].'_'.$file['id']]['files']); + } + } + } - $i++; - } - } - else - { - dol_print_error($db); - } + $i++; + } + } + else + { + dol_print_error($db); + } - $db->free($resd); - } - else { - setEventMessages($langs->trans("ErrorAtLeastOneObjectMustBeSelected"), null, 'errors'); + $db->free($resd); + } + else { + setEventMessages($langs->trans("ErrorSelectAtLeastOne"), null, 'errors'); + $error++; + } } } diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index cc56503c638..210d7082fdf 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -96,7 +96,7 @@ ErrorBadMaskFailedToLocatePosOfSequence=Error, mask without sequence number ErrorBadMaskBadRazMonth=Error, bad reset value ErrorMaxNumberReachForThisMask=Maximum number reached for this mask ErrorCounterMustHaveMoreThan3Digits=Counter must have more than 3 digits -ErrorSelectAtLeastOne=Error. Select at least one entry. +ErrorSelectAtLeastOne=Error, select at least one entry. ErrorDeleteNotPossibleLineIsConsolidated=Delete not possible because record is linked to a bank transaction that is conciliated ErrorProdIdAlreadyExist=%s is assigned to another third ErrorFailedToSendPassword=Failed to send password From 559fc9f61ee0f471c1314c3261cd82c9eb05aab8 Mon Sep 17 00:00:00 2001 From: gmilad <61253440+gmilad@users.noreply.github.com> Date: Sat, 22 Feb 2020 13:07:25 +0100 Subject: [PATCH 17/38] Update note.php Fix : #13168 --- htdocs/adherents/note.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/adherents/note.php b/htdocs/adherents/note.php index c12c45de8b7..6d50ab58f88 100644 --- a/htdocs/adherents/note.php +++ b/htdocs/adherents/note.php @@ -75,7 +75,7 @@ if ($id) $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'rowid', $linkback); + dol_banner_tab($object, 'id', $linkback); print '
'; From d741a025f36aa2fe4cd3d1544173518d6fec8819 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 22 Feb 2020 14:13:15 +0100 Subject: [PATCH 18/38] Fix duplicate error message --- htdocs/cron/class/cronjob.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 82a898a8ddf..81f86b1642d 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1094,7 +1094,7 @@ class Cronjob extends CommonObject $errmsg = ''; if (!is_array($object->errors) || !in_array($object->error, $object->errors)) $errmsg .= $object->error; - if (is_array($object->errors) && count($object->errors)) $errmsg .= ($errmsg ? ', '.$errmsg : '').join(', ', $object->errors); + if (is_array($object->errors) && count($object->errors)) $errmsg .= (($errmsg ? ', ' : '').join(', ', $object->errors)); if (empty($errmsg)) $errmsg = $langs->trans('ErrorUnknown'); dol_syslog(get_class($this)."::run_jobs END result=".$result." error=".$errmsg, LOG_ERR); From 295d42b47680fb7e475356971e311f1b2736d4ab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 22 Feb 2020 14:19:23 +0100 Subject: [PATCH 19/38] Fix trans of status --- htdocs/cron/class/cronjob.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 5cde792bbb5..6139f157f8a 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1320,9 +1320,9 @@ class Cronjob extends CommonObject if ($processing) $moretext = ' ('.$langs->trans("Running").')'; elseif ($lastresult) $moretext .= ' ('.$langs->trans("Error").')'; - $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Draft').$moretext; + $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Disabled').$moretext; $this->labelStatus[self::STATUS_ENABLED] = $langs->trans('Enabled').$moretext; - $this->labelStatusShort[self::STATUS_DISABLED] = $langs->trans('Draft'); + $this->labelStatusShort[self::STATUS_DISABLED] = $langs->trans('Disabled'); $this->labelStatusShort[self::STATUS_ENABLED] = $langs->trans('Enabled'); } From 0d474b2ec9a6ba4725b0f9466f09aa6d706b8a67 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 22 Feb 2020 14:20:42 +0100 Subject: [PATCH 20/38] CSS --- htdocs/compta/accounting-files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 3f7c24c5070..bab53a8f77b 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -453,7 +453,7 @@ print ' - '.$form->selectDate($date_stop, 'date_stop', 0, 0, 0, "", 1, 1, 0)."\n if (!empty($conf->multicompany->enabled) && is_object($mc)) { $mc->getInfo($conf->entity); - print '('.$langs->trans("Entity").' : '; + print '('.$langs->trans("Entity").' : '; print ""; if (!empty($conf->global->MULTICOMPANY_ALLOW_EXPORT_ACCOUNTING_DOC_FOR_ALL_ENTITIES)) { print $mc->select_entities(GETPOSTISSET('search_entity') ? GETPOST('search_entity', 'int') : $mc->id, 'search_entity', '', false, false, false, false, true); From e209fd297320f422967dbbec5435a5d8fc901acf Mon Sep 17 00:00:00 2001 From: ATM john Date: Sat, 22 Feb 2020 16:27:44 +0100 Subject: [PATCH 21/38] Add extrafields on PDF object lines --- .../core/class/commondocgenerator.class.php | 194 +++++++++++++++++- .../facture/doc/pdf_sponge.modules.php | 19 +- 2 files changed, 211 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index dc4cbeff1ac..17f25b2d183 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1074,7 +1074,7 @@ abstract class CommonDocGenerator * @param float $curY curent Y position * @param string $colKey the column key * @param string $columnText column text - * @return int new rank on success and -1 on error + * @return null */ public function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '') { @@ -1096,6 +1096,111 @@ abstract class CommonDocGenerator } } + /** + * get extrafield content for pdf writeHtmlCell compatibility + * usage for PDF line columns and object note block + * + * @param object $object common object + * @param string $extrafieldKey the extrafield key + * @return null + */ + public function getExtrafieldContent($object, $extrafieldKey) + { + global $hookmanager; + + if(empty($object->table_element)){ return; } + + $extrafieldsKeyPrefix = "options_"; + + // Cleanup extrafield key to remove prefix if present + $pos = strpos($extrafieldKey, $extrafieldsKeyPrefix); + if($pos===0){ + $extrafieldKey = substr($extrafieldKey, strlen ( $extrafieldsKeyPrefix)); + } + + $extrafieldOptionsKey = $extrafieldsKeyPrefix.$extrafieldKey; + + + // Load extrafiels if not allready does + if(!isset($this->extrafieldsCache)){ $this->extrafieldsCache = array(); } + if(!isset($this->extrafieldsCache[$object->table_element])){ + $extrafields = new ExtraFields($this->db); + $extrafields->fetch_name_optionals_label($object->table_element); + } + else{ + $extrafields = $this->extrafieldsCache[$object->table_element]; + } + + $extrafieldOutputContent = $extrafields->showOutputField($extrafieldKey, $object->array_options[$extrafieldOptionsKey], '', $object->table_element); + + // TODO : allow showOutputField to be pdf public friendly, ex: in a link to object, clean getNomUrl to remove link and images... like a getName methode ... + if($extrafields->attributes[$object->table_element]['type'][$extrafieldKey] == 'link'){ + // for lack of anything better we cleanup all html tags + $extrafieldOutputContent = dol_string_nohtmltag($extrafieldOutputContent); + } + + $parameters = array( + 'object' => $object, + 'extrafields' => $extrafields, + 'extrafieldKey' => $extrafieldKey, + 'extrafieldOutputContent' =>& $extrafieldOutputContent + ); + $reshook = $hookmanager->executeHooks('getPDFExtrafieldContent', $parameters, $this); // Note that $action and $object may have been modified by hook + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + if ($reshook) + { + $extrafieldOutputContent = $hookmanager->resPrint; + } + + return $extrafieldOutputContent; + } + + + /** + * print extrafields columns content + * + * @param Tcpdf $pdf pdf object + * @param float $curY curent Y position + * @param object $object line of common object + * @return double max y value + */ + public function printLineExtrafieldsColumnsContent($pdf, &$curY, $object) + { + global $hookmanager; + + if(empty($object->table_element) || !isset($this->extrafieldsCache[$object->table_element])){ + return; + } + + $nextY = $curY; + + // get extrafield config from cache + $extrafields =& $this->extrafieldsCache[$object->table_element]; + + /** + * @var $extrafields ExtraFields + */ + + if (is_array($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) + { + $extrafieldColKey = "options_".$key; + + if ($this->getColumnStatus($extrafieldColKey) && isset($object->array_options[$extrafieldColKey])) + { + // TODO : allow showOutputField to be pdf public friendly, ex: in a link to object, clean getNomUrl to remove link and images... + $columnText = $extrafields->showOutputField($key, $object->array_options[$extrafieldColKey], '', $object->table_element); + + + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $columnText); + $nextY = max($pdf->GetY(), $nextY); + } + } + } + + return $nextY; + } + /** * get column status from column key @@ -1167,4 +1272,91 @@ abstract class CommonDocGenerator } return $this->tabTitleHeight; } + + + + /** + * Define Array Column Field for extrafields + * + * @param object $object common object det + * @param Translate $outputlangs langs + * @param int $hidedetails Do not show line details + * @return null + */ + public function defineColumnExtrafield($object, $outputlangs, $hidedetails = 0) + { + global $conf; + + if(!empty($hidedetails)){ + return; + } + + if(empty($object->table_element)){ + return; + } + + $extrafields = new ExtraFields($this->db); + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + + + if (is_array($extrafields->attributes[$object->table_element]['label'])) { + + // For cache on lines loop + if(!isset($this->extrafieldsCache)){ $this->extrafieldsCache = array(); } + $this->extrafieldsCache[$object->table_element] = $extrafields; + + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) + { + // Dont display separator yet even is set to be displayed (not compatible yet) + if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') + { + continue; + } + + // Enable extrafield ? + $enabled = 1; + if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$key])) + { + $enabled = dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1); + } + if ($enabled && isset($extrafields->attributes[$object->table_element]['list'][$key])) + { + $enabled = dol_eval($extrafields->attributes[$object->table_element]['list'][$key], 1); + } + + // Load language if required + if (!empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $outputlangs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); + + // TODO : add more extrafield customisation capacities for PDF like width, rank... + + // set column definition + $def = array( + 'rank' => intval($extrafields->attributes[$object->table_element]['pos'][$key]), + 'width' => 25, // in mm + 'status' => boolval($enabled), + 'title' => array( + 'label' => $outputlangs->transnoentities($label) + ), + 'content' => array( + 'align' => 'C' + ), + 'border-left' => true, // add left line separator + ); + + $alignTypeRight = array('double', 'int', 'price'); + if(in_array($extrafields->attributes[$object->table_element]['type'][$key], $alignTypeRight)){ + $def['content']['align'] = 'R'; + } + + $alignTypeLeft = array('text', 'html'); + if(in_array($extrafields->attributes[$object->table_element]['type'][$key], $alignTypeLeft)){ + $def['content']['align'] = 'L'; + } + + + // for extrafields we use rank of extrafield to place it on PDF + $this->insertNewColumnDef("options_".$key, $def); + } + } + } } diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index a2d103f5531..43b1fa4dbac 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -736,6 +736,18 @@ class pdf_sponge extends ModelePDFFactures $nexY = max($pdf->GetY(), $nexY); } + // Extrafields + if(!empty($object->lines[$i]->array_options)){ + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){ + if ($this->getColumnStatus($extrafieldColKey)) + { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } + $parameters = array( 'object' => $object, @@ -2346,7 +2358,7 @@ class pdf_sponge extends ModelePDFFactures $this->cols['discount']['status'] = true; } - $rank = $rank + 10; + $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100 $this->cols['totalexcltax'] = array( 'rank' => $rank, 'width' => 26, // in mm @@ -2357,6 +2369,11 @@ class pdf_sponge extends ModelePDFFactures 'border-left' => true, // add left line separator ); + // Add extrafields cols + if(!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } $parameters = array( 'object' => $object, From 2b027cfebf1193888ff569a877aa3e206ff1068f Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sat, 22 Feb 2020 15:45:39 +0000 Subject: [PATCH 22/38] Fixing style errors. --- htdocs/core/class/commondocgenerator.class.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 17f25b2d183..0b77ee2a61a 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1115,7 +1115,7 @@ abstract class CommonDocGenerator // Cleanup extrafield key to remove prefix if present $pos = strpos($extrafieldKey, $extrafieldsKeyPrefix); if($pos===0){ - $extrafieldKey = substr($extrafieldKey, strlen ( $extrafieldsKeyPrefix)); + $extrafieldKey = substr($extrafieldKey, strlen($extrafieldsKeyPrefix)); } $extrafieldOptionsKey = $extrafieldsKeyPrefix.$extrafieldKey; @@ -1300,7 +1300,6 @@ abstract class CommonDocGenerator if (is_array($extrafields->attributes[$object->table_element]['label'])) { - // For cache on lines loop if(!isset($this->extrafieldsCache)){ $this->extrafieldsCache = array(); } $this->extrafieldsCache[$object->table_element] = $extrafields; From 60b3d9d4db2954864b02e0919aa8ce79d7037706 Mon Sep 17 00:00:00 2001 From: ATM john Date: Sat, 22 Feb 2020 18:07:15 +0100 Subject: [PATCH 23/38] Add extrafields on PDF object lines for compatible pdf --- .../commande/doc/pdf_eratosthene.modules.php | 18 +- .../expedition/doc/pdf_espadon.modules.php | 17 +- .../modules/propale/doc/pdf_cyan.modules.php | 18 +- .../supplier_order/doc/pdf_cornas.modules.php | 244 ++---------------- 4 files changed, 67 insertions(+), 230 deletions(-) diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php index 5bdc591c2fb..a797d97e59c 100644 --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -702,6 +702,17 @@ class pdf_eratosthene extends ModelePDFCommandes $nexY = max($pdf->GetY(), $nexY); } + // Extrafields + if(!empty($object->lines[$i]->array_options)){ + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){ + if ($this->getColumnStatus($extrafieldColKey)) + { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } $parameters = array( 'object' => $object, @@ -1804,7 +1815,7 @@ class pdf_eratosthene extends ModelePDFCommandes $this->cols['discount']['status'] = true; } - $rank = $rank + 10; + $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100 $this->cols['totalexcltax'] = array( 'rank' => $rank, 'width' => 26, // in mm @@ -1815,6 +1826,11 @@ class pdf_eratosthene extends ModelePDFCommandes 'border-left' => true, // add left line separator ); + // Add extrafields cols + if(!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } $parameters = array( 'object' => $object, diff --git a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php index b47149f26a6..49a3307188a 100644 --- a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php @@ -558,7 +558,17 @@ class pdf_espadon extends ModelePdfExpedition $nexY = max($pdf->GetY(), $nexY); } - + // Extrafields + if(!empty($object->lines[$i]->array_options)){ + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){ + if ($this->getColumnStatus($extrafieldColKey)) + { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } $nexY += 3; if ($weighttxt && $voltxt) $nexY += 2; @@ -1225,6 +1235,11 @@ class pdf_espadon extends ModelePdfExpedition ), ); + // Add extrafields cols + if(!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } $parameters = array( 'object' => $object, diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index cbbf462b446..c7b1b1d715d 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -717,6 +717,17 @@ class pdf_cyan extends ModelePDFPropales $nexY = max($pdf->GetY(), $nexY); } + // Extrafields + if(!empty($object->lines[$i]->array_options)){ + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){ + if ($this->getColumnStatus($extrafieldColKey)) + { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } $parameters = array( 'object' => $object, @@ -1952,7 +1963,7 @@ class pdf_cyan extends ModelePDFPropales $this->cols['discount']['status'] = true; } - $rank = $rank + 10; + $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100 $this->cols['totalexcltax'] = array( 'rank' => $rank, 'width' => 26, // in mm @@ -1963,6 +1974,11 @@ class pdf_cyan extends ModelePDFPropales 'border-left' => true, // add left line separator ); + // Add extrafields cols + if(!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } $parameters = array( 'object' => $object, diff --git a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php index 1c266ae89b6..b7a5f49f06d 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php @@ -649,6 +649,17 @@ class pdf_cornas extends ModelePDFSuppliersOrders $nexY = max($pdf->GetY(), $nexY); } + // Extrafields + if(!empty($object->lines[$i]->array_options)){ + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){ + if ($this->getColumnStatus($extrafieldColKey)) + { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } $parameters = array( 'object' => $object, @@ -1596,7 +1607,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders $this->cols['discount']['status'] = true; } - $rank = $rank + 10; + $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100 $this->cols['totalexcltax'] = array( 'rank' => $rank, 'width' => 26, // in mm @@ -1607,6 +1618,11 @@ class pdf_cornas extends ModelePDFSuppliersOrders 'border-left' => true, // add left line separator ); + // Add extrafields cols + if(!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } $parameters = array( 'object' => $object, @@ -1630,230 +1646,4 @@ class pdf_cornas extends ModelePDFSuppliersOrders $this->cols = $hookmanager->resArray; } } - - /* - * - * DEBUT PARTIE NORMALEMENT DANS LA CLASSE CommonDocGenerator - * - * - */ - - /** - * uasort callback function to Sort columns fields - * - * @param array $a PDF lines array fields configs - * @param array $b PDF lines array fields configs - * @return int Return compare result - */ - public function columnSort($a, $b) - { - if (empty($a['rank'])) { $a['rank'] = 0; } - if (empty($b['rank'])) { $b['rank'] = 0; } - if ($a['rank'] == $b['rank']) { - return 0; - } - return ($a['rank'] > $b['rank']) ? -1 : 1; - } - - /** - * Prepare Array Column Field - * - * @param object $object common object - * @param Translate $outputlangs langs - * @param int $hidedetails Do not show line details - * @param int $hidedesc Do not show desc - * @param int $hideref Do not show ref - * @return null - */ - public function prepareArrayColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) - { - global $conf; - - $this->defineColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref); - - // Sorting - uasort($this->cols, array($this, 'columnSort')); - - // Positionning - $curX = $this->page_largeur - $this->marge_droite; // start from right - - // Array width - $arrayWidth = $this->page_largeur - $this->marge_droite - $this->marge_gauche; - - // Count flexible column - $totalDefinedColWidth = 0; - $countFlexCol = 0; - foreach ($this->cols as $colKey => &$colDef) - { - if (!$this->getColumnStatus($colKey)) continue; // continue if disabled - - if (!empty($colDef['scale'])) { - // In case of column widht is defined by percentage - $colDef['width'] = abs($arrayWidth * $colDef['scale'] / 100); - } - - if (empty($colDef['width'])) { - $countFlexCol++; - } - else { - $totalDefinedColWidth += $colDef['width']; - } - } - - foreach ($this->cols as $colKey => &$colDef) - { - // setting empty conf with default - if (!empty($colDef['title'])) { - $colDef['title'] = array_replace($this->defaultTitlesFieldsStyle, $colDef['title']); - } - else { - $colDef['title'] = $this->defaultTitlesFieldsStyle; - } - - // setting empty conf with default - if (!empty($colDef['content'])) { - $colDef['content'] = array_replace($this->defaultContentsFieldsStyle, $colDef['content']); - } - else { - $colDef['content'] = $this->defaultContentsFieldsStyle; - } - - if ($this->getColumnStatus($colKey)) - { - // In case of flexible column - if (empty($colDef['width'])) { - $colDef['width'] = abs(($arrayWidth - $totalDefinedColWidth)) / $countFlexCol; - } - - // Set positions - $lastX = $curX; - $curX = $lastX - $colDef['width']; - $colDef['xStartPos'] = $curX; - $colDef['xEndPos'] = $lastX; - } - } - } - - /** - * get column content width from column key - * - * @param string $colKey the column key - * @return float width in mm - */ - public function getColumnContentWidth($colKey) - { - $colDef = $this->cols[$colKey]; - return $colDef['width'] - $colDef['content']['padding'][3] - $colDef['content']['padding'][1]; - } - - - /** - * get column content X (abscissa) left position from column key - * - * @param string $colKey the column key - * @return float X position in mm - */ - public function getColumnContentXStart($colKey) - { - $colDef = $this->cols[$colKey]; - return $colDef['xStartPos'] + $colDef['content']['padding'][3]; - } - - /** - * get column position rank from column key - * - * @param string $colKey the column key - * @return int rank on success and -1 on error - */ - public function getColumnRank($colKey) - { - if (!isset($this->cols[$colKey]['rank'])) return -1; - return $this->cols[$colKey]['rank']; - } - - /** - * get column position rank from column key - * - * @param string $newColKey the new column key - * @param array $defArray a single column definition array - * @param string $targetCol target column used to place the new column beside - * @param bool $insertAfterTarget insert before or after target column ? - * @return int new rank on success and -1 on error - */ - public function insertNewColumnDef($newColKey, $defArray, $targetCol = false, $insertAfterTarget = false) - { - // prepare wanted rank - $rank = -1; - - // try to get rank from target column - if (!empty($targetCol)) { - $rank = $this->getColumnRank($targetCol); - if ($rank >= 0 && $insertAfterTarget) { $rank++; } - } - - // get rank from new column definition - if ($rank < 0 && !empty($defArray['rank'])) { - $rank = $defArray['rank']; - } - - // error: no rank - if ($rank < 0) { return -1; } - - foreach ($this->cols as $colKey =>& $colDef) - { - if ($rank <= $colDef['rank']) - { - $colDef['rank'] = $colDef['rank'] + 1; - } - } - - $defArray['rank'] = $rank; - $this->cols[$newColKey] = $defArray; // array_replace is used to preserve keys - - return $rank; - } - - - /** - * print standard column content - * - * @param PDF $pdf pdf object - * @param float $curY curent Y position - * @param string $colKey the column key - * @param string $columnText column text - * @return int new rank on success and -1 on error - */ - public function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '') - { - global $hookmanager; - - $parameters = array( - 'curY' =>& $curY, - 'columnText' => $columnText, - 'colKey' => $colKey - ); - $reshook = $hookmanager->executeHooks('printStdColumnContent', $parameters, $this); // Note that $action and $object may have been modified by hook - if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - if (!$reshook) - { - if (empty($columnText)) return; - $pdf->SetXY($this->getColumnContentXStart($colKey), $curY); // Set curent position - $colDef = $this->cols[$colKey]; - $pdf->MultiCell($this->getColumnContentWidth($colKey), 2, $columnText, '', $colDef['content']['align']); - } - } - - /** - * get column status from column key - * - * @param string $colKey the column key - * @return float width in mm - */ - public function getColumnStatus($colKey) - { - if (!empty($this->cols[$colKey]['status'])) { - return true; - } - else return false; - } } From 8c36dd0ad8f6108a7e7fc7daf658a6616cfadb3c Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 23 Feb 2020 02:26:21 +0100 Subject: [PATCH 24/38] add extrafields in notes --- .../core/class/commondocgenerator.class.php | 81 +++++++++++++------ .../commande/doc/pdf_eratosthene.modules.php | 7 ++ .../expedition/doc/pdf_espadon.modules.php | 16 +++- .../facture/doc/pdf_sponge.modules.php | 7 ++ .../modules/propale/doc/pdf_cyan.modules.php | 8 ++ .../supplier_order/doc/pdf_cornas.modules.php | 7 ++ 6 files changed, 99 insertions(+), 27 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 0b77ee2a61a..2517e5f4709 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1102,7 +1102,7 @@ abstract class CommonDocGenerator * * @param object $object common object * @param string $extrafieldKey the extrafield key - * @return null + * @return string */ public function getExtrafieldContent($object, $extrafieldKey) { @@ -1157,48 +1157,80 @@ abstract class CommonDocGenerator /** - * print extrafields columns content + * display extrafields columns content * - * @param Tcpdf $pdf pdf object - * @param float $curY curent Y position * @param object $object line of common object + * @param Translate $outputlangs Output language * @return double max y value */ - public function printLineExtrafieldsColumnsContent($pdf, &$curY, $object) + public function getExtrafieldsInHtml($object, $outputlangs) { global $hookmanager; - if(empty($object->table_element) || !isset($this->extrafieldsCache[$object->table_element])){ + if(empty($object->table_element)){ return; } - $nextY = $curY; + // Load extrafiels if not allready does + if(!isset($this->extrafieldsCache)){ $this->extrafieldsCache = array(); } + if(!isset($this->extrafieldsCache[$object->table_element])){ + $extrafields = new ExtraFields($this->db); + $extrafields->fetch_name_optionals_label($object->table_element); + } + else{ + $extrafields = $this->extrafieldsCache[$object->table_element]; + } - // get extrafield config from cache - $extrafields =& $this->extrafieldsCache[$object->table_element]; /** * @var $extrafields ExtraFields */ + $html = ''; + $fields = array(); + if (is_array($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { - $extrafieldColKey = "options_".$key; - - if ($this->getColumnStatus($extrafieldColKey) && isset($object->array_options[$extrafieldColKey])) - { - // TODO : allow showOutputField to be pdf public friendly, ex: in a link to object, clean getNomUrl to remove link and images... - $columnText = $extrafields->showOutputField($key, $object->array_options[$extrafieldColKey], '', $object->table_element); - - - $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $columnText); - $nextY = max($pdf->GetY(), $nextY); + // Enable extrafield ? + $enabled = 1; + if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$key])){ + $enabled = dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1); } + + if ($enabled && isset($extrafields->attributes[$object->table_element]['list'][$key])){ + $enabled = dol_eval($extrafields->attributes[$object->table_element]['list'][$key], 1); + } + + // TODO : add extrafields enabled for display from extrafield config panel + + if(empty($enabled)){ + continue; + } + + $field = new stdClass(); + $field->rank = intval($extrafields->attributes[$object->table_element]['pos'][$key]); + $field->content = $this->getExtrafieldContent($object, $key); + $field->label = $outputlangs->transnoentities($label); + + $fields[] = $field; } } - return $nextY; + if(!empty($fields)) + { + uasort($fields, function($a, $b){ + return ($a->rank > $b->rank) ? -1 : 1; + } + ); + + foreach ($fields as $field){ + $html.= !empty($html)?'
':''; + $html.= $field->label.' : '.$field->content; + } + } + + return $html; } @@ -1314,15 +1346,16 @@ abstract class CommonDocGenerator // Enable extrafield ? $enabled = 1; - if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$key])) - { + if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$key])){ $enabled = dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1); } - if ($enabled && isset($extrafields->attributes[$object->table_element]['list'][$key])) - { + + if ($enabled && isset($extrafields->attributes[$object->table_element]['list'][$key])){ $enabled = dol_eval($extrafields->attributes[$object->table_element]['list'][$key], 1); } + // TODO : add extrafields $enabled from extrafield config panel + // Load language if required if (!empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $outputlangs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php index a797d97e59c..fc1d737a7d5 100644 --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -410,6 +410,13 @@ class pdf_eratosthene extends ModelePDFCommandes } } + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) + { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + $pagenb = $pdf->getPage(); if ($notetoshow) { diff --git a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php index 49a3307188a..5d211c2cbae 100644 --- a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php @@ -336,7 +336,17 @@ class pdf_espadon extends ModelePdfExpedition } } - if (!empty($object->note_public) || !empty($object->tracking_number)) + // display note + $notetoshow = empty($object->note_public) ? '' : $object->note_public; + + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) + { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + + if (!empty($notetoshow) || !empty($object->tracking_number)) { $tab_top = 88 + $height_incoterms; $tab_top_alt = $tab_top; @@ -375,10 +385,10 @@ class pdf_espadon extends ModelePdfExpedition } // Notes - if (!empty($object->note_public)) + if (!empty($notetoshow)) { $pdf->SetFont('', '', $default_font_size - 1); // In loop to manage multi-page - $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top_alt, dol_htmlentitiesbr($object->note_public), 0, 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top_alt, dol_htmlentitiesbr($notetoshow), 0, 1); } $nexY = $pdf->GetY(); diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 43b1fa4dbac..cd9327e25b9 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -447,6 +447,13 @@ class pdf_sponge extends ModelePDFFactures } } + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) + { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + $pagenb = $pdf->getPage(); if ($notetoshow) { diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index c7b1b1d715d..702202be988 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -418,6 +418,14 @@ class pdf_cyan extends ModelePDFPropales if (!empty($salerepobj->signature)) $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature); } } + + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) + { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + if (!empty($conf->global->MAIN_ADD_CREATOR_IN_NOTE) && $object->user_author_id > 0) { $tmpuser = new User($this->db); diff --git a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php index b7a5f49f06d..92bc5219688 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php @@ -369,6 +369,13 @@ class pdf_cornas extends ModelePDFSuppliersOrders // Affiche notes $notetoshow = empty($object->note_public) ? '' : $object->note_public; + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) + { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + $pagenb = $pdf->getPage(); if ($notetoshow) { From 281e059487d3633ac1d553751d267a8a50d3e477 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sun, 23 Feb 2020 01:28:30 +0000 Subject: [PATCH 25/38] Fixing style errors. --- htdocs/core/class/commondocgenerator.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 2517e5f4709..9f3502c1836 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1219,9 +1219,9 @@ abstract class CommonDocGenerator if(!empty($fields)) { - uasort($fields, function($a, $b){ + uasort($fields, function ($a, $b) { return ($a->rank > $b->rank) ? -1 : 1; - } + } ); foreach ($fields as $field){ From ff6dc735eeb25371966a430743cef547dfb70d30 Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 23 Feb 2020 10:09:47 +0100 Subject: [PATCH 26/38] fix extrafield conf cache --- .../core/class/commondocgenerator.class.php | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 9f3502c1836..cfab7d7f5d6 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -49,6 +49,10 @@ abstract class CommonDocGenerator */ protected $db; + /** + * @var Extrafields object + */ + public $extrafieldsCache; /** * Constructor @@ -1122,14 +1126,9 @@ abstract class CommonDocGenerator // Load extrafiels if not allready does - if(!isset($this->extrafieldsCache)){ $this->extrafieldsCache = array(); } - if(!isset($this->extrafieldsCache[$object->table_element])){ - $extrafields = new ExtraFields($this->db); - $extrafields->fetch_name_optionals_label($object->table_element); - } - else{ - $extrafields = $this->extrafieldsCache[$object->table_element]; - } + if(empty($this->extrafieldsCache)){ $this->extrafieldsCache = new ExtraFields($this->db); } + if(empty($this->extrafieldsCache->attributes[$object->table_element])){ $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); } + $extrafields = $this->extrafieldsCache; $extrafieldOutputContent = $extrafields->showOutputField($extrafieldKey, $object->array_options[$extrafieldOptionsKey], '', $object->table_element); @@ -1172,14 +1171,9 @@ abstract class CommonDocGenerator } // Load extrafiels if not allready does - if(!isset($this->extrafieldsCache)){ $this->extrafieldsCache = array(); } - if(!isset($this->extrafieldsCache[$object->table_element])){ - $extrafields = new ExtraFields($this->db); - $extrafields->fetch_name_optionals_label($object->table_element); - } - else{ - $extrafields = $this->extrafieldsCache[$object->table_element]; - } + if(empty($this->extrafieldsCache)){ $this->extrafieldsCache = new ExtraFields($this->db); } + if(empty($this->extrafieldsCache->attributes[$object->table_element])){ $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); } + $extrafields = $this->extrafieldsCache; /** @@ -1327,14 +1321,13 @@ abstract class CommonDocGenerator return; } - $extrafields = new ExtraFields($this->db); - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + // Load extrafiels if not allready does + if(empty($this->extrafieldsCache)){ $this->extrafieldsCache = new ExtraFields($this->db); } + if(empty($this->extrafieldsCache->attributes[$object->table_element])){ $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); } + $extrafields = $this->extrafieldsCache; - if (is_array($extrafields->attributes[$object->table_element]['label'])) { - // For cache on lines loop - if(!isset($this->extrafieldsCache)){ $this->extrafieldsCache = array(); } - $this->extrafieldsCache[$object->table_element] = $extrafields; + if (!empty($extrafields->attributes[$object->table_element]) && is_array($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { From d575188d8077a3dc5c2a82787a7132a881b925fd Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sun, 23 Feb 2020 09:11:58 +0000 Subject: [PATCH 27/38] Fixing style errors. --- htdocs/core/class/commondocgenerator.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index cfab7d7f5d6..b9302536dfd 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1328,7 +1328,6 @@ abstract class CommonDocGenerator if (!empty($extrafields->attributes[$object->table_element]) && is_array($extrafields->attributes[$object->table_element]['label'])) { - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { // Dont display separator yet even is set to be displayed (not compatible yet) From fe4e00b139ebabb71aa374327afd15e6982f776b Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 23 Feb 2020 11:32:38 +0100 Subject: [PATCH 28/38] Add new params to extrafields forms to allow extrafields to be displayed on pdf documents --- htdocs/core/actions_extrafields.inc.php | 6 +++-- .../core/class/commondocgenerator.class.php | 21 ++--------------- htdocs/core/class/extrafields.class.php | 23 ++++++++++++++----- htdocs/core/tpl/admin_extrafields_add.tpl.php | 3 +++ .../core/tpl/admin_extrafields_edit.tpl.php | 6 ++++- .../core/tpl/admin_extrafields_view.tpl.php | 4 +++- .../install/mysql/migration/11.0.0-12.0.0.sql | 4 +++- htdocs/langs/en_US/modulebuilder.lang | 2 ++ 8 files changed, 39 insertions(+), 30 deletions(-) diff --git a/htdocs/core/actions_extrafields.inc.php b/htdocs/core/actions_extrafields.inc.php index ca2499ab145..486764b167e 100644 --- a/htdocs/core/actions_extrafields.inc.php +++ b/htdocs/core/actions_extrafields.inc.php @@ -183,7 +183,8 @@ if ($action == 'add') (GETPOST('entitycurrentorall', 'alpha')?0:''), GETPOST('langfile', 'alpha'), 1, - (GETPOST('totalizable', 'alpha')?1:0) + (GETPOST('totalizable', 'alpha')?1:0), + (GETPOST('documentpdf', 'alpha')?1:0) ); if ($result > 0) { @@ -352,7 +353,8 @@ if ($action == 'update') (GETPOST('entitycurrentorall', 'alpha')?0:''), GETPOST('langfile'), 1, - (GETPOST('totalizable', 'alpha')?1:0) + (GETPOST('totalizable', 'alpha')?1:0), + (GETPOST('documentpdf', 'alpha')?1:0) ); if ($result > 0) { diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index cfab7d7f5d6..fcd2837735d 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1187,16 +1187,7 @@ abstract class CommonDocGenerator foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { // Enable extrafield ? - $enabled = 1; - if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$key])){ - $enabled = dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1); - } - - if ($enabled && isset($extrafields->attributes[$object->table_element]['list'][$key])){ - $enabled = dol_eval($extrafields->attributes[$object->table_element]['list'][$key], 1); - } - - // TODO : add extrafields enabled for display from extrafield config panel + $enabled = !empty($extrafields->attributes[$object->table_element]['documentpdf'][$key]); if(empty($enabled)){ continue; @@ -1338,16 +1329,8 @@ abstract class CommonDocGenerator } // Enable extrafield ? - $enabled = 1; - if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$key])){ - $enabled = dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1); - } + $enabled = !empty($extrafields->attributes[$object->table_element]['documentpdf'][$key]); - if ($enabled && isset($extrafields->attributes[$object->table_element]['list'][$key])){ - $enabled = dol_eval($extrafields->attributes[$object->table_element]['list'][$key], 1); - } - - // TODO : add extrafields $enabled from extrafield config panel // Load language if required if (!empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $outputlangs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 5d5540d77b8..7765999339d 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -374,9 +374,11 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is a measure. Must show a total on lists + * @param int $documentpdf Is extrafield displayed on PDF * @return int <=0 if KO, >0 if OK + * @throws Exception */ - private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = 0, $elementtype = 'member', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0) + private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = 0, $elementtype = 'member', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $documentpdf = 0) { // phpcs:enable global $conf, $user; @@ -421,6 +423,7 @@ class ExtraFields $sql .= " perms,"; $sql .= " langs,"; $sql .= " list,"; + $sql .= " documentpdf,"; $sql .= " fielddefault,"; $sql .= " fieldcomputed,"; $sql .= " fk_user_author,"; @@ -444,6 +447,7 @@ class ExtraFields $sql .= " ".($perms ? "'".$this->db->escape($perms)."'" : "null").","; $sql .= " ".($langfile ? "'".$this->db->escape($langfile)."'" : "null").","; $sql .= " '".$this->db->escape($list)."',"; + $sql .= " '".$this->db->escape($documentpdf)."',"; $sql .= " ".($default ? "'".$this->db->escape($default)."'" : "null").","; $sql .= " ".($computed ? "'".$this->db->escape($computed)."'" : "null").","; $sql .= " ".(is_object($user) ? $user->id : 0).","; @@ -590,9 +594,11 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is extrafield totalizable on list + * @param int $documentpdf Is extrafield displayed on PDF * @return int >0 if OK, <=0 if KO + * @throws Exception */ - public function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0) + public function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $documentpdf = 0) { if ($elementtype == 'thirdparty') $elementtype = 'societe'; if ($elementtype == 'contact') $elementtype = 'socpeople'; @@ -642,7 +648,7 @@ class ExtraFields { if ($label) { - $result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable); + $result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable, $documentpdf); } if ($result > 0) { @@ -700,13 +706,15 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is extrafield totalizable on list + * @param int $documentpdf Is extrafield displayed on PDF * @return int <=0 if KO, >0 if OK + * @throws Exception */ - private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0) + private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $documentpdf = 0) { // phpcs:enable global $conf, $user; - dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable); + dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable.", ".$documentpdf); // Clean parameters if ($elementtype == 'thirdparty') $elementtype = 'societe'; @@ -771,6 +779,7 @@ class ExtraFields $sql .= " alwayseditable,"; $sql .= " param,"; $sql .= " list,"; + $sql .= " documentpdf,"; $sql .= " totalizable,"; $sql .= " fielddefault,"; $sql .= " fieldcomputed,"; @@ -794,6 +803,7 @@ class ExtraFields $sql .= " '".$this->db->escape($alwayseditable)."',"; $sql .= " '".$this->db->escape($params)."',"; $sql .= " '".$this->db->escape($list)."', "; + $sql .= " '".$this->db->escape($documentpdf)."', "; $sql .= " ".$totalizable.","; $sql .= " ".(($default != '') ? "'".$this->db->escape($default)."'" : "null").","; $sql .= " ".($computed ? "'".$this->db->escape($computed)."'" : "null").","; @@ -871,7 +881,7 @@ class ExtraFields }*/ // We should not have several time this request. If we have, there is some optimization to do by calling a simple $extrafields->fetch_optionals() in top of code and not into subcode - $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,totalizable,fielddefault,fieldcomputed,entity,enabled,help"; + $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,documentpdf,totalizable,fielddefault,fieldcomputed,entity,enabled,help"; $sql .= " FROM ".MAIN_DB_PREFIX."extrafields"; //$sql.= " WHERE entity IN (0,".$conf->entity.")"; // Filter is done later if ($elementtype) $sql .= " WHERE elementtype = '".$elementtype."'"; // Filed with object->table_element @@ -933,6 +943,7 @@ class ExtraFields $this->attributes[$tab->elementtype]['perms'][$tab->name] = (strlen($tab->perms) == 0 ? 1 : $tab->perms); $this->attributes[$tab->elementtype]['langfile'][$tab->name] = $tab->langs; $this->attributes[$tab->elementtype]['list'][$tab->name] = $tab->list; + $this->attributes[$tab->elementtype]['documentpdf'][$tab->name] = $tab->documentpdf; $this->attributes[$tab->elementtype]['totalizable'][$tab->name] = $tab->totalizable; $this->attributes[$tab->elementtype]['entityid'][$tab->name] = $tab->entity; $this->attributes[$tab->elementtype]['enabled'][$tab->name] = $tab->enabled; diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php index e695c7aa95f..37872f2a5c0 100644 --- a/htdocs/core/tpl/admin_extrafields_add.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php @@ -196,6 +196,9 @@ $langs->load("modulebuilder"); textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc")); ?> + +textwithpicto($langs->trans("DisplayOnPdf"), $langs->trans("DisplayOnPdfDesc")); ?> +> trans("Totalizable"); ?>> diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 4063111a6fb..8e14ad978ca 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -165,6 +165,7 @@ $list=$extrafields->attributes[$elementtype]['list'][$attrname]; $totalizable = $extrafields->attributes[$elementtype]['totalizable'][$attrname]; $help=$extrafields->attributes[$elementtype]['help'][$attrname]; $entitycurrentorall=$extrafields->attributes[$elementtype]['entityid'][$attrname]; +$documentpdf=$extrafields->attributes[$elementtype]['documentpdf'][$attrname]; if((($type == 'select') || ($type == 'checkbox') || ($type == 'radio')) && is_array($param)) { @@ -261,8 +262,12 @@ else trans("Required"); ?>> trans("AlwaysEditable"); ?>> + textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc")); ?> + +textwithpicto($langs->trans("DisplayOnPdf"), $langs->trans("DisplayOnPdfDesc")); ?> +> textwithpicto($langs->trans("Totalizable"), $langs->trans("TotalizableDesc")); ?>> textwithpicto($langs->trans("HelpOnTooltip"), $langs->trans("HelpOnTooltipDesc")); ?> @@ -270,7 +275,6 @@ else trans("AllEntities"); ?>> - diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php index 0ddd3f5a8fa..3bec8cb8d6f 100644 --- a/htdocs/core/tpl/admin_extrafields_view.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php @@ -64,8 +64,9 @@ print ''.$langs->trans("Unique").''; print ''.$langs->trans("Required").''; print ''.$langs->trans("AlwaysEditable").''; print ''.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).''; +print ''.$form->textwithpicto($langs->trans("DisplayOnPdf"), $langs->trans("DisplayOnPdfDesc")).''; print ''.$form->textwithpicto($langs->trans("Totalizable"), $langs->trans("TotalizableDesc")).''; -if ($conf->multicompany->enabled) { +if ($conf->multicompany->enabled){ print ''.$langs->trans("Entities").''; } print ' '; @@ -92,6 +93,7 @@ if (is_array($extrafields->attributes[$elementtype]['type']) && count($extrafiel print ''.yn($extrafields->attributes[$elementtype]['required'][$key])."\n"; print ''.yn($extrafields->attributes[$elementtype]['alwayseditable'][$key])."\n"; print ''.$extrafields->attributes[$elementtype]['list'][$key]."\n"; + print ''.yn($extrafields->attributes[$elementtype]['documentpdf'][$key])."\n"; print ''.yn($extrafields->attributes[$elementtype]['totalizable'][$key])."\n"; if (! empty($conf->multicompany->enabled)) { print ''; diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index 0b47a28e058..0a91f960807 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -179,4 +179,6 @@ INSERT INTO llx_c_ticket_resolution (code, pos, label, active, use_default, desc INSERT INTO llx_c_ticket_resolution (code, pos, label, active, use_default, description) VALUES('CANCELED', '50', 'Canceled', 1, 0, NULL); INSERT INTO llx_c_ticket_resolution (code, pos, label, active, use_default, description) VALUES('OTHER', '90', 'Other', 1, 0, NULL); -DELETE FROM llx_const WHERE name = __ENCRYPT('DONATION_ART885')__; \ No newline at end of file +DELETE FROM llx_const WHERE name = __ENCRYPT('DONATION_ART885')__; + +ALTER TABLE llx_extrafields ADD COLUMN documentpdf integer DEFAULT 0; \ No newline at end of file diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index ca3fd3e68b8..9f64e93f9d1 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -84,6 +84,8 @@ ListOfPermissionsDefined=List of defined permissions SeeExamples=See examples here EnabledDesc=Condition to have this field active (Examples: 1 or $conf->global->MYMODULE_MYOPTION) VisibleDesc=Is the field visible ? (Examples: 0=Never visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create), 5=Visible on list end view form only (not create, not update). Using a negative value means field is not shown by default on list but can be selected for viewing). It can be an expression, for example:
preg_match('/public/', $_SERVER['PHP_SELF'])?0:1
($user->rights->holiday->define_holiday ? 1 : 0) +DisplayOnPdfDesc=Display this field on compatible PDF documents, you can manage position with "Position" field.
Currently, known compatibles PDF models are : eratostene (order), espadon (ship), sponge (invoices), cyan (propal/quotation), cornas (supplier order) +DisplayOnPdf=Display on PDF IsAMeasureDesc=Can the value of field be cumulated to get a total into list? (Examples: 1 or 0) SearchAllDesc=Is the field used to make a search from the quick search tool? (Examples: 1 or 0) SpecDefDesc=Enter here all documentation you want to provide with your module that is not already defined by other tabs. You can use .md or better, the rich .asciidoc syntax. From 8a279ed1240500861c1e4e89fa63ab664be9e040 Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 23 Feb 2020 15:24:59 +0100 Subject: [PATCH 29/38] improve extrafields display in notes --- .../core/class/commondocgenerator.class.php | 107 +++++++++++++++++- 1 file changed, 103 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 29d4fab168b..9abb15494bf 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1160,9 +1160,10 @@ abstract class CommonDocGenerator * * @param object $object line of common object * @param Translate $outputlangs Output language + * @param array $params array of additionals parameters * @return double max y value */ - public function getExtrafieldsInHtml($object, $outputlangs) + public function getExtrafieldsInHtml($object, $outputlangs, $params = array()) { global $hookmanager; @@ -1175,6 +1176,31 @@ abstract class CommonDocGenerator if(empty($this->extrafieldsCache->attributes[$object->table_element])){ $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); } $extrafields = $this->extrafieldsCache; + $defaultParams = array( + 'style' => '', + 'display' => 'auto', // auto, table, list + + 'table' => array( + 'maxItemsInRow' => 2, + 'cellspacing' => 0, + 'cellpadding' => 0, + 'border' => 0, + 'labelcolwidth' => '25%', + 'arrayOfLineBreakType' => array('text', 'html') + ), + + 'list' => array( + 'separator' => '
' + ), + + 'auto' => array( + 'list' => 0, // 0 for default + 'table' => 4 // if there more than x extrafield to display + ), + ); + + $params = $params + $defaultParams; + /** * @var $extrafields ExtraFields @@ -1197,6 +1223,7 @@ abstract class CommonDocGenerator $field->rank = intval($extrafields->attributes[$object->table_element]['pos'][$key]); $field->content = $this->getExtrafieldContent($object, $key); $field->label = $outputlangs->transnoentities($label); + $field->type = $extrafields->attributes[$object->table_element]['type'][$key]; $fields[] = $field; } @@ -1204,14 +1231,86 @@ abstract class CommonDocGenerator if(!empty($fields)) { + // Sort extrafields by rank uasort($fields, function ($a, $b) { return ($a->rank > $b->rank) ? -1 : 1; } ); - foreach ($fields as $field){ - $html.= !empty($html)?'
':''; - $html.= $field->label.' : '.$field->content; + + + // define some HTML content with style + $html.= ''; + + // auto select display format + if($params['display'] == 'auto') { + $lastNnumbItems = 0; + foreach ($params['auto'] as $display => $numbItems){ + if($lastNnumbItems <= $numbItems && count($fields) > $numbItems){ + $lastNnumbItems = $numbItems; + $params['display'] = $display; + } + } + } + + if($params['display'] == 'list') { + // Display in list format + foreach ($fields as $field) { + $html .= !empty($html)?$params['list']['separator']:''; + $html .= '' . $field->label . ' : '; + $html .= $field->content; + } + } + elseif($params['display'] == 'table') { + // Display in table format + $html .= ''; + + $html .= ""; + $itemsInRow = 0; + $maxItemsInRow = $params['table']['maxItemsInRow']; + foreach ($fields as $field) { + //$html.= !empty($html)?'
':''; + if ($itemsInRow >= $maxItemsInRow) { + // start a new line + $html .= ""; + $itemsInRow = 0; + } + + // for some type we need line break + if (in_array($field->type, $params['table']['arrayOfLineBreakType'])) { + + if ($itemsInRow > 0) { + // close table row and empty cols + for ($i = $itemsInRow; $i <= $maxItemsInRow; $i++) { + $html .= ""; + } + $html .= ""; + + // start a new line + $html .= ""; + } + + $itemsInRow = $maxItemsInRow; + $html .= '"; + + } else { + $itemsInRow++; + $html .= '"; + + + $html .= '"; + } + } + $html .= ""; + + $html .= '
'; + $html .= '' . $field->label . ' : '; + $html .= $field->content; + $html .= "'; + $html .= '' . $field->label . ' :'; + $html .= "'; + $html .= $field->content; + $html .= "
'; } } From 222a000d310e6c68cd48722349e0eb6b3f22da9c Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sun, 23 Feb 2020 14:27:22 +0000 Subject: [PATCH 30/38] Fixing style errors. --- htdocs/core/class/commondocgenerator.class.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 9abb15494bf..eb214516a6f 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1278,7 +1278,6 @@ abstract class CommonDocGenerator // for some type we need line break if (in_array($field->type, $params['table']['arrayOfLineBreakType'])) { - if ($itemsInRow > 0) { // close table row and empty cols for ($i = $itemsInRow; $i <= $maxItemsInRow; $i++) { @@ -1295,7 +1294,6 @@ abstract class CommonDocGenerator $html .= '' . $field->label . ' : '; $html .= $field->content; $html .= ""; - } else { $itemsInRow++; $html .= ''; From 0ab16ed5ae22727622035eba824e11c38d76eb7c Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sun, 23 Feb 2020 16:50:24 +0100 Subject: [PATCH 31/38] Fix #10179 discount split --- htdocs/comm/remx.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index aa9307df8d2..4e8da77c5c0 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -121,7 +121,7 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes') $newdiscount2->datec=$discount->datec; $newdiscount1->tva_tx=$discount->tva_tx; $newdiscount2->tva_tx=$discount->tva_tx; - $newdiscount1->amount_ttc=$_POST["amount_ttc_1"]; + $newdiscount1->amount_ttc=$amount_ttc_1; $newdiscount2->amount_ttc=price2num($discount->amount_ttc-$newdiscount1->amount_ttc); $newdiscount1->amount_ht=price2num($newdiscount1->amount_ttc/(1+$newdiscount1->tva_tx/100),'MT'); $newdiscount2->amount_ht=price2num($newdiscount2->amount_ttc/(1+$newdiscount2->tva_tx/100),'MT'); From 07bd6e1fc030ad6de3276031af22956734e59692 Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 23 Feb 2020 20:52:44 +0100 Subject: [PATCH 32/38] Fix On admin page add extrafields form, display on pdf option doesn't saved --- htdocs/core/class/extrafields.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 7765999339d..ff1e6267252 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -225,9 +225,10 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is a measure. Must show a total on lists + * @param int $documentpdf Is extrafield displayed on PDF * @return int <=0 if KO, >0 if OK */ - public function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0) + public function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $documentpdf = 0) { if (empty($attrname)) return -1; if (empty($label)) return -1; @@ -245,7 +246,7 @@ class ExtraFields if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') { // Add declaration of field into table - $result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable); + $result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $documentpdf); $err2 = $this->errno; if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) { From 93c9f07cb935c20f6b102527da57b0d484b82f1d Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 23 Feb 2020 20:59:04 +0100 Subject: [PATCH 33/38] Fix note x position --- htdocs/core/modules/expedition/doc/pdf_espadon.modules.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php index 5d211c2cbae..0ef7acc7bef 100644 --- a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php @@ -313,6 +313,8 @@ class pdf_espadon extends ModelePdfExpedition $tab_height = 130; $tab_height_newpage = 150; + $this->posxdesc = $this->marge_gauche + 1; + // Incoterm $height_incoterms = 0; if ($conf->incoterm->enabled) From 76e33058a851a53d67bb03daa092b7e2cc12e223 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Feb 2020 21:38:24 +0100 Subject: [PATCH 34/38] NEW Can select several fields to personalize list before submit. --- htdocs/core/class/html.form.class.php | 11 +++-- htdocs/core/js/lib_foot.js.php | 63 ++++++++++++++++++++------- htdocs/main.inc.php | 14 +++--- htdocs/theme/eldy/dropdown.inc.php | 2 +- htdocs/theme/eldy/global.inc.php | 10 ++--- 5 files changed, 68 insertions(+), 32 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index e1e7d97f821..4ab0bc44d9d 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6693,8 +6693,10 @@ class Form @@ -7070,7 +7074,6 @@ class Form jQuery(".linkto").click(function() { console.log("We choose to show/hide link for rel="+jQuery(this).attr(\'rel\')); jQuery("#"+jQuery(this).attr(\'rel\')+"list").toggle(); - jQuery(this).toggle(); }); }); diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php index 3d708101d13..0d9b0b59ff4 100644 --- a/htdocs/core/js/lib_foot.js.php +++ b/htdocs/core/js/lib_foot.js.php @@ -81,13 +81,31 @@ print "});\n"; // Wrapper to manage dropdown if (! defined('JS_JQUERY_DISABLE_DROPDOWN')) { - print "\n/* JS CODE TO ENABLE dropdown */\n"; + print "\n/* JS CODE TO ENABLE dropdown (hamburger, linkto, ...) */\n"; print ' - jQuery(document).ready(function () { - $(".dropdown dt a").on(\'click\', function () { - console.log("We click on dropdown"); - //console.log($(this).parent().parent().find(\'dd ul\')); - $(this).parent().parent().find(\'dd ul\').slideToggle(\'fast\'); + jQuery(document).ready(function () { + var lastopendropdown = null; + + // Click onto the link "link to" or "hamburger", toggle dropdown + $(".dropdown dt a").on(\'click\', function () { + console.log("toggle dropdown dt a"); + + //$(this).parent().parent().find(\'dd ul\').slideToggle(\'fast\'); + $(this).parent().parent().find(\'dd ul\').toggleClass("open"); + + if ($(this).parent().parent().find(\'dd ul\').hasClass("open")) { + lastopendropdown = $(this).parent().parent().find(\'dd ul\'); + //console.log(lastopendropdown); + } else { + // We closed the dropdown for hamburger selectfields + if ($("input:hidden[name=formfilteraction]").val() == "listafterchangingselectedfields") { + console.log("resubmit the form saved into lastopendropdown after clicking on hamburger"); + //$(".dropdown dt a").parents(\'form:first\').submit(); + //$(".dropdown dt a").closest("form").submit(); + lastopendropdown.closest("form").submit(); + } + } + // Note: Did not find a way to get exact height (value is update at exit) so i calculate a generic from nb of lines heigthofcontent = 21 * $(this).parent().parent().find(\'dd div ul li\').length; if (heigthofcontent > 300) heigthofcontent = 300; // limited by max-height on css .dropdown dd ul @@ -101,19 +119,32 @@ if (! defined('JS_JQUERY_DISABLE_DROPDOWN')) console.log("We reposition top by "+pix); $(this).parent().parent().find(\'dd\').css("top", pix); } - // $(".dropdown dd ul").slideToggle(\'fast\'); - }); - $(".dropdowncloseonclick").on(\'click\', function () { - console.log("Link has class dropdowncloseonclick, so we close/hide the popup ul"); - $(this).parent().parent().hide(); }); - $(document).bind(\'click\', function (e) { - //console.log("We click outside of dropdown, so we close it."); - var $clicked = $(e.target); - if (!$clicked.parents().hasClass("dropdown")) $(".dropdown dd ul").hide(); + // Click on a link into the popup "link to" or other dropdown that ask to close drop down on element click, so close dropdown + $(".dropdowncloseonclick").on(\'click\', function () { + console.log("Link has class dropdowncloseonclick, so we close/hide the popup ul"); + //$(this).parent().parent().hide(); // $(this).parent().parent() is ul + $(this).parent().parent().removeClass("open"); // $(this).parent().parent() is ul }); - }); + + // Click outside of any dropdown + $(document).bind(\'click\', function (e) { + var $clicked = $(e.target); // This is element we click on + if (!$clicked.parents().hasClass("dropdown")) { + console.log("close dropdown dd ul - we click outside"); + //$(".dropdown dd ul").hide(); + $(".dropdown dd ul").removeClass("open"); + + if ($("input:hidden[name=formfilteraction]").val() == "listafterchangingselectedfields") { + console.log("resubmit form saved into lastopendropdown after clicking outside of dropdown and having change selectlist from selectlist field of hamburger dropdown"); + //$(".dropdown dt a").parents(\'form:first\').submit(); + //$(".dropdown dt a").closest("form").submit(); + lastopendropdown.closest("form").submit(); + } + } + }); + }); '; } diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 0f1f0e01a87..8c1cdd829de 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1898,13 +1898,15 @@ function top_menu_user() $( document ).ready(function() { $(document).on("click", function(event) { if (!$(event.target).closest("#topmenu-login-dropdown").length) { - // Hide the menus. + //console.log("close login dropdown"); + // Hide the menus. $("#topmenu-login-dropdown").removeClass("open"); } }); $("#topmenu-login-dropdown .dropdown-toggle").on("click", function(event) { - event.preventDefault(); + console.log("toggle login dropdown"); + event.preventDefault(); $("#topmenu-login-dropdown").toggleClass("open"); }); @@ -1954,14 +1956,14 @@ function top_menu_bookmark() $( document ).ready(function() { $(document).on("click", function(event) { if (!$(event.target).closest("#topmenu-bookmark-dropdown").length) { - console.log("close"); + //console.log("close bookmark dropdown - we click outside"); // Hide the menus. $("#topmenu-bookmark-dropdown").removeClass("open"); } }); $("#topmenu-bookmark-dropdown .dropdown-toggle").on("click", function(event) { - console.log("toggle"); + console.log("toggle bookmark dropdown"); openBookMarkDropDown(); }); @@ -2077,7 +2079,7 @@ function top_menu_search() // close drop down $(document).on("click", function(event) { if (!$(event.target).closest("#topmenu-global-search-dropdown").length) { - console.log("click close"); + console.log("click close search - we click outside"); // Hide the menus. $("#topmenu-global-search-dropdown").removeClass("open"); } @@ -2085,7 +2087,7 @@ function top_menu_search() // Open drop down $("#topmenu-global-search-dropdown .dropdown-toggle").on("click", function(event) { - console.log("click open"); + console.log("toggle search dropdown"); openGlobalSearchDropDown(); }); diff --git a/htdocs/theme/eldy/dropdown.inc.php b/htdocs/theme/eldy/dropdown.inc.php index 580e9366bc1..69716ce5be3 100644 --- a/htdocs/theme/eldy/dropdown.inc.php +++ b/htdocs/theme/eldy/dropdown.inc.php @@ -9,7 +9,7 @@ button.dropdown-item.global-search-item { outline: none; } -.open>.dropdown-search, .open>.dropdown-bookmark, .open>.dropdown-menu{ +.open>.dropdown-search, .open>.dropdown-bookmark, .open>.dropdown-menu, .dropdown dd ul.open { display: block; } diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index f5c1e328a23..f280cb13d57 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -4983,7 +4983,7 @@ input.select2-input { } .select2-container--default .select2-selection--single .select2-selection__rendered { color: var(--colortext); - background-color: var(--colorbackvmenu1); + /* background-color: var(--colorbackvmenu1); */ } .select2-default { color: #999 !important; @@ -5079,8 +5079,8 @@ input.select2-input { box-shadow: none !important; } .select2-dropdown { - background-color: var(--colorbackvmenu1); - border: 1px solid var(--colorbackvmenu1);; + /*background-color: var(--colorbackvmenu1); + border: 1px solid var(--colorbackvmenu1); */ box-shadow: 1px 2px 10px var(--colorbackvmenu1); } .select2-dropdown-open { @@ -5405,9 +5405,9 @@ dl.dropdown { .dropdown dd ul li span { color: #888; } -.dropdown dd ul li a:hover { +/*.dropdown dd ul li a:hover { background-color: var(--inputbackgroundcolor); -} +}*/ dd.dropdowndd ul li { text-overflow: ellipsis; overflow: hidden; From 189c0d675ba4b73700093d98c272d028ed332297 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Feb 2020 22:05:59 +0100 Subject: [PATCH 35/38] Fix memory report. Xdebug no more required. Try = null instead of unset. --- htdocs/compta/bank/graph.php | 61 ++++++++++++++++--------------- htdocs/core/lib/functions.lib.php | 13 +++---- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/htdocs/compta/bank/graph.php b/htdocs/compta/bank/graph.php index fbcd06a51bc..2e1f36cbeea 100644 --- a/htdocs/compta/bank/graph.php +++ b/htdocs/compta/bank/graph.php @@ -255,13 +255,14 @@ else $px1->draw($file, $fileurl); $show1 = $px1->show(); - unset($graph_datas); - unset($px1); - unset($datas); - unset($datamin); - unset($dataall); - unset($labels); - unset($amounts); + + $px1 = null; + $graph_datas =null; + $datas = null; + $datamin = null; + $dataall = null; + $labels = null; + $amounts = null; } // Graph Balance for the year @@ -392,13 +393,13 @@ else $show2 = $px2->show(); - unset($px2); - unset($graph_datas); - unset($datas); - unset($datamin); - unset($dataall); - unset($labels); - unset($amounts); + $px2 = null; + $graph_datas =null; + $datas = null; + $datamin = null; + $dataall = null; + $labels = null; + $amounts = null; } // Graph 3 - Balance for all time line @@ -460,7 +461,7 @@ else } else { - $datas[$i] = '' +$solde + $subtotal; + $datas[$i] = 0 + $solde + $subtotal; } $datamin[$i] = $object->min_desired; $dataall[$i] = $object->min_allowed; @@ -505,13 +506,13 @@ else $show3 = $px3->show(); - unset($px3); - unset($graph_datas); - unset($datas); - unset($datamin); - unset($dataall); - unset($labels); - unset($amounts); + $px3 = null; + $graph_datas =null; + $datas = null; + $datamin = null; + $dataall = null; + $labels = null; + $amounts = null; } // Tableau 4a - Credit/Debit @@ -634,10 +635,10 @@ else $show4 = $px4->show(); - unset($graph_datas); - unset($px4); - unset($debits); - unset($credits); + $px4 = null; + $graph_datas = null; + $debits = null; + $credits = null; } // Tableau 4b - Credit/Debit @@ -742,10 +743,10 @@ else $show5 = $px5->show(); - unset($graph_datas); - unset($px5); - unset($debits); - unset($credits); + $px5 = null; + $graph_datas = null; + $debits = null; + $credits = null; } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index f5c05fdf969..5f06d72139e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -7618,15 +7618,12 @@ function printCommonFooter($zone = 'private') $micro_end_time = microtime(true); print ' - Build time: '.ceil(1000 * ($micro_end_time - $micro_start_time)).' ms'; } - if (function_exists("memory_get_usage")) - { - print ' - Mem: '.memory_get_usage(); + + if (function_exists("memory_get_usage")) { + print ' - Mem: '.memory_get_usage(); // Do not use true here, it seems it takes the peak amount } - if (function_exists("xdebug_memory_usage")) - { - print ' - XDebug time: '.ceil(1000 * xdebug_time_index()).' ms'; - print ' - XDebug mem: '.xdebug_memory_usage(); - print ' - XDebug mem peak: '.xdebug_peak_memory_usage(); + if (function_exists("memory_get_peak_usage")) { + print ' - Real mem peak: '.memory_get_peak_usage(true); } if (function_exists("zend_loader_file_encoded")) { From 686a93769c3baf61179885832aca085e8db9d4ff Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Feb 2020 22:30:15 +0100 Subject: [PATCH 36/38] Fix delay before closing stale issues --- .github/workflows/stale-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml index 66eb3f0cd40..b50af3ec717 100644 --- a/.github/workflows/stale-issues.yml +++ b/.github/workflows/stale-issues.yml @@ -16,7 +16,7 @@ jobs: stale-issue-label: 'Issue Stale (automatic label)' exempt-issue-label: 'Priority High / Blocking' days-before-stale: 365 - days-before-close: 10 + days-before-close: 15 #stale-pr-message: 'This PR is stale because it has been open 1 year with no activity. If this PR is still mergeable (no conflict, nor Continuous Integration errors), please comment to confirm this merge is still expected. Without comment, this issue will be closed automatically by stale bot in 15 days.' #stale-pr-label: 'PR Stale (automatic label)' #exempt-pr-label: 'Priority Top Strategic' From ca39c680c7853565d1973630d38ddf6e16df9cba Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Feb 2020 23:03:17 +0100 Subject: [PATCH 37/38] Rename field documentpdf into printable (this field already exists due to a very old PR nofinished for same goal). --- htdocs/core/actions_extrafields.inc.php | 4 +-- .../core/class/commondocgenerator.class.php | 4 +-- htdocs/core/class/extrafields.class.php | 34 +++++++++---------- htdocs/core/tpl/admin_extrafields_add.tpl.php | 2 +- .../core/tpl/admin_extrafields_edit.tpl.php | 4 +-- .../core/tpl/admin_extrafields_view.tpl.php | 2 +- .../install/mysql/migration/11.0.0-12.0.0.sql | 5 ++- .../install/mysql/tables/llx_extrafields.sql | 2 +- 8 files changed, 30 insertions(+), 27 deletions(-) diff --git a/htdocs/core/actions_extrafields.inc.php b/htdocs/core/actions_extrafields.inc.php index 486764b167e..abd82a18351 100644 --- a/htdocs/core/actions_extrafields.inc.php +++ b/htdocs/core/actions_extrafields.inc.php @@ -184,7 +184,7 @@ if ($action == 'add') GETPOST('langfile', 'alpha'), 1, (GETPOST('totalizable', 'alpha')?1:0), - (GETPOST('documentpdf', 'alpha')?1:0) + (GETPOST('printable', 'alpha')?1:0) ); if ($result > 0) { @@ -354,7 +354,7 @@ if ($action == 'update') GETPOST('langfile'), 1, (GETPOST('totalizable', 'alpha')?1:0), - (GETPOST('documentpdf', 'alpha')?1:0) + (GETPOST('printable', 'alpha')?1:0) ); if ($result > 0) { diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index eb214516a6f..1bd051d4b55 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1213,7 +1213,7 @@ abstract class CommonDocGenerator foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { // Enable extrafield ? - $enabled = !empty($extrafields->attributes[$object->table_element]['documentpdf'][$key]); + $enabled = !empty($extrafields->attributes[$object->table_element]['printable'][$key]); if(empty($enabled)){ continue; @@ -1425,7 +1425,7 @@ abstract class CommonDocGenerator } // Enable extrafield ? - $enabled = !empty($extrafields->attributes[$object->table_element]['documentpdf'][$key]); + $enabled = !empty($extrafields->attributes[$object->table_element]['printable'][$key]); // Load language if required diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index ff1e6267252..91803dc32db 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -225,10 +225,10 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is a measure. Must show a total on lists - * @param int $documentpdf Is extrafield displayed on PDF + * @param int $printable Is extrafield displayed on PDF * @return int <=0 if KO, >0 if OK */ - public function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $documentpdf = 0) + public function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0) { if (empty($attrname)) return -1; if (empty($label)) return -1; @@ -246,7 +246,7 @@ class ExtraFields if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') { // Add declaration of field into table - $result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $documentpdf); + $result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $printable); $err2 = $this->errno; if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) { @@ -375,11 +375,11 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is a measure. Must show a total on lists - * @param int $documentpdf Is extrafield displayed on PDF + * @param int $printable Is extrafield displayed on PDF * @return int <=0 if KO, >0 if OK * @throws Exception */ - private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = 0, $elementtype = 'member', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $documentpdf = 0) + private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = 0, $elementtype = 'member', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0) { // phpcs:enable global $conf, $user; @@ -424,7 +424,7 @@ class ExtraFields $sql .= " perms,"; $sql .= " langs,"; $sql .= " list,"; - $sql .= " documentpdf,"; + $sql .= " printable,"; $sql .= " fielddefault,"; $sql .= " fieldcomputed,"; $sql .= " fk_user_author,"; @@ -448,7 +448,7 @@ class ExtraFields $sql .= " ".($perms ? "'".$this->db->escape($perms)."'" : "null").","; $sql .= " ".($langfile ? "'".$this->db->escape($langfile)."'" : "null").","; $sql .= " '".$this->db->escape($list)."',"; - $sql .= " '".$this->db->escape($documentpdf)."',"; + $sql .= " '".$this->db->escape($printable)."',"; $sql .= " ".($default ? "'".$this->db->escape($default)."'" : "null").","; $sql .= " ".($computed ? "'".$this->db->escape($computed)."'" : "null").","; $sql .= " ".(is_object($user) ? $user->id : 0).","; @@ -595,11 +595,11 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is extrafield totalizable on list - * @param int $documentpdf Is extrafield displayed on PDF + * @param int $printable Is extrafield displayed on PDF * @return int >0 if OK, <=0 if KO * @throws Exception */ - public function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $documentpdf = 0) + public function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0) { if ($elementtype == 'thirdparty') $elementtype = 'societe'; if ($elementtype == 'contact') $elementtype = 'socpeople'; @@ -649,7 +649,7 @@ class ExtraFields { if ($label) { - $result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable, $documentpdf); + $result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable, $printable); } if ($result > 0) { @@ -707,15 +707,15 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is extrafield totalizable on list - * @param int $documentpdf Is extrafield displayed on PDF + * @param int $printable Is extrafield displayed on PDF * @return int <=0 if KO, >0 if OK * @throws Exception */ - private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $documentpdf = 0) + private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0) { // phpcs:enable global $conf, $user; - dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable.", ".$documentpdf); + dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable.", ".$printable); // Clean parameters if ($elementtype == 'thirdparty') $elementtype = 'societe'; @@ -780,7 +780,7 @@ class ExtraFields $sql .= " alwayseditable,"; $sql .= " param,"; $sql .= " list,"; - $sql .= " documentpdf,"; + $sql .= " printable,"; $sql .= " totalizable,"; $sql .= " fielddefault,"; $sql .= " fieldcomputed,"; @@ -804,7 +804,7 @@ class ExtraFields $sql .= " '".$this->db->escape($alwayseditable)."',"; $sql .= " '".$this->db->escape($params)."',"; $sql .= " '".$this->db->escape($list)."', "; - $sql .= " '".$this->db->escape($documentpdf)."', "; + $sql .= " '".$this->db->escape($printable)."', "; $sql .= " ".$totalizable.","; $sql .= " ".(($default != '') ? "'".$this->db->escape($default)."'" : "null").","; $sql .= " ".($computed ? "'".$this->db->escape($computed)."'" : "null").","; @@ -882,7 +882,7 @@ class ExtraFields }*/ // We should not have several time this request. If we have, there is some optimization to do by calling a simple $extrafields->fetch_optionals() in top of code and not into subcode - $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,documentpdf,totalizable,fielddefault,fieldcomputed,entity,enabled,help"; + $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,printable,totalizable,fielddefault,fieldcomputed,entity,enabled,help"; $sql .= " FROM ".MAIN_DB_PREFIX."extrafields"; //$sql.= " WHERE entity IN (0,".$conf->entity.")"; // Filter is done later if ($elementtype) $sql .= " WHERE elementtype = '".$elementtype."'"; // Filed with object->table_element @@ -944,7 +944,7 @@ class ExtraFields $this->attributes[$tab->elementtype]['perms'][$tab->name] = (strlen($tab->perms) == 0 ? 1 : $tab->perms); $this->attributes[$tab->elementtype]['langfile'][$tab->name] = $tab->langs; $this->attributes[$tab->elementtype]['list'][$tab->name] = $tab->list; - $this->attributes[$tab->elementtype]['documentpdf'][$tab->name] = $tab->documentpdf; + $this->attributes[$tab->elementtype]['printable'][$tab->name] = $tab->printable; $this->attributes[$tab->elementtype]['totalizable'][$tab->name] = $tab->totalizable; $this->attributes[$tab->elementtype]['entityid'][$tab->name] = $tab->entity; $this->attributes[$tab->elementtype]['enabled'][$tab->name] = $tab->enabled; diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php index 37872f2a5c0..5f9a70d272b 100644 --- a/htdocs/core/tpl/admin_extrafields_add.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php @@ -198,7 +198,7 @@ $langs->load("modulebuilder"); textwithpicto($langs->trans("DisplayOnPdf"), $langs->trans("DisplayOnPdfDesc")); ?> -> +> trans("Totalizable"); ?>> diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 8e14ad978ca..f2d3e4e7bb5 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -165,7 +165,7 @@ $list=$extrafields->attributes[$elementtype]['list'][$attrname]; $totalizable = $extrafields->attributes[$elementtype]['totalizable'][$attrname]; $help=$extrafields->attributes[$elementtype]['help'][$attrname]; $entitycurrentorall=$extrafields->attributes[$elementtype]['entityid'][$attrname]; -$documentpdf=$extrafields->attributes[$elementtype]['documentpdf'][$attrname]; +$printable=$extrafields->attributes[$elementtype]['printable'][$attrname]; if((($type == 'select') || ($type == 'checkbox') || ($type == 'radio')) && is_array($param)) { @@ -267,7 +267,7 @@ else textwithpicto($langs->trans("DisplayOnPdf"), $langs->trans("DisplayOnPdfDesc")); ?> -> +> textwithpicto($langs->trans("Totalizable"), $langs->trans("TotalizableDesc")); ?>> textwithpicto($langs->trans("HelpOnTooltip"), $langs->trans("HelpOnTooltipDesc")); ?> diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php index 3bec8cb8d6f..769c12ceaa5 100644 --- a/htdocs/core/tpl/admin_extrafields_view.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php @@ -93,7 +93,7 @@ if (is_array($extrafields->attributes[$elementtype]['type']) && count($extrafiel print ''.yn($extrafields->attributes[$elementtype]['required'][$key])."\n"; print ''.yn($extrafields->attributes[$elementtype]['alwayseditable'][$key])."\n"; print ''.$extrafields->attributes[$elementtype]['list'][$key]."\n"; - print ''.yn($extrafields->attributes[$elementtype]['documentpdf'][$key])."\n"; + print ''.yn($extrafields->attributes[$elementtype]['printable'][$key])."\n"; print ''.yn($extrafields->attributes[$elementtype]['totalizable'][$key])."\n"; if (! empty($conf->multicompany->enabled)) { print ''; diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index 0a91f960807..e4d1dd51135 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -181,4 +181,7 @@ INSERT INTO llx_c_ticket_resolution (code, pos, label, active, use_default, desc DELETE FROM llx_const WHERE name = __ENCRYPT('DONATION_ART885')__; -ALTER TABLE llx_extrafields ADD COLUMN documentpdf integer DEFAULT 0; \ No newline at end of file +ALTER TABLE llx_extrafields MODIFY COLUMN printable integer DEFAULT 0; +ALTER TABLE llx_extrafields ADD COLUMN printable integer DEFAULT 0; + + diff --git a/htdocs/install/mysql/tables/llx_extrafields.sql b/htdocs/install/mysql/tables/llx_extrafields.sql index 4fd80c0d9c2..3578414d98b 100644 --- a/htdocs/install/mysql/tables/llx_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_extrafields.sql @@ -36,7 +36,7 @@ create table llx_extrafields alwayseditable integer DEFAULT 0, -- 1 if field can be edited whatever is element status param text, -- extra parameters to define possible values of field list varchar(255) DEFAULT '1', -- visibility of field. 0=Never visible, 1=Visible on list and forms, 2=Visible on list only. Using a negative value means field is not shown by default on list but can be selected for viewing - printable boolean DEFAULT FALSE, -- is the extrafield output on documents + printable integer DEFAULT 0, -- is the extrafield output on documents totalizable boolean DEFAULT FALSE, -- is extrafield totalizable on list langs varchar(64), -- example: fileofmymodule@mymodule help text, -- to store help tooltip From ee45c3efb6f7d2a63fc43f7cea357a9d2fec1819 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Feb 2020 23:29:13 +0100 Subject: [PATCH 38/38] FIX #13184 --- htdocs/core/class/extrafields.class.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 36b83bb32b7..57debc1311b 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -389,6 +389,7 @@ class ExtraFields if (empty($required)) $required = 0; if (empty($unique)) $unique = 0; if (empty($alwayseditable)) $alwayseditable = 0; + if (empty($totalizable)) $totalizable = 0; if (!empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname) && !is_numeric($attrname)) { @@ -450,7 +451,7 @@ class ExtraFields $sql .= "'" . $this->db->idate(dol_now()) . "',"; $sql.= " ".($enabled?"'".$this->db->escape($enabled)."'":"1").","; $sql.= " ".($help?"'".$this->db->escape($help)."'":"null").","; - $sql.= " ".($totalizable?'1':'0'); + $sql.= " ".($totalizable?'TRUE':'FALSE'); $sql.=')'; dol_syslog(get_class($this)."::create_label", LOG_DEBUG); @@ -793,7 +794,7 @@ class ExtraFields $sql .= " '".$this->db->escape($alwayseditable)."',"; $sql .= " '".$this->db->escape($params)."',"; $sql .= " '".$this->db->escape($list)."', "; - $sql .= " ".$totalizable.","; + $sql .= " ".($totalizable?'TRUE':'FALSE').","; $sql .= " ".(($default != '') ? "'".$this->db->escape($default)."'" : "null").","; $sql .= " ".($computed ? "'".$this->db->escape($computed)."'" : "null").","; $sql .= " ".$user->id.","; @@ -932,7 +933,7 @@ class ExtraFields $this->attributes[$tab->elementtype]['perms'][$tab->name]=(strlen($tab->perms) == 0 ? 1 : $tab->perms); $this->attributes[$tab->elementtype]['langfile'][$tab->name]=$tab->langs; $this->attributes[$tab->elementtype]['list'][$tab->name]=$tab->list; - $this->attributes[$tab->elementtype]['totalizable'][$tab->name]=$tab->totalizable; + $this->attributes[$tab->elementtype]['totalizable'][$tab->name]=($tab->totalizable ? 1 : 0); $this->attributes[$tab->elementtype]['entityid'][$tab->name]=$tab->entity; $this->attributes[$tab->elementtype]['enabled'][$tab->name]=$tab->enabled; $this->attributes[$tab->elementtype]['help'][$tab->name]=$tab->help;