From 637e1a8d211a65c0c0cee59868df80e40d44ddb0 Mon Sep 17 00:00:00 2001 From: mikee2 Date: Sat, 6 May 2017 10:49:37 +0200 Subject: [PATCH 001/177] Update Segment.php Add additional needed fields so that you can invoice yearly items. Have number and text descriptions to avoid future changes that may break existing invoices. --- htdocs/includes/odtphp/Segment.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/htdocs/includes/odtphp/Segment.php b/htdocs/includes/odtphp/Segment.php index 81e9dad9f97..4310c716ee7 100644 --- a/htdocs/includes/odtphp/Segment.php +++ b/htdocs/includes/odtphp/Segment.php @@ -170,8 +170,16 @@ class Segment implements IteratorAggregate, Countable { global $langs; - $patterns=array( '__CURRENTDAY__','__CURRENTDAYTEXT__','__CURRENTMONTHSHORT__','__CURRENTMONTH__','__CURRENTYEAR__' ); - $values=array( date('j'), $langs->trans(date('l')), $langs->trans(date('M')), $langs->trans(date('F')), date('Y') ); + $nextMonth = strtotime('+1 month'); + + $patterns=array( '/__CURRENTDAY__/u','/__CURRENTDAYTEXT__/u', + '/__CURRENTMONTH__/u','/__CURRENTMONTHSHORT__/u','/__CURRENTMONTHLONG__/u', + '/__NEXTMONTH__/u','/__NEXTMONTHSHORT__/u','/__NEXTMONTHLONG__/u', + '/__CURRENTYEAR__/u','/__NEXTYEAR__/u' ); + $values=array( date('j'), $langs->trans(date('l')), + $langs->trans(date('n')), $langs->trans(date('M')), $langs->trans(date('F')), + $langs->trans(date('n', $nextMonth)), $langs->trans(date('M', $nextMonth)), $langs->trans(date('F', $nextMonth)), + date('Y'), date('Y', strtotime('+1 year')) ); $text=preg_replace($patterns, $values, $text); From 6a350470200b224261d20817d3a5159095e2f104 Mon Sep 17 00:00:00 2001 From: mikee2 Date: Wed, 14 Jun 2017 12:53:29 +0200 Subject: [PATCH 002/177] Updated to use dolibarr timme functions Redefined macro strings to adapt to dolibarr date functions return values. Keep same macro names when possible to avoid breaking existing code. Some macro holders (not commonly used) have been dropped because non existing values in dolibarr date functions. Per eldy request changed php date functions with dolibarr's internal date functions to match users time zone. Now dates are those of the user's timezone so check that is is correctly defined in user's profile. --- htdocs/includes/odtphp/Segment.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/htdocs/includes/odtphp/Segment.php b/htdocs/includes/odtphp/Segment.php index 4310c716ee7..d015d6ad263 100644 --- a/htdocs/includes/odtphp/Segment.php +++ b/htdocs/includes/odtphp/Segment.php @@ -170,16 +170,17 @@ class Segment implements IteratorAggregate, Countable { global $langs; - $nextMonth = strtotime('+1 month'); - - $patterns=array( '/__CURRENTDAY__/u','/__CURRENTDAYTEXT__/u', - '/__CURRENTMONTH__/u','/__CURRENTMONTHSHORT__/u','/__CURRENTMONTHLONG__/u', - '/__NEXTMONTH__/u','/__NEXTMONTHSHORT__/u','/__NEXTMONTHLONG__/u', + $hoy = dol_getdate(dol_now('tzuser')); + $nextMonth = dol_get_next_month($hoy['mon'], $hoy['year'])['month']; + + $patterns=array( '/__CURRENTDAY__/u','/__CURENTWEEKDAY__/u', + '/__CURRENTMONTH__/u','/__CURRENTMONTHLONG__/u', + '/__NEXTMONTH__/u','/__NEXTMONTHLONG__/u', '/__CURRENTYEAR__/u','/__NEXTYEAR__/u' ); - $values=array( date('j'), $langs->trans(date('l')), - $langs->trans(date('n')), $langs->trans(date('M')), $langs->trans(date('F')), - $langs->trans(date('n', $nextMonth)), $langs->trans(date('M', $nextMonth)), $langs->trans(date('F', $nextMonth)), - date('Y'), date('Y', strtotime('+1 year')) ); + $values=array( $hoy['mday'], $langs->trans($hoy['weekday']), + $hoy['mon'], $langs->trans($hoy['month']), + $nextMonth, monthArray($langs)[$nextMonth], + $hoy['year'], $hoy['year']+1 ); $text=preg_replace($patterns, $values, $text); From ffb8c684d0353e911029918cd56c762c8c2f4931 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Thu, 6 Jul 2017 13:40:26 +0200 Subject: [PATCH 003/177] NEW : Can transmer from bank account to bank account with different currency --- htdocs/compta/bank/class/account.class.php | 53 +++++++-------- htdocs/compta/bank/transfer.php | 76 +++++++++++++++++++++- htdocs/core/ajax/getaccountcurrency.php | 60 +++++++++++++++++ 3 files changed, 161 insertions(+), 28 deletions(-) create mode 100644 htdocs/core/ajax/getaccountcurrency.php diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 43b6dace19c..b0cf86403be 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -39,7 +39,7 @@ class Account extends CommonObject public $element = 'bank_account'; public $table_element = 'bank_account'; public $picto = 'account'; - + /** * @var int Use id instead of rowid * @deprecated @@ -538,7 +538,7 @@ class Account extends CommonObject $now=dol_now(); $this->db->begin(); - + $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account ("; $sql.= "datec"; $sql.= ", ref"; @@ -619,14 +619,14 @@ class Account extends CommonObject $result=$this->insertExtraFields(); if ($result < 0) $error++; } - + if (! $error && ! $notrigger) { // Call trigger $result=$this->call_trigger('BANKACCOUNT_CREATE',$user); if ($result < 0) $error++; // End call triggers - } + } } else { @@ -670,9 +670,9 @@ class Account extends CommonObject global $langs,$conf, $hookmanager; $error=0; - + $this->db->begin(); - + // Clean parameters $this->state_id = ($this->state_id?$this->state_id:$this->state_id); $this->country_id = ($this->country_id?$this->country_id:$this->country_id); @@ -739,7 +739,7 @@ class Account extends CommonObject if ($result < 0) $error++; } } - + if (! $error && ! $notrigger) { // Call trigger @@ -754,7 +754,7 @@ class Account extends CommonObject $this->error=$this->db->lasterror(); dol_print_error($this->db); } - + if (! $error) { $this->db->commit(); @@ -906,7 +906,7 @@ class Account extends CommonObject $this->date_creation = $this->db->jdate($obj->date_creation); $this->date_update = $this->db->jdate($obj->date_update); - + // Retreive all extrafield for thirdparty // fetch optionals attributes and labels require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); @@ -923,7 +923,8 @@ class Account extends CommonObject } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; + $this->errors[]=$this->error; return -1; } } @@ -983,15 +984,15 @@ class Account extends CommonObject global $conf; $error=0; - + $this->db->begin(); - + // Delete link between tag and bank account if (! $error) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account"; $sql.= " WHERE fk_account = ".$this->id; - + $resql = $this->db->query($sql); if (!$resql) { @@ -999,15 +1000,15 @@ class Account extends CommonObject $this->error = "Error ".$this->db->lasterror(); } } - + if (! $error) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_account"; $sql.= " WHERE rowid = ".$this->rowid; - + dol_syslog(get_class($this)."::delete", LOG_DEBUG); $result = $this->db->query($sql); - if ($result) + if ($result) { // Remove extrafields if ((empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used @@ -1020,13 +1021,13 @@ class Account extends CommonObject } } } - else + else { $error++; $this->error = "Error ".$this->db->lasterror(); - } + } } - + if (! $error) { $this->db->commit(); @@ -1433,7 +1434,7 @@ class Account extends CommonObject * - DeskCode * * Some countries show less or more bank account properties to the user - * + * * @param int $includeibanbic 1=Return also key for IBAN and BIC * @return array * @see useDetailedBBAN @@ -1554,7 +1555,7 @@ class AccountLine extends CommonObject var $element='bank'; var $table_element='bank'; var $picto = 'generic'; - + var $id; var $ref; var $datec; @@ -1842,7 +1843,7 @@ class AccountLine extends CommonObject function update_conciliation(User $user, $cat) { global $conf; - + $this->db->begin(); // Check statement field @@ -1854,7 +1855,7 @@ class AccountLine extends CommonObject return -1; } } - + $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET"; $sql.= " rappro = 1"; $sql.= ", num_releve = '".$this->db->escape($this->num_releve)."'"; @@ -2042,7 +2043,7 @@ class AccountLine extends CommonObject return $result; } - + /** * Return label of status (activity, closed) * @@ -2053,7 +2054,7 @@ class AccountLine extends CommonObject { return $this->LibStatut($this->status,$mode); } - + /** * Renvoi le libelle d'un statut donne * @@ -2097,6 +2098,6 @@ class AccountLine extends CommonObject if ($statut==1) return $langs->trans("InActivity").' '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"'); }*/ } - + } diff --git a/htdocs/compta/bank/transfer.php b/htdocs/compta/bank/transfer.php index 73e94a3d197..7c8d4a1826a 100644 --- a/htdocs/compta/bank/transfer.php +++ b/htdocs/compta/bank/transfer.php @@ -50,6 +50,7 @@ if ($action == 'add') $dateo = dol_mktime(12,0,0,GETPOST('remonth','int'),GETPOST('reday','int'),GETPOST('reyear','int')); $label = GETPOST('label','alpha'); $amount= GETPOST('amount'); + $amountto= GETPOST('amountto'); if (! $label) { @@ -71,6 +72,9 @@ if ($action == 'add') $error=1; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("TransferTo")), null, 'errors'); } + + + if (! $error) { require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; @@ -81,7 +85,18 @@ if ($action == 'add') $accountto=new Account($db); $accountto->fetch(GETPOST('account_to','int')); - if (($accountto->id != $accountfrom->id) && ($accountto->currency_code == $accountfrom->currency_code)) + if ($accountto->currency_code == $accountfrom->currency_code) { + $amountto=$amount; + } else { + if (! $amountto) + { + $error=1; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AmountTo")), null, 'errors'); + } + } + + + if (($accountto->id != $accountfrom->id) && empty($error)) { $db->begin(); @@ -102,7 +117,7 @@ if ($action == 'add') if (! $error) $bank_line_id_from = $accountfrom->addline($dateo, $typefrom, $label, -1*price2num($amount), '', '', $user); if (! ($bank_line_id_from > 0)) $error++; - if (! $error) $bank_line_id_to = $accountto->addline($dateo, $typeto, $label, price2num($amount), '', '', $user); + if (! $error) $bank_line_id_to = $accountto->addline($dateo, $typeto, $label, price2num($amountto), '', '', $user); if (! ($bank_line_id_to > 0)) $error++; if (! $error) $result=$accountfrom->add_url_line($bank_line_id_from, $bank_line_id_to, DOL_URL_ROOT.'/compta/bank/ligne.php?rowid=', '(banktransfert)', 'banktransfert'); @@ -137,6 +152,61 @@ if ($action == 'add') llxHeader(); + +print ' '; + + $form=new Form($db); $account_from=''; @@ -165,6 +235,7 @@ print ''; print ''; print ''; print ''; +print ''; print ''; $var=false; @@ -181,6 +252,7 @@ $form->select_date((! empty($dateo)?$dateo:''),'','','','','add'); print "\n"; print ''; print ''; +print ''; print "
'.$langs->trans("TransferFrom").''.$langs->trans("TransferTo").''.$langs->trans("Date").''.$langs->trans("Description").''.$langs->trans("Amount").'
"; diff --git a/htdocs/core/ajax/getaccountcurrency.php b/htdocs/core/ajax/getaccountcurrency.php new file mode 100644 index 00000000000..40e52672c0e --- /dev/null +++ b/htdocs/core/ajax/getaccountcurrency.php @@ -0,0 +1,60 @@ + + * + * 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/core/ajax/vatrates.php + * \brief File to load vat rates combobox + */ + +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Disables token renewal +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); + +require '../../main.inc.php'; + +$id = GETPOST('id','int'); + +/* + * View + */ + +top_httphead(); + +//print ''."\n"; + +// Load original field value +if (! empty($id)) +{ + require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + $account=new Account($db); + $result = $account->fetch($id); + if ($result<0) { + $return['value'] = ''; + $return['num'] = $result; + $return['error'] = $account->errors[0]; + } else { + $return['value'] = $account->currency_code; + $return['num'] = $result; + $return['error'] = ''; + } + + echo json_encode($return); +} + From 3825e7fd52870e39e94da7ca0899a4bdedf0e445 Mon Sep 17 00:00:00 2001 From: hguibourgdev Date: Sat, 15 Jul 2017 18:55:52 +0200 Subject: [PATCH 004/177] Update replenish.php FIX ">=" instead of ">" for alert test in order to work when negatif stock are allowed --- htdocs/product/stock/replenish.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index a3f4cb8ecaf..695cea9a9af 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -357,17 +357,17 @@ if ($usevirtualstock) if ($salert == 'on') // Option to see when stock is lower than alert { - $sql.= ' AND ('.$sqlalertstock.' > 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')'; + $sql.= ' AND ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')'; $sql.= ' - ('.$sqlCommandesCli.' - '.$sqlExpeditionsCli.') + ('.$sqlCommandesFourn.' - '.$sqlReceptionFourn.')))'; $alertchecked = 'checked'; } } else { - $sql.= ' HAVING (('.$sqldesiredtock.' > 0 AND ('.$sqldesiredtock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; - $sql.= ' OR ('.$sqlalertstock.' > 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").'))))'; + $sql.= ' HAVING (('.$sqldesiredtock.' >= 0 AND ('.$sqldesiredtock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; + $sql.= ' OR ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").'))))'; if ($salert == 'on') // Option to see when stock is lower than alert { - $sql.= ' AND ('.$sqlalertstock.' > 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; + $sql.= ' AND ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; $alertchecked = 'checked'; } } From 17da80832513e19d9efc40a4a7eec117aab45de4 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Fri, 8 Sep 2017 14:35:44 +0200 Subject: [PATCH 005/177] FIX wrong basePath in the swagger view Behind a reverse proxy the basePath seems to be in http. Forcing the basePath to DOL_MAIN_URL_ROOT fixes the problem. --- htdocs/api/class/api.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 40e00d01ffd..79793b0f8de 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -56,7 +56,7 @@ class DolibarrApi $this->db = $db; $production_mode = ( empty($conf->global->API_PRODUCTION_MODE) ? false : true ); $this->r = new Restler($production_mode, $refreshCache); - + $this->r->setBaseUrls(DOL_MAIN_URL_ROOT); $this->r->setAPIVersion(1); } From 681c2a67bd9c7d72554d976bc2d076a19410c4ca Mon Sep 17 00:00:00 2001 From: fappels Date: Mon, 11 Sep 2017 23:22:44 +0200 Subject: [PATCH 006/177] Fix batch required for lot product error message. --- htdocs/langs/en_US/errors.lang | 2 +- htdocs/product/stock/class/mouvementstock.class.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 8dfc02c49f1..47299634de3 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -156,7 +156,7 @@ ErrorPriceExpression22=Negative result '%s' ErrorPriceExpressionInternal=Internal error '%s' ErrorPriceExpressionUnknown=Unknown error '%s' ErrorSrcAndTargetWarehouseMustDiffers=Source and target warehouses must differs -ErrorTryToMakeMoveOnProductRequiringBatchData=Error, trying to make a stock movement without lot/serial information, on a product requiring lot/serial information +ErrorTryToMakeMoveOnProductRequiringBatchData=Error, trying to make a stock movement without lot/serial information, on product '%s' requiring lot/serial information ErrorCantSetReceptionToTotalDoneWithReceptionToApprove=All recorded receptions must first be verified (approved or denied) before being allowed to do this action ErrorCantSetReceptionToTotalDoneWithReceptionDenied=All recorded receptions must first be verified (approved) before being allowed to do this action ErrorGlobalVariableUpdater0=HTTP request failed with error '%s' diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 3e3eb4c28a7..25e0e9e7fce 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -96,6 +96,7 @@ class MouvementStock extends CommonObject require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; + $langs->load("errors"); $error = 0; dol_syslog(get_class($this)."::_create start userid=$user->id, fk_product=$fk_product, warehouse_id=$entrepot_id, qty=$qty, type=$type, price=$price, label=$label, inventorycode=$inventorycode, datem=".$datem.", eatby=".$eatby.", sellby=".$sellby.", batch=".$batch.", skip_batch=".$skip_batch); @@ -141,7 +142,7 @@ class MouvementStock extends CommonObject { if (empty($batch)) { - $this->errors[]=$langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $product->name); + $this->errors[]=$langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $product->ref); dol_syslog("Try to make a movement of a product with status_batch on without any batch data"); $this->db->rollback(); From f68d31d7c591da55f231e16ebdc65d171ea39572 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 12 Sep 2017 17:45:02 +0200 Subject: [PATCH 007/177] Add of $urlwithroot in the setBaseUrls function, to use Dolibarr external domain name in the configuration file --- htdocs/api/class/api.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 79793b0f8de..36eb7c1d7d2 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -56,7 +56,7 @@ class DolibarrApi $this->db = $db; $production_mode = ( empty($conf->global->API_PRODUCTION_MODE) ? false : true ); $this->r = new Restler($production_mode, $refreshCache); - $this->r->setBaseUrls(DOL_MAIN_URL_ROOT); + $this->r->setBaseUrls(DOL_MAIN_URL_ROOT, $urlwithroot); $this->r->setAPIVersion(1); } From ff7b542bfad145d7485d920c34b77594d358b556 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 15 Sep 2017 13:25:54 +0200 Subject: [PATCH 008/177] fix : Avoid warning --- .../class/expensereport.class.php | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index f999a93c57f..0ac2ce64062 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -187,20 +187,22 @@ class ExpenseReport extends CommonObject $resql=$this->db->query($sql); if (!$resql) $error++; - foreach ($this->lines as $i => $val) - { - $newndfline=new ExpenseReportLine($this->db); - $newndfline=$this->lines[$i]; - $newndfline->fk_expensereport=$this->id; - if ($result >= 0) - { - $result=$newndfline->insert(); - } - if ($result < 0) - { - $error++; - break; - } + if (is_array($this->lines) && count($this->lines)>0) { + foreach ($this->lines as $i => $val) + { + $newndfline=new ExpenseReportLine($this->db); + $newndfline=$this->lines[$i]; + $newndfline->fk_expensereport=$this->id; + if ($result >= 0) + { + $result=$newndfline->insert(); + } + if ($result < 0) + { + $error++; + break; + } + } } if (! $error) From 7f57f737b3fc194123e665b2d0bff7f227862d3d Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 15 Sep 2017 18:02:52 +0200 Subject: [PATCH 009/177] New: Ping ldap server before ldap_connect for avoid waiting --- htdocs/adherents/ldap.php | 8 +++--- htdocs/contact/ldap.php | 10 +++---- htdocs/core/class/ldap.class.php | 46 ++++++++++++++++++++++++-------- htdocs/user/group/ldap.php | 4 +-- htdocs/user/ldap.php | 4 +-- 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/htdocs/adherents/ldap.php b/htdocs/adherents/ldap.php index 38e90663c0f..65aea951d76 100644 --- a/htdocs/adherents/ldap.php +++ b/htdocs/adherents/ldap.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006 Regis Houssin +/* Copyright (C) 2006 Laurent Destailleur + * Copyright (C) 2006-2017 Regis Houssin * * 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 @@ -218,13 +218,11 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print ''; - llxFooter(); - $db->close(); diff --git a/htdocs/contact/ldap.php b/htdocs/contact/ldap.php index 16c00bf92cb..759831f7d57 100644 --- a/htdocs/contact/ldap.php +++ b/htdocs/contact/ldap.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006-2012 Regis Houssin + * Copyright (C) 2006-2017 Regis Houssin * * 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 @@ -91,7 +91,7 @@ $head = contact_prepare_head($object); dol_fiche_head($head, 'ldap', $title, -1, 'contact'); dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', ''); - + print '
'; print '
'; @@ -196,15 +196,11 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print ''; - - - llxFooter(); - $db->close(); diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 7c6fc0c5a77..166fe466796 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -123,7 +123,7 @@ class Ldap $this->filter = $conf->global->LDAP_FILTER_CONNECTION; // Filter on user $this->filtermember = $conf->global->LDAP_MEMBER_FILTER; // Filter on member - + // Users $this->attr_login = $conf->global->LDAP_FIELD_LOGIN; //unix $this->attr_sambalogin = $conf->global->LDAP_FIELD_LOGIN_SAMBA; //samba, activedirectory @@ -176,34 +176,40 @@ class Ldap { if ($connected) break; if (empty($host)) continue; - + if (preg_match('/^ldap/',$host)) { - $this->connection = ldap_connect($host); + if ($this->serverPing($host) === true) { + $this->connection = ldap_connect($host); + } + else continue; } else { - $this->connection = ldap_connect($host,$this->serverPort); + if ($this->serverPing($host, $this->serverPort) === true) { + $this->connection = ldap_connect($host,$this->serverPort); + } + else continue; } - + if (is_resource($this->connection)) { // Begin TLS if requested by the configuration - if (! empty($conf->global->LDAP_SERVER_USE_TLS)) + if (! empty($conf->global->LDAP_SERVER_USE_TLS)) { - if (! ldap_start_tls($this->connection)) + if (! ldap_start_tls($this->connection)) { dol_syslog(get_class($this)."::connect_bind failed to start tls", LOG_WARNING); $connected = 0; $this->close(); } } - + // Execute the ldap_set_option here (after connect and before bind) $this->setVersion(); ldap_set_option($this->connection, LDAP_OPT_SIZELIMIT, 0); // no limit here. should return true. - - + + if ($this->serverType == "activedirectory") { $result=$this->setReferrals(); @@ -256,7 +262,7 @@ class Ldap } } } - + if (! $connected) $this->close(); } } @@ -662,6 +668,24 @@ class Ldap } } + /** + * Ping a server before ldap_connect for avoid waiting + * + * @param string $host Server host or address + * @param int $port Server port (default 389) + * @param int $timeout Timeout in second (default 1s) + * @return boolean true or false + */ + function serverPing($host, $port=389, $timeout=1) + { + $op = @fsockopen($host, $port, $errno, $errstr, $timeout); + if (!$op) return false; //DC is N/A + else { + fclose($opanak); //explicitly close open socket connection + return true; //DC is up & running, we can safely connect with ldap_connect + } + } + // Attribute methods ----------------------------------------------------- diff --git a/htdocs/user/group/ldap.php b/htdocs/user/group/ldap.php index c195136863e..b7b1597ea74 100644 --- a/htdocs/user/group/ldap.php +++ b/htdocs/user/group/ldap.php @@ -206,12 +206,10 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print ''; llxFooter(); - $db->close(); - diff --git a/htdocs/user/ldap.php b/htdocs/user/ldap.php index 49739fa7c77..001915a8004 100644 --- a/htdocs/user/ldap.php +++ b/htdocs/user/ldap.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006-2015 Regis Houssin + * Copyright (C) 2006-2017 Regis Houssin * * 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 @@ -214,7 +214,7 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print ''; From 767240698f0d018202d613b24bfaa0e6c7538d87 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 15 Sep 2017 18:31:22 +0200 Subject: [PATCH 010/177] Fix: wrong var name --- htdocs/core/class/ldap.class.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 166fe466796..e06d472f326 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2005-2011 Regis Houssin + * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2006-2015 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify @@ -681,7 +681,7 @@ class Ldap $op = @fsockopen($host, $port, $errno, $errstr, $timeout); if (!$op) return false; //DC is N/A else { - fclose($opanak); //explicitly close open socket connection + fclose($op); //explicitly close open socket connection return true; //DC is up & running, we can safely connect with ldap_connect } } @@ -1435,5 +1435,3 @@ class Ldap return 0; } } - - From 9653280be950b8acdace160016534daf10dfa344 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sat, 16 Sep 2017 10:54:20 +0200 Subject: [PATCH 011/177] New: big refactorization and uniformize code --- htdocs/adherents/card.php | 18 +- .../adherents/class/adherent_type.class.php | 386 ++++++++++++------ .../class/api_memberstypes.class.php | 1 - htdocs/adherents/index.php | 8 +- htdocs/adherents/list.php | 4 +- htdocs/adherents/type.php | 159 +++++--- htdocs/langs/en_US/members.lang | 5 + 7 files changed, 378 insertions(+), 203 deletions(-) diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index bb67ec46468..aec9b6e4b92 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -2,7 +2,7 @@ /* Copyright (C) 2001-2004 Rodolphe Quiedeville * Copyright (C) 2002-2003 Jean-Louis Bergamo * Copyright (C) 2004-2012 Laurent Destailleur - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2012 Marcos GarcĂ­a * Copyright (C) 2012-2016 Philippe Grand * Copyright (C) 2015-2016 Alexandre Spangaro @@ -121,7 +121,16 @@ $hookmanager->initHooks(array('membercard','globalcard')); * Actions */ -if ($cancel) $action=''; +if ($cancel) { + + $action=''; + + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } +} $parameters=array('id'=>$id, 'rowid'=>$id, 'objcanvas'=>$objcanvas); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks @@ -813,6 +822,7 @@ else print '
'; print ''; print ''; + if ($backtopage) print ''; dol_fiche_head(''); @@ -957,7 +967,7 @@ else print '
'; print ''; print '     '; - print ''; + print ''; print '
'; print "
\n"; @@ -1225,7 +1235,7 @@ else print '
'; print ''; print '     '; - print ''; + print ''; print '
'; print ''; diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index eec88a59c11..82753d08590 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2002 Rodolphe Quiedeville * Copyright (C) 2004-2008 Laurent Destailleur * Copyright (C) 2009-2017 Regis Houssin * Copyright (C) 2016 Charlie Benke @@ -22,7 +22,6 @@ * \file htdocs/adherents/class/adherent_type.class.php * \ingroup member * \brief File of class to manage members types - * \author Rodolphe Quiedeville */ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; @@ -64,140 +63,192 @@ class AdherentType extends CommonObject public $mail_valid; - /** + /** * Constructor * * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - $this->statut = 1; - } + */ + function __construct($db) + { + $this->db = $db; + $this->statut = 1; + } - /** - * Fonction qui permet de creer le status de l'adherent - * - * @param User $user User making creation - * @return int >0 if OK, < 0 if KO - */ - function create($user) - { - global $conf; + /** + * Fonction qui permet de creer le status de l'adherent + * + * @param User $user User making creation + * @param int $notrigger 1=do not execute triggers, 0 otherwise + * @return int >0 if OK, < 0 if KO + */ + function create($user,$notrigger=0) + { + global $conf; - $this->statut=(int) $this->statut; - $this->label=(!empty($this->libelle)?trim($this->libelle):trim($this->label)); + $error=0; - $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent_type ("; - $sql.= "libelle"; - $sql.= ", entity"; - $sql.= ") VALUES ("; - $sql.= "'".$this->db->escape($this->label)."'"; - $sql.= ", ".$conf->entity; - $sql.= ")"; + $this->statut=(int) $this->statut; + $this->label=trim($this->label); - dol_syslog("Adherent_type::create", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent_type"); - return $this->update($user); - } - else - { - $this->error=$this->db->error().' sql='.$sql; - return -1; - } - } + $this->db->begin(); + $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent_type ("; + $sql.= "libelle"; + $sql.= ", entity"; + $sql.= ") VALUES ("; + $sql.= "'".$this->db->escape($this->label)."'"; + $sql.= ", ".$conf->entity; + $sql.= ")"; - /** - * Met a jour en base donnees du type - * - * @param User $user Object user making change - * @return int >0 if OK, < 0 if KO - */ - function update($user) - { - global $hookmanager,$conf; + dol_syslog("Adherent_type::create", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent_type"); - $error=0; + $result = $this->update($user,1); + if ($result < 0) + { + $this->db->rollback(); + return -3; + } - $this->label=(!empty($this->libelle)?trim($this->libelle):trim($this->label)); + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_TYPE_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } - $sql = "UPDATE ".MAIN_DB_PREFIX."adherent_type "; - $sql.= "SET "; - $sql.= "statut = ".$this->statut.","; - $sql.= "libelle = '".$this->db->escape($this->label) ."',"; - $sql.= "subscription = '".$this->db->escape($this->subscription)."',"; - $sql.= "note = '".$this->db->escape($this->note)."',"; - $sql.= "vote = '".$this->db->escape($this->vote)."',"; - $sql.= "mail_valid = '".$this->db->escape($this->mail_valid)."'"; - $sql.= " WHERE rowid =".$this->id; + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } - $result = $this->db->query($sql); - if ($result) - { - $action='update'; + /** + * Met a jour en base donnees du type + * + * @param User $user Object user making change + * @param int $notrigger 1=do not execute triggers, 0 otherwise + * @return int >0 if OK, < 0 if KO + */ + function update($user,$notrigger=0) + { + global $conf, $hookmanager; - // Actions on extra fields (by external module or standard code) - $hookmanager->initHooks(array('membertypedao')); - $parameters=array('membertype'=>$this->id); - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - else if ($reshook < 0) $error++; + $error=0; + $this->label=trim($this->label); - return 1; - } - else - { - $this->error=$this->db->error().' sql='.$sql; - return -1; - } - } + $this->db->begin(); - /** - * Fonction qui permet de supprimer le status de l'adherent - * - * @param int $rowid Id of member type to delete - * @return int >0 if OK, 0 if not found, < 0 if KO - */ - function delete($rowid='') - { - if (empty($rowid)) $rowid=$this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX."adherent_type "; + $sql.= "SET "; + $sql.= "statut = ".$this->statut.","; + $sql.= "libelle = '".$this->db->escape($this->label) ."',"; + $sql.= "subscription = '".$this->db->escape($this->subscription)."',"; + $sql.= "note = '".$this->db->escape($this->note)."',"; + $sql.= "vote = '".$this->db->escape($this->vote)."',"; + $sql.= "mail_valid = '".$this->db->escape($this->mail_valid)."'"; + $sql.= " WHERE rowid =".$this->id; - $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent_type WHERE rowid = ".$rowid; + $result = $this->db->query($sql); + if ($result) + { + $action='update'; - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->affected_rows($resql)) - { - return 1; - } - else - { - return 0; - } - } - else - { - print "Err : ".$this->db->error(); - return 0; - } - } + // Actions on extra fields (by external module or standard code) + $hookmanager->initHooks(array('membertypedao')); + $parameters=array('membertype'=>$this->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; + + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_TYPE_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR); + return -$error; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } + + /** + * Fonction qui permet de supprimer le status de l'adherent + * + * @return int >0 if OK, 0 if not found, < 0 if KO + */ + function delete() + { + global $user; + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent_type"; + $sql.= " WHERE rowid = ".$this->id; + + $resql=$this->db->query($sql); + if ($resql) + { + // Call trigger + $result=$this->call_trigger('MEMBER_TYPE_DELETE',$user); + if ($result < 0) { $error++; $this->db->rollback(); return -2; } + // End call triggers + + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + return -1; + } + } /** * Fonction qui permet de recuperer le status de l'adherent @@ -223,7 +274,6 @@ class AdherentType extends CommonObject $this->id = $obj->rowid; $this->ref = $obj->rowid; $this->label = $obj->label; - $this->libelle = $obj->label; // For backward compatibility $this->statut = $obj->statut; $this->subscription = $obj->subscription; $this->mail_valid = $obj->mail_valid; @@ -250,7 +300,7 @@ class AdherentType extends CommonObject $adherenttypes = array(); - $sql = "SELECT rowid, libelle"; + $sql = "SELECT rowid, libelle as label"; $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type"; $sql.= " WHERE entity IN (".getEntity('adherent').")"; @@ -266,7 +316,7 @@ class AdherentType extends CommonObject { $obj = $this->db->fetch_object($resql); - $adherenttypes[$obj->rowid] = $langs->trans($obj->libelle); + $adherenttypes[$obj->rowid] = $langs->trans($obj->label); $i++; } } @@ -278,12 +328,11 @@ class AdherentType extends CommonObject return $adherenttypes; } - /** * Return clicable name (with picto eventually) * * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @param int $maxlen length max libelle + * @param int $maxlen length max label * @return string String with URL */ function getNomUrl($withpicto=0,$maxlen=0) @@ -291,7 +340,7 @@ class AdherentType extends CommonObject global $langs; $result=''; - $label=$langs->trans("ShowTypeCard",$this->libelle); + $label=$langs->trans("ShowTypeCard",$this->label); $link = ''; $linkend=''; @@ -300,20 +349,101 @@ class AdherentType extends CommonObject if ($withpicto) $result.=($link.img_object($label, $picto, 'class="classfortooltip"').$linkend); if ($withpicto && $withpicto != 2) $result.=' '; - $result.=$link.($maxlen?dol_trunc($this->libelle,$maxlen):$this->libelle).$linkend; + $result.=$link.($maxlen?dol_trunc($this->label,$maxlen):$this->label).$linkend; return $result; } - /** * getLibStatut * * @return string Return status of a type of member */ - function getLibStatut() - { - return ''; - } + function getLibStatut() + { + return ''; + } + + /** + * Retourne chaine DN complete dans l'annuaire LDAP pour l'objet + * + * @param array $info Info array loaded by _load_ldap_info + * @param int $mode 0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb) + * 1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb) + * 2=Return key only (uid=qqq) + * @return string DN + */ + function _load_ldap_dn($info,$mode=0) + { + global $conf; + $dn=''; + if ($mode==0) $dn=$conf->global->LDAP_KEY_MEMBERS_TYPES."=".$info[$conf->global->LDAP_KEY_MEMBERS_TYPES].",".$conf->global->LDAP_MEMBER_TYPE_DN; + if ($mode==1) $dn=$conf->global->LDAP_MEMBER_TYPE_DN; + if ($mode==2) $dn=$conf->global->LDAP_KEY_MEMBERS_TYPES."=".$info[$conf->global->LDAP_KEY_MEMBERS_TYPES]; + return $dn; + } + + + /** + * Initialize the info array (array of LDAP values) that will be used to call LDAP functions + * + * @return array Tableau info des attributs + */ + function _load_ldap_info() + { + global $conf,$langs; + + $info=array(); + + // Object classes + $info["objectclass"]=explode(',',$conf->global->LDAP_MEMBER_TYPE_OBJECT_CLASS); + + // Champs + if ($this->label && ! empty($conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME)) $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME] = $this->label; + if ($this->note && ! empty($conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION] = $this->note; + if (! empty($conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS)) + { + $valueofldapfield=array(); + foreach($this->members as $key=>$val) // This is array of users for group into dolibarr database. + { + $member=new Adherent($this->db); + $member->fetch($val->id); + $info2 = $member->_load_ldap_info(); + $valueofldapfield[] = $member->_load_ldap_dn($info2); + } + $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield)?$valueofldapfield:''); + } + return $info; + } + + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void + */ + function initAsSpecimen() + { + global $conf, $user, $langs; + + // Initialise parametres + $this->id = 0; + $this->ref = 0; + $this->specimen=1; + + $this->label='MEMBERS TYPE SPECIMEN'; + $this->note='This is a note'; + $this->mail_valid='This is welcome email'; + $this->subscription=1; + $this->vote=0; + + $this->statut=1; + + // Members of this member type is just me + $this->members=array( + $user->id => $user + ); + } /** * getMailOnValid diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index ff8064d80fb..c6adaf50142 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -272,7 +272,6 @@ class MembersTypes extends DolibarrApi $object = parent::_cleanObjectDatas($object); unset($object->cotisation); - unset($object->libelle); unset($object->array_options); unset($object->linkedObjectsIds); diff --git a/htdocs/adherents/index.php b/htdocs/adherents/index.php index 2614a27d509..54779432a3b 100644 --- a/htdocs/adherents/index.php +++ b/htdocs/adherents/index.php @@ -59,7 +59,7 @@ $AdherentsResilies=array(); $AdherentType=array(); // Liste les adherents -$sql = "SELECT t.rowid, t.libelle, t.subscription,"; +$sql = "SELECT t.rowid, t.libelle as label, t.subscription,"; $sql.= " d.statut, count(d.rowid) as somme"; $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."adherent as d"; @@ -81,7 +81,7 @@ if ($result) $adhtype=new AdherentType($db); $adhtype->id=$objp->rowid; $adhtype->subscription=$objp->subscription; - $adhtype->libelle=$objp->libelle; + $adhtype->label=$objp->label; $AdherentType[$objp->rowid]=$adhtype; if ($objp->statut == -1) { $MemberToValidate[$objp->rowid]=$objp->somme; } @@ -273,7 +273,7 @@ $max=5; $sql = "SELECT a.rowid, a.statut, a.lastname, a.firstname, a.societe as company, a.fk_soc,"; $sql.= " a.tms as datem, datefin as date_end_subscription,"; -$sql.= " ta.rowid as typeid, ta.libelle, ta.subscription"; +$sql.= " ta.rowid as typeid, ta.libelle as label, ta.subscription"; $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a, ".MAIN_DB_PREFIX."adherent_type as ta"; $sql.= " WHERE a.entity IN (".getEntity('adherent').")"; $sql.= " AND a.fk_adherent_type = ta.rowid"; @@ -310,7 +310,7 @@ if ($resql) } $staticmember->ref=$staticmember->getFullName($langs); $statictype->id=$obj->typeid; - $statictype->libelle=$obj->libelle; + $statictype->label=$obj->label; print ''.$staticmember->getNomUrl(1,32).''; print ''.$statictype->getNomUrl(1,32).''; print ''.dol_print_date($db->jdate($obj->datem),'dayhour').''; diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 3dc5439f47f..783934deb34 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -315,7 +315,7 @@ if ($search_type > 0) { $membertype=new AdherentType($db); $result=$membertype->fetch(GETPOST("type",'int')); - $titre.=" (".$membertype->libelle.")"; + $titre.=" (".$membertype->label.")"; } $param=''; @@ -698,7 +698,7 @@ while ($i < min($num, $limit)) if (! empty($arrayfields['t.libelle']['checked'])) { $membertypestatic->id=$obj->type_id; - $membertypestatic->libelle=$obj->type; + $membertypestatic->label=$obj->type; print ''; print $membertypestatic->getNomUrl(1,32); print ''; diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index a0f36c409de..3d4fb786295 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2001-2002 Rodolphe Quiedeville * Copyright (C) 2003 Jean-Louis Bergamo * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2017 Regis Houssin @@ -37,6 +37,7 @@ $langs->load("members"); $rowid = GETPOST('rowid','int'); $action = GETPOST('action','alpha'); $cancel = GETPOST('cancel','alpha'); +$backtopage = GETPOST('backtopage','alpha'); $search_lastname = GETPOST('search_lastname','alpha'); $search_login = GETPOST('search_login','alpha'); @@ -64,6 +65,8 @@ $mail_valid=GETPOST("mail_valid"); // Security check $result=restrictedArea($user,'adherent',$rowid,'adherent_type'); +$object = new AdherentType($db); + $extrafields = new ExtraFields($db); // fetch optionals attributes and labels @@ -87,73 +90,95 @@ $hookmanager->initHooks(array('membertypecard','globalcard')); * Actions */ +if ($cancel) { + + $action=''; + + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } +} + if ($action == 'add' && $user->rights->adherent->configurer) { - if (! $cancel) + $object->label = trim($label); + $object->subscription = (int) trim($subscription); + $object->note = trim($comment); + $object->mail_valid = trim($mail_valid); + $object->vote = (boolean) trim($vote); + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + if ($ret < 0) $error++; + + if ($object->label) { - $object = new AdherentType($db); - - $object->label = trim($label); - $object->subscription = (int) trim($subscription); - $object->note = trim($comment); - $object->mail_valid = (boolean) trim($mail_valid); - $object->vote = (boolean) trim($vote); - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - if ($ret < 0) $error++; - - if ($object->label) + $id=$object->create($user); + if ($id > 0) { - $id=$object->create($user); - if ($id > 0) - { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; - } - else - { - $mesg=$object->error; - $action = 'create'; - } + header("Location: ".$_SERVER["PHP_SELF"]); + exit; } else { - $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")); + $mesg=$object->error; $action = 'create'; } } + else + { + $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")); + $action = 'create'; + } } if ($action == 'update' && $user->rights->adherent->configurer) { - if (! $cancel) + $object->fetch($rowid); + + $object->label = trim($label); + $object->subscription = (int) trim($subscription); + $object->note = trim($comment); + $object->mail_valid = trim($mail_valid); + $object->vote = (boolean) trim($vote); + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + if ($ret < 0) $error++; + + $ret=$object->update($user); + + if ($ret >= 0 && ! count($object->errors)) { - $object = new AdherentType($db); - $object->id = $rowid; - $object->label = trim($label); - $object->subscription = (int) trim($subscription); - $object->note = trim($comment); - $object->mail_valid = (boolean) trim($mail_valid); - $object->vote = (boolean) trim($vote); - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - if ($ret < 0) $error++; - - $object->update($user); - - header("Location: ".$_SERVER["PHP_SELF"]."?rowid=".$_POST["rowid"]); - exit; + setEventMessages($langs->trans("MemberTypeModified"), null, 'mesgs'); } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + + header("Location: ".$_SERVER["PHP_SELF"]."?rowid=".$object->id); + exit; } -if ($action == 'delete' && $user->rights->adherent->configurer) +if ($action == 'confirm_delete' && $user->rights->adherent->configurer) { - $object = new AdherentType($db); - $object->delete($rowid); - header("Location: ".$_SERVER["PHP_SELF"]); - exit; + $object->fetch($rowid); + $res=$object->delete(); + + if ($res > 0) + { + setEventMessages($langs->trans("MemberTypeDeleted"), null, 'mesgs'); + header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } + else + { + setEventMessages($langs->trans("MemberTypeCanNotBeDeleted"), null, 'errors'); + $action=''; + } } @@ -308,7 +333,15 @@ if ($rowid > 0) { $object = new AdherentType($db); $object->fetch($rowid); - $object->fetch_optionals($rowid,$extralabels); + $object->fetch_optionals($object->id,$extralabels); + + /* + * Confirmation suppression + */ + if ($action == 'delete') + { + print $form->formconfirm($_SERVER['PHP_SELF']."?rowid=".$object->id,$langs->trans("DeleteAMemberType"),$langs->trans("ConfirmDeleteMemberType",$object->label),"confirm_delete", '',0,1); + } $head = member_type_prepare_head($object); @@ -337,15 +370,14 @@ if ($rowid > 0) print ''.$langs->trans("WelcomeEMail").''; print nl2br($object->mail_valid).""; - // Other attributes - include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; print ''; - print '
'; + print ''; dol_fiche_end(); - /* * Buttons */ @@ -359,7 +391,7 @@ if ($rowid > 0) } // Add - print ''; + print ''; // Delete if ($user->rights->adherent->configurer) @@ -459,7 +491,7 @@ if ($rowid > 0) $titre.=" (".$membertype->label.")"; } - $param="&rowid=".$rowid; + $param="&rowid=".$object->id; if (! empty($status)) $param.="&status=".$status; if (! empty($search_lastname)) $param.="&search_lastname=".$search_lastname; if (! empty($search_firstname)) $param.="&search_firstname=".$search_firstname; @@ -473,7 +505,7 @@ if ($rowid > 0) } print '
'; - print ''; + print ''; print '
'; print_barre_liste('',$page,$_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecords); @@ -593,12 +625,12 @@ if ($rowid > 0) print ''; if ($user->rights->adherent->creer) { - print ''.img_edit().''; + print ''.img_edit().''; } print ' '; if ($user->rights->adherent->supprimer) { - print ''.img_picto($langs->trans("Resiliate"),'disable.png').''; + print ''.img_picto($langs->trans("Resiliate"),'disable.png').''; } print ""; @@ -631,15 +663,14 @@ if ($rowid > 0) if ($action == 'edit') { $object = new AdherentType($db); - $object->id = $rowid; $object->fetch($rowid); - $object->fetch_optionals($rowid,$extralabels); + $object->fetch_optionals($object->id,$extralabels); $head = member_type_prepare_head($object); - print ''; + print ''; print ''; - print ''; + print ''; print ''; dol_fiche_head($head, 'card', $langs->trans("MemberType"), 0, 'group'); @@ -706,7 +737,7 @@ if ($rowid > 0) print '
'; print ''; print '     '; - print ''; + print ''; print '
'; print "
"; diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang index 5e7ad30ec3f..dc25d792517 100644 --- a/htdocs/langs/en_US/members.lang +++ b/htdocs/langs/en_US/members.lang @@ -57,6 +57,11 @@ NewCotisation=New contribution PaymentSubscription=New contribution payment SubscriptionEndDate=Subscription's end date MembersTypeSetup=Members type setup +MemberTypeModified=Member type modified +DeleteAMemberType=Delete a member type +ConfirmDeleteMemberType=Are you sure you want to delete this member type? +MemberTypeDeleted=Member type deleted +MemberTypeCanNotBeDeleted=Member type can not be deleted NewSubscription=New subscription NewSubscriptionDesc=This form allows you to record your subscription as a new member of the foundation. If you want to renew your subscription (if already a member), please contact foundation board instead by email %s. Subscription=Subscription From 279988bd60a035a1fcca20a17161dd1b1ee16f1e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 16 Sep 2017 12:45:54 +0200 Subject: [PATCH 012/177] Remove warning --- htdocs/core/modules/modFournisseur.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 017ffd1d121..39ebd275c67 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -272,12 +272,12 @@ class modFournisseur extends DolibarrModules $this->rights[$r][5] = 'approve2'; } - + // Menus //------- $this->menu = 1; // This module add menu entries. They are coded into menu manager. - - + + // Exports //-------- $r=0; @@ -435,7 +435,7 @@ class modFournisseur extends DolibarrModules // End add extra fields object $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'societe as s'; - if(!$user->rights->societe->client->voir) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid'; + if (empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,'; $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'facture_fourn as f'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)'; @@ -444,7 +444,7 @@ class modFournisseur extends DolibarrModules $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn as p ON pf.fk_paiementfourn = p.rowid'; $this->export_sql_end[$r] .=' WHERE f.fk_soc = s.rowid'; $this->export_sql_end[$r] .=' AND f.entity IN ('.getEntity('supplier_invoice',1).')'; - if(!$user->rights->societe->client->voir) $this->export_sql_end[$r] .=' AND sc.fk_user = '.$user->id; + if (empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' AND sc.fk_user = '.$user->id; // Order $r++; From f584212700339675d8b17e233ea9caf790c35ef3 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sat, 16 Sep 2017 16:06:34 +0200 Subject: [PATCH 013/177] Fix: use >0 instead !isnull --- htdocs/adherents/class/adherent.class.php | 52 +++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 85665280275..a1b61358820 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -447,33 +447,33 @@ class Adherent extends CommonObject $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; - $sql.= " civility = ".(!is_null($this->civility_id)?$this->db->escape($this->civility_id):"null"); + $sql.= " civility = ".($this->civility_id>0?$this->db->escape($this->civility_id):"null"); $sql.= ", firstname = ".($this->firstname?"'".$this->db->escape($this->firstname)."'":"null"); - $sql.= ", lastname=" .($this->lastname?"'".$this->db->escape($this->lastname)."'":"null"); - $sql.= ", login=" .($this->login?"'".$this->db->escape($this->login)."'":"null"); - $sql.= ", societe=" .($this->societe?"'".$this->db->escape($this->societe)."'":"null"); - $sql.= ", fk_soc=" .($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null"); - $sql.= ", address=" .($this->address?"'".$this->db->escape($this->address)."'":"null"); - $sql.= ", zip=" .($this->zip?"'".$this->db->escape($this->zip)."'":"null"); - $sql.= ", town=" .($this->town?"'".$this->db->escape($this->town)."'":"null"); - $sql.= ", country=".($this->country_id>0?$this->db->escape($this->country_id):"null"); - $sql.= ", state_id=".($this->state_id>0?$this->db->escape($this->state_id):"null"); - $sql.= ", email='".$this->db->escape($this->email)."'"; - $sql.= ", skype='".$this->db->escape($this->skype)."'"; - $sql.= ", phone=" .($this->phone?"'".$this->db->escape($this->phone)."'":"null"); - $sql.= ", phone_perso=" .($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null"); - $sql.= ", phone_mobile=" .($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null"); - $sql.= ", note_private=" .($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); - $sql.= ", note_public=" .($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); - $sql.= ", photo=" .($this->photo?"'".$this->db->escape($this->photo)."'":"null"); - $sql.= ", public='".$this->db->escape($this->public)."'"; - $sql.= ", statut=" .$this->statut; - $sql.= ", fk_adherent_type=".$this->typeid; - $sql.= ", morphy='".$this->db->escape($this->morphy)."'"; - $sql.= ", birth=" .($this->birth?"'".$this->db->idate($this->birth)."'":"null"); - if ($this->datefin) $sql.= ", datefin='".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription - if ($this->datevalid) $sql.= ", datevalid='".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member - $sql.= ", fk_user_mod=".($user->id>0?$user->id:'null'); // Can be null because member can be create by a guest + $sql.= ", lastname = ".($this->lastname?"'".$this->db->escape($this->lastname)."'":"null"); + $sql.= ", login = ".($this->login?"'".$this->db->escape($this->login)."'":"null"); + $sql.= ", societe = ".($this->societe?"'".$this->db->escape($this->societe)."'":"null"); + $sql.= ", fk_soc = ".($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null"); + $sql.= ", address = ".($this->address?"'".$this->db->escape($this->address)."'":"null"); + $sql.= ", zip = ".($this->zip?"'".$this->db->escape($this->zip)."'":"null"); + $sql.= ", town = ".($this->town?"'".$this->db->escape($this->town)."'":"null"); + $sql.= ", country = ".($this->country_id>0?$this->db->escape($this->country_id):"null"); + $sql.= ", state_id = ".($this->state_id>0?$this->db->escape($this->state_id):"null"); + $sql.= ", email = '".$this->db->escape($this->email)."'"; + $sql.= ", skype = '".$this->db->escape($this->skype)."'"; + $sql.= ", phone = ".($this->phone?"'".$this->db->escape($this->phone)."'":"null"); + $sql.= ", phone_perso = ".($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null"); + $sql.= ", phone_mobile = ".($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null"); + $sql.= ", note_private = ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); + $sql.= ", note_public = ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); + $sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null"); + $sql.= ", public = '".$this->db->escape($this->public)."'"; + $sql.= ", statut = ".$this->statut; + $sql.= ", fk_adherent_type = ".$this->typeid; + $sql.= ", morphy = '".$this->db->escape($this->morphy)."'"; + $sql.= ", birth = ".($this->birth?"'".$this->db->idate($this->birth)."'":"null"); + if ($this->datefin) $sql.= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription + if ($this->datevalid) $sql.= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member + $sql.= ", fk_user_mod = ".($user->id>0?$user->id:'null'); // Can be null because member can be create by a guest $sql.= " WHERE rowid = ".$this->id; dol_syslog(get_class($this)."::update update member", LOG_DEBUG); From 4ab1f68102df45a099d10c8c4bd8212c4f715705 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sat, 16 Sep 2017 17:12:51 +0200 Subject: [PATCH 014/177] Fix: check connectivity for avoid ldap errors --- htdocs/core/class/ldap.class.php | 18 +- ...interface_50_modLdap_Ldapsynchro.class.php | 928 +++++++++--------- 2 files changed, 471 insertions(+), 475 deletions(-) diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index e06d472f326..58eedc0ad9d 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -195,15 +195,15 @@ class Ldap if (is_resource($this->connection)) { // Begin TLS if requested by the configuration - if (! empty($conf->global->LDAP_SERVER_USE_TLS)) - { - if (! ldap_start_tls($this->connection)) - { - dol_syslog(get_class($this)."::connect_bind failed to start tls", LOG_WARNING); - $connected = 0; - $this->close(); - } - } + if (! empty($conf->global->LDAP_SERVER_USE_TLS)) + { + if (! ldap_start_tls($this->connection)) + { + dol_syslog(get_class($this)."::connect_bind failed to start tls", LOG_WARNING); + $connected = 0; + $this->close(); + } + } // Execute the ldap_set_option here (after connect and before bind) $this->setVersion(); diff --git a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php index 561ba330694..9c5112dd68a 100644 --- a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php +++ b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php @@ -1,6 +1,7 @@ - * Copyright (C) 2014 Marcos GarcĂ­a +/* Copyright (C) 2005-2012 Laurent Destailleur + * Copyright (C) 2005-2017 Regis Houssin + * Copyright (C) 2014 Marcos GarcĂ­a * * 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 @@ -49,553 +50,548 @@ class InterfaceLdapsynchro extends DolibarrTriggers * @return int <0 if KO, 0 if no triggered ran, >0 if OK */ public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) - { - if (empty($conf->ldap->enabled)) return 0; // Module not active, we do nothing + { + if (empty($conf->ldap->enabled)) return 0; // Module not active, we do nothing - if (! function_exists('ldap_connect')) - { - dol_syslog("Warning, module LDAP is enabled but LDAP functions not available in this PHP", LOG_WARNING); - return 0; - } + if (! function_exists('ldap_connect')) + { + dol_syslog("Warning, module LDAP is enabled but LDAP functions not available in this PHP", LOG_WARNING); + return 0; + } - // Users - if ($action == 'USER_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + $result=0; - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); + // Users + if ($action == 'USER_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $result=$ldap->add($dn,$info,$user); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); } - return $result; - } - } - elseif ($action == 'USER_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; - } - } - elseif ($action == 'USER_NEW_PASSWORD') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_NEW_PASSWORD') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'USER_ENABLEDISABLE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - } - elseif ($action == 'USER_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; - } - } - elseif ($action == 'USER_SETINGROUP') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - // Must edit $object->newgroupid - $usergroup=new UserGroup($this->db); - if ($object->newgroupid > 0) - { - $usergroup->fetch($object->newgroupid); + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_ENABLEDISABLE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + } + elseif ($action == 'USER_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $oldinfo=$usergroup->_load_ldap_info(); - $olddn=$usergroup->_load_ldap_dn($oldinfo); + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); - // Verify if entry exist - $container=$usergroup->_load_ldap_dn($oldinfo,1); - $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } + $result=$ldap->delete($dn); + } - $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) - $dn=$usergroup->_load_ldap_dn($info); + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_SETINGROUP') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - } - return $result; - } - } - elseif ($action == 'USER_REMOVEFROMGROUP') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + if ($result > 0) + { + // Must edit $object->newgroupid + $usergroup=new UserGroup($this->db); + if ($object->newgroupid > 0) + { + $usergroup->fetch($object->newgroupid); - // Must edit $object->newgroupid - $usergroup=new UserGroup($this->db); - if ($object->oldgroupid > 0) - { - $usergroup->fetch($object->oldgroupid); + $oldinfo=$usergroup->_load_ldap_info(); + $olddn=$usergroup->_load_ldap_dn($oldinfo); - $oldinfo=$usergroup->_load_ldap_info(); - $olddn=$usergroup->_load_ldap_dn($oldinfo); + // Verify if entry exist + $container=$usergroup->_load_ldap_dn($oldinfo,1); + $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } - // Verify if entry exist - $container=$usergroup->_load_ldap_dn($oldinfo,1); - $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } + $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$usergroup->_load_ldap_dn($info); - $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) - $dn=$usergroup->_load_ldap_dn($info); + $result=$ldap->update($dn,$info,$user,$olddn); + } + } - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - } - return $result; - } - } + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_REMOVEFROMGROUP') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + // Must edit $object->newgroupid + $usergroup=new UserGroup($this->db); + if ($object->oldgroupid > 0) + { + $usergroup->fetch($object->oldgroupid); + + $oldinfo=$usergroup->_load_ldap_info(); + $olddn=$usergroup->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$usergroup->_load_ldap_dn($oldinfo,1); + $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$usergroup->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } // Groupes - elseif ($action == 'GROUP_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + elseif ($action == 'GROUP_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - // Get a gid number for objectclass PosixGroup - if(in_array('posixGroup',$info['objectclass'])) - $info['gidNumber'] = $ldap->getNextGroupGid(); - - $result=$ldap->add($dn,$info,$user); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid(); + } + + $result=$ldap->add($dn,$info,$user); } - return $result; - } - } - elseif ($action == 'GROUP_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } - - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'GROUP_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - - // Contacts - elseif ($action == 'CONTACT_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->add($dn,$info,$user); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'CONTACT_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } - - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'CONTACT_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } - } + } + elseif ($action == 'GROUP_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - // Members - elseif ($action == 'MEMBER_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->add($dn,$info,$user); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; - } - } - elseif ($action == 'MEMBER_VALIDATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'GROUP_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->delete($dn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + // Contacts + elseif ($action == 'CONTACT_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'CONTACT_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'CONTACT_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->delete($dn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + // Members + elseif ($action == 'MEMBER_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_VALIDATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If status field is setup to be synchronized if (! empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only status - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only status + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } - } - elseif ($action == 'MEMBER_SUBSCRIPTION') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + } + elseif ($action == 'MEMBER_SUBSCRIPTION') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If subscriptions fields are setup to be synchronized if ($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE - || $conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT - || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE - || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT - || $conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION) + || $conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT + || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE + || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT + || $conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only subscriptions - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only subscriptions + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } - } - elseif ($action == 'MEMBER_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + } + elseif ($action == 'MEMBER_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } - - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; - } - } - elseif ($action == 'MEMBER_NEW_PASSWORD') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_NEW_PASSWORD') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If password field is setup to be synchronized if ($conf->global->LDAP_FIELD_PASSWORD || $conf->global->LDAP_FIELD_PASSWORD_CRYPTED) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only password - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only password + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } } - elseif ($action == 'MEMBER_RESILIATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + elseif ($action == 'MEMBER_RESILIATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If status field is setup to be synchronized if (! empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only status - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only status + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } - } - elseif ($action == 'MEMBER_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + } + elseif ($action == 'MEMBER_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->delete($dn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } - // If not found -/* - else - { - dol_syslog("Trigger '".$this->name."' for action '$action' was ran by ".__FILE__." but no handler found for this action."); - return -1; - } -*/ - return 0; + return $result; } } From 87b81fb2fda13f2bf507b4a1f8dc521b776626ee Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sat, 16 Sep 2017 17:51:18 +0200 Subject: [PATCH 015/177] NEW add members types ldap group management --- htdocs/adherents/class/adherent.class.php | 171 +++++----- .../adherents/class/adherent_type.class.php | 301 +++++++++++------- htdocs/adherents/type.php | 24 +- htdocs/adherents/type_ldap.php | 189 +++++++++++ htdocs/admin/ldap.php | 15 +- htdocs/admin/ldap_groups.php | 5 +- htdocs/admin/ldap_members_types.php | 252 +++++++++++++++ htdocs/core/class/conf.class.php | 1 + htdocs/core/class/ldap.class.php | 7 +- htdocs/core/lib/ldap.lib.php | 8 + htdocs/core/lib/member.lib.php | 10 + ...interface_50_modLdap_Ldapsynchro.class.php | 200 +++++++++++- htdocs/langs/en_US/admin.lang | 12 +- htdocs/langs/en_US/errors.lang | 1 + htdocs/langs/en_US/ldap.lang | 2 + htdocs/user/group/ldap.php | 23 +- 16 files changed, 989 insertions(+), 232 deletions(-) create mode 100644 htdocs/adherents/type_ldap.php create mode 100644 htdocs/admin/ldap_members_types.php diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index a1b61358820..47bf219216c 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -714,109 +714,108 @@ class Adherent extends CommonObject * Fonction qui supprime l'adherent et les donnees associees * * @param int $rowid Id of member to delete - * @param User $user User object + * @param User $user User object * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int <0 if KO, 0=nothing to do, >0 if OK */ - function delete($rowid, $user, $notrigger=0) - { - global $conf, $langs; + function delete($rowid, $user, $notrigger=0) + { + global $conf, $langs; - $result = 0; + $result = 0; $error=0; $errorflag=0; // Check parameters if (empty($rowid)) $rowid=$this->id; - $this->db->begin(); + $this->db->begin(); - if (! $error && ! $notrigger) - { - // Call trigger - $result=$this->call_trigger('MEMBER_DELETE',$user); - if ($result < 0) $error++; - // End call triggers - } + // Remove category + $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-1; + } - // Remove category - $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-1; + // Remove subscription + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-2; + } + } - } + // Remove linked user + if (! $error) + { + $ret=$this->setUserId(0); + if ($ret < 0) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-3; + } + } - // Remove subscription - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-2; - } - } + // Removed extrafields + if (! $error) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $error++; + $errorflag=-4; + dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); + } + } + } - // Remove linked user - if (! $error) - { - $ret=$this->setUserId(0); - if ($ret < 0) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-3; - } - } + // Remove adherent + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-5; + } + } - // Removed extrafields - if (! $error) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->deleteExtraFields(); - if ($result < 0) - { - $error++; - $errorflag=-4; - dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); - } - } - } + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_DELETE',$user); + if ($result < 0) $error++; + // End call triggers + } - // Remove adherent - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-5; - } - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return $errorflag; - } - } + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return $errorflag; + } + } /** diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 82753d08590..7293fd10e90 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -61,6 +61,8 @@ class AdherentType extends CommonObject public $vote; /** @var bool Email sent during validation */ public $mail_valid; + /** @var array Array of members */ + public $members=array(); /** @@ -250,83 +252,137 @@ class AdherentType extends CommonObject } } - /** - * Fonction qui permet de recuperer le status de l'adherent - * - * @param int $rowid Id of member type to load - * @return int <0 if KO, >0 if OK - */ - function fetch($rowid) - { - $sql = "SELECT d.rowid, d.libelle as label, d.statut, d.subscription, d.mail_valid, d.note, d.vote"; - $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d"; - $sql .= " WHERE d.rowid = ".$rowid; + /** + * Fonction qui permet de recuperer le status de l'adherent + * + * @param int $rowid Id of member type to load + * @param bool $load_members Load members or not + * @return int <0 if KO, >0 if OK + */ + function fetch($rowid, $load_members = true) + { + $sql = "SELECT d.rowid, d.libelle as label, d.statut, d.subscription, d.mail_valid, d.note, d.vote"; + $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d"; + $sql .= " WHERE d.rowid = ".$rowid; - dol_syslog("Adherent_type::fetch", LOG_DEBUG); + dol_syslog("Adherent_type::fetch", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - $obj = $this->db->fetch_object($resql); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); - $this->id = $obj->rowid; - $this->ref = $obj->rowid; - $this->label = $obj->label; - $this->statut = $obj->statut; - $this->subscription = $obj->subscription; - $this->mail_valid = $obj->mail_valid; - $this->note = $obj->note; - $this->vote = $obj->vote; - } - return 1; - } - else - { - $this->error=$this->db->lasterror(); - return -1; - } - } + $this->id = $obj->rowid; + $this->ref = $obj->rowid; + $this->label = $obj->label; + $this->statut = $obj->statut; + $this->subscription = $obj->subscription; + $this->mail_valid = $obj->mail_valid; + $this->note = $obj->note; + $this->vote = $obj->vote; - /** - * Return list of members' type - * - * @return array List of types of members - */ - function liste_array() - { - global $conf,$langs; + if ($load_members) { + $this->members=$this->listMembersForMemberType(); + } + } - $adherenttypes = array(); + return 1; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } - $sql = "SELECT rowid, libelle as label"; - $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type"; - $sql.= " WHERE entity IN (".getEntity('adherent').")"; + /** + * Return list of members' type + * + * @return array List of types of members + */ + function liste_array() + { + global $conf,$langs; - $resql=$this->db->query($sql); - if ($resql) - { - $nump = $this->db->num_rows($resql); + $adherenttypes = array(); - if ($nump) - { - $i = 0; - while ($i < $nump) - { - $obj = $this->db->fetch_object($resql); + $sql = "SELECT rowid, libelle as label"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type"; + $sql.= " WHERE entity IN (".getEntity('adherent').")"; - $adherenttypes[$obj->rowid] = $langs->trans($obj->label); - $i++; - } - } - } - else - { - print $this->db->error(); - } - return $adherenttypes; - } + $resql=$this->db->query($sql); + if ($resql) + { + $nump = $this->db->num_rows($resql); + + if ($nump) + { + $i = 0; + while ($i < $nump) + { + $obj = $this->db->fetch_object($resql); + + $adherenttypes[$obj->rowid] = $langs->trans($obj->label); + $i++; + } + } + } + else + { + print $this->db->error(); + } + return $adherenttypes; + } + + /** + * Return array of Member objects for member type this->id (or all if this->id not defined) + * + * @param string $excludefilter Filter to exclude + * @param int $mode 0=Return array of member instance, 1=Return array of members id only + * @return mixed Array of members or -1 on error + */ + function listMembersForMemberType($excludefilter='', $mode=0) + { + global $conf, $user; + + $ret=array(); + + $sql = "SELECT a.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; + $sql.= " WHERE a.entity IN (".getEntity('member').")"; + $sql.= " AND a.fk_adherent_type = ".$this->id; + if (! empty($excludefilter)) $sql.=' AND ('.$excludefilter.')'; + + dol_syslog(get_class($this)."::listUsersForGroup", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { + if (! array_key_exists($obj->rowid, $ret)) + { + if ($mode != 1) + { + $memberstatic=new Adherent($this->db); + $memberstatic->fetch($obj->rowid); + $ret[$obj->rowid]=$memberstatic; + } + else $ret[$obj->rowid]=$obj->rowid; + } + } + + $this->db->free($resql); + + return $ret; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } /** * Return clicable name (with picto eventually) @@ -445,60 +501,63 @@ class AdherentType extends CommonObject ); } - /** - * getMailOnValid - * - * @return string Return mail model - */ - function getMailOnValid() - { - global $conf; + /** + * getMailOnValid + * + * @return string Return mail model + */ + function getMailOnValid() + { + global $conf; - if (! empty($this->mail_valid) && trim(dol_htmlentitiesbr_decode($this->mail_valid))) - { - return $this->mail_valid; - } - else - { - return $conf->global->ADHERENT_MAIL_VALID; - } - } + if (! empty($this->mail_valid) && trim(dol_htmlentitiesbr_decode($this->mail_valid))) + { + return $this->mail_valid; + } + else + { + return $conf->global->ADHERENT_MAIL_VALID; + } + } - /** - * getMailOnSubscription - * - * @return string Return mail model - */ - function getMailOnSubscription() - { - global $conf; - // mail_subscription not defined so never used - if (! empty($this->mail_subscription) && trim(dol_htmlentitiesbr_decode($this->mail_subscription))) // Property not yet defined - { - return $this->mail_subscription; - } - else - { - return $conf->global->ADHERENT_MAIL_COTIS; - } - } + /** + * getMailOnSubscription + * + * @return string Return mail model + */ + function getMailOnSubscription() + { + global $conf; + + // mail_subscription not defined so never used + if (! empty($this->mail_subscription) && trim(dol_htmlentitiesbr_decode($this->mail_subscription))) // Property not yet defined + { + return $this->mail_subscription; + } + else + { + return $conf->global->ADHERENT_MAIL_COTIS; + } + } + + /** + * getMailOnResiliate + * + * @return string Return mail model + */ + function getMailOnResiliate() + { + global $conf; + + // NOTE mail_resiliate not defined so never used + if (! empty($this->mail_resiliate) && trim(dol_htmlentitiesbr_decode($this->mail_resiliate))) // Property not yet defined + { + return $this->mail_resiliate; + } + else + { + return $conf->global->ADHERENT_MAIL_RESIL; + } + } - /** - * getMailOnResiliate - * - * @return string Return mail model - */ - function getMailOnResiliate() - { - global $conf; - // NOTE mail_resiliate not defined so never used - if (! empty($this->mail_resiliate) && trim(dol_htmlentitiesbr_decode($this->mail_resiliate))) // Property not yet defined - { - return $this->mail_resiliate; - } - else - { - return $conf->global->ADHERENT_MAIL_RESIL; - } - } } diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 3d4fb786295..b59d8b7530d 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -113,7 +113,24 @@ if ($action == 'add' && $user->rights->adherent->configurer) $ret = $extrafields->setOptionalsFromPost($extralabels,$object); if ($ret < 0) $error++; - if ($object->label) + if (empty($object->label)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")), null, 'errors'); + } + else { + $sql = "SELECT libelle FROM ".MAIN_DB_PREFIX."adherent_type WHERE libelle='".$db->escape($object->label)."'"; + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + } + if ($num) { + $error++; + $langs->load("errors"); + setEventMessages($langs->trans("ErrorLabelAlreadyExists",$login), null, 'errors'); + } + } + + if (! $error) { $id=$object->create($user); if ($id > 0) @@ -123,13 +140,12 @@ if ($action == 'add' && $user->rights->adherent->configurer) } else { - $mesg=$object->error; + setEventMessages($object->error, $object->errors, 'errors'); $action = 'create'; } } else { - $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")); $action = 'create'; } } @@ -138,6 +154,8 @@ if ($action == 'update' && $user->rights->adherent->configurer) { $object->fetch($rowid); + $object->oldcopy = clone $object; + $object->label = trim($label); $object->subscription = (int) trim($subscription); $object->note = trim($comment); diff --git a/htdocs/adherents/type_ldap.php b/htdocs/adherents/type_ldap.php new file mode 100644 index 00000000000..e610f651df5 --- /dev/null +++ b/htdocs/adherents/type_ldap.php @@ -0,0 +1,189 @@ + + * Copyright (C) 2006-2017 Regis Houssin + * + * 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/adherents/type_ldap.php + * \ingroup ldap + * \brief Page fiche LDAP members types + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/ldap.lib.php'; + +$langs->load("members"); +$langs->load("admin"); +$langs->load("ldap"); + +$id = GETPOST('rowid', 'int'); +$action = GETPOST('action','alpha'); + +// Security check +$result=restrictedArea($user,'adherent',$id,'adherent_type'); + +$object = new AdherentType($db); +$object->fetch($id); + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('membertypeldapcard','globalcard')); + +/* + * Actions + */ + + +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + if ($action == 'dolibarr2ldap') + { + $ldap = new Ldap(); + $result = $ldap->connect_bind(); + + if ($result > 0) + { + $info = $object->_load_ldap_info(); + $dn = $object->_load_ldap_dn($info); + $olddn = $dn; // We can say that old dn = dn as we force synchro + + $result = $ldap->update($dn, $info, $user, $olddn); + } + + if ($result >= 0) { + setEventMessages($langs->trans("MemberTypeSynchronized"), null, 'mesgs'); + } + else { + setEventMessages($ldap->error, $ldap->errors, 'errors'); + } + } +} + +/* + * View + */ + +llxHeader(); + +$form = new Form($db); + +$head = member_type_prepare_head($object); + +dol_fiche_head($head, 'ldap', $langs->trans("MemberType"), -1, 'group'); + +$linkback = ''.$langs->trans("BackToList").''; + +dol_banner_tab($object, 'rowid', $linkback); + +print '
'; +print '
'; + +print ''; + +// LDAP DN +print '\n"; + +// LDAP Cle +print '\n"; + +// LDAP Server +print '\n"; +print '\n"; +print '\n"; +print '\n"; +print '\n"; + +print '
LDAP '.$langs->trans("LDAPMemberTypeDn").''.$conf->global->LDAP_MEMBER_TYPE_DN."
LDAP '.$langs->trans("LDAPNamingAttribute").''.$conf->global->LDAP_KEY_MEMBERS_TYPES."
LDAP '.$langs->trans("Type").''.$conf->global->LDAP_SERVER_TYPE."
LDAP '.$langs->trans("Version").''.$conf->global->LDAP_SERVER_PROTOCOLVERSION."
LDAP '.$langs->trans("LDAPPrimaryServer").''.$conf->global->LDAP_SERVER_HOST."
LDAP '.$langs->trans("LDAPSecondaryServer").''.$conf->global->LDAP_SERVER_HOST_SLAVE."
LDAP '.$langs->trans("LDAPServerPort").''.$conf->global->LDAP_SERVER_PORT."
'; + +print '
'; + +dol_fiche_end(); + +/* + * Barre d'actions + */ + +print '
'; + +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == 1) +{ + print ''.$langs->trans("ForceSynchronize").''; +} + +print "
\n"; + +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == 1) print "
\n"; + + + +// Affichage attributs LDAP +print load_fiche_titre($langs->trans("LDAPInformationsForThisMemberType")); + +print ''; + +print ''; +print ''; +print ''; +print ''; + +// Lecture LDAP +$ldap=new Ldap(); +$result=$ldap->connect_bind(); +if ($result > 0) +{ + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info,1); + $search = "(".$object->_load_ldap_dn($info,2).")"; + $records = $ldap->getAttribute($dn,$search); + + //print_r($records); + + // Affichage arbre + if ((! is_numeric($records) || $records != 0) && (! isset($records['count']) || $records['count'] > 0)) + { + if (! is_array($records)) + { + print ''; + } + else + { + $result=show_ldap_content($records,0,$records['count'],true); + } + } + else + { + print ''; + } + + $ldap->unbind(); + $ldap->close(); +} +else +{ + setEventMessages($ldap->error, $ldap->errors, 'errors'); +} + +print '
'.$langs->trans("LDAPAttributes").''.$langs->trans("Value").'
'.$langs->trans("ErrorFailedToReadLDAP").'
'.$langs->trans("LDAPRecordNotFound").' (dn='.$dn.' - search='.$search.')
'; + +llxFooter(); +$db->close(); diff --git a/htdocs/admin/ldap.php b/htdocs/admin/ldap.php index d5720835f3c..77fdf6fc579 100644 --- a/htdocs/admin/ldap.php +++ b/htdocs/admin/ldap.php @@ -68,6 +68,7 @@ if (empty($reshook)) if (! dolibarr_set_const($db, 'LDAP_SYNCHRO_ACTIVE',GETPOST("activesynchro"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_CONTACT_ACTIVE',GETPOST("activecontact"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_MEMBER_ACTIVE',GETPOST("activemembers"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_ACTIVE',GETPOST("activememberstypes"),'chaine',0,'',$conf->entity)) $error++; if (! $error) { @@ -135,7 +136,6 @@ print ''; // Synchro contact active if (! empty($conf->societe->enabled)) { - print ''.$langs->trans("LDAPDnContactActive").''; $arraylist=array(); $arraylist['0']=$langs->trans("No"); @@ -147,7 +147,6 @@ if (! empty($conf->societe->enabled)) // Synchro member active if (! empty($conf->adherent->enabled)) { - print ''.$langs->trans("LDAPDnMemberActive").''; $arraylist=array(); $arraylist['0']=$langs->trans("No"); @@ -157,6 +156,18 @@ if (! empty($conf->adherent->enabled)) print ''.$langs->trans("LDAPDnMemberActiveExample").''; } +// Synchro member type active +if (! empty($conf->adherent->enabled)) +{ + print ''.$langs->trans("LDAPDnMemberTypeActive").''; + $arraylist=array(); + $arraylist['0']=$langs->trans("No"); + $arraylist['1']=$langs->trans("DolibarrToLDAP"); + //$arraylist['ldap2dolibarr']=$langs->trans("LDAPToDolibarr").' ('.$langs->trans("SupportedForLDAPImportScriptOnly").')'; + print $form->selectarray('activememberstypes',$arraylist,$conf->global->LDAP_MEMBER_TYPE_ACTIVE); + print ''.$langs->trans("LDAPDnMemberTypeActiveExample").''; +} + // Fields from hook $parameters=array(); $reshook=$hookmanager->executeHooks('addAdminLdapOptions',$parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index fc68d815439..d431a7aaf30 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -220,8 +220,9 @@ if (function_exists("ldap_connect")) $dn=$object->_load_ldap_dn($info); // Get a gid number for objectclass PosixGroup - if(in_array('posixGroup',$info['objectclass'])) - $info['gidNumber'] = $ldap->getNextGroupGid(); + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); + } $result1=$ldap->delete($dn); // To be sure to delete existing records $result2=$ldap->add($dn,$info,$user); // Now the test diff --git a/htdocs/admin/ldap_members_types.php b/htdocs/admin/ldap_members_types.php new file mode 100644 index 00000000000..47286dc98da --- /dev/null +++ b/htdocs/admin/ldap_members_types.php @@ -0,0 +1,252 @@ + + * Copyright (C) 2004 Sebastien Di Cintio + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2005-2017 Regis Houssin + * Copyright (C) 2006-2011 Laurent Destailleur + * Copyright (C) 2011-2013 Juanjo Menent + * + * 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/admin/ldap_members_types.php + * \ingroup ldap + * \brief Page to setup LDAP synchronization for members types + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/ldap.lib.php'; + +$langs->load("admin"); +$langs->load("errors"); + +if (!$user->admin) + accessforbidden(); + +$action = GETPOST('action','aZ09'); + + +/* + * Actions + */ + +if ($action == 'setvalue' && $user->admin) +{ + $error=0; + $db->begin(); + + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_DN',GETPOST("membertype"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_OBJECT_CLASS',GETPOST("objectclass"),'chaine',0,'',$conf->entity)) $error++; + + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_FULLNAME',GETPOST("fieldfullname"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_DESCRIPTION',GETPOST("fielddescription"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS',GETPOST("fieldmembertypemembers"),'chaine',0,'',$conf->entity)) $error++; + + // This one must be after the others + $valkey=''; + $key=GETPOST("key"); + if ($key) $valkey=$conf->global->$key; + if (! dolibarr_set_const($db, 'LDAP_KEY_MEMBERS_TYPES',$valkey,'chaine',0,'',$conf->entity)) $error++; + + if (! $error) + { + $db->commit(); + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + $db->rollback(); + dol_print_error($db); + } +} + + + +/* + * View + */ + +llxHeader('',$langs->trans("LDAPSetup"),'EN:Module_LDAP_En|FR:Module_LDAP|ES:Módulo_LDAP'); +$linkback=''.$langs->trans("BackToModuleList").''; + +print load_fiche_titre($langs->trans("LDAPSetup"),$linkback,'title_setup'); + +$head = ldap_prepare_head(); + +// Test si fonction LDAP actives +if (! function_exists("ldap_connect")) +{ + setEventMessages($langs->trans("LDAPFunctionsNotAvailableOnPHP"), null, 'errors'); +} + +dol_fiche_head($head, 'memberstypes', $langs->trans("LDAPSetup"), -1); + + +print $langs->trans("LDAPDescMembersTypes").'
'; +print '
'; + + +print '
'; +print ''; + +$form=new Form($db); + +print ''; +$var=true; + +print ''; +print ''; +print "\n"; + +// DN pour les types de membres + +print ''; +print ''; +print ''; + +// List of object class used to define attributes in structure + +print ''; +print ''; +print ''; + +print '
'.$langs->trans("LDAPSynchronizeMembersTypes").'
'.$langs->trans("LDAPMemberTypeDn").''; +print ''; +print ''.$langs->trans("LDAPMemberTypepDnExample").' 
'.$langs->trans("LDAPMemberTypeObjectClassList").''; +print ''; +print ''.$langs->trans("LDAPMemberTypeObjectClassListExample").' 
'; +print '
'; +print ''; +$var=true; + +print ''; +print ''; +print ''; +print ''; +print "\n"; + +// Filtre + +// Common name + +print ''; +print '"; +print ''; + +// Description + +print ''; +print '"; +print ''; + +// User group + +print ''; +print '"; +print ''; + +print '
'.$langs->trans("LDAPDolibarrMapping").''.$langs->trans("LDAPLdapMapping").''.$langs->trans("LDAPNamingAttribute").'
'.$langs->trans("LDAPFieldName").''; +print ''; +print ''.$langs->trans("LDAPFieldCommonNameExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBERS_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME)?' checked':'').">
'.$langs->trans("LDAPFieldDescription").''; +print ''; +print ''.$langs->trans("LDAPFieldDescriptionExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBER_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION)?' checked':'').">
'.$langs->trans("LDAPFieldGroupMembers").''; +print ''; +print ''.$langs->trans("LDAPFieldGroupMembersExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBERS_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS)?' checked':'').">
'; + +print info_admin($langs->trans("LDAPDescValues")); + +dol_fiche_end(); + +print '
'; + +print '
'; + + +/* + * Test de la connexion + */ +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') +{ + $butlabel=$langs->trans("LDAPTestSynchroMemberType"); + $testlabel='testmembertype'; + $key=$conf->global->LDAP_KEY_MEMBERS_TYPES; + $dn=$conf->global->LDAP_MEMBER_TYPE_DN; + $objectclass=$conf->global->LDAP_MEMBER_TYPE_OBJECT_CLASS; + + show_ldap_test_button($butlabel,$testlabel,$key,$dn,$objectclass); +} + +if (function_exists("ldap_connect")) +{ + if ($_GET["action"] == 'testmembertype') + { + // Creation objet + $object=new AdherentType($db); + $object->initAsSpecimen(); + + // Test synchro + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_MEMBERS_TYPES'); + } + + $result1=$ldap->delete($dn); // To be sure to delete existing records + $result2=$ldap->add($dn,$info,$user); // Now the test + $result3=$ldap->delete($dn); // Clean what we did + + if ($result2 > 0) + { + print img_picto('','info').' '; + print ''.$langs->trans("LDAPSynchroOK").'
'; + } + else + { + print img_picto('','error').' '; + print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); + print ': '.$ldap->error; + print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; + } + + print "
\n"; + print "LDAP input file used for test:

\n"; + print nl2br($ldap->dump_content($dn,$info)); + print "\n
"; + } + else + { + print img_picto('','error').' '; + print ''.$langs->trans("LDAPSynchroKO"); + print ': '.$ldap->error; + print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; + } + } +} + +llxFooter(); +$db->close(); diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index ad224fec97d..8dba7f0e8c5 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -254,6 +254,7 @@ class Conf if (! isset($this->global->LDAP_KEY_GROUPS)) $this->global->LDAP_KEY_GROUPS=$this->global->LDAP_FIELD_FULLNAME; if (! isset($this->global->LDAP_KEY_CONTACTS)) $this->global->LDAP_KEY_CONTACTS=$this->global->LDAP_FIELD_FULLNAME; if (! isset($this->global->LDAP_KEY_MEMBERS)) $this->global->LDAP_KEY_MEMBERS=$this->global->LDAP_FIELD_FULLNAME; + if (! isset($this->global->LDAP_KEY_MEMBERS_TYPES)) $this->global->LDAP_KEY_MEMBERS_TYPES=$this->global->LDAP_FIELD_FULLNAME; // Load translation object with current language if (empty($this->global->MAIN_LANG_DEFAULT)) $this->global->MAIN_LANG_DEFAULT="en_US"; diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 58eedc0ad9d..790772a9803 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -1411,13 +1411,16 @@ class Ldap /** * Return available value of group GID * + * @param string Key of group * @return int gid number */ - function getNextGroupGid() + function getNextGroupGid($keygroup='LDAP_KEY_GROUPS') { global $conf; - $search='('.$conf->global->LDAP_KEY_GROUPS.'=*)'; + if (empty($keygroup)) $keygroup='LDAP_KEY_GROUPS'; + + $search='('.$conf->global->$keygroup.'=*)'; $result = $this->search($this->groups,$search); if($result) { diff --git a/htdocs/core/lib/ldap.lib.php b/htdocs/core/lib/ldap.lib.php index f684af594e5..3db36723b32 100644 --- a/htdocs/core/lib/ldap.lib.php +++ b/htdocs/core/lib/ldap.lib.php @@ -75,6 +75,14 @@ function ldap_prepare_head() $h++; } + if (! empty($conf->adherent->enabled) && ! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE)) + { + $head[$h][0] = DOL_URL_ROOT."/admin/ldap_members_types.php"; + $head[$h][1] = $langs->trans("LDAPMembersTypesSynchro"); + $head[$h][2] = 'memberstypes'; + $h++; + } + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab diff --git a/htdocs/core/lib/member.lib.php b/htdocs/core/lib/member.lib.php index 472c040e450..7e5e5e0c604 100644 --- a/htdocs/core/lib/member.lib.php +++ b/htdocs/core/lib/member.lib.php @@ -124,6 +124,16 @@ function member_type_prepare_head(AdherentType $object) $head[$h][2] = 'card'; $h++; + if (! empty($conf->ldap->enabled) && ! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE)) + { + $langs->load("ldap"); + + $head[$h][0] = DOL_URL_ROOT.'/adherents/type_ldap.php?rowid='.$object->id; + $head[$h][1] = $langs->trans("LDAPCard"); + $head[$h][2] = 'ldap'; + $h++; + } + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab diff --git a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php index 9c5112dd68a..05a9a5a1b20 100644 --- a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php +++ b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php @@ -271,7 +271,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers // Get a gid number for objectclass PosixGroup if (in_array('posixGroup',$info['objectclass'])) { - $info['gidNumber'] = $ldap->getNextGroupGid(); + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); } $result=$ldap->add($dn,$info,$user); @@ -429,6 +429,33 @@ class InterfaceLdapsynchro extends DolibarrTriggers $dn=$object->_load_ldap_dn($info); $result=$ldap->add($dn,$info,$user); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $membertype=new AdherentType($this->db); + if ($object->typeid > 0) + { + $membertype->fetch($object->typeid); + + $oldinfo=$membertype->_load_ldap_info(); + $olddn=$membertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$membertype->_load_ldap_dn($oldinfo,1); + $search = "(".$membertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$membertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$membertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } } if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; @@ -518,6 +545,59 @@ class InterfaceLdapsynchro extends DolibarrTriggers $dn=$object->_load_ldap_dn($info); $result=$ldap->update($dn,$info,$user,$olddn); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + if ($object->oldcopy->typeid != $object->typeid) + { + /* + * Add member in new member type + */ + $newmembertype=new AdherentType($this->db); + $newmembertype->fetch($object->typeid); + + $oldinfo=$newmembertype->_load_ldap_info(); + $olddn=$newmembertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$newmembertype->_load_ldap_dn($oldinfo,1); + $search = "(".$newmembertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$newmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$newmembertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + + /* + * Remove member in old member type + */ + $oldmembertype=new AdherentType($this->db); + $oldmembertype->fetch($object->oldcopy->typeid); + + $oldinfo=$oldmembertype->_load_ldap_info(); + $olddn=$oldmembertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$oldmembertype->_load_ldap_dn($oldinfo,1); + $search = "(".$oldmembertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$oldmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$oldmembertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } } if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; @@ -585,13 +665,125 @@ class InterfaceLdapsynchro extends DolibarrTriggers $dn=$object->_load_ldap_dn($info); $result=$ldap->delete($dn); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + if ($object->typeid > 0) + { + /* + * Remove member in member type + */ + $membertype=new AdherentType($this->db); + $membertype->fetch($object->typeid); + + $oldinfo=$membertype->_load_ldap_info(); + $olddn=$membertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$membertype->_load_ldap_dn($oldinfo,1); + $search = "(".$membertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$membertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$membertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } } if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } - } + } - return $result; - } + // Members types + elseif ($action == 'MEMBER_TYPE_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_MEMBERS_TYPE'); + } + + $result=$ldap->add($dn,$info,$user); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_TYPE_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_TYPE_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->delete($dn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + return $result; + } } diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 0fe1040b389..759e7402515 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1253,6 +1253,7 @@ LDAPUsersSynchro=Users LDAPGroupsSynchro=Groups LDAPContactsSynchro=Contacts LDAPMembersSynchro=Members +LDAPMembersTypesSynchro=Members types LDAPSynchronization=LDAP synchronisation LDAPFunctionsNotAvailableOnPHP=LDAP functions are not available on your PHP LDAPToDolibarr=LDAP -> Dolibarr @@ -1261,7 +1262,8 @@ LDAPNamingAttribute=Key in LDAP LDAPSynchronizeUsers=Organization of users in LDAP LDAPSynchronizeGroups=Organization of groups in LDAP LDAPSynchronizeContacts=Organization of contacts in LDAP -LDAPSynchronizeMembers=Organization of foundation's members in LDAP +LDAPSynchronizeMembers=Organization of foundation's members in LDAP +LDAPSynchronizeMembersTypes=Organization of foundation's members types in LDAP LDAPPrimaryServer=Primary server LDAPSecondaryServer=Secondary server LDAPServerPort=Server port @@ -1285,12 +1287,18 @@ LDAPDnContactActive=Contacts' synchronization LDAPDnContactActiveExample=Activated/Unactivated synchronization LDAPDnMemberActive=Members' synchronization LDAPDnMemberActiveExample=Activated/Unactivated synchronization +LDAPDnMemberTypeActive=Members types' synchronization +LDAPDnMemberTypeActiveExample=Activated/Unactivated synchronization LDAPContactDn=Dolibarr contacts' DN LDAPContactDnExample=Complete DN (ex: ou=contacts,dc=example,dc=com) LDAPMemberDn=Dolibarr members DN LDAPMemberDnExample=Complete DN (ex: ou=members,dc=example,dc=com) LDAPMemberObjectClassList=List of objectClass LDAPMemberObjectClassListExample=List of objectClass defining record attributes (ex: top,inetOrgPerson or top,user for active directory) +LDAPMemberTypeDn=Dolibarr members types DN +LDAPMemberTypepDnExample=Complete DN (ex: ou=memberstypes,dc=example,dc=com) +LDAPMemberTypeObjectClassList=List of objectClass +LDAPMemberTypeObjectClassListExample=List of objectClass defining record attributes (ex: top,groupOfUniqueNames) LDAPUserObjectClassList=List of objectClass LDAPUserObjectClassListExample=List of objectClass defining record attributes (ex: top,inetOrgPerson or top,user for active directory) LDAPGroupObjectClassList=List of objectClass @@ -1302,6 +1310,7 @@ LDAPTestSynchroContact=Test contacts synchronization LDAPTestSynchroUser=Test user synchronization LDAPTestSynchroGroup=Test group synchronization LDAPTestSynchroMember=Test member synchronization +LDAPTestSynchroMemberType=Test member type synchronization LDAPTestSearch= Test a LDAP search LDAPSynchroOK=Synchronization test successful LDAPSynchroKO=Failed synchronization test @@ -1367,6 +1376,7 @@ LDAPDescContact=This page allows you to define LDAP attributes name in LDAP tree LDAPDescUsers=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr users. LDAPDescGroups=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr groups. LDAPDescMembers=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr members module. +LDAPDescMembersTypes=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr members types. LDAPDescValues=Example values are designed for OpenLDAP with following loaded schemas: core.schema, cosine.schema, inetorgperson.schema). If you use thoose values and OpenLDAP, modify your LDAP config file slapd.conf to have all thoose schemas loaded. ForANonAnonymousAccess=For an authenticated access (for a write access for example) PerfDolibarr=Performance setup/optimizing report diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 003eedeac8a..a4777f3ae09 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -104,6 +104,7 @@ ErrorForbidden2=Permission for this login can be defined by your Dolibarr admini ErrorForbidden3=It seems that Dolibarr is not used through an authenticated session. Take a look at Dolibarr setup documentation to know how to manage authentications (htaccess, mod_auth or other...). ErrorNoImagickReadimage=Class Imagick is not found in this PHP. No preview can be available. Administrators can disable this tab from menu Setup - Display. ErrorRecordAlreadyExists=Record already exists +ErrorLabelAlreadyExists=This label already exists ErrorCantReadFile=Failed to read file '%s' ErrorCantReadDir=Failed to read directory '%s' ErrorBadLoginPassword=Bad value for login or password diff --git a/htdocs/langs/en_US/ldap.lang b/htdocs/langs/en_US/ldap.lang index 42e699de311..d6360f3e540 100644 --- a/htdocs/langs/en_US/ldap.lang +++ b/htdocs/langs/en_US/ldap.lang @@ -6,6 +6,7 @@ LDAPInformationsForThisContact=Information in LDAP database for this contact LDAPInformationsForThisUser=Information in LDAP database for this user LDAPInformationsForThisGroup=Information in LDAP database for this group LDAPInformationsForThisMember=Information in LDAP database for this member +LDAPInformationsForThisMemberType=Information in LDAP database for this member type LDAPAttributes=LDAP attributes LDAPCard=LDAP card LDAPRecordNotFound=Record not found in LDAP database @@ -20,6 +21,7 @@ LDAPFieldSkypeExample=Example : skypeName UserSynchronized=User synchronized GroupSynchronized=Group synchronized MemberSynchronized=Member synchronized +MemberTypeSynchronized=Member type synchronized ContactSynchronized=Contact synchronized ForceSynchronize=Force synchronizing Dolibarr -> LDAP ErrorFailedToReadLDAP=Failed to read LDAP database. Check LDAP module setup and database accessibility. diff --git a/htdocs/user/group/ldap.php b/htdocs/user/group/ldap.php index b7b1597ea74..ae0d974be9a 100644 --- a/htdocs/user/group/ldap.php +++ b/htdocs/user/group/ldap.php @@ -63,30 +63,31 @@ $object->getrights(); if ($action == 'dolibarr2ldap') { - $db->begin(); - $ldap=new Ldap(); $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - // Get a gid number for objectclass PosixGroup - if(in_array('posixGroup',$info['objectclass'])) - $info['gidNumber'] = $ldap->getNextGroupGid(); + if ($result > 0) + { + $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We can say that old dn = dn as we force synchro + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); + } - $result=$ldap->update($dn,$info,$user,$olddn); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We can say that old dn = dn as we force synchro + + $result=$ldap->update($dn,$info,$user,$olddn); + } if ($result >= 0) { setEventMessages($langs->trans("GroupSynchronized"), null, 'mesgs'); - $db->commit(); } else { setEventMessages($ldap->error, $ldap->errors, 'errors'); - $db->rollback(); } } From d9b3a4e45673667a8d4a32cebef1c44fdf455607 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sat, 16 Sep 2017 21:58:05 +0200 Subject: [PATCH 016/177] Fix: phpcs --- htdocs/core/class/ldap.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 790772a9803..64e6f9fd5ef 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -1411,8 +1411,8 @@ class Ldap /** * Return available value of group GID * - * @param string Key of group - * @return int gid number + * @param string $keygroup Key of group + * @return int gid number */ function getNextGroupGid($keygroup='LDAP_KEY_GROUPS') { From 1f88e624c26d95ec8abbdb87b2c9c97acffd4f9c Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sun, 17 Sep 2017 10:42:00 +0200 Subject: [PATCH 017/177] Fix: add ldap import/export script --- htdocs/admin/ldap.php | 2 +- .../sync_members_types_dolibarr2ldap.php | 131 +++++++++++ .../sync_members_types_ldap2dolibarr.php | 221 ++++++++++++++++++ test/phpunit/AdherentTest.php | 4 +- 4 files changed, 355 insertions(+), 3 deletions(-) create mode 100755 scripts/members/sync_members_types_dolibarr2ldap.php create mode 100755 scripts/members/sync_members_types_ldap2dolibarr.php diff --git a/htdocs/admin/ldap.php b/htdocs/admin/ldap.php index 77fdf6fc579..f9b863e487e 100644 --- a/htdocs/admin/ldap.php +++ b/htdocs/admin/ldap.php @@ -163,7 +163,7 @@ if (! empty($conf->adherent->enabled)) $arraylist=array(); $arraylist['0']=$langs->trans("No"); $arraylist['1']=$langs->trans("DolibarrToLDAP"); - //$arraylist['ldap2dolibarr']=$langs->trans("LDAPToDolibarr").' ('.$langs->trans("SupportedForLDAPImportScriptOnly").')'; + $arraylist['ldap2dolibarr']=$langs->trans("LDAPToDolibarr").' ('.$langs->trans("SupportedForLDAPImportScriptOnly").')'; print $form->selectarray('activememberstypes',$arraylist,$conf->global->LDAP_MEMBER_TYPE_ACTIVE); print ''.$langs->trans("LDAPDnMemberTypeActiveExample").''; } diff --git a/scripts/members/sync_members_types_dolibarr2ldap.php b/scripts/members/sync_members_types_dolibarr2ldap.php new file mode 100755 index 00000000000..939a98c8728 --- /dev/null +++ b/scripts/members/sync_members_types_dolibarr2ldap.php @@ -0,0 +1,131 @@ +#!/usr/bin/env php + + * Copyright (C) 2006 Laurent Destailleur + * Copyright (C) 2017 Regis Houssin + * + * 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 scripts/user/sync_members_types_dolibarr2ldap.php + * \ingroup ldap core + * \brief Script de mise a jour des types de membres dans LDAP depuis base Dolibarr + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit(-1); +} + +if (! isset($argv[1]) || ! $argv[1]) { + print "Usage: ".$script_file." now\n"; + exit(-1); +} +$now=$argv[1]; + +require_once($path."../../htdocs/master.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php"); +require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php"); + +// Global variables +$version=DOL_VERSION; +$error=0; + + +/* + * Main + */ + +@set_time_limit(0); +print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; +dol_syslog($script_file." launched with arg ".join(',',$argv)); + +/* +if (! $conf->global->LDAP_SYNCHRO_ACTIVE) +{ + print $langs->trans("LDAPSynchronizationNotSetupInDolibarr"); + exit(-1); +} +*/ + +$sql = "SELECT rowid"; +$sql .= " FROM ".MAIN_DB_PREFIX."adherent_type"; + +$resql = $db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + $i = 0; + + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + while ($i < $num) + { + $ldap->error=""; + + $obj = $db->fetch_object($resql); + + $membertype = new AdherentType($db); + $membertype->id = $obj->rowid; + $membertype->fetch($membertype->id); + + print $langs->trans("UpdateMemberType")." rowid=".$membertype->id." ".$membertype-label; + + $oldobject=$membertype; + + $oldinfo=$membertype->_load_ldap_info(); + $olddn=$membertype->_load_ldap_dn($oldinfo); + + $info=$membertype->_load_ldap_info(); + $dn=$membertype->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); // Wil fail if already exists + $result=$ldap->update($dn,$info,$user,$olddn); + if ($result > 0) + { + print " - ".$langs->trans("OK"); + } + else + { + $error++; + print " - ".$langs->trans("KO").' - '.$ldap->error; + } + print "\n"; + + $i++; + } + + $ldap->unbind(); + $ldap->close(); + } + else { + print $ldap->error; + } +} +else +{ + dol_print_error($db); +} + +exit($error); diff --git a/scripts/members/sync_members_types_ldap2dolibarr.php b/scripts/members/sync_members_types_ldap2dolibarr.php new file mode 100755 index 00000000000..fb8fb160d36 --- /dev/null +++ b/scripts/members/sync_members_types_ldap2dolibarr.php @@ -0,0 +1,221 @@ +#!/usr/bin/env php + + * Copyright (C) 2006-2012 Laurent Destailleur + * Copyright (C) 2013 Maxime Kohlhaas + * Copyright (C) 2017 Regis Houssin + * + * 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 scripts/user/sync_members_types_ldap2dolibarr.php + * \ingroup ldap member + * \brief Script to update members types into Dolibarr from LDAP + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit(-1); +} + +require_once($path."../../htdocs/master.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php"); +require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php"); + +$langs->load("main"); +$langs->load("errors"); + + +// Global variables +$version=DOL_VERSION; +$error=0; +$forcecommit=0; +$confirmed=0; + + +/* + * Main + */ + +@set_time_limit(0); +print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; +dol_syslog($script_file." launched with arg ".join(',',$argv)); + +// List of fields to get from LDAP +$required_fields = array( + $conf->global->LDAP_KEY_MEMBERS_TYPES, + $conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME, + $conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION, + $conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS +); + +// Remove from required_fields all entries not configured in LDAP (empty) and duplicated +$required_fields=array_unique(array_values(array_filter($required_fields, "dolValidElement"))); + + +if (! isset($argv[1])) { + //print "Usage: $script_file (nocommitiferror|commitiferror) [id_group]\n"; + print "Usage: $script_file (nocommitiferror|commitiferror) [--server=ldapserverhost] [--excludeuser=user1,user2...] [-y]\n"; + exit(-1); +} + +foreach($argv as $key => $val) +{ + if ($val == 'commitiferror') $forcecommit=1; + if (preg_match('/--server=([^\s]+)$/',$val,$reg)) $conf->global->LDAP_SERVER_HOST=$reg[1]; + if (preg_match('/--excludeuser=([^\s]+)$/',$val,$reg)) $excludeuser=explode(',',$reg[1]); + if (preg_match('/-y$/',$val,$reg)) $confirmed=1; +} + +print "Mails sending disabled (useless in batch mode)\n"; +$conf->global->MAIN_DISABLE_ALL_MAILS=1; // On bloque les mails +print "\n"; +print "----- Synchronize all records from LDAP database:\n"; +print "host=".$conf->global->LDAP_SERVER_HOST."\n"; +print "port=".$conf->global->LDAP_SERVER_PORT."\n"; +print "login=".$conf->global->LDAP_ADMIN_DN."\n"; +print "pass=".preg_replace('/./i','*',$conf->global->LDAP_ADMIN_PASS)."\n"; +print "DN to extract=".$conf->global->LDAP_MEMBER_TYPE_DN."\n"; +print 'Filter=('.$conf->global->LDAP_KEY_MEMBERS_TYPES.'=*)'."\n"; +print "----- To Dolibarr database:\n"; +print "type=".$conf->db->type."\n"; +print "host=".$conf->db->host."\n"; +print "port=".$conf->db->port."\n"; +print "login=".$conf->db->user."\n"; +print "database=".$conf->db->name."\n"; +print "----- Options:\n"; +print "commitiferror=".$forcecommit."\n"; +print "Mapped LDAP fields=".join(',',$required_fields)."\n"; +print "\n"; + +if (! $confirmed) +{ + print "Hit Enter to continue or CTRL+C to stop...\n"; + $input = trim(fgets(STDIN)); +} + +if (empty($conf->global->LDAP_MEMBER_TYPE_DN)) +{ + print $langs->trans("Error").': '.$langs->trans("LDAP setup for members types not defined inside Dolibarr"); + exit(-1); +} + + +$ldap = new Ldap(); +$result = $ldap->connect_bind(); +if ($result >= 0) +{ + $justthese=array(); + + + // We disable synchro Dolibarr-LDAP + $conf->global->LDAP_MEMBER_TYPE_ACTIVE=0; + + $ldaprecords = $ldap->getRecords('*',$conf->global->LDAP_MEMBER_TYPE_DN, $conf->global->LDAP_KEY_MEMBERS_TYPES, $required_fields, 0, array($conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS)); + if (is_array($ldaprecords)) + { + $db->begin(); + + // Warning $ldapuser has a key in lowercase + foreach ($ldaprecords as $key => $ldapgroup) + { + $membertype = new AdherentType($db); + $membertype->fetch('', $ldapgroup[$conf->global->LDAP_KEY_MEMBERS_TYPES]); + $membertype->label = $ldapgroup[$conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME]; + $membertype->description = $ldapgroup[$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION]; + $membertype->entity = $conf->entity; + + //print_r($ldapgroup); + + if ($membertype->id > 0) { // Member type update + print $langs->transnoentities("MemberTypeUpdate").' # '.$key.': name='.$membertype->label; + $res=$membertype->update($user); + + if ($res > 0) + { + print ' --> Updated member type id='.$membertype->id.' name='.$membertype->label; + } + else + { + $error++; + print ' --> '.$res.' '.$membertype->error; + } + print "\n"; + } else { // Member type creation + print $langs->transnoentities("MemberTypeCreate").' # '.$key.': name='.$membertype->label; + $res=$membertype->create($user); + + if ($res > 0) + { + print ' --> Created member type id='.$membertype->id.' name='.$membertype->label; + } + else + { + $error++; + print ' --> '.$res.' '.$membertype->error; + } + print "\n"; + } + + //print_r($membertype); + } + + if (! $error || $forcecommit) + { + if (! $error) print $langs->transnoentities("NoErrorCommitIsDone")."\n"; + else print $langs->transnoentities("ErrorButCommitIsDone")."\n"; + $db->commit(); + } + else + { + print $langs->transnoentities("ErrorSomeErrorWereFoundRollbackIsDone",$error)."\n"; + $db->rollback(); + } + print "\n"; + } + else + { + dol_print_error('',$ldap->error); + $error++; + } +} +else +{ + dol_print_error('',$ldap->error); + $error++; +} + + +exit($error); + + +/** + * Function to say if a value is empty or not + * + * @param string $element Value to test + * @return boolean True of false + */ +function dolValidElement($element) +{ + return (trim($element) != ''); +} + diff --git a/test/phpunit/AdherentTest.php b/test/phpunit/AdherentTest.php index 34ec0a80917..357ae3744e9 100644 --- a/test/phpunit/AdherentTest.php +++ b/test/phpunit/AdherentTest.php @@ -138,8 +138,8 @@ class AdherentTest extends PHPUnit_Framework_TestCase $localobject=new AdherentType($this->savdb); $localobject->statut=1; - $localobject->libelle='Adherent type test'; - $localobject->cotisation=1; + $localobject->label='Adherent type test'; + $localobject->subscription=1; $localobject->vote=1; $result=$localobject->create($user); print __METHOD__." result=".$result."\n"; From 99149b5cfeada8c2062ae969841ef9629c01335c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 17 Sep 2017 21:21:12 +0200 Subject: [PATCH 018/177] Fix box activity again --- htdocs/core/boxes/box_activity.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index a05fcf761b6..7aa5974efbd 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -438,11 +438,6 @@ class box_activity extends ModeleBoxes 'td' => 'align="center"', 'text'=>$langs->trans("NoRecordedInvoices"), ); - } else { - $this->info_box_contents[0][0] = array( - 'td' => '', - 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), - ); } } From f76b675e092ba5053ac3dbffe8f4b1ab5d977bea Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 17 Sep 2017 21:24:30 +0200 Subject: [PATCH 019/177] Fix box activity again --- htdocs/core/boxes/box_activity.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index 7aa5974efbd..2f923855dbb 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -147,7 +147,7 @@ class box_activity extends ModeleBoxes if (! empty($data)) { $j=0; - while ($line < count($data)) + while ($j < count($data)) { $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', @@ -230,7 +230,7 @@ class box_activity extends ModeleBoxes if (! empty($data)) { $j=0; - while ($line < count($data)) { + while ($j < count($data)) { $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', 'url' => DOL_URL_ROOT."/commande/list.php?mainmenu=commercial&leftmenu=orders&viewstatut=".$data[$j]->fk_statut, @@ -315,7 +315,7 @@ class box_activity extends ModeleBoxes if (! empty($data)) { $j=0; - while ($line < count($data)) { + while ($j < count($data)) { $billurl="search_status=2&paye=1&year=".$data[$j]->annee; $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', @@ -400,7 +400,7 @@ class box_activity extends ModeleBoxes $alreadypaid=-1; - while ($line < count($data)) { + while ($j < count($data)) { $billurl="search_status=".$data[$j]->fk_statut."&paye=0"; $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', From eaee8ee5864c0e2b1481adc6530d2a166f885186 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 17 Sep 2017 21:29:25 +0200 Subject: [PATCH 020/177] Fix box activity again --- htdocs/core/boxes/box_activity.php | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index 2f923855dbb..71a9a4e3125 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -77,7 +77,6 @@ class box_activity extends ModeleBoxes include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $totalMnt = 0; $totalnb = 0; $line = 0; $cachetime = 3600; @@ -173,7 +172,6 @@ class box_activity extends ModeleBoxes 'td' => 'class="right"', 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), ); - $totalMnt += $data[$j]->Mnttot; $this->info_box_contents[$line][4] = array( 'td' => 'align="right" width="18"', 'text' => $propalstatic->LibStatut($data[$j]->fk_statut,3), @@ -255,7 +253,6 @@ class box_activity extends ModeleBoxes 'td' => 'class="right"', 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), ); - $totalMnt += $data[$j]->Mnttot; $this->info_box_contents[$line][4] = array( 'td' => 'align="right" width="18"', 'text' => $commandestatic->LibStatut($data[$j]->fk_statut,0,3), @@ -342,10 +339,8 @@ class box_activity extends ModeleBoxes ); // We add only for the current year - if ($data[$j]->annee == date("Y")) { - $totalnb += $data[$j]->nb; - $totalMnt += $data[$j]->Mnttot; - } + $totalnb += $data[$j]->nb; + $this->info_box_contents[$line][4] = array( 'td' => 'align="right" width="18"', 'text' => $facturestatic->LibStatut(1,$data[$j]->fk_statut,3), @@ -396,10 +391,9 @@ class box_activity extends ModeleBoxes } if (! empty($data)) { - $j=0; - $alreadypaid=-1; + $j=0; while ($j < count($data)) { $billurl="search_status=".$data[$j]->fk_statut."&paye=0"; $this->info_box_contents[$line][0] = array( @@ -425,7 +419,6 @@ class box_activity extends ModeleBoxes 'td' => 'class="right"', 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), ); - $totalMnt += $objp->Mnttot; $this->info_box_contents[$line][4] = array( 'td' => 'align="right" width="18"', 'text' => $facturestatic->LibStatut(0,$data[$j]->fk_statut,3, $alreadypaid), From 4043141ae3f3dfbb45c2d89f93fcb758f95a3636 Mon Sep 17 00:00:00 2001 From: TuxGasy Date: Mon, 18 Sep 2017 14:11:21 +0200 Subject: [PATCH 021/177] Allow create shipping if STOCK_SUPPORTS_SERVICES option is enabled --- htdocs/commande/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 4d8bc4335e5..9de9ffed222 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2541,7 +2541,7 @@ if ($action == 'create' && $user->rights->commande->creer) if (! empty($conf->expedition->enabled)) { $numshipping = $object->nb_expedition(); - if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && $object->getNbOfProductsLines() > 0) { + if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES))) { if (($conf->expedition_bon->enabled && $user->rights->expedition->creer) || ($conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer)) { if ($user->rights->expedition->creer) { print ''; From 4c97f5514db91f78e08b087ec3d25582c9822792 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Sep 2017 15:25:04 +0200 Subject: [PATCH 022/177] FIX #7366 renaming table with pgsql --- htdocs/install/mysql/migration/4.0.0-5.0.0.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql index cd535c5c119..42389a5c2dd 100644 --- a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql +++ b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql @@ -4,6 +4,7 @@ -- when current version is 4.0.0 or higher. -- -- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- -- VPGSQL8.2 ALTER SEQUENCE IF EXISTS llx_table_rowid_seq RENAME TO llx_table_new_rowid_seq; -- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; -- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); -- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; @@ -120,6 +121,8 @@ create table llx_expensereport_extrafields ALTER TABLE llx_expensereport_extrafields ADD INDEX idx_expensereport_extrafields (fk_object); ALTER TABLE llx_cotisation RENAME TO llx_subscription; +-- VPGSQL8.2 ALTER SEQUENCE IF EXISTS llx_cotisation_rowid_seq RENAME TO llx_subscription_rowid_seq; + ALTER TABLE llx_subscription ADD UNIQUE INDEX uk_subscription (fk_adherent,dateadh); ALTER TABLE llx_subscription CHANGE COLUMN cotisation subscription real; ALTER TABLE llx_adherent_type CHANGE COLUMN cotisation subscription varchar(3) NOT NULL DEFAULT '1'; From 278bcfa8da6fd13becd9cfeff8a32b359794acae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Sep 2017 15:31:22 +0200 Subject: [PATCH 023/177] FIX #7148 --- htdocs/admin/multicurrency.php | 36 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index b03872a8fbd..9ae20ac06d7 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -61,7 +61,7 @@ if (preg_match('/set_(.*)/',$action,$reg)) dol_print_error($db); } } - + if (preg_match('/del_(.*)/',$action,$reg)) { $code=$reg[1]; @@ -79,7 +79,7 @@ if (preg_match('/del_(.*)/',$action,$reg)) if ($action == 'add_currency') { $langs->loadCacheCurrencies(''); - + $code = GETPOST('code', 'alpha'); $rate = GETPOST('rate', 'alpha'); $currency = new MultiCurrency($db); @@ -96,23 +96,23 @@ if ($action == 'add_currency') elseif ($action == 'update_currency') { $submit = GETPOST('submit', 'alpha'); - + if ($submit == $langs->trans('Modify')) { $fk_multicurrency = GETPOST('fk_multicurrency', 'int'); - $rate = GETPOST('rate', 'float'); + $rate = price2num(GETPOST('rate', 'alpha')); $currency = new MultiCurrency($db); - + if ($currency->fetch($fk_multicurrency) > 0) { $currency->updateRate($rate); - } + } } elseif ($submit == $langs->trans('Delete')) { $fk_multicurrency = GETPOST('fk_multicurrency', 'int'); $currency = new MultiCurrency($db); - + if ($currency->fetch($fk_multicurrency) > 0) { if ($currency->delete() > 0) setEventMessages($langs->trans('RecordDeleted'), array()); @@ -120,14 +120,14 @@ elseif ($action == 'update_currency') } } } -elseif ($action == 'synchronize') +elseif ($action == 'synchronize') { $response = GETPOST('response'); $response = json_decode($response); - + if ($response->success) { - MultiCurrency::syncRates($response); + MultiCurrency::syncRates($response); } else { @@ -226,7 +226,7 @@ print ''; print ''; */ -/* TODO uncomment when the functionality will integrated +/* TODO uncomment when the functionality will integrated $var=!$var; print ''; print ''.$langs->transnoentitiesnoconv("multicurrency_modifyRateApplication").''; @@ -259,8 +259,8 @@ if (!empty($conf->global->MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION)) print $langs->trans("Value").' '; print ''; print ''; - - + + $var=!$var; print ''; print ''.$langs->transnoentitiesnoconv("multicurrency_appId").''; @@ -273,7 +273,7 @@ if (!empty($conf->global->MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION)) print ''; print ''; print ''; - + $var=!$var; print ''; print ''.$langs->transnoentitiesnoconv("multicurrency_appCurrencySource").''; @@ -286,7 +286,7 @@ if (!empty($conf->global->MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION)) print ''; print ''; print ''; - + $var=!$var; print ''; print ''.$langs->transnoentitiesnoconv("multicurrency_alternateCurrencySource").''; @@ -299,7 +299,7 @@ if (!empty($conf->global->MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION)) print ''; print ''; print ''; - + print ''; print '
'; } @@ -334,7 +334,7 @@ print ''; foreach ($TCurrency as &$currency) { if($currency->code == $conf->currency) continue; - + $var=!$var; print ''; print ''.$currency->code.' - '.$currency->name.''; @@ -363,7 +363,7 @@ print ' { $("#bt_sync").attr("disabled", true); var url_sync = "http://apilayer.net/api/live?access_key='.$conf->global->MULTICURRENCY_APP_ID.'&format=1'.(!empty($conf->global->MULTICURRENCY_APP_SOURCE) ? '&source='.$conf->global->MULTICURRENCY_APP_SOURCE : '').'"; - + $.ajax({ url: url_sync, dataType: "jsonp" From 0536d6cbed522893ddbfd3ce7c69847a8eac8fee Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Sep 2017 15:46:17 +0200 Subject: [PATCH 024/177] FIX #7330 --- htdocs/contrat/list.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 17246751600..221a4233f5a 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2014 Juanjo Menent @@ -271,11 +271,8 @@ $sql.= " GROUP BY c.rowid, c.ref, c.datec, c.tms, c.date_contrat, c.statut, c.re $sql.= ' s.rowid, s.nom, s.town, s.zip, s.fk_pays, s.client, s.code_client,'; $sql.= " typent.code,"; $sql.= " state.code_departement, state.nom"; -// Add where from extra fields -foreach ($extrafields->attribute_label as $key => $val) -{ - $sql .= ', ef.'.$key; -} +// Add fields from extrafields +foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key : ''); // Add where from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook From 6ac1b6e82eed373a7a0d061a3961268f6dd2689d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Sep 2017 15:48:04 +0200 Subject: [PATCH 025/177] Fix template --- htdocs/modulebuilder/template/myobject_list.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 96b7d7ca733..c4e7875e89a 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -237,6 +237,21 @@ foreach ($search_array_options as $key => $val) $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook $sql.=$hookmanager->resPrint; + +/* If a group by is required +$sql.= " GROUP BY " +foreach($object->fields as $key => $val) +{ + $sql.='t.'.$key.', '; +} +// Add fields from extrafields +foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key : ''); +// Add where from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; +*/ + $sql.=$db->order($sortfield,$sortorder); // Count total nb of records From aba907d1a8805e1133f8fe337593674d177a7b93 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Sep 2017 15:49:21 +0200 Subject: [PATCH 026/177] FIX #7420 --- htdocs/includes/odtphp/Segment.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/htdocs/includes/odtphp/Segment.php b/htdocs/includes/odtphp/Segment.php index 40668215647..525cd5b4f3f 100644 --- a/htdocs/includes/odtphp/Segment.php +++ b/htdocs/includes/odtphp/Segment.php @@ -24,7 +24,7 @@ class Segment implements IteratorAggregate, Countable protected $images = array(); protected $odf; protected $file; - + /** * Constructor * @@ -86,15 +86,15 @@ class Segment implements IteratorAggregate, Countable */ public function merge() { - // To provide debug information on line number processed + // To provide debug information on line number processed global $count; if (empty($count)) $count=1; else $count++; - + if (empty($this->savxml)) $this->savxml = $this->xml; // Sav content of line at first line merged, so we will reuse original for next steps $this->xml = $this->savxml; $tmpvars = $this->vars; // Store into $tmpvars so we won't modify this->vars when completing data with empty values - + // Search all tags fou into condition to complete $tmpvars, so we will proceed all tests even if not defined $reg='@\[!--\sIF\s([{}a-zA-Z0-9\.\,_]+)\s--\]@smU'; preg_match_all($reg, $this->xml, $matches, PREG_SET_ORDER); @@ -106,7 +106,7 @@ class Segment implements IteratorAggregate, Countable $tmpvars[$match[1]] = ''; // Not defined, so we set it to '', we just need entry into this->vars for next loop } } - + // Conditionals substitution // Note: must be done before static substitution, else the variable will be replaced by its value and the conditional won't work anymore foreach($tmpvars as $key => $value) @@ -133,7 +133,7 @@ class Segment implements IteratorAggregate, Countable $this->xml = preg_replace($reg, '', $this->xml); } } - + $this->xmlParsed .= str_replace(array_keys($tmpvars), array_values($tmpvars), $this->xml); if ($this->hasChildren()) { foreach ($this->children as $child) { @@ -143,7 +143,7 @@ class Segment implements IteratorAggregate, Countable } $reg = "/\[!--\sBEGIN\s$this->name\s--\](.*)\[!--\sEND\s$this->name\s--\]/sm"; $this->xmlParsed = preg_replace($reg, '$1', $this->xmlParsed); - // Miguel Erill 09704/2017 - Add macro replacement to invoice lines + // Miguel Erill 09704/2017 - Add macro replacement to invoice lines $this->xmlParsed = $this->macroReplace($this->xmlParsed); $this->file->open($this->odf->getTmpfile()); foreach ($this->images as $imageKey => $imageValue) { @@ -155,28 +155,28 @@ class Segment implements IteratorAggregate, Countable } } $this->file->close(); - + return $this->xmlParsed; } /** * Function to replace macros for invoice short and long month, invoice year - * + * * Substitution occur when the invoice is generated, not considering the invoice date * so do not (re)generate in a diferent date than the one that the invoice belongs to * Perhaps it would be better to use the invoice issued date but I still do not know * how to get it here * * Miguel Erill 09/04/2017 - * + * * @param string $value String to convert */ public function macroReplace($text) { global $langs; - $patterns=array( '__CURRENTDAY__','__CURRENTDAYTEXT__','__CURRENTMONTHSHORT__','__CURRENTMONTH__','__CURRENTYEAR__' ); - $values=array( date('j'), $langs->trans(date('l')), $langs->trans(date('M')), $langs->trans(date('F')), date('Y') ); + $patterns=array('/__CURRENTDAY__/','/__CURRENTDAYTEXT__/','/__CURRENTMONTHSHORT__/','/__CURRENTMONTH__/','/__CURRENTYEAR__/'); + $values=array(date('j'), $langs->trans(date('l')), $langs->trans(date('M')), $langs->trans(date('F')), date('Y')); $text=preg_replace($patterns, $values, $text); @@ -203,7 +203,7 @@ class Segment implements IteratorAggregate, Countable } return $this; } - + /** * Assign a template variable to replace * From c11ff4a18c7f488b3588793451165370f28beb4b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Sep 2017 15:55:25 +0200 Subject: [PATCH 027/177] FIX #7368 --- htdocs/install/mysql/migration/5.0.0-6.0.0.sql | 1 + htdocs/install/mysql/migration/repair.sql | 1 + 2 files changed, 2 insertions(+) diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 14990f1bfdc..3a5810d19e4 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -510,6 +510,7 @@ ALTER TABLE llx_user_rights DROP FOREIGN KEY fk_user_rights_fk_user_user; ALTER TABLE llx_user_rights DROP INDEX uk_user_rights; ALTER TABLE llx_user_rights DROP INDEX fk_user; ALTER TABLE llx_user_rights ADD UNIQUE INDEX uk_user_rights (entity, fk_user, fk_id); +DELETE FROM llx_user_rights WHERE fk_user NOT IN (select rowid from llx_user); ALTER TABLE llx_user_rights ADD CONSTRAINT fk_user_rights_fk_user_user FOREIGN KEY (fk_user) REFERENCES llx_user (rowid); ALTER TABLE llx_usergroup_rights ADD COLUMN entity integer DEFAULT 1 NOT NULL AFTER rowid; diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index 59be09bcb8b..3a61ef4b216 100755 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -89,6 +89,7 @@ delete from llx_livraison where ref = ''; delete from llx_expeditiondet where fk_expedition in (select rowid from llx_expedition where ref = ''); delete from llx_expedition where ref = ''; delete from llx_holiday_logs where fk_user_update not IN (select rowid from llx_user); +delete from llx_user_rights where fk_user not IN (select rowid from llx_user); update llx_deplacement set dated='2010-01-01' where dated < '2000-01-01'; From 70b11f18b51fac1f679080f832c3931e825468f5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Sep 2017 16:06:58 +0200 Subject: [PATCH 028/177] FIX #7367 --- htdocs/core/lib/files.lib.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 9ff9ec0df63..b1031153507 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1559,7 +1559,7 @@ function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile= } /** - * Convert an image file into anoher format. + * Convert an image file into another format. * This need Imagick php extension. * * @param string $fileinput Input file name @@ -1567,14 +1567,19 @@ function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile= * @param string $fileoutput Output filename * @return int <0 if KO, 0=Nothing done, >0 if OK */ -function dol_convert_file($fileinput,$ext='png',$fileoutput='') +function dol_convert_file($fileinput, $ext='png', $fileoutput='') { global $langs; if (class_exists('Imagick')) { $image=new Imagick(); - $ret = $image->readImage($fileinput); + try { + $ret = $image->readImage($fileinput); + } catch(Exception $e) { + dol_syslog("Failed to read image using Imagick. Try to install package 'apt-get install ghostscript'.", LOG_WARNING); + return 0; + } if ($ret) { $ret = $image->setImageFormat($ext); From cdd1473cfa00a7bc7bed8b767defe36a40fa1436 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 18 Sep 2017 16:30:01 +0200 Subject: [PATCH 029/177] Fix: avoid Warning: A non-numeric value encountered --- htdocs/product/price.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index b03a8763770..7c58069585e 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -1,9 +1,9 @@ +/* Copyright (C) 2001-2007 Rodolphe Quiedeville * Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2005 Eric Seigne - * Copyright (C) 2005-2015 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2005-2017 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2014 Florian Henry * Copyright (C) 2014-2016 Juanjo Menent * Copyright (C) 2014-2015 Philippe Grand @@ -1171,7 +1171,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) } print ''; print ''; - + $parameters=array('colspan' => 2); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook @@ -1493,10 +1493,8 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) $sortfield = GETPOST("sortfield", 'alpha'); $sortorder = GETPOST("sortorder", 'alpha'); - $page = GETPOST("page", 'int'); - if ($page == - 1) { - $page = 0; - } + $page = (GETPOST("page",'int')?GETPOST("page", 'int'):0); + if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $conf->liste_limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; From ee99483b0def49e496f7abcf233b8127a51e9385 Mon Sep 17 00:00:00 2001 From: Kjeld Borch Egevang Date: Mon, 18 Sep 2017 22:30:08 +0200 Subject: [PATCH 030/177] Changed "Solde" to "Balance". --- htdocs/accountancy/bookkeeping/balance.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index c6d0d5cf40e..382d0697b6a 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -210,7 +210,7 @@ else { print_liste_field_titre("Label", $_SERVER['PHP_SELF'], "t.label_operation", "", $options, "", $sortfield, $sortorder); print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $options, 'align="right"', $sortfield, $sortorder); print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $options, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre("Solde", $_SERVER["PHP_SELF"], "", $options, "", 'align="right"', $sortfield, $sortorder); + print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $options, "", 'align="right"', $sortfield, $sortorder); print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $options, "", 'width="60" align="center"', $sortfield, $sortorder); print "\n"; @@ -280,4 +280,4 @@ else { llxFooter(); } -$db->close(); \ No newline at end of file +$db->close(); From 9838199de148579753f5602dadf6c5924c6827ab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Sep 2017 23:31:07 +0200 Subject: [PATCH 031/177] FIX Sign of amount in origin currency on credit note created from lines --- htdocs/compta/facture/card.php | 17 +++++++++++------ htdocs/compta/facture/class/facture.class.php | 7 ++++++- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 82eeb3d49c0..c66285ae0c8 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -841,13 +841,18 @@ if (empty($reshook)) $line->fk_facture = $object->id; $line->fk_parent_line = $fk_parent_line; - $line->subprice =-$line->subprice; // invert price for object + $line->subprice = -$line->subprice; // invert price for object $line->pa_ht = $line->pa_ht; // we choosed to have buy/cost price always positive, so no revert of sign here - $line->total_ht=-$line->total_ht; - $line->total_tva=-$line->total_tva; - $line->total_ttc=-$line->total_ttc; - $line->total_localtax1=-$line->total_localtax1; - $line->total_localtax2=-$line->total_localtax2; + $line->total_ht = -$line->total_ht; + $line->total_tva = -$line->total_tva; + $line->total_ttc = -$line->total_ttc; + $line->total_localtax1 = -$line->total_localtax1; + $line->total_localtax2 = -$line->total_localtax2; + + $line->multicurrency_subprice = -$line->multicurrency_subprice; + $line->multicurrency_total_ht = -$line->multicurrency_total_ht; + $line->multicurrency_total_tva = -$line->multicurrency_total_tva; + $line->multicurrency_total_ttc = -$line->multicurrency_total_ttc; $result = $line->insert(0, 1); // When creating credit note with same lines than source, we must ignore error if discount alreayd linked diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 9cc9a63f313..c3b58117dd7 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1568,7 +1568,7 @@ class Facture extends CommonInvoice $facligne->desc=$remise->description; // Description ligne $facligne->vat_src_code=$remise->vat_src_code; $facligne->tva_tx=$remise->tva_tx; - $facligne->subprice=-$remise->amount_ht; + $facligne->subprice = -$remise->amount_ht; $facligne->fk_product=0; // Id produit predefini $facligne->qty=1; $facligne->remise_percent=0; @@ -1591,6 +1591,11 @@ class Facture extends CommonInvoice $facligne->total_tva = -$remise->amount_tva; $facligne->total_ttc = -$remise->amount_ttc; + $facligne->multicurrency_subprice = -$remise->multicurrency_subprice; + $facligne->multicurrency_total_ht = -$remise->multicurrency_total_ht; + $facligne->multicurrency_total_tva = -$remise->multicurrency_total_tva; + $facligne->multicurrency_total_ttc = -$remise->multicurrency_total_ttc; + $lineid=$facligne->insert(); if ($lineid > 0) { From f936b17d68928caf7c8af9131a2276e837f1faa4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 00:24:52 +0200 Subject: [PATCH 032/177] FIX Protection to avoid to apply credit note discount > remain to pay --- htdocs/comm/remx.php | 24 +++++++++--------- htdocs/compta/facture/card.php | 37 ++++++++++++++++++++-------- htdocs/core/class/discount.class.php | 7 ++++++ htdocs/langs/en_US/bills.lang | 1 + htdocs/langs/en_US/errors.lang | 2 +- 5 files changed, 48 insertions(+), 23 deletions(-) diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 9964db9ecde..94142b6ec54 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -125,7 +125,7 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes') if ($res > 0 && $newid1 > 0 && $newid2 > 0) { $db->commit(); - header("Location: ".$_SERVER["PHP_SELF"].'?id='.$id); // To avoid pb whith back + header("Location: ".$_SERVER["PHP_SELF"].'?id='.$id.($backtopage?'&backtopage='.urlencode($backtopage):'')); // To avoid pb whith back exit; } else @@ -275,13 +275,13 @@ if ($socid > 0) print ''; print ''; - + if ($user->rights->societe->creer) { print '
'; - + print load_fiche_titre($langs->trans("NewGlobalDiscount"),'',''); - + print '
'; print ''; print ''; @@ -293,7 +293,7 @@ if ($socid > 0) print ''; print ''; print ''; - + print "
'.$langs->trans("AmountHT").'
'.$langs->trans("NoteReason").'
"; } @@ -362,7 +362,7 @@ if ($socid > 0) while ($i < $num) { $obj = $db->fetch_object($resql); - + print ''; print ''.dol_print_date($db->jdate($obj->dc),'dayhour').''; if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) @@ -408,14 +408,14 @@ if ($socid > 0) if ($user->rights->societe->creer || $user->rights->facture->creer) { print ''; - print 'rowid.'">'.img_split($langs->trans("SplitDiscount")).''; + print 'rowid.($backtopage?'&backtopage='.urlencode($backtopage):'').'">'.img_split($langs->trans("SplitDiscount")).''; print '   '; - print 'rowid.'">'.img_delete($langs->trans("RemoveDiscount")).''; + print 'rowid.($backtopage?'&backtopage='.urlencode($backtopage):'').'">'.img_delete($langs->trans("RemoveDiscount")).''; print ''; } else print ' '; print ''; - + if ($_GET["action"]=='split' && GETPOST('remid') == $obj->rowid) { $showconfirminfo['rowid']=$obj->rowid; @@ -427,7 +427,7 @@ if ($socid > 0) else { print ''.$langs->trans("None").''; - } + } $db->free($resql); print ""; @@ -441,7 +441,7 @@ if ($socid > 0) array('type' => 'text', 'name' => 'amount_ttc_2', 'label' => $langs->trans("AmountTTC").' 2', 'value' => $amount2, 'size' => '5') ); $langs->load("dict"); - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&remid='.$showconfirminfo['rowid'], $langs->trans('SplitDiscount'), $langs->trans('ConfirmSplitDiscount',price($showconfirminfo['amount_ttc']),$langs->transnoentities("Currency".$conf->currency)), 'confirm_split', $formquestion, 0, 0); + print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&remid='.$showconfirminfo['rowid'].($backtopage?'&backtopage='.urlencode($backtopage):''), $langs->trans('SplitDiscount'), $langs->trans('ConfirmSplitDiscount',price($showconfirminfo['amount_ttc']),$langs->transnoentities("Currency".$conf->currency)), 'confirm_split', $formquestion, 0, 0); } } else @@ -590,7 +590,7 @@ if ($socid > 0) { print ''.$langs->trans("None").''; } - + print ""; } else diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index c66285ae0c8..6cfed39a02f 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -378,7 +378,9 @@ if (empty($reshook)) else if ($action == "setabsolutediscount" && $user->rights->facture->creer) { - // POST[remise_id] ou POST[remise_id_for_payment] + // POST[remise_id] or POST[remise_id_for_payment] + + // We use the credit to reduce amount of invoice if (! empty($_POST["remise_id"])) { $ret = $object->fetch($id); if ($ret > 0) { @@ -390,14 +392,28 @@ if (empty($reshook)) dol_print_error($db, $object->error); } } - if (! empty($_POST["remise_id_for_payment"])) { + // We use the credit to reduce remain to pay + if (! empty($_POST["remise_id_for_payment"])) + { require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php'; $discount = new DiscountAbsolute($db); $discount->fetch($_POST["remise_id_for_payment"]); - $result = $discount->link_to_invoice(0, $id); - if ($result < 0) { - setEventMessages($discount->error, $discount->errors, 'errors'); + //var_dump($object->getRemainToPay(0)); + //var_dump($discount->amount_ttc);exit; + if ($discount->amount_ttc > $object->getRemainToPay(0)) + { + // TODO Split the discount in 2 automatically + $error++; + setEventMessages($langs->trans("ErrorDiscountLargerThanRemainToPaySplitItBefore"), null, 'errors'); + } + + if (! $error) + { + $result = $discount->link_to_invoice(0, $id); + if ($result < 0) { + setEventMessages($discount->error, $discount->errors, 'errors'); + } } } } @@ -3175,6 +3191,7 @@ else if ($id > 0 || ! empty($ref)) $addrelativediscount = '' . $langs->trans("EditRelativeDiscounts") . ''; $addabsolutediscount = '' . $langs->trans("EditGlobalDiscounts") . ''; $addcreditnote = '' . $langs->trans("AddCreditNote") . ''; + $viewabsolutediscount = '' . $langs->trans("ViewAvailableGlobalDiscounts") . ''; print '' . $langs->trans('Discounts'); print ''; @@ -3184,7 +3201,7 @@ else if ($id > 0 || ! empty($ref)) print $langs->trans("CompanyHasNoRelativeDiscount"); // print ' ('.$addrelativediscount.')'; - // Is there commercial discount or down payment available ? + // Is there is commercial discount or down payment available ? if ($absolute_discount > 0) { print '. '; if ($object->statut > 0 || $object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT) { @@ -3209,7 +3226,7 @@ else if ($id > 0 || ! empty($ref)) } else { if ($absolute_creditnote > 0) // If not, link will be added later { - if ($object->statut == 0 && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT) + if ($object->statut == Facture::STATUS_DRAFT && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT) print ' (' . $addabsolutediscount . ')
'; else print '. '; @@ -3220,7 +3237,7 @@ else if ($id > 0 || ! empty($ref)) if ($absolute_creditnote > 0) { // If validated, we show link "add credit note to payment" - if ($object->statut != 1 || $object->type == Facture::TYPE_CREDIT_NOTE) { + if ($object->statut != Facture::STATUS_VALIDATED || $object->type == Facture::TYPE_CREDIT_NOTE) { if ($object->statut == 0 && $object->type != Facture::TYPE_DEPOSIT) { $text = $langs->trans("CompanyHasCreditNote", price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency)); print $form->textwithpicto($text, $langs->trans("CreditNoteDepositUse")); @@ -3231,13 +3248,13 @@ else if ($id > 0 || ! empty($ref)) // There is credit notes discounts available if (! $absolute_discount) print '
'; // $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer); - $more=' ('.$addcreditnote.')'; + $more=' ('.$addcreditnote. (($addcreditnote && $viewabsolutediscount) ? ' - ' : '') . $viewabsolutediscount . ')'; $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0, $more); // We allow credit note even if amount is higher } } if (! $absolute_discount && ! $absolute_creditnote) { print $langs->trans("CompanyHasNoAbsoluteDiscount"); - if ($object->statut == 0 && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT) + if ($object->statut == Facture::STATUS_DRAFT && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT) print ' (' . $addabsolutediscount . ')
'; else print '. '; diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index 443534eb1b3..89bb230d34f 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -78,6 +78,7 @@ class DiscountAbsolute $sql = "SELECT sr.rowid, sr.fk_soc,"; $sql.= " sr.fk_user,"; $sql.= " sr.amount_ht, sr.amount_tva, sr.amount_ttc, sr.tva_tx,"; + $sql.= " sr.multicurrency_amount_ht, sr.multicurrency_amount_tva, sr.multicurrency_amount_ttc,"; $sql.= " sr.fk_facture_line, sr.fk_facture, sr.fk_facture_source, sr.description,"; $sql.= " sr.datec,"; $sql.= " f.facnumber as ref_facture_source"; @@ -97,9 +98,15 @@ class DiscountAbsolute $this->id = $obj->rowid; $this->fk_soc = $obj->fk_soc; + $this->amount_ht = $obj->amount_ht; $this->amount_tva = $obj->amount_tva; $this->amount_ttc = $obj->amount_ttc; + + $this->multicurrency_amount_ht = $obj->multicurrency_amount_ht; + $this->multicurrency_amount_tva = $obj->multicurrency_amount_tva; + $this->multicurrency_amount_ttc = $obj->multicurrency_amount_ttc; + $this->tva_tx = $obj->tva_tx; $this->fk_user = $obj->fk_user; $this->fk_facture_line = $obj->fk_facture_line; diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 189ef5c1fe2..df00aec79fe 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -338,6 +338,7 @@ DateIsNotEnough=Date not reached yet InvoiceGeneratedFromTemplate=Invoice %s generated from recurring template invoice %s WarningInvoiceDateInFuture=Warning, the invoice date is higher than current date WarningInvoiceDateTooFarInFuture=Warning, the invoice date is too far from current date +ViewAvailableGlobalDiscounts=View available discounts # PaymentConditions Statut=Status PaymentConditionShortRECEP=Due Upon Receipt diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 8dfc02c49f1..e42e701bb3a 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -196,7 +196,7 @@ ErrorBadLinkSourceSetButBadValueForRef=The link you use is not valid. A 'source' ErrorTooManyErrorsProcessStopped=Too many errors. Process was stopped. ErrorOnlyInvoiceValidatedCanBeSentInMassAction=Only validated invoices can be sent using the "Send by email" mass action. ErrorChooseBetweenFreeEntryOrPredefinedProduct=You must choose if article is a predefined product or not - +ErrorDiscountLargerThanRemainToPaySplitItBefore=The discount you try to apply is larger than remain to pay. Split the discount in 2 smaller discounts before. # Warnings 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. WarningMandatorySetupNotComplete=Mandatory setup parameters are not yet defined From 1e33495f429fb6b346b85a235aa23ecc856ae84a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 00:31:51 +0200 Subject: [PATCH 033/177] Fix remove warnings --- htdocs/accountancy/admin/account.php | 10 ++++------ htdocs/comm/mailing/advtargetemailing.php | 14 +++++++------- htdocs/product/stats/commande_fournisseur.php | 14 +++++++------- htdocs/product/stats/propal.php | 12 +++++++----- htdocs/product/stats/supplier_proposal.php | 12 +++++++----- htdocs/societe/price.php | 4 +--- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 5c4e836986e..fb48bc8094f 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -53,12 +53,10 @@ if (! $user->rights->accounting->chartofaccount) accessforbidden(); // Load variable for pagination $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'sortorder'); -$page = GETPOST("page", 'int'); -if ($page == - 1) { - $page = 0; -} +$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 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/comm/mailing/advtargetemailing.php b/htdocs/comm/mailing/advtargetemailing.php index 39d1b7c8d8d..cfafdaa725b 100644 --- a/htdocs/comm/mailing/advtargetemailing.php +++ b/htdocs/comm/mailing/advtargetemailing.php @@ -45,13 +45,13 @@ if (! empty($conf->categorie->enabled)) { if (! $user->rights->mailing->lire || $user->societe_id > 0) accessforbidden(); -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'alpha'); -$page = GETPOST("page", 'int'); -if ($page == - 1) { - $page = 0; -} -$offset = $conf->liste_limit * $page; +// Load variable for pagination +$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 +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) diff --git a/htdocs/product/stats/commande_fournisseur.php b/htdocs/product/stats/commande_fournisseur.php index 4b9aa67236e..17d4bb5f962 100644 --- a/htdocs/product/stats/commande_fournisseur.php +++ b/htdocs/product/stats/commande_fournisseur.php @@ -51,13 +51,13 @@ $hookmanager->initHooks(array ( $mesg = ''; -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'alpha'); -$page = GETPOST("page", 'int'); -if ($page == - 1) { - $page = 0; -} -$offset = $conf->liste_limit * $page; +// Load variable for pagination +$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 +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) diff --git a/htdocs/product/stats/propal.php b/htdocs/product/stats/propal.php index 3f6eae0bfce..aa2c9a8e603 100644 --- a/htdocs/product/stats/propal.php +++ b/htdocs/product/stats/propal.php @@ -48,11 +48,13 @@ $hookmanager->initHooks(array ('productstatspropal')); $mesg = ''; -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'alpha'); -$page = GETPOST("page", 'int'); -if ($page == - 1) { $page = 0;} -$offset = $conf->liste_limit * $page; +// Load variable for pagination +$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 +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) $sortorder = "DESC"; diff --git a/htdocs/product/stats/supplier_proposal.php b/htdocs/product/stats/supplier_proposal.php index 1e0cefc3150..9406ade286f 100644 --- a/htdocs/product/stats/supplier_proposal.php +++ b/htdocs/product/stats/supplier_proposal.php @@ -48,11 +48,13 @@ $hookmanager->initHooks(array ('productstatspropal')); $mesg = ''; -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'alpha'); -$page = GETPOST("page", 'int'); -if ($page == - 1) { $page = 0;} -$offset = $conf->liste_limit * $page; +// Load variable for pagination +$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 +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) $sortorder = "DESC"; diff --git a/htdocs/societe/price.php b/htdocs/societe/price.php index 515aef60a6a..fc864bd5e01 100644 --- a/htdocs/societe/price.php +++ b/htdocs/societe/price.php @@ -237,9 +237,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { $sortorder = GETPOST("sortorder", 'alpha'); $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $page = GETPOST("page", 'int'); - if ($page == - 1) { - $page = 0; - } + if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; From 89bfb81cc75a196c8af67576d156747fc3d99fec Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 01:05:13 +0200 Subject: [PATCH 034/177] Fix repair --- htdocs/install/repair.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index 7fc3744e334..a93081cd5b2 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -211,7 +211,8 @@ if ($ok) $extrafields=new ExtraFields($db); $listofmodulesextra=array('societe'=>'societe','adherent'=>'adherent','product'=>'product', 'socpeople'=>'socpeople', 'commande'=>'commande', 'facture'=>'facture', - 'commande_fournisseur'=>'commande_fournisseur', 'actioncomm'=>'actioncomm', + 'supplier_proposal'=>'supplier_proposal', 'commande_fournisseur'=>'commande_fournisseur', 'facture_fourn'=>'facture_fourn', + 'actioncomm'=>'actioncomm', 'adherent_type'=>'adherent_type','user'=>'user','projet'=>'projet', 'projet_task'=>'projet_task'); print '
*** Check fields into extra table structure match table of definition. If not add column into table'; foreach($listofmodulesextra as $tablename => $elementtype) @@ -303,6 +304,10 @@ if ($ok) print " \n"; } + else + { + dol_print_error($db); + } } } From b723d2c2d2604cfd513de68ea8a958f37bbf406d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 01:39:22 +0200 Subject: [PATCH 035/177] Fix scrutinizer bugs --- htdocs/core/actions_massactions.inc.php | 4 ++-- htdocs/core/lib/agenda.lib.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index b17c047860a..2ac0b3a5885 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -147,11 +147,11 @@ if (! $error && $massaction == 'confirm_presend') foreach($receiver as $key=>$val) { // Recipient was provided from combo list - if ($val == 'thirdparty') // Id of third party + if ($val == 'thirdparty') // Id of third party or user { $tmparray[] = $thirdparty->name.' <'.$thirdparty->email.'>'; } - elseif ($val) // Id du contact + elseif ($val && method_exists($thirdparty, 'contact_get_property')) // Id of contact { $tmparray[] = $thirdparty->contact_get_property((int) $val,'email'); $sendtoid[] = $val; diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index a1571f7ac08..526e6386f0f 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -54,6 +54,9 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh $langs->load("companies"); + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions=new FormActions($db); + // Filters print '
'; print ''; @@ -95,9 +98,6 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh print ''; } - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; - $formactions=new FormActions($db); - // Type print ''; print ''; From 978702d04b3ded8ea709f41b45726d65eaa2d046 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 01:41:57 +0200 Subject: [PATCH 036/177] Fix false deprecated warning --- htdocs/core/lib/json.lib.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/json.lib.php b/htdocs/core/lib/json.lib.php index 55bfcf96061..425b5713565 100644 --- a/htdocs/core/lib/json.lib.php +++ b/htdocs/core/lib/json.lib.php @@ -46,7 +46,7 @@ if (! function_exists('json_encode')) */ function dol_json_encode($elements) { - dol_syslog("For better permorfance, enable the native json in your PHP", LOG_WARNING); + dol_syslog("For better performance, enable the native json in your PHP", LOG_WARNING); $num=0; if (is_object($elements)) // Count number of properties for an object @@ -225,12 +225,11 @@ if (! function_exists('json_decode')) * @param string $json Json encoded to PHP Object or Array * @param bool $assoc False return an object, true return an array. Try to always use it with true ! * @return mixed Object or Array or false on error - * @deprecated PHP >= 5.3 supports native json_decode * @see json_decode() */ function dol_json_decode($json, $assoc=false) { - dol_syslog('dol_json_decode() is deprecated. Please update your code to use native json_decode().', LOG_WARNING); + dol_syslog("For better performance, enable the native json in your PHP", LOG_WARNING); $comment = false; From 0b67ac36f144ed3ac6320cc2d2ebf2f2cf1316f7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 02:01:05 +0200 Subject: [PATCH 037/177] Show image on tool page --- htdocs/core/tools.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/tools.php b/htdocs/core/tools.php index 51378c9246a..8010f726c4f 100644 --- a/htdocs/core/tools.php +++ b/htdocs/core/tools.php @@ -49,7 +49,8 @@ print load_fiche_titre($text); print $langs->trans("ToolsDesc").'

'; - +// Show logo +print '
'; llxFooter(); From 7375afca3ecd6e0916b2905fdd02da84f0b18c91 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Tue, 19 Sep 2017 09:03:25 +0200 Subject: [PATCH 038/177] fix : rest API URL --- htdocs/api/admin/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/api/admin/index.php b/htdocs/api/admin/index.php index 218ab58467e..f2c5160db38 100644 --- a/htdocs/api/admin/index.php +++ b/htdocs/api/admin/index.php @@ -128,7 +128,7 @@ $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain // Show message $message=''; -$url=$urlwithroot.'/api/index.php/login?login=auserlogin&userpassword=thepassword[&reset=1]'; +$url=$urlwithroot.'/api/index.php/login?login=auserlogin&password=thepassword[&reset=1]'; $message.=$langs->trans("UrlToGetKeyToUseAPIs").':
'; $message.=img_picto('','object_globe.png').' '.$url; print $message; From f5bc9c08b124b50f9661304c4c4a102d6c2e8ec9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 11:38:28 +0200 Subject: [PATCH 039/177] Missing css --- htdocs/theme/eldy/style.css.php | 6 ++++++ htdocs/theme/md/style.css.php | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 90bcb8522de..6c07c9fa734 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -586,6 +586,12 @@ div.myavailability { text-overflow: ellipsis; white-space: nowrap; } +.tdoverflowmax200 { /* For tdoverflow, the max-midth become a minimum ! */ + max-width: 200px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} .tdoverflowmax300 { /* For tdoverflow, the max-midth become a minimum ! */ max-width: 300px; overflow: hidden; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 60c52e8683f..ff217042b23 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -564,6 +564,12 @@ div.myavailability { text-overflow: ellipsis; white-space: nowrap; } +.tdoverflowmax200 { /* For tdoverflow, the max-midth become a minimum ! */ + max-width: 200px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} .tdoverflowmax300 { max-width: 300px; overflow: hidden; From 77d1a150160ac9a1e13cb2b14a314e08d4bac8a9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 12:03:48 +0200 Subject: [PATCH 040/177] Activate warning for french "Loi Finance 2016" --- htdocs/core/modules/modCashDesk.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modCashDesk.class.php b/htdocs/core/modules/modCashDesk.class.php index f153631dc20..33b44297628 100644 --- a/htdocs/core/modules/modCashDesk.class.php +++ b/htdocs/core/modules/modCashDesk.class.php @@ -70,7 +70,7 @@ class modCashDesk extends DolibarrModules $this->phpmin = array(4,1); // Minimum version of PHP required by module $this->need_dolibarr_version = array(2,4); // Minimum version of Dolibarr required by module $this->langfiles = array("cashdesk"); - //$this->warnings_activation = array('FR'=>'WarningNoteModulePOSForFrenchLaw'); // Warning to show when we activate module. array('always'='text') or array('FR'='text') + $this->warnings_activation = array('FR'=>'WarningNoteModulePOSForFrenchLaw'); // Warning to show when we activate module. array('always'='text') or array('FR'='text') //$this->warnings_activation_ext = array('FR'=>'WarningInstallationMayBecomeNotCompliantWithLaw'); // Warning to show when we activate an external module. array('always'='text') or array('FR'='text') // Constants From 0803e03ca97a9fbeae5d9b56240be2f08acfbff7 Mon Sep 17 00:00:00 2001 From: tysauron Date: Tue, 19 Sep 2017 14:53:34 +0200 Subject: [PATCH 041/177] For use ajax combobox for societe and contacts in action card create. --- htdocs/comm/action/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 7b1c81af59c..e35d47691da 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -773,9 +773,9 @@ if ($action == 'create') $events[]=array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1',1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled')); //For external user force the company to user company if (!empty($user->societe_id)) { - print $form->select_thirdparty_list($user->societe_id, 'socid', '', 1, 1, 0, $events); + print $form->select_company($user->societe_id, 'socid', '', 1, 1, 0, $events); } else { - print $form->select_thirdparty_list('', 'socid', '', 'SelectThirdParty', 1, 0, $events); + print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, $events); } } @@ -783,7 +783,7 @@ if ($action == 'create') // Related contact print ''.$langs->trans("ActionOnContact").''; - $form->select_contacts(GETPOST('socid','int'), GETPOST('contactid'), 'contactid', 1, '', '', 0, 'minwidth200'); + $form->selectcontacts(GETPOST('socid','int'), GETPOST('contactid'), 'contactid', 1, '', '', 0, 'minwidth200'); print ''; From 815d0aff900af35cc5d9e819c143df1862a5ad90 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Tue, 19 Sep 2017 15:10:18 +0200 Subject: [PATCH 042/177] FIX for free line select unit was wrong --- htdocs/core/class/html.form.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index a684cff7165..32480e5cf15 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3274,7 +3274,7 @@ class Form $return= ''; @@ -1008,8 +1015,8 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $level++; if ($lines[$i]->id > 0) { - if ($parent == 0) projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $var); - else projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $var); + if ($parent == 0) projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable); + else projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable); } $level--; } @@ -1163,7 +1170,6 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= $sql2.= " GROUP BY p.rowid, p.ref, p.title, p.fk_soc, s.nom, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_amount, p.dateo, p.datee"; $sql2.= " ORDER BY p.title, p.ref"; - $var=true; $resql = $db->query($sql2); if ($resql) { diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index ad9ead401dd..10589c9d0b4 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -284,7 +284,7 @@ class Holiday extends CommonObject * @param string $filter SQL Filter * @return int -1 if KO, 1 if OK, 2 if no result */ - function fetchByUser($user_id,$order='',$filter='') + function fetchByUser($user_id, $order='', $filter='') { global $langs, $conf; @@ -692,13 +692,17 @@ class Holiday extends CommonObject } /** - * verifDateHolidayCP + * Check if a user is on holiday (partially or completely) into a period. + * This function can be used to avoid to have 2 leave requests on same period for example. + * Warning: It consumes a lot of memory because it load in ->holiday all holiday of a dedicated user at each call. * * @param int $fk_user Id user - * @param date $dateDebut Start date - * @param date $dateFin End date - * @param int $halfday Tag to define half day when holiday start and end - * @return boolean + * @param date $dateDebut Start date of period to check + * @param date $dateFin End date of period to check + * @param int $halfday Tag to define how start and end the period to check: + * 0:Full days, 2:Sart afternoon end monring, -1:Start afternoon, 1:End morning + * @return boolean False is on holiday at least partially into the period, True is never on holiday during chcked period. + * @see verifDateHolidayForTimestamp */ function verifDateHolidayCP($fk_user, $dateDebut, $dateFin, $halfday=0) { @@ -710,14 +714,103 @@ class Holiday extends CommonObject if ($infos_CP['statut'] == 5) continue; // ignore not validated holidays // TODO Also use halfday for the check - if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) - { - return false; - } + if ($halfday == 0) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == -1) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == 1) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == 2) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + else + { + dol_print_error('', 'Bad value of parameter halfday when calling function verifDateHolidayCP'); + } } return true; + } + + /** + * Check a user is not on holiday for a particular timestamp + * + * @param int $fk_user Id user + * @param timestamp $timestamp Time stamp date for a day (YYYY-MM-DD) without hours (= 12:00AM in english and not 12:00PM that is 12:00) + * @return array array('morning'=> ,'afternoon'=> ), Boolean is true if user is available for day timestamp. + * @see verifDateHolidayCP + */ + function verifDateHolidayForTimestamp($fk_user, $timestamp) + { + global $langs, $conf; + + $isavailablemorning=true; + $isavailableafternoon=true; + + $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday"; + $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp"; + $sql.= " WHERE cp.entity IN (".getEntity('holiday').")"; + $sql.= " AND cp.fk_user = ".(int) $fk_user; + $sql.= " AND date_debut <= '".$this->db->idate($timestamp)."' AND date_fin >= '".$this->db->idate($timestamp)."'"; + + $resql = $this->db->query($sql); + if ($resql) + { + $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon + if ($num_rows > 0) + { + $i=0; + while ($i < $num_rows) + { + $obj = $this->db->fetch_object($resql); + + // Note: $obj->halday is 0:Full days, 2:Sart afternoon end morning, -1:Start afternoon, 1:End morning + $arrayofrecord[$obj->rowid]=array('date_start'=>$this->db->jdate($obj->date_start), 'date_end'=>$this->db->jdate($obj->date_end), 'halfday'=>$obj->halfday); + $i++; + } + + // We found a record, user is on holiday by default, so is not available is true. + $isavailablemorning = true; + foreach($arrayofrecord as $record) + { + if ($timestamp == $record['date_start'] && $record['halfday'] == 2) continue; + if ($timestamp == $record['date_start'] && $record['halfday'] == -1) continue; + $isavailablemorning = false; + break; + } + $isavailableafternoon = true; + foreach($arrayofrecord as $record) + { + if ($timestamp == $record['date_end'] && $record['halfday'] == 2) continue; + if ($timestamp == $record['date_end'] && $record['halfday'] == 1) continue; + $isavailableafternoon = false; + break; + } + } + } + else dol_print_error($this->db); + + return array('morning'=>$isavailablemorning, 'afternoon'=>$isavailableafternoon); } diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index da789675cb8..ad1815c5efc 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; $langs->load('projects'); $langs->load('users'); @@ -484,10 +485,17 @@ print "\n"; // By default, we can edit only tasks we are assigned to $restrictviewformytask=(empty($conf->global->PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED)?1:0); +// Get if user is available or not for each day +$holiday = new Holiday($db); +$isavailable=array(); + +$isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $daytoparse); // $daytoparse is a date with hours = 0 +$isavailable[$daytoparse]=$isavailablefordayanduser; // in projectLinesPerWeek later, we are using $firstdaytoshow and dol_time_plus_duree to loop on each day + if (count($tasksarray) > 0) { $j=0; - projectLinesPerDay($j, 0, $usertoprocess, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $daytoparse); + projectLinesPerDay($j, 0, $usertoprocess, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $daytoparse, $isavailable); $colspan = 8; if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) $colspan++; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index c0482967c9e..caf2a3e4e84 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; $langs->load('projects'); $langs->load('users'); @@ -474,9 +475,25 @@ print ''.$langs->trans("TimeSpent").'' $startday=dol_mktime(12, 0, 0, $startdayarray['first_month'], $startdayarray['first_day'], $startdayarray['first_year']); -for($i=0;$i<7;$i++) +// Get if user is available or not for each day +$holiday = new Holiday($db); +$isavailable=array(); + +for ($i=0;$i<7;$i++) { - print ''.dol_print_date($startday + ($i * 3600 * 24), '%a').'
'.dol_print_date($startday + ($i * 3600 * 24), 'dayreduceformat').''; + $dayinloopfromfirstdaytoshow = dol_time_plus_duree($firstdaytoshow, $i, 'd'); // $firstdaytoshow is a date with hours = 0 + $dayinloop = dol_time_plus_duree($startday, $i, 'd'); + + // Useless because $dayinloopwithouthours should be same than $dayinloopfromfirstdaytoshow + //$tmparray = dol_getdate($dayinloop); + //$dayinloopwithouthours=dol_mktime(0, 0, 0, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); + //print dol_print_date($dayinloop, 'dayhour').' '; + //print dol_print_date($dayinloopwithouthours, 'dayhour').' '; + //print dol_print_date($dayinloopfromfirstdaytoshow, 'dayhour').'
'; + + $isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $dayinloopfromfirstdaytoshow); + $isavailable[$dayinloopfromfirstdaytoshow]=$isavailablefordayanduser; // in projectLinesPerWeek later, we are using $firstdaytoshow and dol_time_plus_duree to loop on each day + print ''.dol_print_date($dayinloopfromfirstdaytoshow, '%a').'
'.dol_print_date($dayinloopfromfirstdaytoshow, 'dayreduceformat').''; } print ''; print "\n"; @@ -491,7 +508,7 @@ if (count($tasksarray) > 0) $j=0; $level=0; - projectLinesPerWeek($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask); + projectLinesPerWeek($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $isavailable); $colspan=7; if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) $colspan++; From caf4ca74517f1dc0f748bd6df315b2cca7d70c15 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 19 Sep 2017 16:56:27 +0200 Subject: [PATCH 044/177] FIX Implementation of a Luracast recommandation for the REST api server (#7370) --- htdocs/api/class/api.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 36eb7c1d7d2..d76759532dc 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -48,7 +48,7 @@ class DolibarrApi */ function __construct($db, $cachedir='', $refreshCache=false) { - global $conf; + global $conf, $dolibarr_main_url_root; if (empty($cachedir)) $cachedir = $conf->api->dir_temp; Defaults::$cacheDirectory = $cachedir; @@ -57,6 +57,8 @@ class DolibarrApi $production_mode = ( empty($conf->global->API_PRODUCTION_MODE) ? false : true ); $this->r = new Restler($production_mode, $refreshCache); $this->r->setBaseUrls(DOL_MAIN_URL_ROOT, $urlwithroot); + $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); + $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file $this->r->setAPIVersion(1); } From d5966f944fac0834fbab0ea1cb561b55d9fa0ebf Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 19 Sep 2017 16:58:09 +0200 Subject: [PATCH 045/177] FIX Implementation of a Luracast recommandation for the REST api server (#7370) --- htdocs/api/class/api.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index d76759532dc..55b728d2a80 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -56,9 +56,9 @@ class DolibarrApi $this->db = $db; $production_mode = ( empty($conf->global->API_PRODUCTION_MODE) ? false : true ); $this->r = new Restler($production_mode, $refreshCache); - $this->r->setBaseUrls(DOL_MAIN_URL_ROOT, $urlwithroot); - $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); - $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); + $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + $this->r->setBaseUrls($urlwithroot); $this->r->setAPIVersion(1); } From cc7aee6c3e5618855e43f95f38adb3b899c260d1 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 19 Sep 2017 16:59:19 +0200 Subject: [PATCH 046/177] FIX Implementation of a Luracast recommandation for the REST api server (#7370) --- htdocs/api/class/api.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 55b728d2a80..dcda8255e7c 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -58,7 +58,7 @@ class DolibarrApi $this->r = new Restler($production_mode, $refreshCache); $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file - $this->r->setBaseUrls($urlwithroot); + $this->r->setBaseUrls(DOL_MAIN_URL_ROOT, $urlwithroot); $this->r->setAPIVersion(1); } From f4ddce727421d81f85a68111536c1f14bddd6024 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 17:05:50 +0200 Subject: [PATCH 047/177] FIX View of timespent for another user --- htdocs/projet/activity/perday.php | 2 +- htdocs/projet/activity/perweek.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index 4dff34ad30b..3dbf7e32650 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -84,7 +84,7 @@ if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) $usertoprocess=$user; $search_usertoprocessid=$usertoprocess->id; } -elseif (search_usertoprocessid > 0) +elseif ($search_usertoprocessid > 0) { $usertoprocess=new User($db); $usertoprocess->fetch($search_usertoprocessid); diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 6ea60f3d76f..3b6ce8efd91 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -97,7 +97,7 @@ if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) $usertoprocess=$user; $search_usertoprocessid=$usertoprocess->id; } -elseif (search_usertoprocessid > 0) +elseif ($search_usertoprocessid > 0) { $usertoprocess=new User($db); $usertoprocess->fetch($search_usertoprocessid); From 5f7631a95d83fe0fc26c8750f22ba50b06ef845a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 17:07:39 +0200 Subject: [PATCH 048/177] NEW Days where user is on vacation use different colors in timesheet. --- htdocs/core/lib/project.lib.php | 10 ++++++---- htdocs/projet/activity/perday.php | 2 +- htdocs/projet/activity/perweek.php | 2 +- htdocs/theme/eldy/style.css.php | 8 +++++++- htdocs/theme/md/style.css.php | 7 +++++++ 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 2e5799f970c..0de84d581f1 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -733,8 +733,9 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr print ''; $cssonholiday=''; - if (! $isavailable[$preselectedday]['morning']) $cssonholiday.='onholidaymorning '; - if (! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayafternoon '; + if (! $isavailable[$preselectedday]['morning'] && ! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayallday '; + elseif (! $isavailable[$preselectedday]['morning']) $cssonholiday.='onholidaymorning '; + elseif (! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayafternoon '; // Duration print ''; @@ -970,8 +971,9 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $tmpday=dol_time_plus_duree($firstdaytoshow, $idw, 'd'); $cssonholiday=''; - if (! $isavailable[$tmpday]['morning']) $cssonholiday.='onholidaymorning '; - if (! $isavailable[$tmpday]['afternoon']) $cssonholiday.='onholidayafternoon '; + if (! $isavailable[$tmpday]['morning'] && ! $isavailable[$tmpday]['afternoon']) $cssonholiday.='onholidayallday '; + elseif (! $isavailable[$tmpday]['morning']) $cssonholiday.='onholidaymorning '; + elseif (! $isavailable[$tmpday]['afternoon']) $cssonholiday.='onholidayafternoon '; $tmparray=dol_getdate($tmpday); $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$tmpday][$lines[$i]->id]; diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index ad1815c5efc..c9c577742e6 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -85,7 +85,7 @@ if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) $usertoprocess=$user; $search_usertoprocessid=$usertoprocess->id; } -elseif (search_usertoprocessid > 0) +elseif ($search_usertoprocessid > 0) { $usertoprocess=new User($db); $usertoprocess->fetch($search_usertoprocessid); diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index caf2a3e4e84..b808017123d 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -98,7 +98,7 @@ if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) $usertoprocess=$user; $search_usertoprocessid=$usertoprocess->id; } -elseif (search_usertoprocessid > 0) +elseif ($search_usertoprocessid > 0) { $usertoprocess=new User($db); $usertoprocess->fetch($search_usertoprocessid); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 3d58211fbde..a83d2ed9dd8 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -387,12 +387,18 @@ input.buttonpaymentstripe { background-repeat: no-repeat; background-position: 8px 7px; } +/* Used by timesheets */ span.timesheetalreadyrecorded input { border: none; border-bottom: solid 1px rgba(0,0,0,0.4); margin-right: 1px !important; } - +td.onholidaymorning, td.onholidayafternoon { + background-color: #fdf6f2; +} +td.onholidayallday { + background-color: #f4eede; +} select.flat, form.flat select { font-weight: normal; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 36fbd2bdd20..0f3711bf45b 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -384,11 +384,18 @@ input.buttonpaymentstripe { background-repeat: no-repeat; background-position: 8px 7px; } +/* Used for timesheets */ span.timesheetalreadyrecorded input { border: none; border-bottom: solid 1px rgba(0,0,0,0.1); margin-right: 1px !important; } +td.onholidaymorning, td.onholidayafternoon { + background-color: #fdf6f2; +} +td.onholidayallday { + background-color: #f4eede; +} select.flat, form.flat select { font-weight: normal; From 5643d4e867557f134daf56f64564f91203496107 Mon Sep 17 00:00:00 2001 From: tysauron Date: Tue, 19 Sep 2017 17:26:18 +0200 Subject: [PATCH 049/177] Rename "->fk_action" in "->type_id" (is old name) --- htdocs/comm/action/class/actioncomm.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index cb6da443404..ec1c84dd652 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -754,7 +754,7 @@ class ActionComm extends CommonObject $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm "; $sql.= " SET percent = '".$this->db->escape($this->percentage)."'"; - if ($this->fk_action > 0) $sql.= ", fk_action = '".$this->db->escape($this->fk_action)."'"; + if ($this->type_id > 0) $sql.= ", fk_action = '".$this->db->escape($this->type_id)."'"; $sql.= ", label = ".($this->label ? "'".$this->db->escape($this->label)."'":"null"); $sql.= ", datep = ".(strval($this->datep)!='' ? "'".$this->db->idate($this->datep)."'" : 'null'); $sql.= ", datep2 = ".(strval($this->datef)!='' ? "'".$this->db->idate($this->datef)."'" : 'null'); From c38ed5499054c0f80fc18231ba649abdf1b501d2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 17:31:37 +0200 Subject: [PATCH 050/177] Disable old datepicker --- htdocs/admin/system/perf.php | 2 +- htdocs/core/class/html.form.class.php | 4 ++-- htdocs/core/lib/project.lib.php | 4 ++-- htdocs/main.inc.php | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/admin/system/perf.php b/htdocs/admin/system/perf.php index 25079d8f185..3a8e1e42bf4 100644 --- a/htdocs/admin/system/perf.php +++ b/htdocs/admin/system/perf.php @@ -336,7 +336,7 @@ jQuery(document).ready(function() { var compjsphpstring; getjsphpurl = $.ajax({ type: "GET", - url: \''.DOL_URL_ROOT.'/core/js/datepicker.js.php\', + url: \''.DOL_URL_ROOT.'/core/js/lib_head.js.php\', cache: false, /* async: false, */ /* crossDomain: true,*/ diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index bca87c7a65f..628be5660df 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5046,11 +5046,11 @@ class Form else return 'BadValueForParameterTypeHour'; if ($typehour!='text') $retstring.=' '.$langs->trans('HourShort'); - else $retstring.=':'; + else $retstring.=':'; // Minutes if ($minunderhours) $retstring.='
'; - else $retstring.=" "; + else $retstring.=' '; if ($typehour=='select' || $typehour=='textselect') { diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 0de84d581f1..af49fa6b27d 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -738,7 +738,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr elseif (! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayafternoon '; // Duration - print ''; + print ''; $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$preselectedday][$lines[$i]->id]; $alreadyspent=''; @@ -748,7 +748,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $tableCell=''; $tableCell.=''; - $tableCell.=' + '; + $tableCell.=' + '; //$tableCell.='   '; $tableCell.=$form->select_duration($lines[$i]->id.'duration','',$disabledtask,'text',0,1); //$tableCell.=' '; diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 06a6b4658ae..675c82aa499 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1322,10 +1322,10 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; // Add datepicker default options - if (! defined('DISABLE_DATE_PICKER')) + /*if (! defined('DISABLE_DATE_PICKER')) { print ''."\n"; - } + }*/ // JS forced by modules (relative url starting with /) if (! empty($conf->modules_parts['js'])) // $conf->modules_parts['js'] is array('module'=>array('file1','file2')) From 8123562dedfbc9521b4b903bb451562c0e3cb027 Mon Sep 17 00:00:00 2001 From: fappels Date: Tue, 19 Sep 2017 18:42:29 +0200 Subject: [PATCH 051/177] Fix extrafield copy next situation invoice --- htdocs/compta/facture/card.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 6cfed39a02f..1d621d153f5 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1356,6 +1356,7 @@ if (empty($reshook)) { $line->origin = $object->origin; $line->origin_id = $line->id; + $line->fetch_optionals($line->id); } } @@ -1377,7 +1378,21 @@ if (empty($reshook)) $object->situation_counter = $object->situation_counter + 1; $id = $object->createFromCurrent($user); - if ($id <= 0) $mesg = $object->error; + if ($id <= 0) + { + $mesg = $object->error; + } + else + { + $nextSituationInvoice = new Facture($db); + $nextSituationInvoice->fetch($id); + // create extrafields with data from create form + $extralabels = $extrafields->fetch_name_optionals_label($nextSituationInvoice->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $nextSituationInvoice); + if ($ret > 0) { + $nextSituationInvoice->insertExtraFields(); + } + } } } From 13d5471dd00357a0274cad9aa42fac9978d1031d Mon Sep 17 00:00:00 2001 From: fappels Date: Tue, 19 Sep 2017 18:43:00 +0200 Subject: [PATCH 052/177] Fix extrafield copy shipment --- htdocs/expedition/card.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index f15c091263e..4a7df9e73b2 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -780,9 +780,15 @@ if ($action == 'create') $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; - if (empty($reshook) && ! empty($extrafields->attribute_label)) { - print $object->showOptionals($extrafields, 'edit'); - } + if (empty($reshook) && ! empty($extrafields->attribute_label)) { + // copy from order + $orderExtrafields = new Extrafields($db); + $orderExtrafieldLabels = $orderExtrafields->fetch_name_optionals_label($object->table_element); + if ($object->fetch_optionals($object->id, $orderExtrafieldLabels) > 0) { + $expe->array_options = array_merge($expe->array_options, $object->array_options); + } + print $object->showOptionals($extrafields, 'edit'); + } // Incoterms @@ -1304,9 +1310,14 @@ if ($action == 'create') if (is_array($extralabelslines) && count($extralabelslines)>0) { $colspan=5; + $orderLineExtrafields = new Extrafields($db); + $orderLineExtrafieldLabels = $orderLineExtrafields->fetch_name_optionals_label($object->table_element_line); + $srcLine = new OrderLine($db); + $srcLine->fetch_optionals($line->id,$orderLineExtrafieldLabels); // fetch extrafields also available in orderline $line = new ExpeditionLigne($db); $line->fetch_optionals($object->id,$extralabelslines); - print ''; + $line->array_options = array_merge($line->array_options, $srcLine->array_options); + print ''; print $line->showOptionals($extrafieldsline, 'edit', array('style'=>$bc[$var], 'colspan'=>$colspan),$indiceAsked); print ''; } From cec91ae837528050908f5506e9d80c8b68689b82 Mon Sep 17 00:00:00 2001 From: fappels Date: Tue, 19 Sep 2017 18:44:49 +0200 Subject: [PATCH 053/177] Fix extrafield copy receipt --- htdocs/livraison/card.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/htdocs/livraison/card.php b/htdocs/livraison/card.php index 02b126306f2..e6d39ec7019 100644 --- a/htdocs/livraison/card.php +++ b/htdocs/livraison/card.php @@ -565,6 +565,14 @@ else } // Other attributes + if ($action = 'create_delivery') { + // copy from expedition + $expeditionExtrafields = new Extrafields($db); + $expeditionExtrafieldLabels = $expeditionExtrafields->fetch_name_optionals_label($expedition->table_element); + if ($expedition->fetch_optionals($object->origin_id, $expeditionExtrafieldLabels) > 0) { + $object->array_options = array_merge($object->array_options, $expedition->array_options); + } + } $cols = 2; include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; @@ -665,6 +673,13 @@ else $mode = ($object->statut == 0) ? 'edit' : 'view'; $line = new LivraisonLigne($db); $line->fetch_optionals($object->lines[$i]->id,$extralabelslines); + if ($action = 'create_delivery') { + $srcLine = new ExpeditionLigne($db); + $expeditionLineExtrafields = new Extrafields($db); + $expeditionLineExtrafieldLabels = $expeditionLineExtrafields->fetch_name_optionals_label($srcLine->table_element); + $srcLine->fetch_optionals($expedition->lines[$i]->id,$expeditionLineExtrafieldLabels); + $line->array_options = array_merge($line->array_options, $srcLine->array_options); + } print ''; print $line->showOptionals($extrafieldsline, $mode, array('style'=>$bc[$var], 'colspan'=>$colspan),$i); print ''; From ddeca6cc06ade604c2fc374ba5871d53fa253ada Mon Sep 17 00:00:00 2001 From: fappels Date: Tue, 19 Sep 2017 18:52:27 +0200 Subject: [PATCH 054/177] fix oddeven revert --- htdocs/expedition/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 4a7df9e73b2..728556b3940 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1317,7 +1317,7 @@ if ($action == 'create') $line = new ExpeditionLigne($db); $line->fetch_optionals($object->id,$extralabelslines); $line->array_options = array_merge($line->array_options, $srcLine->array_options); - print ''; + print ''; print $line->showOptionals($extrafieldsline, 'edit', array('style'=>$bc[$var], 'colspan'=>$colspan),$indiceAsked); print ''; } From ffe2ee82324cc266bacd093edcf88cd0e3ca6691 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 19:00:28 +0200 Subject: [PATCH 055/177] Standardize code --- htdocs/compta/bank/index.php | 17 ++++++++--------- htdocs/core/menus/standard/eldy.lib.php | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 80bf9d6f50c..5a0ab062b29 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -46,7 +46,7 @@ $toselect = GETPOST('toselect', 'array'); $search_ref=GETPOST('search_ref','alpha'); $search_label=GETPOST('search_label','alpha'); $search_number=GETPOST('search_number','alpha'); -$statut=GETPOST('statut')?GETPOST('statut', 'alpha'):'opened'; // 'all' or ''='opened' +$search_status=GETPOST('search_status')?GETPOST('search_status', 'alpha'):'opened'; // 'all' or ''='opened' $optioncss = GETPOST('optioncss','alpha'); // Security check @@ -123,11 +123,10 @@ include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; // Purge search criteria if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All test are required to be compatible with all browsers { - $statut = 'all'; $search_ref=''; $search_label=''; $search_number=''; - $search_statut=''; + $search_status=''; } @@ -153,8 +152,8 @@ $sql.=$hookmanager->resPrint; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account as b"; if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."bankcacount_extrafields as ef on (c.rowid = ef.fk_object)"; $sql.= " WHERE entity IN (".getEntity('bank_account').")"; -if ($statut == 'opened') $sql.= " AND clos = 0"; -if ($statut == 'closed') $sql.= " AND clos = 1"; +if ($search_status == 'opened') $sql.= " AND clos = 0"; +if ($search_status == 'closed') $sql.= " AND clos = 1"; if ($search_ref != '') $sql.=natural_search('b.ref', $search_ref); if ($search_label != '') $sql.=natural_search('b.label', $search_label); if ($search_number != '') $sql.=natural_search('b.number', $search_number); @@ -222,7 +221,7 @@ if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; if ($search_ref != '') $param.='&search_ref='.$search_ref; if ($search_label != '') $param.='&search_label='.$search_label; if ($search_number != '') $param.='&search_number='.$search_number; -if ($statut != '') $param.='&statut='.$statut; +if ($search_status != '') $param.='&search_status='.$search_status; if ($show_files) $param.='&show_files=' .$show_files; if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields @@ -377,7 +376,7 @@ if (! empty($arrayfields['b.tms']['checked'])) print ''; print ''; } -// Statut +// Status if (! empty($arrayfields['b.clos']['checked'])) { print ''; @@ -385,7 +384,7 @@ if (! empty($arrayfields['b.clos']['checked'])) 'opened'=>$langs->trans("Opened"), 'closed'=>$langs->trans("Closed") ); - print $form->selectarray("statut", $array, $statut, 1); + print $form->selectarray("search_status", $array, $search_status, 1); print ''; } // Balance @@ -584,7 +583,7 @@ foreach ($accounts as $key=>$type) if (! $i) $totalarray['nbfield']++; } - // Statut + // Status if (! empty($arrayfields['b.clos']['checked'])) { print ''.$acc->getLibStatut(5).''; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index fb503cfea9d..55d3b75fe13 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -977,7 +977,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/defaultaccounts.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuDefaultAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 50); if (! empty($conf->banque->enabled)) { - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/compta/bank/index.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuBankAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_bank', 51); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/compta/bank/index.php?mainmenu=accountancy&leftmenu=accountancy_admin&search_status=-1", $langs->trans("MenuBankAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_bank', 51); } if (! empty($conf->facture->enabled) || ! empty($conf->fournisseur->enabled)) { From f87614e2d396cdd4044afdfdb16e3074291ad15d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 19:12:54 +0200 Subject: [PATCH 056/177] Fix missing translation --- htdocs/compta/prelevement/class/bonprelevement.class.php | 1 + htdocs/compta/prelevement/create.php | 2 +- htdocs/langs/en_US/withdrawals.lang | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 0278d97d724..a3d50d58143 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -953,6 +953,7 @@ class BonPrelevement extends CommonObject { $prev_id = $this->db->last_insert_id(MAIN_DB_PREFIX."prelevement_bons"); $this->id = $prev_id; + $this->ref = $ref; } else { diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index 6743ea3098b..09102ec1309 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -80,7 +80,7 @@ if ($action == 'create') } else { - setEventMessages($langs->trans("DirectDebitOrderCreated"), null); + setEventMessages($langs->trans("DirectDebitOrderCreated", $bprev->getNomUrl(1)), null); } } diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index 8e80a111516..29b5766215b 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -12,7 +12,7 @@ WithdrawalsLines=Direct debit order lines RequestStandingOrderToTreat=Request for direct debit payment order to process RequestStandingOrderTreated=Request for direct debit payment order processed NotPossibleForThisStatusOfWithdrawReceiptORLine=Not yet possible. Withdraw status must be set to 'credited' before declaring reject on specific lines. -NbOfInvoiceToWithdraw=Nb. of invoice with direct debit order +NbOfInvoiceToWithdraw=Nb. of qualified invoice with waiting direct debit order NbOfInvoiceToWithdrawWithInfo=Nb. of customer invoice with direct debit payment orders having defined bank account information InvoiceWaitingWithdraw=Invoice waiting for direct debit AmountToWithdraw=Amount to withdraw @@ -94,6 +94,7 @@ SEPAFrstOrRecur=Type of payment ModeRECUR=Reccurent payment ModeFRST=One-off payment PleaseCheckOne=Please check one only +DirectDebitOrderCreated=Direct debit order %s created ### Notifications InfoCreditSubject=Payment of direct debit payment order %s by the bank From 6a0ef4b561ab32717f53d1d4528c96fa12a57f10 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 19:29:00 +0200 Subject: [PATCH 057/177] Fix info ot total in direct debit page --- htdocs/compta/prelevement/factures.php | 29 ++++++++++++++++---------- htdocs/langs/en_US/withdrawals.lang | 3 ++- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index f7e41bdc997..60215005446 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -145,9 +145,9 @@ if ($prev_id > 0 || $ref) // List of invoices -$sql = "SELECT pf.rowid"; -$sql.= ",f.rowid as facid, f.facnumber as ref, f.total_ttc"; -$sql.= ", s.rowid as socid, s.nom as name, pl.statut"; +$sql = "SELECT pf.rowid,"; +$sql.= " f.rowid as facid, f.facnumber as ref, f.total_ttc,"; +$sql.= " s.rowid as socid, s.nom as name, pl.statut, pl.amount as amount_requested"; $sql.= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; $sql.= ", ".MAIN_DB_PREFIX."prelevement_lignes as pl"; $sql.= ", ".MAIN_DB_PREFIX."prelevement_facture as pf"; @@ -202,14 +202,14 @@ if ($result) print ''; print_liste_field_titre("Bill",$_SERVER["PHP_SELF"],"p.ref",'',$param,'',$sortfield,$sortorder); print_liste_field_titre("ThirdParty",$_SERVER["PHP_SELF"],"s.nom",'',$param,'',$sortfield,$sortorder); - print_liste_field_titre("Amount",$_SERVER["PHP_SELF"],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre("AmountInvoice",$_SERVER["PHP_SELF"],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre("AmountRequested",$_SERVER["PHP_SELF"],"pl.amount_requested","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre("StatusDebitCredit",$_SERVER["PHP_SELF"],"","",$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre(''); print "\n"; - $var=false; - - $total = 0; + $totalinvoices = 0; + $totalamount_requested = 0; while ($i < min($num, $limit)) { @@ -231,9 +231,12 @@ if ($result) print $thirdpartytmp->getNomUrl(1); print "\n"; - // Amount + // Amount of invoice print ''.price($obj->total_ttc)."\n"; + // Amount requested + print ''.price($obj->amount_requested)."\n"; + // Status of requests print ''; @@ -256,7 +259,8 @@ if ($result) print "\n"; - $total += $obj->total_ttc; + $totalinvoices += $obj->total_ttc; + $totalamount_requested += $obj->amount_requested; $i++; } @@ -267,8 +271,11 @@ if ($result) print ''.$langs->trans("Total").''; print ' '; print ''; - if ($total != $object->amount) print img_warning("AmountOfFileDiffersFromSumOfInvoices"); - print price($total); + //if ($totalinvoices != $object->amount) print img_warning("AmountOfFileDiffersFromSumOfInvoices"); // It is normal to have total that differs. For an amount of invoice of 100, request to pay may be 50 only. + if ($totalamount_requested != $object->amount) print img_warning("AmountOfFileDiffersFromSumOfInvoices"); + print "\n"; + print ''; + print price($totalamount_requested); print "\n"; print ' '; print ' '; diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index 29b5766215b..308987575f5 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -72,7 +72,7 @@ IfInvoiceNeedOnWithdrawPaymentWontBeClosed=However, if invoice has at least one DoStandingOrdersBeforePayments=This tab allows you to request a direct debit payment order. Once done, go into menu Bank->Direct Debit orders to manage the direct debit payment order. When payment order is closed, payment on invoice will be automatically recorded, and invoice closed if remainder to pay is null. WithdrawalFile=Withdrawal file SetToStatusSent=Set to status "File Sent" -ThisWillAlsoAddPaymentOnInvoice=This will also apply payments to invoices and will classify them as "Paid" +ThisWillAlsoAddPaymentOnInvoice=This will also record payments to invoices and will classify them as "Paid" if remain to pay is null StatisticsByLineStatus=Statistics by status of lines RUM=UMR RUMLong=Unique Mandate Reference @@ -95,6 +95,7 @@ ModeRECUR=Reccurent payment ModeFRST=One-off payment PleaseCheckOne=Please check one only DirectDebitOrderCreated=Direct debit order %s created +AmountRequested=Amount requested ### Notifications InfoCreditSubject=Payment of direct debit payment order %s by the bank From 04e1458a3f1e47f7f42831cc4b57af68acbc7dff Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 22:03:44 +0200 Subject: [PATCH 058/177] Fix clean parameters --- .../facture/class/facture-rec.class.php | 3 +++ htdocs/contrat/class/contrat.class.php | 27 +++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index b12f848323d..b3a8a68611d 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -715,6 +715,9 @@ class FactureRec extends CommonInvoice dol_syslog(get_class($this)."::updateline facid=".$facid." rowid=$rowid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva,txlocaltax1=$txlocaltax1,txlocaltax2=$txlocaltax2,fk_product=$fk_product,remise_percent=$remise_percent,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type,fk_unit=$fk_unit", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + // Clean parameters + if (empty($remise_percent)) $remise_percent = 0; + // Check parameters if ($type < 0) return -1; diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 6e9fc443e03..69bda6f2b1c 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -538,11 +538,13 @@ class Contrat extends CommonObject /** * Load a contract from database * - * @param int $id Id of contract to load - * @param string $ref Ref - * @return int <0 if KO, id of contract if OK + * @param int $id Id of contract to load + * @param string $ref Ref + * @param string $ref_customer Customer ref + * @param string $ref_supplier Supplier ref + * @return int <0 if KO, 0 if not found, Id of contract if OK */ - function fetch($id,$ref='') + function fetch($id, $ref='', $ref_customer='', $ref_supplier='') { $sql = "SELECT rowid, statut, ref, fk_soc, mise_en_service as datemise,"; $sql.= " ref_supplier, ref_customer,"; @@ -553,12 +555,20 @@ class Contrat extends CommonObject $sql.= " fk_commercial_signature, fk_commercial_suivi,"; $sql.= " note_private, note_public, model_pdf, extraparams"; $sql.= " FROM ".MAIN_DB_PREFIX."contrat"; + if (! $id) $sql.=" WHERE entity IN (".getEntity('contract', 0).")"; + else $sql.= " WHERE rowid=".$id; + if ($ref_customer) + { + $sql.= " AND ref_customer = '".$this->db->escape($ref_customer)."'"; + } + if ($ref_supplier) + { + $sql.= " AND ref_supplier = '".$this->db->escape($ref_supplier)."'"; + } if ($ref) { - $sql.= " WHERE ref='".$this->db->escape($ref)."'"; - $sql.= " AND entity IN (".getEntity('contract', 0).")"; + $sql.= " AND ref='".$this->db->escape($ref)."'"; } - else $sql.= " WHERE rowid=".$id; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $resql = $this->db->query($sql); @@ -628,7 +638,7 @@ class Contrat extends CommonObject { dol_syslog(get_class($this)."::Fetch Erreur contrat non trouve"); $this->error="Contract not found"; - return -2; + return 0; } } else @@ -2834,6 +2844,7 @@ class ContratLigne extends CommonObjectLine if (empty($this->total_ttc)) $this->total_ttc = 0; if (empty($this->localtax1_tx)) $this->localtax1_tx = 0; if (empty($this->localtax2_tx)) $this->localtax2_tx = 0; + if (empty($this->remise_percent)) $this->remise_percent = 0; // Check parameters // Put here code to add control on parameters values From cfd29841e10117b8c0fda4f9c295d44d2de99436 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 23:42:20 +0200 Subject: [PATCH 059/177] NEW Option STOCK_SUPPORTS_SERVICES become visible. --- htdocs/admin/stock.php | 172 ++++++++++++++++++--------------- htdocs/langs/en_US/stocks.lang | 4 +- 2 files changed, 97 insertions(+), 79 deletions(-) diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index f7e18851306..a2f0a4b5346 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -45,6 +45,10 @@ if($action) { $db->begin(); + if ($action == 'STOCK_SUPPORTS_SERVICES') + { + $res = dolibarr_set_const($db, "STOCK_SUPPORTS_SERVICES", GETPOST('STOCK_SUPPORTS_SERVICES','alpha'),'chaine',0,'',$conf->entity); + } if ($action == 'STOCK_USERSTOCK_AUTOCREATE') { $res = dolibarr_set_const($db, "STOCK_USERSTOCK_AUTOCREATE", GETPOST('STOCK_USERSTOCK_AUTOCREATE','alpha'),'chaine',0,'',$conf->entity); @@ -164,8 +168,8 @@ $found=0; print ''; -print ''.$langs->trans("DeStockOnBill").''; -print ''; +print ''.$langs->trans("DeStockOnBill").''; +print ''; if (! empty($conf->facture->enabled)) { print ""; @@ -184,8 +188,8 @@ $found++; print ''; -print ''.$langs->trans("DeStockOnValidateOrder").''; -print ''; +print ''.$langs->trans("DeStockOnValidateOrder").''; +print ''; if (! empty($conf->commande->enabled)) { print ""; @@ -206,8 +210,8 @@ $found++; //{ print ''; -print ''.$langs->trans("DeStockOnShipment").''; -print ''; +print ''.$langs->trans("DeStockOnShipment").''; +print ''; if (! empty($conf->expedition->enabled)) { print ""; @@ -226,8 +230,8 @@ $found++; print ''; -print ''.$langs->trans("DeStockOnShipmentOnClosing").''; -print ''; +print ''.$langs->trans("DeStockOnShipmentOnClosing").''; +print ''; if (! empty($conf->expedition->enabled)) { print ""; @@ -268,8 +272,8 @@ $found=0; print ''; -print ''.$langs->trans("ReStockOnBill").''; -print ''; +print ''.$langs->trans("ReStockOnBill").''; +print ''; if (! empty($conf->fournisseur->enabled)) { print ""; @@ -289,8 +293,8 @@ $found++; print ''; -print ''.$langs->trans("ReStockOnValidateOrder").''; -print ''; +print ''.$langs->trans("ReStockOnValidateOrder").''; +print ''; if (! empty($conf->fournisseur->enabled)) { print ""; @@ -309,8 +313,8 @@ $found++; print ''; -print ''.$langs->trans("ReStockOnDispatchOrder").''; -print ''; +print ''.$langs->trans("ReStockOnDispatchOrder").''; +print ''; if (! empty($conf->fournisseur->enabled)) { print ""; @@ -346,8 +350,8 @@ print ''."\n"; print ''; -print ''.$langs->trans("WarehouseAllowNegativeTransfer").''; -print ''; +print ''.$langs->trans("WarehouseAllowNegativeTransfer").''; +print ''; print ""; print ''; print ""; @@ -361,8 +365,8 @@ print "\n"; if($conf->invoice->enabled) { $var = !$var; print ''; - print ''.$langs->trans("StockMustBeEnoughForInvoice").''; - print ''; + print ''.$langs->trans("StockMustBeEnoughForInvoice").''; + print ''; print ""; print ''; print ""; @@ -376,8 +380,8 @@ if($conf->invoice->enabled) { if($conf->order->enabled) { $var = !$var; print ''; - print ''.$langs->trans("StockMustBeEnoughForOrder").''; - print ''; + print ''.$langs->trans("StockMustBeEnoughForOrder").''; + print ''; print ""; print ''; print ""; @@ -391,8 +395,8 @@ if($conf->order->enabled) { if($conf->expedition->enabled) { $var = !$var; print ''; - print ''.$langs->trans("StockMustBeEnoughForShipment").''; - print ''; + print ''.$langs->trans("StockMustBeEnoughForShipment").''; + print ''; print ""; print ''; print ""; @@ -404,6 +408,9 @@ if($conf->expedition->enabled) { } print ''; + +print '
'; + $virtualdiffersfromphysical=0; if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) @@ -411,7 +418,6 @@ if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) if ($virtualdiffersfromphysical) { - print '
'; print ''; print ''; print " \n"; @@ -419,8 +425,8 @@ if ($virtualdiffersfromphysical) print ''."\n"; $var = !$var; print ''; - print ''; - print ''; + print '\n"; print "\n"; print '
".$langs->trans("RuleForStockReplenishment")." ".img_help('help',$langs->trans("VirtualDiffersFromPhysical"))."
'.$langs->trans("UseVirtualStockByDefault").''; + print ''.$langs->trans("UseVirtualStockByDefault").''; print ""; print ''; print ""; @@ -430,9 +436,70 @@ if ($virtualdiffersfromphysical) print "
'; + print '
'; } +print ''; + +print ''; +print " \n"; +print " \n"; +print ''."\n"; + +print ''; +print ''; +print '\n"; +print "\n"; + +print ''; +print ''; +print '\n"; +print "\n"; + +print ''; +print ''; +print '\n"; +print "\n"; + +if (! empty($conf->fournisseur->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) { + + print ''; + print ''; + print '\n\n"; +} + +print '
".$langs->trans("Other")." 
'.$langs->trans("UserWarehouseAutoCreate").''; +print ""; +print ''; +print ""; +print $form->selectyesno("STOCK_USERSTOCK_AUTOCREATE",$conf->global->STOCK_USERSTOCK_AUTOCREATE,1); +print ''; +print ''; +print "
'; +print $form->textwithpicto($langs->trans("StockSupportServices"), $langs->trans("StockSupportServicesDesc")).''; +print "
"; +print ''; +print ""; +print $form->selectyesno("STOCK_SUPPORTS_SERVICES",$conf->global->STOCK_SUPPORTS_SERVICES,1); +print ''; +print '
'; +print "
'.$langs->trans("AllowAddLimitStockByWarehouse").''; +print "
"; +print ''; +print ""; +print $form->selectyesno("STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE",$conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE,1); +print ''; +print '
'; +print "
'.$langs->trans("UseDispatchStatus").''; + print "
"; + print ''; + print ""; + print $form->selectyesno("SUPPLIER_ORDER_USE_DISPATCH_STATUS",$conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS,1); + print ''; + print "
\n"; + print "
'; + print '
'; if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { @@ -484,54 +551,6 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) print ''; } -print ''; - -print ''; -print " \n"; -print " \n"; -print ''."\n"; - -if (! empty($conf->fournisseur->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) { - - print ''; - print ''; - print '\n\n"; -} - -print ''; -print ''; -print '\n"; -print "\n"; - -print ''; -print ''; - -print '\n"; -print "\n"; - -print '
'; - /* I keep the option/feature, but hidden to end users for the moment. If feature is used by module, no need to have users see it. If not used by a module, I still need to understand in which case user may need this now we can set rule on product page. if ($conf->global->PRODUIT_SOUSPRODUITS) @@ -539,9 +558,8 @@ if ($conf->global->PRODUIT_SOUSPRODUITS) print ''; - print ''; - - print ''; + print '
".$langs->trans("Other")." 
'.$langs->trans("UseDispatchStatus").''; - print "
"; - print ''; - print ""; - print $form->selectyesno("SUPPLIER_ORDER_USE_DISPATCH_STATUS",$conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS,1); - print ''; - print "
\n"; - print "
'.$langs->trans("UserWarehouseAutoCreate").''; -print "
"; -print ''; -print ""; -print $form->selectyesno("STOCK_USERSTOCK_AUTOCREATE",$conf->global->STOCK_USERSTOCK_AUTOCREATE,1); -print ''; -print '
'; -print "
'.$langs->trans("AllowAddLimitStockByWarehouse").''; -print "
"; -print ''; -print ""; -print $form->selectyesno("STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE",$conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE,1); -print ''; -print '
'; -print "
'.$langs->trans("IndependantSubProductStock").''; + print ''.$langs->trans("IndependantSubProductStock").''; print "
"; print ''; print ""; @@ -553,8 +571,6 @@ if ($conf->global->PRODUIT_SOUSPRODUITS) } */ -print '
'; - llxFooter(); diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index cda14147ece..6019977120e 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -195,4 +195,6 @@ InventoryFlushed=Inventory flushed ExitEditMode=Exit edition inventoryDeleteLine=Delete line RegulateStock=Regulate Stock -ListInventory=List \ No newline at end of file +ListInventory=List +StockSupportServices=Stock management support services +StockSupportServicesDesc=By default, you can stock only product with type "product". If on, and if module service is on, you can also stock a product with type "service" \ No newline at end of file From 8bb3130aab8ba7d0ae6600c2efdec472bf8796b4 Mon Sep 17 00:00:00 2001 From: tysauron Date: Wed, 20 Sep 2017 00:35:52 +0200 Subject: [PATCH 060/177] For use ajax select company --- htdocs/projet/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 97f9ff41d54..1146ba49b80 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -528,7 +528,7 @@ if ($action == 'create' && $user->rights->projet->creer) print ''; $filteronlist=''; if (! empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) $filteronlist=$conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; - $text=$form->select_thirdparty_list(GETPOST('socid','int'), 'socid', $filteronlist, 'SelectThirdParty', 1, 0, array(), '', 0, 0, 'minwidth300'); + $text=$form->select_company(GETPOST('socid','int'), 'socid', $filteronlist, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300'); if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) { $texthelp=$langs->trans("IfNeedToUseOhterObjectKeepEmpty"); @@ -747,7 +747,7 @@ elseif ($object->id > 0) print ''; $filteronlist=''; if (! empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) $filteronlist=$conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; - $text=$form->select_thirdparty_list($object->thirdparty->id, 'socid', $filteronlist, 'None', 1, 0, array(), '', 0, 0, 'minwidth300'); + $text=$form->select_company($object->thirdparty->id, 'socid', $filteronlist, 'None', 1, 0, array(), 0, 'minwidth300'); if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) { $texthelp=$langs->trans("IfNeedToUseOhterObjectKeepEmpty"); From 3220225af3377ec32ecabcce2da9852cedfffdd0 Mon Sep 17 00:00:00 2001 From: tysauron Date: Wed, 20 Sep 2017 00:53:48 +0200 Subject: [PATCH 061/177] Bug get socid with old object sosciete --- htdocs/projet/tasks/contact.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/tasks/contact.php b/htdocs/projet/tasks/contact.php index 3d834fe28b6..6cdbc204749 100644 --- a/htdocs/projet/tasks/contact.php +++ b/htdocs/projet/tasks/contact.php @@ -397,7 +397,7 @@ if ($id > 0 || ! empty($ref)) print ''; $thirdpartyofproject=$projectstatic->getListContactId('thirdparty'); - $selectedCompany = isset($_GET["newcompany"])?$_GET["newcompany"]:$projectstatic->societe->id; + $selectedCompany = isset($_GET["newcompany"])?$_GET["newcompany"]:$projectstatic->socid; $selectedCompany = $formcompany->selectCompaniesForNewContact($object, 'id', $selectedCompany, 'newcompany', $thirdpartyofproject, 0, '&withproject='.$withproject); print ''; From 78b45bd972155766311893f81361b1ae0cb5af31 Mon Sep 17 00:00:00 2001 From: Pilon David Date: Wed, 20 Sep 2017 09:41:32 +0200 Subject: [PATCH 062/177] Update interface_20_modWorkflow_WorkflowManager.class.php --- ...e_20_modWorkflow_WorkflowManager.class.php | 79 ++++++++++--------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index fa93db2503c..bfa0efad8e6 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -55,7 +55,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers // Proposals to order if ($action == 'PROPAL_CLOSE_SIGNED') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_PROPAL_AUTOCREATE_ORDER)) { include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; @@ -74,7 +74,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers // Order to invoice if ($action == 'ORDER_CLOSE') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); if (! empty($conf->facture->enabled) && ! empty($conf->global->WORKFLOW_ORDER_AUTOCREATE_INVOICE)) { include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; @@ -90,12 +90,10 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } - - // Order classify billed proposal if ($action == 'ORDER_CLASSIFY_BILLED') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); if (! empty($conf->propal->enabled) && ! empty($conf->global->WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL)) { $object->fetchObjectLinked('','propal',$object->id,$object->element); @@ -106,8 +104,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers { if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht; } - dol_syslog("Amount of linked proposals = ".$totalonlinkedelements.", of order = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) + dol_syslog( "Amount of linked proposals = ".$totalonlinkedelements.", of order = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) { foreach($object->linkedObjects['propal'] as $element) { @@ -119,11 +117,35 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } - // classify billed order + // classify billed order & billed propososal if ($action == 'BILL_VALIDATE') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); - + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); + + // First classify billed the order to allow the proposal classify process + if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER)) + { + $object->fetchObjectLinked('','commande',$object->id,$object->element); + if (! empty($object->linkedObjects)) + { + $totalonlinkedelements=0; + foreach($object->linkedObjects['commande'] as $element) + { + if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht; + } + dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) + { + foreach($object->linkedObjects['commande'] as $element) + { + $ret=$element->classifyBilled($user); + } + } + } + return $ret; + } + + // Second classify billed the proposal. if (! empty($conf->propal->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL)) { $object->fetchObjectLinked('','propal',$object->id,$object->element); @@ -134,8 +156,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers { if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht; } - dol_syslog("Amount of linked proposals = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) + dol_syslog( "Amount of linked proposals = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) { foreach($object->linkedObjects['propal'] as $element) { @@ -145,34 +167,13 @@ class InterfaceWorkflowManager extends DolibarrTriggers } return $ret; } - - if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER)) - { - $object->fetchObjectLinked('','commande',$object->id,$object->element); - if (! empty($object->linkedObjects)) - { - $totalonlinkedelements=0; - foreach($object->linkedObjects['commande'] as $element) - { - if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht; - } - dol_syslog("Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) - { - foreach($object->linkedObjects['commande'] as $element) - { - $ret=$element->classifyBilled($user); - } - } - } - return $ret; - } + } // Invoice classify billed order if ($action == 'BILL_PAYED') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER)) { @@ -184,8 +185,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers { if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht; } - dol_syslog("Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) + dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) { foreach($object->linkedObjects['commande'] as $element) { @@ -199,8 +200,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers if ($action=='SHIPPING_VALIDATE') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); - + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); if (! empty($conf->commande->enabled) && ! empty($conf->expedition->enabled) && ! empty($conf->global->WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING)) { @@ -234,6 +234,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } } + //Build array of quantity ordered by product if (is_array($order->lines) && count($order->lines)>0) { foreach($order->lines as $orderline) { From 052e025537b33e8bdd57095e23e44a34eb4b0b5a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Sep 2017 11:42:05 +0200 Subject: [PATCH 063/177] Better detection of log to include merge labels --- build/makepack-dolibarr.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 80cc9b0856c..e0fa89d924d 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -366,7 +366,9 @@ if ($nboftargetok) { } else # For a maintenance release { - print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e \'^FIX\|NEW\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa'; + #print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e \'^FIX\|NEW\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa'; + print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. | grep -v "Merge branch" | grep -v "Merge pull" | grep "^ " | sed -e "s/^[0-9a-z]* *//" | grep -e \'^FIX\|NEW\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa'; + } print "\n"; if (! $ret) From 5e2cc050472a98bd3b1517dfd0f896c645966a32 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Sep 2017 11:12:47 +0200 Subject: [PATCH 064/177] Prepare 6.0.1 --- ChangeLog | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/ChangeLog b/ChangeLog index aafbbf5ff45..994e1702407 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,48 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 6.0.1 compared to 6.0.* ***** + +FIX: #7000 Dashboard link for late pending payment supplier invoices do not work +FIX: #7325 Default VAT rate when editing template invoices is 0% +FIX: #7330 +FIX: #7359 +FIX: #7367 +FIX: #7368 +FIX: #7391 +FIX: #7420 +FIX: Add some missing attributes in Adherent:makeSubstitution (type, phone… +FIX: Bad const name +FIX: Bad link to unpayed suppliers invoices +FIX: Better protection to no send email when we change limit +FIX: Calculation in the activity box +FIX: Clean bad parameters when inserting line of template invoice +FIX: dateSelector was not taken into account +FIX: hidden option MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN +FIX: journalization for bank journal should not rely on a label. +FIX: menu enty when url is external link +FIX: missing supplier qty and supplier discount in available fields for product export. +FIX: multicompany better accuracy in rounding and with revenue stamp. +FIX: Must use pdf format page as default for merging PDF. +FIX: PDF output was sharing 2 different currencies in same total +FIX: Position of signature on strato template +FIX: Protection to avoid to apply credit note discount > remain to pay +FIX: Remove warning when using log into syslog +FIX: Responsive +FIX: Security fixes (filter onload js, less verbose error message in +FIX: SEPA recording payment must save one payment in bank per customer +FIX: Several problem with the last event box on project/tasks +FIX: Sign of amount in origin currency on credit note created from lines +FIX: Some page of admin were not responsive +FIX: SQL injection +FIX: time.php crashed without project id in param +FIX: transfer of line extrafields from order to invoice +FIX: Upgrade missing on field +FIX: View of timespent for another user +FIX: ODT generation +FIX: CVE-2017-9840, CVE-2017-14238, CVE-2017-14239, CVE-2017-14240, CVE-2017-14241, + CVE-2017-14242 + ***** ChangeLog for 6.0.0 compared to 5.0.* ***** NEW: Add experimental BlockeLog module (to log business events in a non reversible log file). From 1314e00bc642b3085755865b621c7310b0c297d2 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 20 Sep 2017 14:46:51 +0200 Subject: [PATCH 065/177] Fix: check if array and check empty value if required --- htdocs/core/class/extrafields.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 12d958b6ebb..53327f67a15 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1708,7 +1708,7 @@ class ExtraFields if (! empty($onlykey) && $key != $onlykey) continue; $key_type = $this->attribute_type[$key]; - if($this->attribute_required[$key] && !GETPOST("options_$key",2)) + if ($this->attribute_required[$key] && empty($_POST["options_".$key])) // Check if empty without GETPOST, value can be alpha, int, array, etc... { $nofillrequired++; $error_field_required[] = $value; @@ -1721,7 +1721,7 @@ class ExtraFields } else if (in_array($key_type,array('checkbox','chkbxlst'))) { - $value_arr=GETPOST("options_".$key); + $value_arr=GETPOST("options_".$key, 'array'); // check if an array if (!empty($value_arr)) { $value_key=implode($value_arr,','); }else { @@ -1740,7 +1740,7 @@ class ExtraFields $object->array_options["options_".$key]=$value_key; } - if($nofillrequired) { + if ($nofillrequired) { $langs->load('errors'); setEventMessages($langs->trans('ErrorFieldsRequired').' : '.implode(', ',$error_field_required), null, 'errors'); return -1; From 1d6213ea7d829767834ebe5486e7ef8422c65546 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Sep 2017 15:29:47 +0200 Subject: [PATCH 066/177] Add picto for cheque payment --- htdocs/public/payment/newpayment.php | 2 +- htdocs/theme/common/cheque.png | Bin 0 -> 2483 bytes htdocs/theme/eldy/style.css.php | 26 +++++++++----------------- htdocs/theme/md/style.css.php | 6 ++++-- 4 files changed, 14 insertions(+), 20 deletions(-) create mode 100644 htdocs/theme/common/cheque.png diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 72ad0390cce..62f82bc33d1 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -602,7 +602,7 @@ print $text; // Output payment summary form print ''; print ''; -print ''."\n"; +print ''."\n"; $found=false; $error=0; diff --git a/htdocs/theme/common/cheque.png b/htdocs/theme/common/cheque.png new file mode 100644 index 0000000000000000000000000000000000000000..34b89a1e1d010a5fc6246970393cecced8228904 GIT binary patch literal 2483 zcmV;k2~75hP)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00|pOL_t(|+U=ct>>O1U$3L^b z<=2*4i@ZcAEttw1g_v0^yyI z5RkXLA%zeWLjkomk%uk){r0!lKkl9U&febHojW_TGdp{~$!2HnJa*=M@44sPbI-jC z0RbtoB@hKM3^zUv`~>(AQ0DVAaBvXK@Zox3y&$q}J_?usE(#(V4$J_au}E}%CV?*o zaaA8@q#!fa)ZYhjRUdCS2vxuaV4ZcW1nLipCn%fv{ z;2pF5u4i{d883K`KtZ{L{!VOv46HTVE#Q35d(8rl4iuD+2ZgiqBT+uj1QXgGpAUjK z%f}*ND>qrq@x2~)G`6MR4I(WUvw_zIA?Jx>hi4%4-5}EPaj76~Eif*Qz2!;j1h6!S zv|P*-q)pN}fPHiZE&X#4Y5Dk-aE|^Y%I5SZskOp>5zJV4EP;a&dwnZauJ_IChsOsZ&gc5(7%aI$=vs73I5R(9)-Z zILpV0g3vcb`8Ya-)7LpVAc(YFY;A%AF(I-~xh#Wo^l}hs`M5=BscbeQbP(T%)J?$W zgGkH8d_mg(fc?a=3o~fxWkICn<1V44zqSGm>j|SULx(R2P26A|Tb02%S{6iFE@lC* z2ts}=j(weMqc9;HSTfEN#I3UkdEJxL7I173Y58aw;#$C0MfsQLoe5}X*{=%XEFYH$ za_$r5TLP~+NNgD==p5iG2dT4yNXx}ert1*TQa0&_0T1Dx z%#`#ZOT_g{@gJJ23!#g6GbKVf;oD-*gc-Eg+po8I0AV-X_ zOwND_waML;=|r-4wG>|sJI90(LC;UUJ7{S+gvKOZD)yfTp73;z<^V@o4p)FdGlQ$F zfWI3Xh83EkOPLI5?ST%|1AGtot7j!V!vrn>{spW+kLDCn0iy)-5hav$>#il4q$r_W z89(GxUC!;>%Uw(I3Mg6ouPRIX0KQyfLY0rXYvir+Ilwpa6VaK^RClx3 z_jsrp@C)3Dj{f-IH1x8rqhLb^Ho%={py5`}mSG(D>4-GB?K}uo1J>FV8D9G5HP+I? zHMD5E`XYKdzt8WC0pA<}4IL^kSK{0ZmF$>Nj}-nw?qbto;Yf{(pcS60UcRFS-a$GoI;E0Q-8? zLw57>Xo91ZLV5;0zXWt9-<~D_;Cirr>}$NpMvU3$6~>gu^*0M!8V!-7G?C!JE;9Z^ zT-go<9`EOeeNfg43m?apsBT==@tB>{Vl@C>nM`H=r}^BM$)_ zSR+E)J~p&UH*?$K;2!2DC`_FYW z!CT{w3Mn>^?AY7gu1k_v2{VDSm>yQU(R|;KveGQ4 z+N+Yy0KR43rX*>80@#S2Dp-_Vj?nQ=iL=mC3s140(@tUe1)b{x4a$l0v40bJbX%G! z1)282S|vCPrvm>3ejrGD((zn_ezwY@=-Fp^5jzhZB7CG~UalRSUpy!qT6Q0GEqWo2 zy1~mSY7kI$c-j6y=S$=+frYwi=<(?I zt`b22nR1%6qDj(zQoPn)WLaJ#_a8y8F4LEWHb=PTuddkh{08`03S}Y>LhEQVuOc~T z7fXYZ%6pC2bX&Vgo;!wK5v}iTOWIg&9c|{hL-L%tr=SFnwpxUSNYN;Hxmmj{0Ylv6 z+BdDMO|2>>ite_|Ku=csK>UE57MP^rip{4FMkG(`vtK}^Xg%ycp=+vNWc59ho|T0A z+POfzDz`10ZYy>wM;~Upszk$7{RUI6J>KX{By? xUmUhJ>D^s_#^>@kVw<{}9P)Pq0s_jw{{h9JxNccM6oLQ%002ovPDHLkV1ffXjZy#r literal 0 HcmV?d00001 diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index a83d2ed9dd8..1c991f9ccd7 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -344,48 +344,40 @@ input.buttongen { vertical-align: middle; } input.buttonpayment { - width: 300px; + min-width: 280px; margin-bottom: 15px; background-image: none; line-height: 24px; padding: 8px; + background: none; + border: 2px solid #666666; } input.buttonpaymentcb { background-image: url(); background-size: 26px; background-repeat: no-repeat; - background-position: 5px 5px; + background-position: 2px 11px; } input.buttonpaymentcheque { background-image: url(); - background-repeat: no-repeat; - background-position: 8px 7px; -} -input.buttonpaymentcb { - background-image: url(); background-size: 24px; background-repeat: no-repeat; - background-position: 5px 4px; -} -input.buttonpaymentcheque { - background-image: url(); - background-repeat: no-repeat; - background-position: 5px 4px; + background-position: 2px 8px; } input.buttonpaymentpaypal { background-image: url(); background-repeat: no-repeat; - background-position: 8px 7px; + background-position: 8px 11px; } input.buttonpaymentpaybox { background-image: url(); background-repeat: no-repeat; - background-position: 8px 7px; + background-position: 8px 11px; } input.buttonpaymentstripe { background-image: url(); background-repeat: no-repeat; - background-position: 8px 7px; + background-position: 8px 11px; } /* Used by timesheets */ span.timesheetalreadyrecorded input { @@ -3147,7 +3139,7 @@ div.titre { /* text-shadow: 1px 1px 2px #FFFFFF; */ } -#dolpaymenttable { width: 600px; font-size: 13px; } +#dolpaymenttable { max-width: 600px; font-size: 16px; } #tablepublicpayment { border: 1px solid #CCCCCC !important; width: 100%; padding: 20px; } #tablepublicpayment .CTableRow1 { background-color: #F0F0F0 !important; } #tablepublicpayment tr.liste_total { border-bottom: 1px solid #CCCCCC !important; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 0f3711bf45b..1ed9b433be7 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -341,11 +341,13 @@ input.buttongen { vertical-align: middle; } input.buttonpayment { - width: 300px; + min-width: 280px; margin-bottom: 15px; background-image: none; line-height: 24px; padding: 8px; + background: none; + border: 2px solid #666666; } input.buttonpaymentcb { background-image: url(); @@ -3237,7 +3239,7 @@ div.titre { dol_optimize_smallscreen)?'':'margin-top: 4px;'); ?> } -#dolpaymenttable { width: 600px; font-size: 13px; } +#dolpaymenttable { max-width: 600px; font-size: 16px; } #tablepublicpayment { border: 1px solid #CCCCCC !important; width: 100%; padding: 20px; } #tablepublicpayment .CTableRow1 { background-color: #F0F0F0 !important; } #tablepublicpayment tr.liste_total { border-bottom: 1px solid #CCCCCC !important; } From 77fea1983c14f3739cc0623472bdde6f52007857 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 20 Sep 2017 16:57:38 +0200 Subject: [PATCH 067/177] Fix: wrong supplier product price id --- htdocs/fourn/class/fournisseur.commande.class.php | 6 +++--- htdocs/fourn/commande/card.php | 2 +- htdocs/product/class/product.class.php | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 0c2c7044e5d..528e32fd4a4 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1414,7 +1414,7 @@ class CommandeFournisseur extends CommonOrder if ($remise_percent == 0 && $prod->remise_percent !=0) $remise_percent =$prod->remise_percent; - + } if ($result == 0) // If result == 0, we failed to found the supplier reference price { @@ -2678,14 +2678,14 @@ class CommandeFournisseur extends CommonOrder if ($db->num_rows($query)) { $obj = $db->fetch_object($query); - + $string = $langs->trans($obj->code); if ($string == $obj->code) { $string = $obj->label != '-' ? $obj->label : ''; } return $string; - } + } } else dol_print_error($db); } diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 56566438206..48a2e72661b 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -409,7 +409,7 @@ if (empty($reshook)) $localtax1_tx, $localtax2_tx, $idprod, - $productsupplier->id, + $productsupplier->product_fourn_price_id, $productsupplier->fourn_ref, $remise_percent, 'HT', diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index a6a4ef25f09..05adfc1b5c5 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1532,6 +1532,7 @@ class Product extends CommonObject $obj->price = $price_result; } } + $this->product_fourn_price_id = $obj->rowid; $this->buyprice = $obj->price; // deprecated $this->fourn_pu = $obj->price / $obj->quantity; // Unit price of product of supplier $this->fourn_price_base_type = 'HT'; // Price base type @@ -1577,6 +1578,7 @@ class Product extends CommonObject $obj->price = $price_result; } } + $this->product_fourn_price_id = $obj->rowid; $this->buyprice = $obj->price; // deprecated $this->fourn_qty = $obj->quantity; // min quantity for price for a virtual supplier $this->fourn_pu = $obj->price / $obj->quantity; // Unit price of product for a virtual supplier From 577c64cc3735d6db8f75ee7efbe1767b606b7dfa Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Sep 2017 17:23:36 +0200 Subject: [PATCH 068/177] WIP work on param download on payment page --- htdocs/compta/facture/class/facture.class.php | 17 +++++++++++++++++ htdocs/public/payment/newpayment.php | 16 ++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 76b41f3ce86..41cc8042144 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1051,6 +1051,23 @@ class Facture extends CommonInvoice else return -1; } + /** + * Return link to download file from a direct external access + * + * @param int $withpicto Add download picto into link + * @return string HTML link to file + */ + function getDirectExternalLink($withpicto=0) + { + // Define $urlwithroot + $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); + $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + + $url='eee'; + return ''.$this->ref.''; + } + /** * Return clicable link of object (with eventually picto) * diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 62f82bc33d1..0c8fbbc733d 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -808,7 +808,7 @@ if ($source == 'invoice') print ''."\n"; // Debitor @@ -821,8 +821,8 @@ if ($source == 'invoice') $text=''.$langs->trans("PaymentInvoiceRef",$invoice->ref).''; print ''."\n"; // Amount @@ -846,13 +846,21 @@ if ($source == 'invoice') print ''."\n"; // Tag - print ''."\n"; + // Add download link + if (GETPOST('download','int') > 0) + { + print ''."\n"; + } + // Shipping address $shipToName=$invoice->thirdparty->name; $shipToStreet=$invoice->thirdparty->address; From e61032a313ebfef3ed64a4749e9b30dab2d17400 Mon Sep 17 00:00:00 2001 From: tysauron Date: Wed, 20 Sep 2017 00:53:48 +0200 Subject: [PATCH 069/177] Bug get socid with old object sosciete --- htdocs/projet/tasks/contact.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/tasks/contact.php b/htdocs/projet/tasks/contact.php index 3d834fe28b6..6cdbc204749 100644 --- a/htdocs/projet/tasks/contact.php +++ b/htdocs/projet/tasks/contact.php @@ -397,7 +397,7 @@ if ($id > 0 || ! empty($ref)) print ''; From 2f317c583400dfeb326364acd530ba9d1a98b117 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Sep 2017 19:34:14 +0200 Subject: [PATCH 070/177] Debug online payment using unique form --- htdocs/public/payment/newpayment.php | 55 ++++++++++++++-------------- htdocs/public/payment/paymentko.php | 2 +- htdocs/public/payment/paymentok.php | 5 +-- htdocs/theme/eldy/style.css.php | 4 +- htdocs/theme/md/style.css.php | 5 ++- 5 files changed, 37 insertions(+), 34 deletions(-) diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 0c8fbbc733d..faf40e17067 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -66,21 +66,21 @@ $suffix=GETPOST("suffix",'aZ09'); $amount=price2num(GETPOST("amount",'alpha')); if (! GETPOST("currency",'alpha')) $currency=$conf->currency; else $currency=GETPOST("currency",'alpha'); -$source = GETPOST("source",'alpha'); +$source = GETPOST("s",'alpha')?GETPOST("s",'alpha'):GETPOST("source",'alpha'); if (! $action) { - if (! GETPOST("amount",'alpha') && ! GETPOST("source",'alpha')) + if (! GETPOST("amount",'alpha') && ! $source) { print $langs->trans('ErrorBadParameters')." - amount or source"; exit; } - if (is_numeric($amount) && ! GETPOST("tag",'alpha') && ! GETPOST("source",'alpha')) + if (is_numeric($amount) && ! GETPOST("tag",'alpha') && ! $source) { print $langs->trans('ErrorBadParameters')." - tag or source"; exit; } - if (GETPOST("source",'alpha') && ! GETPOST("ref",'alpha')) + if ($source && ! GETPOST("ref",'alpha')) { print $langs->trans('ErrorBadParameters')." - ref"; exit; @@ -111,7 +111,6 @@ $urlok=$urlwithroot.'/public/payment/paymentok.php?'; $urlko=$urlwithroot.'/public/payment/paymentko.php?'; // Complete urls for post treatment -$SOURCE=GETPOST("source",'alpha'); $ref=$REF=GETPOST('ref','alpha'); $TAG=GETPOST("tag",'alpha'); $FULLTAG=GETPOST("fulltag",'alpha'); // fulltag is tag with more informations @@ -123,10 +122,10 @@ if (! empty($suffix)) $urlok.='suffix='.urlencode($suffix).'&'; $urlko.='suffix='.urlencode($suffix).'&'; } -if (! empty($SOURCE)) +if ($source) { - $urlok.='source='.urlencode($SOURCE).'&'; - $urlko.='source='.urlencode($SOURCE).'&'; + $urlok.='s='.urlencode($source).'&'; + $urlko.='s='.urlencode($source).'&'; } if (! empty($REF)) { @@ -143,15 +142,16 @@ if (! empty($FULLTAG)) $urlok.='fulltag='.urlencode($FULLTAG).'&'; $urlko.='fulltag='.urlencode($FULLTAG).'&'; } +/* This make url too long. Seems not required into the back url if (! empty($SECUREKEY)) { $urlok.='securekey='.urlencode($SECUREKEY).'&'; $urlko.='securekey='.urlencode($SECUREKEY).'&'; -} +}*/ if (! empty($entity)) { - $urlok.='entity='.urlencode($entity).'&'; - $urlko.='entity='.urlencode($entity).'&'; + $urlok.='e='.urlencode($entity).'&'; + $urlko.='e='.urlencode($entity).'&'; } $urlok=preg_replace('/&$/','',$urlok); // Remove last & $urlko=preg_replace('/&$/','',$urlko); // Remove last & @@ -223,7 +223,7 @@ if (! empty($conf->global->PAYMENT_SECURITY_TOKEN)) { if (! empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { - if ($SOURCE && $REF) $token = dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . $SOURCE . $REF, 2); // Use the source in the hash to avoid duplicates if the references are identical + if ($source && $REF) $token = dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . $source . $REF, 2); // Use the source in the hash to avoid duplicates if the references are identical else $token = dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); } else @@ -340,13 +340,14 @@ if ($action == 'dopayment') elseif (empty($email)) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("YourEMail")); elseif (! isValidEMail($email)) $mesg=$langs->trans("ErrorBadEMail",$email); elseif (! $origfulltag) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("PaymentCode")); - elseif (dol_strlen($urlok) > 150) $mesg='Error urlok too long '.$urlok; - elseif (dol_strlen($urlko) > 150) $mesg='Error urlko too long '.$urlko; + elseif (dol_strlen($urlok) > 150) $mesg='Error urlok too long '.$urlok.'( Paybox requires 150, found '.strlen($urlok).')'; + elseif (dol_strlen($urlko) > 150) $mesg='Error urlko too long '.$urlko.'( Paybox requires 150, found '.strlen($urlok).')'; if (empty($mesg)) { dol_syslog("newpayment.php call paybox api and do redirect", LOG_DEBUG); + include_once DOL_DOCUMENT_ROOT.'/paybox/lib/paybox.lib.php'; print_paybox_redirect($PRICE, $conf->currency, $email, $urlok, $urlko, $FULLTAG); session_destroy(); @@ -499,10 +500,10 @@ $conf->dol_hide_leftmenu=1; llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody'); // Check link validity -if (! empty($SOURCE) && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', ''))) +if ($source && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', ''))) { $langs->load("errors"); - dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $SOURCE, $ref)); + dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $source, $ref)); llxFooter(); $db->close(); exit; @@ -528,7 +529,7 @@ print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; -print ''; +print ''; print "\n"; print ''."\n"; print ''."\n"; @@ -709,8 +710,8 @@ if ($source == 'order') $text=''.$langs->trans("PaymentOrderRef",$order->ref).''; print ''."\n"; // Amount @@ -821,7 +822,7 @@ if ($source == 'invoice') $text=''.$langs->trans("PaymentInvoiceRef",$invoice->ref).''; print ''."\n"; @@ -1004,8 +1005,8 @@ if ($source == 'contractline') print ''."\n"; // Quantity @@ -1146,8 +1147,8 @@ if ($source == 'membersubscription') $text=''.$langs->trans("PaymentSubscription").''; print ''."\n"; if ($member->last_subscription_date || $member->last_subscription_amount) @@ -1272,7 +1273,7 @@ if ($action != 'dopayment') if (! empty($conf->stripe->enabled)) { // If STRIPE_PICTO_FOR_PAYMENT is 'cb' we show a picto of a crdit card instead of stripe - print '
'; + print '
'; } if (! empty($conf->paypal->enabled)) @@ -1365,12 +1366,12 @@ if (preg_match('/^dopayment/',$action)) print ''."\n"; print ''."\n"; print ''."\n"; - print ''."\n"; + print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; - print ''; + print ''; print ''."\n"; print ''."\n"; diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index cbea7db650f..bdc301a0dce 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -31,7 +31,7 @@ define("NOCSRFCHECK",1); // We accept to go on this page from external web site. // For MultiCompany module. // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php // TODO This should be useless. Because entity must be retreive from object ref and not from url. -$entity=(! empty($_GET['entity']) ? (int) $_GET['entity'] : (! empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); +$entity=(! empty($_GET['e']) ? (int) $_GET['e'] : (! empty($_POST['e']) ? (int) $_POST['e'] : 1)); if (is_numeric($entity)) define("DOLENTITY", $entity); require '../../main.inc.php'; diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 29d2b78d142..7ccd95abcdf 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -31,7 +31,7 @@ define("NOCSRFCHECK",1); // We accept to go on this page from external web site. // For MultiCompany module. // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php // TODO This should be useless. Because entity must be retreive from object ref and not from url. -$entity=(! empty($_GET['entity']) ? (int) $_GET['entity'] : (! empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); +$entity=(! empty($_GET['e']) ? (int) $_GET['e'] : (! empty($_POST['e']) ? (int) $_POST['e'] : 1)); if (is_numeric($entity)) define("DOLENTITY", $entity); require '../../main.inc.php'; @@ -76,7 +76,7 @@ if (! empty($conf->paypal->enabled)) $FULLTAG=GETPOST('FULLTAG'); if (empty($FULLTAG)) $FULLTAG=GETPOST('fulltag'); -$source=GETPOST('source'); +$source=GETPOST('s','alpha')?GETPOST('s','alpha'):GETPOST('source','alpha'); $ref=GETPOST('ref'); $suffix=GETPOST("suffix",'aZ09'); @@ -145,7 +145,6 @@ $conf->dol_hide_leftmenu=1; llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody'); - // Show message print ''."\n"; print '
'."\n"; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 1c991f9ccd7..e6bf4d8233a 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1084,7 +1084,7 @@ div.fiche { dol_hide_leftmenu)) print 'margin-bottom: 12px;'."\n"; ?> } body.onlinepaymentbody div.fiche { /* For online payment page */ - margin: 40px !important; + margin: 20px !important; } div.fiche>table:first-child { margin-bottom: 15px !important; @@ -3139,7 +3139,7 @@ div.titre { /* text-shadow: 1px 1px 2px #FFFFFF; */ } -#dolpaymenttable { max-width: 600px; font-size: 16px; } +#dolpaymenttable { min-width: 310px; font-size: 16px; } /* Width must have min to make stripe input area visible */ #tablepublicpayment { border: 1px solid #CCCCCC !important; width: 100%; padding: 20px; } #tablepublicpayment .CTableRow1 { background-color: #F0F0F0 !important; } #tablepublicpayment tr.liste_total { border-bottom: 1px solid #CCCCCC !important; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 1ed9b433be7..64210218799 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1120,6 +1120,9 @@ div.fiche { dol_hide_leftmenu) && ! empty($conf->dol_hide_topmenu)) print 'margin-top: 4px;'; ?> margin-bottom: 15px; } +body.onlinepaymentbody div.fiche { /* For online payment page */ + margin: 20px !important; +} div.fichecenter { width: 100%; clear: both; /* This is to have div fichecenter that are true rectangles */ @@ -3239,7 +3242,7 @@ div.titre { dol_optimize_smallscreen)?'':'margin-top: 4px;'); ?> } -#dolpaymenttable { max-width: 600px; font-size: 16px; } +#dolpaymenttable { min-width: 320px; font-size: 16px; } /* Width must have min to make stripe input area visible */ #tablepublicpayment { border: 1px solid #CCCCCC !important; width: 100%; padding: 20px; } #tablepublicpayment .CTableRow1 { background-color: #F0F0F0 !important; } #tablepublicpayment tr.liste_total { border-bottom: 1px solid #CCCCCC !important; } From 0eb416d4afd3a4aeee16bfae41dea2223e3e5dd1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Sep 2017 20:41:40 +0200 Subject: [PATCH 071/177] Fix removal of a file --- htdocs/ecm/docfile.php | 26 +++++++++++---------- htdocs/ecm/index.php | 34 +++++++++++++--------------- htdocs/langs/en_US/ecm.lang | 3 ++- htdocs/public/payment/newpayment.php | 3 ++- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/htdocs/ecm/docfile.php b/htdocs/ecm/docfile.php index 192240b4943..29f1b21a321 100644 --- a/htdocs/ecm/docfile.php +++ b/htdocs/ecm/docfile.php @@ -19,12 +19,12 @@ * \file htdocs/ecm/docfile.php * \ingroup ecm * \brief Card of a file for ECM module - * \author Laurent Destailleur */ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php'; +require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/ecm.lib.php'; @@ -103,11 +103,9 @@ if (! empty($_GET["fileid"])) -/******************************************************************* - * ACTIONS - * - * Put here all code to do according to value of "action" parameter - ********************************************************************/ +/* + * Actions + */ if ($action == 'cancel') { @@ -166,11 +164,9 @@ if ($action == 'update') -/******************************************************************* - * PAGE - * - * Put here all code to do according to value of "action" parameter - ********************************************************************/ +/* + * View + */ llxHeader(); @@ -253,6 +249,13 @@ print dol_print_size($totalsize); print ''; */ +$filepath=$relativepath.$file->label; + +print '
'; + // Define $urlwithroot $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file @@ -264,7 +267,6 @@ $forcedownload=1; $rellink='/document.php?modulepart='.$modulepart; if ($forcedownload) $rellink.='&attachment=1'; if (! empty($object->entity)) $rellink.='&entity='.$object->entity; -$filepath=$relativepath.$file->label; $rellink.='&file='.urlencode($filepath); $fulllink=$urlwithroot.$rellink; print img_picto('','object_globe.png').' '; diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php index 94b1781ab81..77fb16f5afd 100644 --- a/htdocs/ecm/index.php +++ b/htdocs/ecm/index.php @@ -143,26 +143,24 @@ if ($action == 'confirm_deletefile') { if (GETPOST('confirm') == 'yes') { + // GETPOST('urlfile','alpha') is full relative URL from ecm root dir. Contains path of all sections. + //var_dump(GETPOST('urlfile'));exit; $langs->load("other"); - if ($section) - { - $result=$ecmdir->fetch($section); - if (! ($result > 0)) - { - dol_print_error($db,$ecmdir->error); - exit; - } - $relativepath=$ecmdir->getRelativePath(); - } - else $relativepath=''; + $upload_dir = $conf->ecm->dir_output.($relativepath?'/'.$relativepath:''); - $file = $upload_dir . "/" . GETPOST('urlfile'); // Do not use urldecode here ($_GET and $_POST are already decoded by PHP). + $file = $upload_dir . "/" . GETPOST('urlfile','alpha'); // Do not use urldecode here ($_GET and $_POST are already decoded by PHP). + //var_dump($file);exit; - $ret=dol_delete_file($file); - if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); - else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); - - $result=$ecmdir->changeNbOfFiles('-'); + $ret=dol_delete_file($file); // This include also the delete from file index in database. + if ($ret) + { + setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile','alpha')), null, 'mesgs'); + $result=$ecmdir->changeNbOfFiles('-'); + } + else + { + setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile','alpha')), null, 'errors'); + } clearstatcache(); } @@ -375,7 +373,7 @@ else print ''; } $url=((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))?'#':($_SERVER["PHP_SELF"].'?action=refreshmanual'.($module?'&module='.$module:'').($section?'&section='.$section:''))); -print ''; +print ''; print ''; print ''; diff --git a/htdocs/langs/en_US/ecm.lang b/htdocs/langs/en_US/ecm.lang index 5f651413301..a238a8cd384 100644 --- a/htdocs/langs/en_US/ecm.lang +++ b/htdocs/langs/en_US/ecm.lang @@ -41,4 +41,5 @@ ECMDirectoryForFiles=Relative directory for files CannotRemoveDirectoryContainsFiles=Removed not possible because it contains some files ECMFileManager=File manager ECMSelectASection=Select a directory on left tree... -DirNotSynchronizedSyncFirst=This directory seems to be created or modified outside ECM module. You must click on "Refresh" button first to synchronize disk and database to get content of this directory. +DirNotSynchronizedSyncFirst=This directory seems to be created or modified outside ECM module. You must click on "Resync" button first to synchronize disk and database to get content of this directory. +ReSyncListOfDir=Resync list of directories \ No newline at end of file diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index faf40e17067..52aa5950a92 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -67,6 +67,7 @@ $amount=price2num(GETPOST("amount",'alpha')); if (! GETPOST("currency",'alpha')) $currency=$conf->currency; else $currency=GETPOST("currency",'alpha'); $source = GETPOST("s",'alpha')?GETPOST("s",'alpha'):GETPOST("source",'alpha'); +$download = GETPOST('d','int')?GETPOST('d','int'):GETPOST('download','int'); if (! $action) { @@ -854,7 +855,7 @@ if ($source == 'invoice') print ''."\n"; // Add download link - if (GETPOST('download','int') > 0) + if ($download > 0) { print ''; */ +$relativetodocument = 'ecm/'.$relativepath; // $relativepath is relative to ECM dir, we need relative to document $filepath=$relativepath.$file->label; +$filepathtodocument=$relativetodocument.$file->label; print ''; // Define $urlwithroot @@ -261,6 +273,19 @@ $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($ $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current +print ''; + print ''; + print '
'.$langs->trans("ThisIsInformationOnPayment").' :
'.$langs->trans("ThisIsInformationOnPayment").' :
'.$langs->trans("Creditor"); print ''.$creditor.''; - print ''; + print ''; print '
'.$langs->trans("Designation"); print ''.$text; - print ''; - print ''; + print ''; + print ''; print '
'.$langs->trans("PaymentCode"); print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("Document"); + print ''; + print $invoice->getDirectExternalLink(1); + print '
'; $thirdpartyofproject=$projectstatic->getListContactId('thirdparty'); - $selectedCompany = isset($_GET["newcompany"])?$_GET["newcompany"]:$projectstatic->societe->id; + $selectedCompany = isset($_GET["newcompany"])?$_GET["newcompany"]:$projectstatic->socid; $selectedCompany = $formcompany->selectCompaniesForNewContact($object, 'id', $selectedCompany, 'newcompany', $thirdpartyofproject, 0, '&withproject='.$withproject); print '
'.$langs->trans("Designation"); print ''.$text; - print ''; - print ''; + print ''; + print ''; print '
'.$langs->trans("Designation"); print ''.$text; - print ''; + print ''; print ''; print '
'.$langs->trans("Designation"); print ''.$text; - print ''; - print ''; + print ''; + print ''; print '
'.$langs->trans("Designation"); print ''.$text; - print ''; - print ''; + print ''; + print ''; print '
'.$langs->trans("HashSaved").''; +$ecmfile = new EcmFiles($db); +print $filepath; +print '
'.$langs->trans("Document"); print ''; From beac7a7439e9aa638c568b658550de4a55063ece Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Sep 2017 21:29:27 +0200 Subject: [PATCH 072/177] Work on direct download links --- htdocs/core/lib/files.lib.php | 2 +- htdocs/ecm/class/ecmfiles.class.php | 2 +- htdocs/ecm/docfile.php | 36 +++++++++++++++++++++++++---- htdocs/langs/en_US/ecm.lang | 4 +++- htdocs/langs/en_US/main.lang | 3 ++- 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 238728068c9..83259aa41d2 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1537,7 +1537,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio $ecmfile=new EcmFiles($db); $ecmfile->filepath = $rel_dir; $ecmfile->filename = $filename; - $ecmfile->label = md5_file(dol_osencode($destfull)); + $ecmfile->label = md5_file(dol_osencode($destfull)); // MD5 of file content $ecmfile->fullpath_orig = $TFile['name'][$i]; $ecmfile->gen_or_uploaded = 'uploaded'; $ecmfile->description = ''; // indexed content diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index f1090757dad..abe5c403462 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -46,7 +46,7 @@ class EcmFiles //extends CommonObject /** */ - public $label; + public $label; // hash of file md5_file(dol_osencode($destfull)), so MD5 of file content public $entity; public $filename; public $filepath; diff --git a/htdocs/ecm/docfile.php b/htdocs/ecm/docfile.php index 29f1b21a321..045c3ebda8b 100644 --- a/htdocs/ecm/docfile.php +++ b/htdocs/ecm/docfile.php @@ -249,11 +249,23 @@ print dol_print_size($totalsize); print '
'.$langs->trans("HashSaved").''; $ecmfile = new EcmFiles($db); -print $filepath; +//$filenametosearch=basename($filepath); +//$filedirtosearch=basedir($filepath); +$ecmfile->fetch(0, '', $filepathtodocument); +if (! empty($ecmfile->label)) +{ + print $ecmfile->label; +} +else +{ + print img_warning().' '.$langs->trans("FileNotYetIndexedInDatabase"); +} print '
'.$langs->trans("DirectDownloadInternalLink").''; +$modulepart='ecm'; +$forcedownload=1; +$rellink='/document.php?modulepart='.$modulepart; +if ($forcedownload) $rellink.='&attachment=1'; +if (! empty($object->entity)) $rellink.='&entity='.$object->entity; +$rellink.='&file='.urlencode($filepath); +$fulllink=$urlwithroot.$rellink; +print img_picto('','object_globe.png').' '; +print ''; +print ' '.$langs->trans("Download").''; +print '
'.$langs->trans("DirectDownloadLink").''; $modulepart='ecm'; $forcedownload=1; @@ -269,12 +294,15 @@ if ($forcedownload) $rellink.='&attachment=1'; if (! empty($object->entity)) $rellink.='&entity='.$object->entity; $rellink.='&file='.urlencode($filepath); $fulllink=$urlwithroot.$rellink; -print img_picto('','object_globe.png').' '; -print ''; -print ' '.$langs->trans("Download").''; +// TODO +//print img_picto('','object_globe.png').' '; +//print ''; +//print ' '.$langs->trans("Download").''; print '
'; +print ajax_autoselect('downloadinternallink'); print ajax_autoselect('downloadlink'); dol_fiche_end(); diff --git a/htdocs/langs/en_US/ecm.lang b/htdocs/langs/en_US/ecm.lang index a238a8cd384..f7c0f0ab737 100644 --- a/htdocs/langs/en_US/ecm.lang +++ b/htdocs/langs/en_US/ecm.lang @@ -42,4 +42,6 @@ CannotRemoveDirectoryContainsFiles=Removed not possible because it contains some ECMFileManager=File manager ECMSelectASection=Select a directory on left tree... DirNotSynchronizedSyncFirst=This directory seems to be created or modified outside ECM module. You must click on "Resync" button first to synchronize disk and database to get content of this directory. -ReSyncListOfDir=Resync list of directories \ No newline at end of file +ReSyncListOfDir=Resync list of directories +HashSaved=Hash of file +FileNotYetIndexedInDatabase=File not yet indexed into database (try to re-upload it) \ No newline at end of file diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 1b92d87e9ba..dfe38b7fe65 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -792,7 +792,8 @@ GroupBy=Group by... ViewFlatList=View flat list RemoveString=Remove string '%s' SomeTranslationAreUncomplete=Some languages may be partially translated or may contains errors. If you detect some, you can fix language files registering to https://transifex.com/projects/p/dolibarr/. -DirectDownloadLink=Direct download link +DirectDownloadLink=Direct download link (public/external) +DirectDownloadInternalLink=Direct download link (need to be logged and permissions) Download=Download ActualizeCurrency=Update currency rate Fiscalyear=Fiscal year From 03ffbe55ce6f6f696f915d770008cc842f3ec46c Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Thu, 21 Sep 2017 11:34:19 +0200 Subject: [PATCH 073/177] fix ressource list --- htdocs/resource/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index c4d783739c0..98efb786f72 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -237,7 +237,7 @@ print "\n"; print ''; if (! empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'],$_SERVER["PHP_SELF"],"t.ref","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['ty.label']['checked'])) print_liste_field_titre($arrayfields['ty.label']['label'],$_SERVER["PHP_SELF"],"t.code","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['ty.label']['checked'])) print_liste_field_titre($arrayfields['ty.label']['label'],$_SERVER["PHP_SELF"],"ty.label","",$param,"",$sortfield,$sortorder); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { From e56840b9ec668e95647b707c186b2cc1f073de82 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Sep 2017 11:35:18 +0200 Subject: [PATCH 074/177] Clean deprecated code --- htdocs/comm/action/card.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 7b1c81af59c..b491c9007cb 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -397,7 +397,7 @@ if ($action == 'update') $datep=dol_mktime($fulldayevent?'00':$aphour, $fulldayevent?'00':$apmin, 0, $_POST["apmonth"], $_POST["apday"], $_POST["apyear"]); $datef=dol_mktime($fulldayevent?'23':$p2hour, $fulldayevent?'59':$p2min, $fulldayevent?'59':'0', $_POST["p2month"], $_POST["p2day"], $_POST["p2year"]); - $object->fk_action = dol_getIdFromCode($db, GETPOST("actioncode"), 'c_actioncomm'); + $object->type_id = dol_getIdFromCode($db, GETPOST("actioncode"), 'c_actioncomm'); $object->label = GETPOST("label"); $object->datep = $datep; $object->datef = $datef; @@ -407,8 +407,6 @@ if ($action == 'update') $object->location = GETPOST('location'); $object->socid = GETPOST("socid"); $object->contactid = GETPOST("contactid",'int'); - //$object->societe->id = $_POST["socid"]; // deprecated - //$object->contact->id = $_POST["contactid"]; // deprecated $object->fk_project = GETPOST("projectid",'int'); $object->note = GETPOST("note"); $object->pnote = GETPOST("note"); @@ -869,7 +867,7 @@ if ($id > 0) $datep=dol_mktime($fulldayevent?'00':$aphour, $fulldayevent?'00':$apmin, 0, $_POST["apmonth"], $_POST["apday"], $_POST["apyear"]); $datef=dol_mktime($fulldayevent?'23':$p2hour, $fulldayevent?'59':$p2min, $fulldayevent?'59':'0', $_POST["p2month"], $_POST["p2day"], $_POST["p2year"]); - $object->fk_action = dol_getIdFromCode($db, GETPOST("actioncode"), 'c_actioncomm'); + $object->type_id = dol_getIdFromCode($db, GETPOST("actioncode"), 'c_actioncomm'); $object->label = GETPOST("label"); $object->datep = $datep; $object->datef = $datef; @@ -879,8 +877,6 @@ if ($id > 0) $object->location = GETPOST('location'); $object->socid = GETPOST("socid"); $object->contactid = GETPOST("contactid",'int'); - //$object->societe->id = $_POST["socid"]; // deprecated - //$object->contact->id = $_POST["contactid"]; // deprecated $object->fk_project = GETPOST("projectid",'int'); $object->note = GETPOST("note"); From 52402171443b57b58d598dcf63cd1cbe8ae1774d Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Thu, 21 Sep 2017 11:36:50 +0200 Subject: [PATCH 075/177] fix again resource list --- htdocs/resource/list.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 98efb786f72..01d8f0929e0 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -135,6 +135,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x', { $search_ref=""; $search_label=""; + $search_type=""; $search_array_options=array(); $filter=array(); } From 8a06a1f43372a925e18d6c854395f84212b85254 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Sep 2017 11:50:36 +0200 Subject: [PATCH 076/177] Code comment --- htdocs/projet/document.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/htdocs/projet/document.php b/htdocs/projet/document.php index 8777d83e419..fbf9574bd75 100644 --- a/htdocs/projet/document.php +++ b/htdocs/projet/document.php @@ -20,7 +20,7 @@ /** * \file htdocs/projet/document.php * \ingroup project - * \brief Page de gestion des documents attachees a un projet + * \brief Page to managed related documents linked to a project */ require '../main.inc.php'; @@ -106,11 +106,11 @@ if ($object->id > 0) $totalsize+=$file['size']; } - + // Project card - + $linkback = ''.$langs->trans("BackToList").''; - + $morehtmlref='
'; // Title $morehtmlref.=$object->title; @@ -120,19 +120,19 @@ if ($object->id > 0) $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1, 'project'); } $morehtmlref.='
'; - + // Define a complementary filter for search of next/prev ref. if (! $user->rights->projet->all->lire) { $objectsListId = $object->getProjectsAuthorizedForUser($user,0,0); $object->next_prev_filter=" rowid in (".(count($objectsListId)?join(',',array_keys($objectsListId)):'0').")"; } - + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - - + + print '
'; - print '
'; + print '
'; print ''; @@ -141,10 +141,10 @@ if ($object->id > 0) print ''; print "
'.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
\n"; - + print '
'; - + dol_fiche_end(); $modulepart = 'project'; From 23604a2b54dd2905885e35099252239d022488dc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Sep 2017 11:54:37 +0200 Subject: [PATCH 077/177] NEW Add hidden option PROJECT_DISABLE_UNLINK_FROM_OVERVIEW --- htdocs/projet/element.php | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 1e4d4132944..f76b6f9f0cc 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -643,33 +643,6 @@ foreach ($listofreferent as $key => $value) $total_ttc = -$total_ttc; } - /*switch ($classname) { - case 'FactureFournisseur': - $newclassname = 'SupplierInvoice'; - break; - case 'Facture': - $newclassname = 'Bill'; - break; - case 'Propal': - $newclassname = 'CommercialProposal'; - break; - case 'Commande': - $newclassname = 'Order'; - break; - case 'Expedition': - $newclassname = 'Sending'; - break; - case 'Contrat': - $newclassname = 'Contract'; - break; - case 'MouvementStock': - $newclassname = 'StockMovement'; - break; - default: - $newclassname = $classname; - }*/ - - $var = ! $var; print ''; // Module print ''.$name.''; @@ -693,7 +666,6 @@ print ''; print ""; - print '

'; print '
'; @@ -771,7 +743,7 @@ foreach ($listofreferent as $key => $value) print ''; print ''; - // Remove link + // Remove link column print ''; // Ref print ''.$langs->trans("Ref").''; @@ -862,11 +834,15 @@ foreach ($listofreferent as $key => $value) } print ''; + // Remove link print '\n"; From cafcbe03e1c7d3b214b7b1a1f3873bef9e38cfdf Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Thu, 21 Sep 2017 12:02:45 +0200 Subject: [PATCH 078/177] agin fix list ressource --- htdocs/resource/list.php | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 01d8f0929e0..1b5c11df748 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -164,14 +164,7 @@ if ($action == 'delete_resource') print $form->formconfirm($_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_resource",'','',1); } -// Load object list -$ret = $object->fetch_all($sortorder, $sortfield, $limit, $offset, $filter); -if($ret == -1) { - dol_print_error($db,$object->error); - exit; -} else { - print_barre_liste($pagetitle, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $ret+1, $object->num_all,'title_generic.png'); -} + $var=true; @@ -188,6 +181,26 @@ print ''; print ''; print ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $ret = $object->fetch_all('', '', 0, 0, $filter); + if($ret == -1) { + dol_print_error($db,$object->error); + exit; + } else { + $nbtotalofrecords = $ret; + } +} + +// Load object list +$ret = $object->fetch_all($sortorder, $sortfield, $limit, $offset, $filter); +if($ret == -1) { + dol_print_error($db,$object->error); + exit; +} else { + print_barre_liste($pagetitle, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $ret+1, $nbtotalofrecords,'title_generic.png', 0, '', '', $limit); +} + $moreforfilter = ''; print '
'; From 296e678c1be26500c87a56bc46fbe0db84573b7b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Sep 2017 12:02:46 +0200 Subject: [PATCH 079/177] Solve url too long with paybox --- htdocs/public/payment/newpayment.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 52aa5950a92..1862a5b8a47 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -143,12 +143,11 @@ if (! empty($FULLTAG)) $urlok.='fulltag='.urlencode($FULLTAG).'&'; $urlko.='fulltag='.urlencode($FULLTAG).'&'; } -/* This make url too long. Seems not required into the back url if (! empty($SECUREKEY)) { $urlok.='securekey='.urlencode($SECUREKEY).'&'; $urlko.='securekey='.urlencode($SECUREKEY).'&'; -}*/ +} if (! empty($entity)) { $urlok.='e='.urlencode($entity).'&'; @@ -336,6 +335,10 @@ if ($action == 'dopayment') $origfulltag=GETPOST("fulltag",'alpha'); + // Securekey into back url useless for back url and we need an url lower than 150. + $urlok = preg_replace('/securekey=[^&]+/', '', $urlok); + $urlko = preg_replace('/securekey=[^&]+/', '', $urlko); + $mesg=''; if (empty($PRICE) || ! is_numeric($PRICE)) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Amount")); elseif (empty($email)) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("YourEMail")); From 76c3fe1260cd5cd50f16b6f50997381543183401 Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Thu, 21 Sep 2017 12:06:43 +0200 Subject: [PATCH 080/177] Fix: Stripe not working on live mode --- htdocs/stripe/config.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php index 0cc15c7fb60..9aaed7cf0b9 100644 --- a/htdocs/stripe/config.php +++ b/htdocs/stripe/config.php @@ -1,6 +1,7 @@ * Copyright (C) 2017 Saasprov + * Copyright (C) 2017 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 @@ -32,7 +33,7 @@ global $conf; //use \includes\stripe as stripe; $stripe = array(); -if (empty($conf->global->SKYPE_LIVE)) +if (empty($conf->global->STRIPE_LIVE)) { $stripe = array( "secret_key" => $conf->global->STRIPE_TEST_SECRET_KEY, From 01f9d59e759d6daef533521f08a0508877169467 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 21 Sep 2017 12:16:01 +0200 Subject: [PATCH 081/177] Fix: use another method --- htdocs/adherents/class/adherent.class.php | 18 +++---- .../adherents/class/adherent_type.class.php | 9 ++-- htdocs/adherents/type.php | 4 ++ htdocs/adherents/type_ldap.php | 2 + ...interface_50_modLdap_Ldapsynchro.class.php | 54 +++++++++++-------- 5 files changed, 49 insertions(+), 38 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 47bf219216c..ffeb68c9445 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -729,7 +729,15 @@ class Adherent extends CommonObject // Check parameters if (empty($rowid)) $rowid=$this->id; - $this->db->begin(); + $this->db->begin(); + + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_DELETE',$user); + if ($result < 0) $error++; + // End call triggers + } // Remove category $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid; @@ -797,14 +805,6 @@ class Adherent extends CommonObject } } - if (! $error && ! $notrigger) - { - // Call trigger - $result=$this->call_trigger('MEMBER_DELETE',$user); - if ($result < 0) $error++; - // End call triggers - } - if (! $error) { $this->db->commit(); diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 7293fd10e90..30c85618bfa 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -256,10 +256,9 @@ class AdherentType extends CommonObject * Fonction qui permet de recuperer le status de l'adherent * * @param int $rowid Id of member type to load - * @param bool $load_members Load members or not * @return int <0 if KO, >0 if OK */ - function fetch($rowid, $load_members = true) + function fetch($rowid) { $sql = "SELECT d.rowid, d.libelle as label, d.statut, d.subscription, d.mail_valid, d.note, d.vote"; $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d"; @@ -282,10 +281,6 @@ class AdherentType extends CommonObject $this->mail_valid = $obj->mail_valid; $this->note = $obj->note; $this->vote = $obj->vote; - - if ($load_members) { - $this->members=$this->listMembersForMemberType(); - } } return 1; @@ -375,6 +370,8 @@ class AdherentType extends CommonObject $this->db->free($resql); + $this->members=$ret; + return $ret; } else diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index b59d8b7530d..ee9f9b2f3c8 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -154,6 +154,10 @@ if ($action == 'update' && $user->rights->adherent->configurer) { $object->fetch($rowid); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') { + $object->listMembersForMemberType(); + } + $object->oldcopy = clone $object; $object->label = trim($label); diff --git a/htdocs/adherents/type_ldap.php b/htdocs/adherents/type_ldap.php index e610f651df5..d4de1a2afdb 100644 --- a/htdocs/adherents/type_ldap.php +++ b/htdocs/adherents/type_ldap.php @@ -63,6 +63,8 @@ if (empty($reshook)) if ($result > 0) { + $object->listMembersForMemberType(); + $info = $object->_load_ldap_info(); $dn = $object->_load_ldap_dn($info); $olddn = $dn; // We can say that old dn = dn as we force synchro diff --git a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php index 05a9a5a1b20..a906ec821ed 100644 --- a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php +++ b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php @@ -437,6 +437,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers if ($object->typeid > 0) { $membertype->fetch($object->typeid); + $membertype->listMembersForMemberType(); $oldinfo=$membertype->_load_ldap_info(); $olddn=$membertype->_load_ldap_dn($oldinfo); @@ -549,36 +550,38 @@ class InterfaceLdapsynchro extends DolibarrTriggers // For member type if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') { + /* + * Change member info + */ + $newmembertype=new AdherentType($this->db); + $newmembertype->fetch($object->typeid); + $newmembertype->listMembersForMemberType(); + + $oldinfo=$newmembertype->_load_ldap_info(); + $olddn=$newmembertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$newmembertype->_load_ldap_dn($oldinfo,1); + $search = "(".$newmembertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$newmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$newmembertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + if ($object->oldcopy->typeid != $object->typeid) { - /* - * Add member in new member type - */ - $newmembertype=new AdherentType($this->db); - $newmembertype->fetch($object->typeid); - - $oldinfo=$newmembertype->_load_ldap_info(); - $olddn=$newmembertype->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$newmembertype->_load_ldap_dn($oldinfo,1); - $search = "(".$newmembertype->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$newmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) - $dn=$newmembertype->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - /* * Remove member in old member type */ $oldmembertype=new AdherentType($this->db); $oldmembertype->fetch($object->oldcopy->typeid); + $oldmembertype->listMembersForMemberType(); $oldinfo=$oldmembertype->_load_ldap_info(); $olddn=$oldmembertype->_load_ldap_dn($oldinfo); @@ -676,6 +679,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers */ $membertype=new AdherentType($this->db); $membertype->fetch($object->typeid); + $membertype->listMembersForMemberType('a.rowid != ' . $object->id); // remove deleted member from the list $oldinfo=$membertype->_load_ldap_info(); $olddn=$membertype->_load_ldap_dn($oldinfo); @@ -742,6 +746,8 @@ class InterfaceLdapsynchro extends DolibarrTriggers $object->oldcopy = clone $object; } + $object->oldcopy->listMembersForMemberType(); + $oldinfo=$object->oldcopy->_load_ldap_info(); $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); @@ -754,6 +760,8 @@ class InterfaceLdapsynchro extends DolibarrTriggers $olddn = ''; } + $object->listMembersForMemberType(); + $info=$object->_load_ldap_info(); $dn=$object->_load_ldap_dn($info); From 71fc5a99d6c08758f80c394122aa88be7c86ae0d Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 21 Sep 2017 12:19:14 +0200 Subject: [PATCH 082/177] Fix: list already load in trigger --- htdocs/adherents/type.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index ee9f9b2f3c8..b59d8b7530d 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -154,10 +154,6 @@ if ($action == 'update' && $user->rights->adherent->configurer) { $object->fetch($rowid); - if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') { - $object->listMembersForMemberType(); - } - $object->oldcopy = clone $object; $object->label = trim($label); From 8f19ffd097f695f10c45f8d44cf7d654a626741e Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Thu, 21 Sep 2017 12:22:10 +0200 Subject: [PATCH 083/177] Fix contract class for date --- htdocs/contrat/class/contrat.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 24b51e835a2..52bc7efd860 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -872,7 +872,7 @@ class Contrat extends CommonObject $sql.= " fk_commercial_signature, fk_commercial_suivi, fk_projet,"; $sql.= " ref, entity, note_private, note_public, ref_customer, ref_supplier, ref_ext)"; $sql.= " VALUES ('".$this->db->idate($now)."',".$this->socid.",".$user->id; - $sql.= ", '".$this->db->idate($this->date_contrat)."'"; + $sql.= ", ".(dol_strlen($this->date_contrat)!=0 ? "'".$this->db->idate($this->date_contrat)."'" : "NULL"); $sql.= ",".($this->commercial_signature_id>0?$this->commercial_signature_id:"NULL"); $sql.= ",".($this->commercial_suivi_id>0?$this->commercial_suivi_id:"NULL"); $sql.= ",".($this->fk_project>0?$this->fk_project:"NULL"); From 96efe43e3cbcc8c8f7a94b5187be927cbc679068 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Sep 2017 12:48:07 +0200 Subject: [PATCH 084/177] NEW Provide a way to download a file from a public URL. --- htdocs/document.php | 37 ++++++++++++++++++++++++++--- htdocs/ecm/class/ecmfiles.class.php | 15 +++++++++--- htdocs/ecm/docfile.php | 30 ++++++++++++++--------- 3 files changed, 65 insertions(+), 17 deletions(-) diff --git a/htdocs/document.php b/htdocs/document.php index d35021005e6..c09441ea0ed 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -59,24 +59,28 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $encoding = ''; $action=GETPOST('action','alpha'); -$original_file=GETPOST('file','alpha'); // Do not use urldecode here ($_GET are already decoded by PHP). +$original_file=GETPOST('file','alpha'); // Do not use urldecode here ($_GET are already decoded by PHP). +$hashn=GETPOST('hashn','aZ09'); +$hashc=GETPOST('hashc','aZ09'); $modulepart=GETPOST('modulepart','alpha'); $urlsource=GETPOST('urlsource','alpha'); $entity=GETPOST('entity','int')?GETPOST('entity','int'):$conf->entity; // Security check -if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart'); +if (empty($modulepart)) accessforbidden('Bad link. Bad value for parameter modulepart',0,0,1); +if (empty($original_file) && empty($hashn) && empty($hashc)) accessforbidden('Bad link. Missing identification to find file (original_file, hasn or hashc)',0,0,1); if ($modulepart == 'fckeditor') $modulepart='medias'; // For backward compatibility $socid=0; if ($user->societe_id > 0) $socid = $user->societe_id; // For some module part, dir may be privates -if (in_array($modulepart,array('facture_paiement','unpaid'))) +if (in_array($modulepart, array('facture_paiement','unpaid'))) { if (! $user->rights->societe->client->voir || $socid) $original_file='private/'.$user->id.'/'.$original_file; // If user has no permission to see all, output dir is specific to user } + /* * Action */ @@ -99,6 +103,33 @@ if (preg_match('/\.(html|htm)$/i',$original_file)) $attachment = false; if (isset($_GET["attachment"])) $attachment = GETPOST("attachment",'alpha')?true:false; if (! empty($conf->global->MAIN_DISABLE_FORCE_SAVEAS)) $attachment=false; +// If we have a hash (hashc or hashn), we guess the original_file. Note: using hashn is not reliable. +if (! empty($hashn) || ! empty($hashc)) +{ + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(0, $hashn, '', $hashc); + if ($result > 0) + { + $tmp = explode('/', $ecmfile->filepath, 2); // $ecmfile->filepatch is relative to document directory + $moduleparttocheck = $tmp[0]; + if ($moduleparttocheck == $modulepart) + { + $original_file = (($tmp[1]?$tmp[1].'/':'').$ecmfile->filename); // this is relative to module dir + //var_dump($original_file); exit; + } + else + { + accessforbidden('Bad link. File owns to another module part.',0,0,1); + } + } + else + { + accessforbidden('Bad link. File was not found or removed recently.',0,0,1); + } +} + + // Security: Delete string ../ into $original_file $original_file = str_replace("../","/", $original_file); diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index abe5c403462..77fa294aeed 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -157,6 +157,7 @@ class EcmFiles //extends CommonObject // Insert request $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '('; + $sql.= 'ref,'; $sql.= 'label,'; $sql.= 'entity,'; $sql.= 'filename,'; @@ -174,6 +175,7 @@ class EcmFiles //extends CommonObject $sql.= 'fk_user_m,'; $sql.= 'acl'; $sql .= ') VALUES ('; + $sql .= " '".dol_hash($this->filepath.'/'.$this->filename, 3)."', "; $sql .= ' '.(! isset($this->label)?'NULL':"'".$this->db->escape($this->label)."'").','; $sql .= ' '.(! isset($this->entity)?$conf->entity:$this->entity).','; $sql .= ' '.(! isset($this->filename)?'NULL':"'".$this->db->escape($this->filename)."'").','; @@ -232,11 +234,12 @@ class EcmFiles //extends CommonObject * Load object in memory from the database * * @param int $id Id object - * @param string $ref Not used yet. Will contains a hash id from filename+filepath + * @param string $ref Hash of file name (filename+filepath). Not always defined on some version. * @param string $relativepath Relative path of file from document directory. Example: path/path2/file + * @param string $hashoffile Hash of file content. Take the first one found if same file is at different places. This hash will also change if file content is changed. * @return int <0 if KO, 0 if not found, >0 if OK */ - public function fetch($id, $ref = null, $relativepath = '') + public function fetch($id, $ref = '', $relativepath = '', $hashoffile='') { dol_syslog(__METHOD__, LOG_DEBUG); @@ -268,11 +271,16 @@ class EcmFiles //extends CommonObject if ($relativepath) { $sql .= " AND t.filepath = '" . $this->db->escape(dirname($relativepath)) . "' AND t.filename = '".$this->db->escape(basename($relativepath))."'"; } - elseif (null !== $ref) { + elseif (! empty($ref)) { $sql .= " AND t.ref = '".$this->db->escape($ref)."'"; + } + elseif (! empty($hashoffile)) { + $sql .= " AND t.label = '".$this->db->escape($hashoffile)."'"; } else { $sql .= ' AND t.rowid = ' . $id; } + $this->db->plimit(1); + $this->db->order('t.rowid', 'ASC'); // When we search on hash of content, we take the first one. $resql = $this->db->query($sql); if ($resql) { @@ -484,6 +492,7 @@ class EcmFiles //extends CommonObject // Update request $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET'; + $sql .= ' ref = '.dol_hash($this->filepath.'/'.$this->filename, 3); $sql .= ' label = '.(isset($this->label)?"'".$this->db->escape($this->label)."'":"null").','; $sql .= ' entity = '.(isset($this->entity)?$this->entity:$conf->entity).','; $sql .= ' filename = '.(isset($this->filename)?"'".$this->db->escape($this->filename)."'":"null").','; diff --git a/htdocs/ecm/docfile.php b/htdocs/ecm/docfile.php index 045c3ebda8b..aa708a85f24 100644 --- a/htdocs/ecm/docfile.php +++ b/htdocs/ecm/docfile.php @@ -287,17 +287,25 @@ print ' '.$langs->trans("Download").''; print '
'; print ''; print '
'; if ($tablename != 'projet_task' && $tablename != 'stock_mouvement') { - print '' . img_picto($langs->trans('Unlink'), 'editdelete') . ''; + if (empty($conf->global->PROJECT_DISABLE_UNLINK_FROM_OVERVIEW) || $user->admin) // PROJECT_DISABLE_UNLINK_FROM_OVERVIEW is empty by defaut, so this test true + { + print '' . img_picto($langs->trans('Unlink'), 'editdelete') . ''; + } } print "
'.$langs->trans("DirectDownloadLink").''; -$modulepart='ecm'; -$forcedownload=1; -$rellink='/document.php?modulepart='.$modulepart; -if ($forcedownload) $rellink.='&attachment=1'; -if (! empty($object->entity)) $rellink.='&entity='.$object->entity; -$rellink.='&file='.urlencode($filepath); -$fulllink=$urlwithroot.$rellink; -// TODO -//print img_picto('','object_globe.png').' '; -//print ''; -//print ' '.$langs->trans("Download").''; +if (! empty($ecmfile->ref) || ! empty($ecmfile->label)) +{ + $modulepart='ecm'; + $forcedownload=1; + $rellink='/document.php?modulepart='.$modulepart; + if ($forcedownload) $rellink.='&attachment=1'; + if (! empty($object->entity)) $rellink.='&entity='.$object->entity; + //$rellink.='&file='.urlencode($filepath); // No need of name of file for public link, we will use the hash + $fulllink=$urlwithroot.$rellink; + if (! empty($ecmfile->ref)) $fulllink.='&hashn='.$ecmfile->ref; // Hash of file path + elseif (! empty($ecmfile->label)) $fulllink.='&hashc='.$ecmfile->label; // Hash of file content + print img_picto('','object_globe.png').' '; + print ''; + print ' '.$langs->trans("Download").''; +} +else +{ + print img_warning().' '.$langs->trans("FileNotYetIndexedInDatabase"); +} print '
'; From 57358f0ce5d5a626f38ae87385c493b5fde641fe Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Sep 2017 14:02:42 +0200 Subject: [PATCH 085/177] NEW Provide a way to download a file from a public URL for files in ECM --- htdocs/document.php | 11 +- htdocs/ecm/class/ecmfiles.class.php | 43 ++++- htdocs/ecm/docfile.php | 162 +++++++++++------- .../install/mysql/migration/6.0.0-7.0.0.sql | 5 + htdocs/install/mysql/tables/llx_ecm_files.sql | 5 +- htdocs/langs/en_US/ecm.lang | 5 +- htdocs/langs/en_US/main.lang | 3 +- htdocs/langs/en_US/website.lang | 2 +- 8 files changed, 158 insertions(+), 78 deletions(-) diff --git a/htdocs/document.php b/htdocs/document.php index c09441ea0ed..590d47d2c13 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -60,15 +60,14 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $encoding = ''; $action=GETPOST('action','alpha'); $original_file=GETPOST('file','alpha'); // Do not use urldecode here ($_GET are already decoded by PHP). -$hashn=GETPOST('hashn','aZ09'); -$hashc=GETPOST('hashc','aZ09'); +$hashp=GETPOST('hashp','aZ09'); $modulepart=GETPOST('modulepart','alpha'); $urlsource=GETPOST('urlsource','alpha'); $entity=GETPOST('entity','int')?GETPOST('entity','int'):$conf->entity; // Security check if (empty($modulepart)) accessforbidden('Bad link. Bad value for parameter modulepart',0,0,1); -if (empty($original_file) && empty($hashn) && empty($hashc)) accessforbidden('Bad link. Missing identification to find file (original_file, hasn or hashc)',0,0,1); +if (empty($original_file) && empty($hashp)) accessforbidden('Bad link. Missing identification to find file (original_file or hashp)',0,0,1); if ($modulepart == 'fckeditor') $modulepart='medias'; // For backward compatibility $socid=0; @@ -103,12 +102,12 @@ if (preg_match('/\.(html|htm)$/i',$original_file)) $attachment = false; if (isset($_GET["attachment"])) $attachment = GETPOST("attachment",'alpha')?true:false; if (! empty($conf->global->MAIN_DISABLE_FORCE_SAVEAS)) $attachment=false; -// If we have a hash (hashc or hashn), we guess the original_file. Note: using hashn is not reliable. -if (! empty($hashn) || ! empty($hashc)) +// If we have a hash public (hashp), we guess the original_file. +if (! empty($hashp)) { include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; $ecmfile=new EcmFiles($db); - $result = $ecmfile->fetch(0, $hashn, '', $hashc); + $result = $ecmfile->fetch(0, '', '', '', $hashp); if ($result > 0) { $tmp = explode('/', $ecmfile->filepath, 2); // $ecmfile->filepatch is relative to document directory diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index 77fa294aeed..0035b18d3c7 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -46,7 +46,9 @@ class EcmFiles //extends CommonObject /** */ - public $label; // hash of file md5_file(dol_osencode($destfull)), so MD5 of file content + public $ref; // hash of file path + public $label; // hash of file content (md5_file(dol_osencode($destfull)) + public $share; // hash for file sharing. empty by default public $entity; public $filename; public $filepath; @@ -94,10 +96,15 @@ class EcmFiles //extends CommonObject $error = 0; // Clean parameters - + if (isset($this->ref)) { + $this->ref = trim($this->ref); + } if (isset($this->label)) { $this->label = trim($this->label); } + if (isset($this->share)) { + $this->share = trim($this->share); + } if (isset($this->entity)) { $this->entity = trim($this->entity); } @@ -136,6 +143,10 @@ class EcmFiles //extends CommonObject } if (empty($this->date_c)) $this->date_c = dol_now(); + // If ref not defined + if (empty($ref)) $ref = dol_hash($this->filepath.'/'.$this->filename, 3); + + $maxposition=0; if (empty($this->position)) // Get max used { @@ -159,6 +170,7 @@ class EcmFiles //extends CommonObject $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '('; $sql.= 'ref,'; $sql.= 'label,'; + $sql.= 'share,'; $sql.= 'entity,'; $sql.= 'filename,'; $sql.= 'filepath,'; @@ -175,8 +187,9 @@ class EcmFiles //extends CommonObject $sql.= 'fk_user_m,'; $sql.= 'acl'; $sql .= ') VALUES ('; - $sql .= " '".dol_hash($this->filepath.'/'.$this->filename, 3)."', "; + $sql .= " '".$ref."', "; $sql .= ' '.(! isset($this->label)?'NULL':"'".$this->db->escape($this->label)."'").','; + $sql .= ' '.(! isset($this->share)?'NULL':"'".$this->db->escape($this->share)."'").','; $sql .= ' '.(! isset($this->entity)?$conf->entity:$this->entity).','; $sql .= ' '.(! isset($this->filename)?'NULL':"'".$this->db->escape($this->filename)."'").','; $sql .= ' '.(! isset($this->filepath)?'NULL':"'".$this->db->escape($this->filepath)."'").','; @@ -237,9 +250,10 @@ class EcmFiles //extends CommonObject * @param string $ref Hash of file name (filename+filepath). Not always defined on some version. * @param string $relativepath Relative path of file from document directory. Example: path/path2/file * @param string $hashoffile Hash of file content. Take the first one found if same file is at different places. This hash will also change if file content is changed. + * @param string $hashforshare Hash of file sharing. * @return int <0 if KO, 0 if not found, >0 if OK */ - public function fetch($id, $ref = '', $relativepath = '', $hashoffile='') + public function fetch($id, $ref = '', $relativepath = '', $hashoffile='', $hashforshare='') { dol_syslog(__METHOD__, LOG_DEBUG); @@ -247,6 +261,7 @@ class EcmFiles //extends CommonObject $sql .= ' t.rowid,'; $sql .= " t.ref,"; $sql .= " t.label,"; + $sql .= " t.share,"; $sql .= " t.entity,"; $sql .= " t.filename,"; $sql .= " t.filepath,"; @@ -276,11 +291,15 @@ class EcmFiles //extends CommonObject } elseif (! empty($hashoffile)) { $sql .= " AND t.label = '".$this->db->escape($hashoffile)."'"; + } + elseif (! empty($hashforshare)) { + $sql .= " AND t.share = '".$this->db->escape($hashforshare)."'"; } else { $sql .= ' AND t.rowid = ' . $id; } + // When we search on hash of content, we take the first one. Solve also hash conflict. $this->db->plimit(1); - $this->db->order('t.rowid', 'ASC'); // When we search on hash of content, we take the first one. + $this->db->order('t.rowid', 'ASC'); $resql = $this->db->query($sql); if ($resql) { @@ -291,6 +310,7 @@ class EcmFiles //extends CommonObject $this->id = $obj->rowid; $this->ref = $obj->ref; $this->label = $obj->label; + $this->share = $obj->share; $this->entity = $obj->entity; $this->filename = $obj->filename; $this->filepath = $obj->filepath; @@ -352,6 +372,7 @@ class EcmFiles //extends CommonObject $sql = 'SELECT'; $sql .= ' t.rowid,'; $sql .= " t.label,"; + $sql .= " t.share,"; $sql .= " t.entity,"; $sql .= " t.filename,"; $sql .= " t.filepath,"; @@ -401,8 +422,9 @@ class EcmFiles //extends CommonObject $line = new EcmfilesLine(); $line->id = $obj->rowid; - + $line->ref = $obj->ref; $line->label = $obj->label; + $line->share = $obj->share; $line->entity = $obj->entity; $line->filename = $obj->filename; $line->filepath = $obj->filepath; @@ -446,9 +468,15 @@ class EcmFiles //extends CommonObject // Clean parameters + if (isset($this->ref)) { + $this->ref = trim($this->ref); + } if (isset($this->label)) { $this->label = trim($this->label); } + if (isset($this->share)) { + $this->share = trim($this->share); + } if (isset($this->entity)) { $this->entity = trim($this->entity); } @@ -492,8 +520,9 @@ class EcmFiles //extends CommonObject // Update request $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET'; - $sql .= ' ref = '.dol_hash($this->filepath.'/'.$this->filename, 3); + $sql .= " ref = '".dol_hash($this->filepath.'/'.$this->filename, 3)."',"; $sql .= ' label = '.(isset($this->label)?"'".$this->db->escape($this->label)."'":"null").','; + $sql .= ' share = '.(! empty($this->share)?"'".$this->db->escape($this->share)."'":"null").','; $sql .= ' entity = '.(isset($this->entity)?$this->entity:$conf->entity).','; $sql .= ' filename = '.(isset($this->filename)?"'".$this->db->escape($this->filename)."'":"null").','; $sql .= ' filepath = '.(isset($this->filepath)?"'".$this->db->escape($this->filepath)."'":"null").','; diff --git a/htdocs/ecm/docfile.php b/htdocs/ecm/docfile.php index aa708a85f24..a856ab22c36 100644 --- a/htdocs/ecm/docfile.php +++ b/htdocs/ecm/docfile.php @@ -39,6 +39,9 @@ $langs->load("bills"); $langs->load("contracts"); $langs->load("categories"); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'alpha'); + if (!$user->rights->ecm->setup) accessforbidden(); // Get parameters @@ -61,8 +64,6 @@ $pagenext = $page + 1; if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="label"; -$cancel=GETPOST('cancel','alpha'); -$action=GETPOST('action','aZ09'); $section=GETPOST("section"); if (! $section) { @@ -87,19 +88,25 @@ if (! $result > 0) $relativepath=$ecmdir->getRelativePath(); $upload_dir = $conf->ecm->dir_output.'/'.$relativepath; +$fullpath=$conf->ecm->dir_output.'/'.$relativepath.$urlfile; -/* -$ecmfile = new ECMFile($db); -if (! empty($_GET["fileid"])) +$file = new stdClass(); +$file->section_id=$ecmdir->id; +$file->label=$urlfile; + +$relativetodocument = 'ecm/'.$relativepath; // $relativepath is relative to ECM dir, we need relative to document +$filepath=$relativepath.$file->label; +$filepathtodocument=$relativetodocument.$file->label; + +// Try to load object from index +$object = new ECMFiles($db); +$result=$object->fetch(0, '', $filepathtodocument); +if (! ($result >= 0)) { - $result=$ecmfile->fetch($_GET["fileid"]); - if (! $result > 0) - { - dol_print_error($db,$ecmfile->error); - exit; - } + dol_print_error($db, $object->error, $object->errors); + exit; } -*/ + @@ -107,7 +114,7 @@ if (! empty($_GET["fileid"])) * Actions */ -if ($action == 'cancel') +if ($cancel) { $action =''; if ($backtourl) @@ -117,7 +124,7 @@ if ($action == 'cancel') } else { - header("Location: ".DOL_URL_ROOT.'/ecm/index.php?action=file_manager§ion='.$section); + header("Location: ".DOL_URL_ROOT.'/ecm/docfile.php?urlfile='.$urlfile.'§ion='.$section); exit; } } @@ -127,8 +134,9 @@ if ($action == 'update') { $error=0; - $oldlabel=GETPOST('urlfile'); - $newlabel=GETPOST('label'); + $oldlabel=GETPOST('urlfile', 'alpha'); + $newlabel=GETPOST('label', 'alpha'); + $shareenabled = GETPOST('shareenabled', 'alpha'); //$db->begin(); @@ -142,7 +150,7 @@ if ($action == 'update') //print $oldfile.' - '.$newfile; if ($newlabel != $oldlabel) { - $result=dol_move($oldfile, $newfile); + $result=dol_move($oldfile, $newfile); // This include update of database if (! $result) { $langs->load('errors'); @@ -151,14 +159,39 @@ if ($action == 'update') } } + // Now we update index of file + $db->begin(); + if (! $error) { - //$db->commit(); + if (is_object($object)) + { + if ($shareenabled) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; + $object->share = getRandomPassword(true); + } + else + { + $object->share = ''; + } + $result = $object->update($user); + if ($result < 0) + { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } + } + } + + if (!$error) + { + $db->commit(); $urlfile=$newlabel; } else { - //$db->rollback(); + $db->rollback(); } } @@ -168,25 +201,20 @@ if ($action == 'update') * View */ -llxHeader(); - $form=new Form($db); -$fullpath=$conf->ecm->dir_output.'/'.$relativepath.$urlfile; - -$file = new stdClass(); -$file->section_id=$ecmdir->id; -$file->label=$urlfile; +llxHeader(); $head = ecm_file_prepare_head($file); -if ($_GET["action"] == 'edit') +if ($action == 'edit') { print ''; print ''; print ''; print ''; print ''; + print ''; } dol_fiche_head($head, 'card', $langs->trans("File"), 0, 'generic'); @@ -217,11 +245,11 @@ while ($tmpecmdir && $result > 0) print img_picto('','object_dir').' '.$langs->trans("ECMRoot").' -> '; print $s; print ' -> '; -if (GETPOST('action','aZ09') == 'edit') print ''; +if ($action == 'edit') print ''; else print $urlfile; print ''; /*print ''.$langs->trans("Description").''; -if ($_GET["action"] == 'edit') +if ($action == 'edit') { print ''; + } + else + { + print ''; + } + print ''; print ''; } print ''."\n"; @@ -292,7 +304,7 @@ if ($action == 'create') // Part to edit record if (($id || $ref) && $action == 'edit') { - print load_fiche_titre($langs->trans("MyModule")); + print load_fiche_titre($langs->trans("MyObject")); print ''; print ''; @@ -308,9 +320,21 @@ if (($id || $ref) && $action == 'edit') print ''.$langs->trans($val['label']).''; - print ''; + print ''; + if ($val['type'] == 'text') + { + print ''; + } + else + { + print ''; + } + print ''; print ''; } print ''; @@ -326,6 +350,7 @@ if (($id || $ref) && $action == 'edit') + // Part to show record if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 35731bc3bb0..96947035113 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -275,11 +275,11 @@ if ($action == 'add') } else { - $objectpage->title = GETPOST('WEBSITE_TITLE'); - $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME'); - $objectpage->description = GETPOST('WEBSITE_DESCRIPTION'); - $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS'); - $objectpage->lang = GETPOST('WEBSITE_LANG'); + $objectpage->title = GETPOST('WEBSITE_TITLE','alpha'); + $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME','alpha'); + $objectpage->description = GETPOST('WEBSITE_DESCRIPTION','alpha'); + $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS','alpha'); + $objectpage->lang = GETPOST('WEBSITE_LANG','alpha'); } if (! $error) @@ -392,7 +392,7 @@ if ($action == 'updatecss') // $htmlheadercontent.= "header('Content-type: text/html');\n"; // Not required. htmlheader.html is never call as a standalone page $htmlheadercontent.= "// END PHP ?>\n";*/ - $htmlheadercontent.= preg_replace(array('/\n*/ims','/<\/html>\n*/ims'),array('',''),GETPOST('WEBSITE_HTML_HEADER')); + $htmlheadercontent.= preg_replace(array('/\n*/ims','/<\/html>\n*/ims'),array('',''),GETPOST('WEBSITE_HTML_HEADER', 'none')); /*$htmlheadercontent.= "\n".'\n"; - $csscontent.= GETPOST('WEBSITE_CSS_INLINE'); + $csscontent.= GETPOST('WEBSITE_CSS_INLINE', 'none'); $csscontent.= "\n".'\n";*/ - $robotcontent.= GETPOST('WEBSITE_ROBOT'); + $robotcontent.= GETPOST('WEBSITE_ROBOT', 'none'); /*$robotcontent.= "\n".'\n";*/ - $htaccesscontent.= GETPOST('WEBSITE_HTACCESS'); + $htaccesscontent.= GETPOST('WEBSITE_HTACCESS', 'none'); /*$robotcontent.= "\n".'old_object = clone $objectpage; - $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME'); - $objectpage->title = GETPOST('WEBSITE_TITLE'); - $objectpage->description = GETPOST('WEBSITE_DESCRIPTION'); - $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS'); - $objectpage->lang = GETPOST('WEBSITE_LANG'); + $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME', 'alpha'); + $objectpage->title = GETPOST('WEBSITE_TITLE', 'alpha'); + $objectpage->description = GETPOST('WEBSITE_DESCRIPTION', 'alpha'); + $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS', 'alpha'); + $objectpage->lang = GETPOST('WEBSITE_LANG', 'alpha'); $res = $objectpage->update($user); if (! $res > 0) From e1b4788bc232433ccad802fb8bba966937ed8dee Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 23 Sep 2017 01:52:14 +0200 Subject: [PATCH 105/177] Update vat rates --- htdocs/install/mysql/data/llx_c_tva.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/install/mysql/data/llx_c_tva.sql b/htdocs/install/mysql/data/llx_c_tva.sql index cce279d79da..b4389ca8397 100644 --- a/htdocs/install/mysql/data/llx_c_tva.sql +++ b/htdocs/install/mysql/data/llx_c_tva.sql @@ -88,6 +88,8 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 9 -- CYPRUS (id country=78) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (781, 78, '19','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (782, 78, '9','0','VAT Rate 9',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (783, 78, '5','0','VAT Rate 5',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (784, 78, '0','0','VAT Rate 0',1); -- DANMERK (id country=80) From 2ca5f2e27e001ea58209569d615f031f86023771 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 23 Sep 2017 01:52:49 +0200 Subject: [PATCH 106/177] Prepare 6.0.2 --- htdocs/filefunc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index cbec259b2aa..394686cc5e4 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION','6.0.1'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','6.0.2'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); From a94f2b07e1c6a759a8888d02c1bccc83a12b8263 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 23 Sep 2017 02:46:33 +0200 Subject: [PATCH 107/177] Fix css --- htdocs/core/boxes/modules_boxes.php | 2 +- htdocs/theme/eldy/style.css.php | 9 +++++---- htdocs/theme/md/style.css.php | 9 +++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 9c496964942..93b8fa3d9d2 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -286,7 +286,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" if (isset($contents[$i])) { // TR - if (isset($contents[$i][0]['tr'])) $out.= ''; + if (isset($contents[$i][0]['tr'])) $out.= ''; else $out.= ''; // Loop on each TD diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index e6bf4d8233a..2cf1f276d24 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -52,7 +52,7 @@ $colortexttitlenotab='100,60,20'; $colortexttitle='0,0,0'; $colortext='0,0,0'; $colortextlink='0,0,100'; -$fontsize='13'; +$fontsize='14'; $fontsizesmaller='12'; if (defined('THEME_ONLY_CONSTANT')) return; @@ -118,7 +118,7 @@ if (empty($conf->global->THEME_ELDY_ENABLE_PERSONALIZED)) $conf->global->THEME_ELDY_BACKTABCARD1='255,255,255'; // card $conf->global->THEME_ELDY_BACKTABACTIVE='234,234,234'; $conf->global->THEME_ELDY_TEXT='0,0,0'; - $conf->global->THEME_ELDY_FONT_SIZE1='13'; + $conf->global->THEME_ELDY_FONT_SIZE1='14'; $conf->global->THEME_ELDY_FONT_SIZE2='12'; } @@ -3025,11 +3025,12 @@ div.warning { color: #302020; padding: 0.3em 0.3em 0.3em 0.3em; margin: 0.5em 0em 0.5em 0em; - border: 1px solid #e0d0b0; + /* border: 1px solid #e0d0b0; */ + border: 2px solid #805000; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; - background: #EFDF9A; + /* background: #EFDF9A; */ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 64210218799..a3bc638aec1 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -53,7 +53,7 @@ $colortexttitlenotab='90,90,90'; $colortexttitle='20,20,20'; $colortext='0,0,0'; $colortextlink='0,0,120'; -$fontsize='13'; +$fontsize='14'; $fontsizesmaller='11'; if (defined('THEME_ONLY_CONSTANT')) return; @@ -120,7 +120,7 @@ if (empty($conf->global->THEME_ELDY_ENABLE_PERSONALIZED)) $conf->global->THEME_ELDY_BACKTABCARD1='255,255,255'; // card $conf->global->THEME_ELDY_BACKTABACTIVE='234,234,234'; $conf->global->THEME_ELDY_TEXT='0,0,0'; - $conf->global->THEME_ELDY_FONT_SIZE1='13'; + $conf->global->THEME_ELDY_FONT_SIZE1='14'; $conf->global->THEME_ELDY_FONT_SIZE2='11'; } @@ -3124,11 +3124,12 @@ div.warning { color: #302020; padding: 0.3em 0.3em 0.3em 0.3em; margin: 0.5em 0em 0.5em 0em; - border: 1px solid #e0d0b0; + /* border: 1px solid #e0d0b0; */ + border: 2px solid #805000 -moz-border-radius:3px; -webkit-border-radius: 3px; border-radius: 3px; - background: #EFDF9A; + /* background: #EFDF9A; */ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); } From 839f3ca41dd39d37e870fc2cf57aa810315887fa Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 23 Sep 2017 03:22:48 +0200 Subject: [PATCH 108/177] NEW Can use an url like $conf->global>-MYPARAM for menu urls --- htdocs/core/menus/standard/auguria.lib.php | 7 +++++++ htdocs/core/menus/standard/eldy.lib.php | 7 +++++++ htdocs/theme/eldy/style.css.php | 4 ++-- htdocs/theme/md/style.css.php | 4 ++-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index 5fc0ab2c516..9119afc7696 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -73,6 +73,13 @@ function print_auguria_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$m $showmode=dol_auguria_showmenu($type_user,$newTabMenu[$i],$listofmodulesforexternal); if ($showmode == 1) { + // $menu_array[$i]['url'] can be a relative url, a full external url or a dynamic value like '$conf->global->APARAM) + if (preg_match('/^\$conf->global->([^\?]+)/', $newTabMenu[$i]['url'], $reg)) + { + $keyforsconst=$reg[1]; + $newTabMenu[$i]['url'] = $conf->global->$keyforsconst; + } + $url = $shorturl = $newTabMenu[$i]['url']; if (! preg_match("/^(http:\/\/|https:\/\/)/i",$newTabMenu[$i]['url'])) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 8c03d0c1ffc..013b6ea74ae 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1598,6 +1598,13 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } } + // $menu_array[$i]['url'] can be a relative url, a full external url or a dynamic value like '$conf->global->APARAM) + if (preg_match('/^\$conf->global->([^\?]+)/', $menu_array[$i]['url'], $reg)) + { + $keyforsconst=$reg[1]; + $menu_array[$i]['url'] = $conf->global->$keyforsconst; + } + $url = $shorturl = $menu_array[$i]['url']; if (! preg_match("/^(http:\/\/|https:\/\/)/i",$menu_array[$i]['url'])) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 2cf1f276d24..5226cb266e5 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -52,7 +52,7 @@ $colortexttitlenotab='100,60,20'; $colortexttitle='0,0,0'; $colortext='0,0,0'; $colortextlink='0,0,100'; -$fontsize='14'; +$fontsize='13'; $fontsizesmaller='12'; if (defined('THEME_ONLY_CONSTANT')) return; @@ -118,7 +118,7 @@ if (empty($conf->global->THEME_ELDY_ENABLE_PERSONALIZED)) $conf->global->THEME_ELDY_BACKTABCARD1='255,255,255'; // card $conf->global->THEME_ELDY_BACKTABACTIVE='234,234,234'; $conf->global->THEME_ELDY_TEXT='0,0,0'; - $conf->global->THEME_ELDY_FONT_SIZE1='14'; + $conf->global->THEME_ELDY_FONT_SIZE1='13'; $conf->global->THEME_ELDY_FONT_SIZE2='12'; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index a3bc638aec1..283f1aad16f 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -53,7 +53,7 @@ $colortexttitlenotab='90,90,90'; $colortexttitle='20,20,20'; $colortext='0,0,0'; $colortextlink='0,0,120'; -$fontsize='14'; +$fontsize='13'; $fontsizesmaller='11'; if (defined('THEME_ONLY_CONSTANT')) return; @@ -120,7 +120,7 @@ if (empty($conf->global->THEME_ELDY_ENABLE_PERSONALIZED)) $conf->global->THEME_ELDY_BACKTABCARD1='255,255,255'; // card $conf->global->THEME_ELDY_BACKTABACTIVE='234,234,234'; $conf->global->THEME_ELDY_TEXT='0,0,0'; - $conf->global->THEME_ELDY_FONT_SIZE1='14'; + $conf->global->THEME_ELDY_FONT_SIZE1='13'; $conf->global->THEME_ELDY_FONT_SIZE2='11'; } From 35d00fd2ec45cf7939eec3ca0da40a00916f4dc0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 23 Sep 2017 09:28:31 +0200 Subject: [PATCH 109/177] Fix wrap on lites_total --- htdocs/core/boxes/box_activity.php | 2 +- htdocs/theme/eldy/style.css.php | 16 +++++++++------- htdocs/theme/md/style.css.php | 21 ++++++++++++--------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index 71a9a4e3125..d3059daba53 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -435,7 +435,7 @@ class box_activity extends ModeleBoxes } // Add the sum in the bottom of the boxes - $this->info_box_contents[$line][0] = array('tr' => 'class="liste_total"'); + $this->info_box_contents[$line][0] = array('tr' => 'class="liste_total_wrap"'); $this->info_box_contents[$line][1] = array('td' => 'align="left" class="liste_total" ', 'text' => $langs->trans("Total")." ".$textHead); $this->info_box_contents[$line][2] = array('td' => 'align="right" class="liste_total" ', 'text' => $totalnb); $this->info_box_contents[$line][3] = array('td' => 'align="right" class="liste_total" ', 'text' => ''); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 5226cb266e5..4451135830c 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -863,11 +863,11 @@ div.fiche>form>div.div-table-responsive { .minwidth500imp { min-width: 250px !important; } } -/* Force values for small screen 570 */ +/* Force values for small screen 767 */ @media only screen and (max-width: 767px) { body { - font-size: px; + font-size: px; } } @@ -875,7 +875,7 @@ div.fiche>form>div.div-table-responsive { @media only screen and (max-width: 570px) { body { - font-size: px; + font-size: px; } .divmainbodylarge { margin-left: 20px !important; margin-right: 20px !important; } @@ -2749,14 +2749,16 @@ input.liste_titre { line-height: 24px; } -.noborder tr.liste_total, .noborder tr.liste_total td, tr.liste_total, form.liste_total { - /* height: 32px; */ -} -.noborder tr.liste_total td, tr.liste_total td, form.liste_total div { +.noborder tr.liste_total td, tr.liste_total td, form.liste_total div, .noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div { color: #551188; font-weight: normal; +} +.noborder tr.liste_total td, tr.liste_total td, form.liste_total div { white-space: nowrap; } +.noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div { + white-space: normal; +} form.liste_total div { border-top: 1px solid #DDDDDD; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 283f1aad16f..13aca2545dd 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -865,11 +865,11 @@ div.fiche>form>div.div-table-responsive { .minwidth500imp { min-width: 100px !important; } } -/* Force values for small screen 570 */ +/* Force values for small screen 767 */ @media only screen and (max-width: 767px) { body { - font-size: px; + font-size: px; } } @@ -877,7 +877,7 @@ div.fiche>form>div.div-table-responsive { @media only screen and (max-width: 570px) { body { - font-size: px; + font-size: px; } .divmainbodylarge { margin-left: 20px; margin-right: 20px; } @@ -2865,16 +2865,19 @@ input.liste_titre { border: 0px; } -.noborder tr.liste_total, .noborder tr.liste_total td, tr.liste_total, form.liste_total { - /* height: 32px; */ -} -.noborder tr.liste_total td, tr.liste_total td, form.liste_total div { - /* border-top: 1px solid #f4f4f4; */ +.noborder tr.liste_total td, tr.liste_total td, form.liste_total div, .noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div { color: #332266; font-weight: normal; - white-space: nowrap; padding: 4px; } +.noborder tr.liste_total td, tr.liste_total td, form.liste_total div { + white-space: nowrap; +} +.noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div { + white-space: normal; +} + + tr.liste_sub_total, tr.liste_sub_total td { border-bottom: 2px solid #aaa; } From 91beb3a4d6fed9dfa6b9faf78e7a72041e0c9ba7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 23 Sep 2017 11:39:09 +0200 Subject: [PATCH 110/177] Debug modulebuilder --- htdocs/modulebuilder/index.php | 193 +++++++++++++++++---------------- 1 file changed, 101 insertions(+), 92 deletions(-) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 43f679541ab..31514435cd7 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -967,12 +967,14 @@ elseif (! empty($module)) $linktoenabledisable.=img_picto($langs->trans("Disabled"),'switch_off'); $linktoenabledisable.="\n"; } - - $modulestatusinfo=img_info('').' '.$langs->trans("ModuleIsNotActive", $urltomodulesetup); - if (! empty($conf->$module->enabled)) + if (! empty($conf->$modulelowercase->enabled)) { $modulestatusinfo=img_warning().' '.$langs->trans("ModuleIsLive"); } + else + { + $modulestatusinfo=img_info('').' '.$langs->trans("ModuleIsNotActive", $urltomodulesetup); + } $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=description&module='.$module.($forceddirread?'@'.$dirread:''); $head2[$h][1] = $langs->trans("Description"); @@ -1308,12 +1310,12 @@ elseif (! empty($module)) //$objectname = preg_replace('/\.txt$/', '', $fileobj['name']); $objectname = $reg[1]; if (empty($firstobjectname)) $firstobjectname = $objectname; - } - $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname; - $head3[$h][1] = $objectname; - $head3[$h][2] = $objectname; - $h++; + $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname; + $head3[$h][1] = $objectname; + $head3[$h][2] = $objectname; + $h++; + } } $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj=deleteobject'; @@ -1483,98 +1485,105 @@ elseif (! empty($module)) print ''; print ''; - // Line to add a property - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - $properties = dol_sort_array($tmpobjet->fields, 'position'); - foreach($properties as $propkey => $propval) + if (! empty($properties)) { - /* If from Reflection - if ($propval->class == $tabobj) - { - $propname=$propval->getName(); - $comment=$propval->getDocComment(); - $type=gettype($tmpobjet->$propname); - $default=$propdefault[$propname]; - // Discard generic properties - if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'isnolinkedbythird', 'ismultientitymanaged'))) continue; + // Line to add a property + print ''; + print ''; + print ''; + print ''; + print ''; + //print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; - // Keep or not lines - if (in_array($propname, array('fk_element', 'lines'))) continue; - }*/ + foreach($properties as $propkey => $propval) + { + /* If from Reflection + if ($propval->class == $tabobj) + { + $propname=$propval->getName(); + $comment=$propval->getDocComment(); + $type=gettype($tmpobjet->$propname); + $default=$propdefault[$propname]; + // Discard generic properties + if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'isnolinkedbythird', 'ismultientitymanaged'))) continue; - $propname=$propkey; - $proplabel=$propval['label']; - $proptype=$propval['type']; - $propnotnull=$propval['notnull']; - $propsearchall=$propval['searchall']; - //$propdefault=$propval['default']; - $propindex=$propval['index']; - $propposition=$propval['position']; - $propenabled=$propval['enabled']; - $propvisible=$propval['visible']; - $propisameasure=$propval['isameasure']; - $propcomment=$propval['comment']; + // Keep or not lines + if (in_array($propname, array('fk_element', 'lines'))) continue; + }*/ - print ''; + $propname=$propkey; + $proplabel=$propval['label']; + $proptype=$propval['type']; + $propnotnull=$propval['notnull']; + $propsearchall=$propval['searchall']; + //$propdefault=$propval['default']; + $propindex=$propval['index']; + $propposition=$propval['position']; + $propenabled=$propval['enabled']; + $propvisible=$propval['visible']; + $propisameasure=$propval['isameasure']; + $propcomment=$propval['comment']; - print ''; - print $propname; - print ''; - print ''; - print $proplabel; - print ''; - print ''; - print $proptype; - print ''; - print ''; - print $propnotnull; - print ''; - /*print ''; - print $propdefault; - print '';*/ - print ''; - print $propindex?'X':''; - print ''; - print ''; - print $propposition; - print ''; - print ''; - print $propenabled?$propenabled:''; - print ''; - print ''; - print $propvisible?$propvisible:''; - print ''; - print ''; - print $propisameasure?$propisameasure:''; - print ''; - print ''; - print $propsearchall?'X':''; - print ''; - print ''; - print $propcomment; - print ''; - print ''; - print ''.img_delete().''; - print ''; + print ''; - print ''; + print ''; + print $propname; + print ''; + print ''; + print $proplabel; + print ''; + print ''; + print $proptype; + print ''; + print ''; + print $propnotnull; + print ''; + /*print ''; + print $propdefault; + print '';*/ + print ''; + print $propindex?'X':''; + print ''; + print ''; + print $propposition; + print ''; + print ''; + print $propenabled?$propenabled:''; + print ''; + print ''; + print $propvisible?$propvisible:''; + print ''; + print ''; + print $propisameasure?$propisameasure:''; + print ''; + print ''; + print $propsearchall?'X':''; + print ''; + print ''; + print $propcomment; + print ''; + print ''; + print ''.img_delete().''; + print ''; + + print ''; + } + } + else + { + print ''.$langs->trans('Property $field not found into the class. The class was probably not generated by modulebuilder.').''; } print ''; print ''; From 414f633e750d892269e4fc027a81d9ff4ce794dd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 23 Sep 2017 12:59:49 +0200 Subject: [PATCH 111/177] Fix css --- htdocs/core/class/html.form.class.php | 4 +- htdocs/core/class/html.formactions.class.php | 107 ++++++++++-------- htdocs/langs/en_US/modulebuilder.lang | 10 +- htdocs/modulebuilder/index.php | 32 +++++- .../template/doc/Specifications.asciidoc | 4 +- .../modulebuilder/template/myobject_card.php | 4 +- htdocs/theme/eldy/style.css.php | 4 +- 7 files changed, 103 insertions(+), 62 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index ed318bbd900..931c3c5d1ce 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5551,8 +5551,8 @@ class Form { $nbofdifferenttypes = count($object->linkedObjects); - print '
'; - print load_fiche_titre($langs->trans('RelatedObjects'), $morehtmlright, ''); + print ''; + print load_fiche_titre($langs->trans('RelatedObjects'), $morehtmlright, '', 0, 0, 'showlinkedobjectblock'); print '
'; diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index b93083d9a9f..84c7ab389f3 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -187,20 +187,22 @@ class FormActions elseif ($typeelement == 'project') $title=$langs->trans('LatestLinkedEvents', $max?$max:''); elseif ($typeelement == 'task') $title=$langs->trans('LatestLinkedEvents', $max?$max:''); elseif ($typeelement == 'member') $title=$langs->trans('LatestLinkedEvents', $max?$max:''); - else $title=$langs->trans("Actions"); + else $title=$langs->trans("LatestLinkedEvents", $max?$max:''); $urlbacktopage=$_SERVER['PHP_SELF'].'?id='.$object->id.($moreparambacktopage?'&'.$moreparambacktopage:''); $buttontoaddnewevent = ''; $buttontoaddnewevent.= $langs->trans("AddEvent"); $buttontoaddnewevent.= ''; + + print ''."\n"; print load_fiche_titre($title, $buttontoaddnewevent, ''); $page=0; $param=''; $total = 0; - print '
'; + print '
'; print ''; print ''; print getTitleFieldOfList('Ref', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); @@ -214,63 +216,70 @@ class FormActions $userstatic = new User($this->db); - $cursorevent = 0; - foreach($listofactions as $action) + if (count($listofactions)) { - if ($max && $cursorevent >= $max) break; + $cursorevent = 0; + foreach($listofactions as $action) + { + if ($max && $cursorevent >= $max) break; - $ref=$action->getNomUrl(1,-1); - $label=$action->getNomUrl(0,38); + $ref=$action->getNomUrl(1,-1); + $label=$action->getNomUrl(0,38); - print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; - print ''; - print ''; - print ''; + print $action->type; + print ''; + print ''; + print ''; + print ''; + print ''; - $cursorevent++; + $cursorevent++; + } + } + else + { + print ''; } if ($max && $num > $max) { - print ''; + print ''; } print '
'.$ref.''.$label.''; - if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) - { - if ($action->type_picto) print img_picto('', $action->type_picto); - else { - if ($action->type_code == 'AC_RDV') print img_picto('', 'object_group').' '; - if ($action->type_code == 'AC_TEL') print img_picto('', 'object_phoning').' '; - if ($action->type_code == 'AC_FAX') print img_picto('', 'object_phoning_fax').' '; - if ($action->type_code == 'AC_EMAIL') print img_picto('', 'object_email').' '; - } - } - print $action->type; - print ''.dol_print_date($action->datep,'dayhour'); - if ($action->datef) - { - $tmpa=dol_getdate($action->datep); - $tmpb=dol_getdate($action->datef); - if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) + print '
'.$ref.''.$label.''; + if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) { - if ($tmpa['hours'] != $tmpb['hours'] || $tmpa['minutes'] != $tmpb['minutes'] && $tmpa['seconds'] != $tmpb['seconds']) print '-'.dol_print_date($action->datef,'hour'); + if ($action->type_picto) print img_picto('', $action->type_picto); + else { + if ($action->type_code == 'AC_RDV') print img_picto('', 'object_group').' '; + if ($action->type_code == 'AC_TEL') print img_picto('', 'object_phoning').' '; + if ($action->type_code == 'AC_FAX') print img_picto('', 'object_phoning_fax').' '; + if ($action->type_code == 'AC_EMAIL') print img_picto('', 'object_email').' '; + } } - else print '-'.dol_print_date($action->datef,'dayhour'); - } - print ''; - if (! empty($action->userownerid)) - { - $userstatic->fetch($action->userownerid); // TODO Introduce a cache on users fetched - print $userstatic->getNomUrl(-1, '', 0, 0, 16, 0, '', ''); - } - print ''; - if (! empty($action->author->id)) - { - print $action->getLibStatut(3); - } - print '
'.dol_print_date($action->datep,'dayhour'); + if ($action->datef) + { + $tmpa=dol_getdate($action->datep); + $tmpb=dol_getdate($action->datef); + if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) + { + if ($tmpa['hours'] != $tmpb['hours'] || $tmpa['minutes'] != $tmpb['minutes'] && $tmpa['seconds'] != $tmpb['seconds']) print '-'.dol_print_date($action->datef,'hour'); + } + else print '-'.dol_print_date($action->datef,'dayhour'); + } + print ''; + if (! empty($action->userownerid)) + { + $userstatic->fetch($action->userownerid); // TODO Introduce a cache on users fetched + print $userstatic->getNomUrl(-1, '', 0, 0, 16, 0, '', ''); + } + print ''; + if (! empty($action->author->id)) + { + print $action->getLibStatut(3); + } + print '
'.$langs->trans("None").'
'.$langs->trans("More").'...
'.$langs->trans("More").'...
'; diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 732514de9c1..081f67fb022 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -64,8 +64,14 @@ IsAMeasure=Is a measure DirScanned=Directory scanned NoTrigger=No trigger NoWidget=No widget +ListOfPermissionsDefined=List of defined permissions EnabledDesc=Condition to have this field active (Examples: 1 or $conf->global->MYMODULE_MYOPTION) -VisibleDesc=Is field is visible in list (-1 means not shown by default but can be added into list to be viewed) +VisibleDesc=Is the field visible into list ? (Examples: 0=not visible, 1=visible by default on list, -1=not shown by default on list but can be added into list to be viewed) +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. +LanguageDefDesc=Enter in this files, all the key and the translation for each language file. MenusDefDesc=Define here the menus provided by your module (once defined, they are visible into the menu editor %s) PermissionsDefDesc=Define here the new permissions provided by your module (once defined, they are visible into the default permissions setup %s) -ListOfPermissionsDefined=List of defined permissions +HooksDefDesc=Define in the module_parts['hooks'] property in the module descriptor the context of hooks you want to manage (list of contexts can be found by a search on 'initHooks(' in core code).
Edit the hook file to add code of your hooked functions (hookable functions can be found by a search on 'executeHooks' in core code). +TriggerDefDesc=Define in the trigger file the code you want to execute for each business event executed diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 31514435cd7..145d68f7c2f 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -1194,6 +1194,9 @@ elseif (! empty($module)) { if ($action != 'editfile' || empty($file)) { + print $langs->trans("SpecDefDesc").'
'; + print '
'; + $specs=dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$'); foreach ($specs as $spec) @@ -1241,6 +1244,9 @@ elseif (! empty($module)) { if ($action != 'editfile' || empty($file)) { + print $langs->trans("LanguageDefDesc").'
'; + print '
'; + $langfiles=dol_dir_list(dol_buildpath($modulelowercase.'/langs', 0), 'files', 1, '\.lang$'); foreach ($langfiles as $langfile) @@ -1419,11 +1425,14 @@ elseif (! empty($module)) print '
'; print '
'; + $urloflist = dol_buildpath(strtolower($module).'/'.strtolower($tabobj).'_list.php', 1); + $urlofcard = dol_buildpath(strtolower($module).'/'.strtolower($tabobj).'_card.php', 1); + print '
'; - print ' '.$langs->trans("PageForList").' : '.$pathtolist.''; + print ' '.$langs->trans("PageForList").' : '.$pathtolist.''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; - print ' '.$langs->trans("PageForCreateEditView").' : '.$pathtocard.''; + print ' '.$langs->trans("PageForCreateEditView").' : '.$pathtocard.'?action=create'; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print ' '.$langs->trans("PageForAgendaTab").' : '.$pathtoagenda.''; @@ -1479,8 +1488,8 @@ elseif (! empty($module)) print ''.$langs->trans("Position").''; print ''.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc")).''; print ''.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).''; - print ''.$langs->trans("IsAMeasure").''; - print ''.$langs->trans("SearchAll").''; + print ''.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).''; + print ''.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).''; print ''.$langs->trans("Comment").''; print ''; print ''; @@ -1885,8 +1894,16 @@ elseif (! empty($module)) { if ($action != 'editfile' || empty($file)) { - $pathtohook = strtolower($module).'/class/actions_'.strtolower($module).'.class.php'; - print ' '.$langs->trans("HooksFile").' : '.$pathtohook.''; + print $langs->trans("HooksDefDesc").'
'; + print '
'; + + $pathtofile = $modulelowercase.'/core/modules/mod'.$module.'.class.php'; + print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; + + $pathtohook = strtolower($module).'/class/actions_'.strtolower($module).'.class.php'; + print ' '.$langs->trans("HooksFile").' : '.$pathtohook.''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; } @@ -1926,6 +1943,9 @@ elseif (! empty($module)) if ($action != 'editfile' || empty($file)) { + print $langs->trans("TriggerDefDesc").'
'; + print '
'; + if (! empty($triggers)) { foreach ($triggers as $trigger) diff --git a/htdocs/modulebuilder/template/doc/Specifications.asciidoc b/htdocs/modulebuilder/template/doc/Specifications.asciidoc index 7b1711cf514..d2150c0865d 100644 --- a/htdocs/modulebuilder/template/doc/Specifications.asciidoc +++ b/htdocs/modulebuilder/template/doc/Specifications.asciidoc @@ -1 +1,3 @@ -# SPECIFICATIONS OF MODULE MYMODULE FOR DOLIBARR ERP CRM \ No newline at end of file +# SPECIFICATIONS OF MODULE MYMODULE FOR DOLIBARR ERP CRM + +There is no detailed specification available yet. diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 9aa0f8cd361..97662c150da 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -534,10 +534,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; + $MAXEVENT = 10; + // List of actions on element include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'myobject', $socid, 1); + $somethingshown = $formactions->showactions($object, 'myobject', $socid, 1, '', $MAXEVENT); print '
'; } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 4451135830c..1fbd4e44037 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -719,7 +719,9 @@ div.myavailability { margin-top: 6px; margin-bottom: 12px; } - +#builddoc_form ~ .showlinkedobjectblock { + margin-top: 20px; +} /* For the long description of module */ .moduledesclong p img, .moduledesclong p a img { From 7d580105c81c4dc65ae9065f3cdac5ad94839654 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 23 Sep 2017 13:02:25 +0200 Subject: [PATCH 112/177] Fix css --- htdocs/theme/md/style.css.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 13aca2545dd..4d46f2e781e 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -730,7 +730,9 @@ div.myavailability { margin-top: 6px; margin-bottom: 12px; } - +#builddoc_form ~ .showlinkedobjectblock { + margin-top: 20px; +} /* For the long description of module */ .moduledesclong p img,.moduledesclong p a img { From bee94b32d9c98e14a761eac75522664f3eddca53 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 23 Sep 2017 15:12:25 +0200 Subject: [PATCH 113/177] Debug modulebuilder --- htdocs/core/lib/functions.lib.php | 4 +- htdocs/langs/en_US/modulebuilder.lang | 1 + htdocs/modulebuilder/index.php | 325 ++++++++++++++------------ 3 files changed, 180 insertions(+), 150 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c995c1269ad..41cd039d1e6 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -601,8 +601,8 @@ function dol_include_once($relpath, $classname='') * * @param string $path Relative path to file (if mode=0) or relative url (if mode=1). Ie: mydir/myfile, ../myfile * @param int $type 0=Used for a Filesystem path, 1=Used for an URL path (output relative), 2=Used for an URL path (output full path using same host that current url), 3=Used for an URL path (output full path using host defined into $dolibarr_main_url_root of conf file) - * @param int $returnemptyifnotfound If file was not found, do not return default path but an empty string - * @return string Full filesystem path (if mode=0), Full url path (if mode=1) + * @param int $returnemptyifnotfound If path==0 and if file was not found, do not return default path but an empty string + * @return string Full filesystem path (if path=0), Full url path (if mode=1) */ function dol_buildpath($path, $type=0, $returnemptyifnotfound=0) { diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 081f67fb022..0f62870b299 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -64,6 +64,7 @@ IsAMeasure=Is a measure DirScanned=Directory scanned NoTrigger=No trigger NoWidget=No widget +GoToApiExplorer=Go to API explorer ListOfPermissionsDefined=List of defined permissions EnabledDesc=Condition to have this field active (Examples: 1 or $conf->global->MYMODULE_MYOPTION) VisibleDesc=Is the field visible into list ? (Examples: 0=not visible, 1=visible by default on list, -1=not shown by default on list but can be added into list to be viewed) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 145d68f7c2f..48bfb1731ae 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -1395,53 +1395,66 @@ elseif (! empty($module)) $pathtosql = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.sql'; $pathtosqlextra = strtolower($module).'/sql/llx_'.strtolower($tabobj).'_extrafields.sql'; $pathtosqlkey = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.key.sql'; + + $realpathtoclass = dol_buildpath($pathtoclass, 0, 1); + $realpathtoapi = dol_buildpath($pathtoapi, 0, 1); + $realpathtoagenda = dol_buildpath($pathtoagenda, 0, 1); + $realpathtocard = dol_buildpath($pathtocard, 0, 1); + $realpathtodocument = dol_buildpath($pathtodocument, 0, 1); + $realpathtolist = dol_buildpath($pathtolist, 0, 1); + $realpathtonote = dol_buildpath($pathtonote, 0, 1); + $realpathtophpunit = dol_buildpath($pathtophpunit, 0, 1); + $realpathtosql = dol_buildpath($pathtosql, 0, 1); + $realpathtosqlextra = dol_buildpath($pathtosqlextra, 0, 1); + $realpathtosqlkey = dol_buildpath($pathtosqlkey, 0, 1); + print '
'; - print ' '.$langs->trans("ClassFile").' : '.$pathtoclass.''; + print ' '.$langs->trans("ClassFile").' : '.($realpathtoclass?'':'').$pathtoclass.($realpathtoclass?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; - print ' '.$langs->trans("ApiClassFile").' : '.$pathtoapi.''; + print ' '.$langs->trans("ApiClassFile").' : '.($realpathtoapi?'':'').$pathtoapi.($realpathtoapi?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '   '.$langs->trans("GoToApiExplorer").''; print '
'; - print ' '.$langs->trans("TestClassFile").' : '.$pathtophpunit.''; + print ' '.$langs->trans("TestClassFile").' : '.($realpathtophpunit?'':'').$pathtophpunit.($realpathtophpunit?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print '
'; - print ' '.$langs->trans("SqlFile").' : '.$pathtosql.''; + print ' '.$langs->trans("SqlFile").' : '.($realpathtosql?'':'').$pathtosql.($realpathtosql?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '   '.$langs->trans("DropTableIfEmpty").''; - print '   '.$langs->trans("RunSql").''; + //print '   '.$langs->trans("RunSql").''; print '
'; - print ' '.$langs->trans("SqlFileExtraFields").' : '.$pathtosqlextra.''; + print ' '.$langs->trans("SqlFileExtraFields").' : '.($realpathtosqlextra?'':'').$pathtosqlextra.($realpathtosqlextra?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '   '.$langs->trans("RunSql").''; + //print '   '.$langs->trans("RunSql").''; print '
'; - print ' '.$langs->trans("SqlFileKey").' : '.$pathtosqlkey.''; + print ' '.$langs->trans("SqlFileKey").' : '.($realpathtosqlkey?'':'').$pathtosqlkey.($realpathtosqlkey?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '   '.$langs->trans("RunSql").''; + //print '   '.$langs->trans("RunSql").''; print '
'; print '
'; print '
'; - $urloflist = dol_buildpath(strtolower($module).'/'.strtolower($tabobj).'_list.php', 1); - $urlofcard = dol_buildpath(strtolower($module).'/'.strtolower($tabobj).'_card.php', 1); + $urloflist = dol_buildpath($pathtolist, 1); + $urlofcard = dol_buildpath($pathtocard, 1); print '
'; - print ' '.$langs->trans("PageForList").' : '.$pathtolist.''; + print ' '.$langs->trans("PageForList").' : '.($realpathtosql?'':'').$pathtolist.($realpathtosql?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; - print ' '.$langs->trans("PageForCreateEditView").' : '.$pathtocard.'?action=create'; + print ' '.$langs->trans("PageForCreateEditView").' : '.($realpathtocard?'':'').$pathtocard.($realpathtocard?'':'').'?action=create'; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; - print ' '.$langs->trans("PageForAgendaTab").' : '.$pathtoagenda.''; + print ' '.$langs->trans("PageForAgendaTab").' : '.($realpathtoagenda?'':'').$pathtoagenda.($realpathtoagenda?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; - print ' '.$langs->trans("PageForDocumentTab").' : '.$pathtodocument.''; + print ' '.$langs->trans("PageForDocumentTab").' : '.($realpathtodocument?'':'').$pathtodocument.($realpathtodocument?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; - print ' '.$langs->trans("PageForNoteTab").' : '.$pathtonote.''; + print ' '.$langs->trans("PageForNoteTab").' : '.($realpathtonote?'':'').$pathtonote.($realpathtonote?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; @@ -1455,149 +1468,165 @@ elseif (! empty($module)) { $result = @include_once($dirread.'/'.$pathtoclass); } - if (class_exists($tabobj)) $tmpobjet = new $tabobj($db); - - $reflector = new ReflectionClass($tabobj); - $properties = $reflector->getProperties(); // Can also use get_object_vars - $propdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars - //$propstat = $reflector->getStaticProperties(); - - print load_fiche_titre($langs->trans("Properties"), '', ''); - - print ''; - - print ''; - print ''; - print ''; - print ''; - print ''; - - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $properties = dol_sort_array($tmpobjet->fields, 'position'); - - if (! empty($properties)) + if (class_exists($tabobj)) { - // Line to add a property - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + try { + $tmpobjet = @new $tabobj($db); + } + catch(Exception $e) + { + dol_syslog('Failed to load Constructor of class: '.$e->getMessage(), LOG_WARNING); + } + } - foreach($properties as $propkey => $propval) + if (! empty($tmpobjet)) + { + $reflector = new ReflectionClass($tabobj); + $properties = $reflector->getProperties(); // Can also use get_object_vars + $propdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars + //$propstat = $reflector->getStaticProperties(); + + print load_fiche_titre($langs->trans("Properties"), '', ''); + + print ''; + + print ''; + print ''; + print ''; + print ''; + print ''; + + print '
'; + print '
'.$langs->trans("Property"); - print ' ('.$langs->trans("Example").')'; - print ''; - print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey")); - print ''.$langs->trans("Type").''.$langs->trans("NotNull").''.$langs->trans("DefaultValue").''.$langs->trans("DatabaseIndex").''.$langs->trans("Position").''.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc")).''.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).''.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).''.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).''.$langs->trans("Comment").'
'; - print ''; - print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + //print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $properties = dol_sort_array($tmpobjet->fields, 'position'); + + if (! empty($properties)) { - /* If from Reflection - if ($propval->class == $tabobj) - { - $propname=$propval->getName(); - $comment=$propval->getDocComment(); - $type=gettype($tmpobjet->$propname); - $default=$propdefault[$propname]; - // Discard generic properties - if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'isnolinkedbythird', 'ismultientitymanaged'))) continue; + // Line to add a property + print ''; + print ''; + print ''; + print ''; + print ''; + //print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; - // Keep or not lines - if (in_array($propname, array('fk_element', 'lines'))) continue; - }*/ + foreach($properties as $propkey => $propval) + { + /* If from Reflection + if ($propval->class == $tabobj) + { + $propname=$propval->getName(); + $comment=$propval->getDocComment(); + $type=gettype($tmpobjet->$propname); + $default=$propdefault[$propname]; + // Discard generic properties + if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'isnolinkedbythird', 'ismultientitymanaged'))) continue; - $propname=$propkey; - $proplabel=$propval['label']; - $proptype=$propval['type']; - $propnotnull=$propval['notnull']; - $propsearchall=$propval['searchall']; - //$propdefault=$propval['default']; - $propindex=$propval['index']; - $propposition=$propval['position']; - $propenabled=$propval['enabled']; - $propvisible=$propval['visible']; - $propisameasure=$propval['isameasure']; - $propcomment=$propval['comment']; + // Keep or not lines + if (in_array($propname, array('fk_element', 'lines'))) continue; + }*/ - print ''; + $propname=$propkey; + $proplabel=$propval['label']; + $proptype=$propval['type']; + $propnotnull=$propval['notnull']; + $propsearchall=$propval['searchall']; + //$propdefault=$propval['default']; + $propindex=$propval['index']; + $propposition=$propval['position']; + $propenabled=$propval['enabled']; + $propvisible=$propval['visible']; + $propisameasure=$propval['isameasure']; + $propcomment=$propval['comment']; - print ''; - print ''; - print ''; - print ''; - /*print '';*/ - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + /*print '';*/ + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + print ''; + } } + else + { + print ''; + } + print '
'.$langs->trans("Property"); + print ' ('.$langs->trans("Example").')'; + print ''; + print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey")); + print ''.$langs->trans("Type").''.$langs->trans("NotNull").''.$langs->trans("DefaultValue").''.$langs->trans("DatabaseIndex").''.$langs->trans("Position").''.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc")).''.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).''.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).''.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).''.$langs->trans("Comment").'
'; + print ''; + print '
'; - print $propname; - print ''; - print $proplabel; - print ''; - print $proptype; - print ''; - print $propnotnull; - print ''; - print $propdefault; - print ''; - print $propindex?'X':''; - print ''; - print $propposition; - print ''; - print $propenabled?$propenabled:''; - print ''; - print $propvisible?$propvisible:''; - print ''; - print $propisameasure?$propisameasure:''; - print ''; - print $propsearchall?'X':''; - print ''; - print $propcomment; - print ''; - print ''.img_delete().''; - print '
'; + print $propname; + print ''; + print $proplabel; + print ''; + print $proptype; + print ''; + print $propnotnull; + print ''; + print $propdefault; + print ''; + print $propindex?'X':''; + print ''; + print $propposition; + print ''; + print $propenabled?$propenabled:''; + print ''; + print $propvisible?$propvisible:''; + print ''; + print $propisameasure?$propisameasure:''; + print ''; + print $propsearchall?'X':''; + print ''; + print $propcomment; + print ''; + print ''.img_delete().''; + print '
'.$langs->trans('Property $field not found into the class. The class was probably not generated by modulebuilder.').'
'; + print '
'; + + print ''; } else - { - print ''.$langs->trans('Property $field not found into the class. The class was probably not generated by modulebuilder.').''; - } - print ''; - print '
'; - - print ''; + { + print ''.$langs->trans('Failed to init the object with the new.').''; + } } catch(Exception $e) { From b4e461e7ea9f73fd3687e51d1df8e0a1fbbfe2be Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 23 Sep 2017 18:17:34 +0200 Subject: [PATCH 114/177] Debug modulebuilder --- htdocs/core/lib/modulebuilder.lib.php | 67 ++++++++++++--- htdocs/langs/en_US/modulebuilder.lang | 2 + htdocs/modulebuilder/index.php | 85 +++++++++++-------- .../template/class/myobject.class.php | 14 +-- .../modulebuilder/template/myobject_card.php | 21 ++++- 5 files changed, 129 insertions(+), 60 deletions(-) diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index 282a02835c3..23d6597b227 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -34,7 +34,7 @@ * @param string $readdir Directory source (use $destdir when not defined) * @param string $addfieldentry Array of the field entry to add array('key'=>,'type'=>,''label'=>,'visible'=>,'enabled'=>,'position'=>,'notnull'=>','index'=>,'searchall'=>,'comment'=>,'help'=>,'isameasure') * @param string $delfieldentry Id of field to remove - * @return int <=0 if KO, >0 if OK + * @return int|object <=0 if KO, Object if OK */ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='', $addfieldentry=array() ,$delfieldentry='') { @@ -43,6 +43,12 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir=' if (empty($objectname)) return -1; if (empty($readdir)) $readdir=$destdir; + if (! empty($addfieldentry['arrayofkeyval']) && ! is_array($addfieldentry['arrayofkeyval'])) + { + dol_print_error('', 'Bad parameter addfieldentry with a property arrayofkeyval defined but that is not an array.'); + return -1; + } + // Check parameters if (count($addfieldentry) > 0) { @@ -92,8 +98,9 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir=' { if (is_array($addfieldentry) && count($addfieldentry)) { - $name=$addfieldentry['name']; + $name=$addfieldentry['name']; unset($addfieldentry['name']); + $object->fields[$name]=$addfieldentry; } if (! empty($delfieldentry)) @@ -114,6 +121,7 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir=' if (count($object->fields)) { + foreach($object->fields as $key => $val) { $i++; @@ -127,11 +135,24 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir=' if ($val['comment']) $texttoinsert.= " 'comment'=>'".$val['comment']."',"; if ($val['isameasure']) $texttoinsert.= " 'isameasure'=>'".$val['isameasure']."',"; if ($val['help']) $texttoinsert.= " 'help'=>'".$val['help']."',"; + if ($val['arrayofkeyval']) + { + $texttoinsert.= " 'arrayofkeyval'=>array("; + $i=0; + foreach($val['arrayofkeyval'] as $key2 => $val2) + { + if ($i) $texttoinsert.=", "; + $texttoinsert.="'".$key2."'=>'".$val2."'"; + $i++; + } + $texttoinsert.= ")"; + } $texttoinsert.= "),\n"; } } $texttoinsert.= "\t".');'."\n"; + //print ($texttoinsert);exit; if (count($object->fields)) { @@ -162,7 +183,7 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir=' file_put_contents(dol_osencode($pathoffiletoedittarget), $contentclass); @chmod($pathoffiletoedittarget, octdec($newmask)); - return 1; + return $object; } catch(Exception $e) { @@ -179,12 +200,15 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir=' * @param string $objectname Name of object * @param string $newmask New mask * @param string $readdir Directory source (use $destdir when not defined) + * @param Object $object If object was already loaded/known, it is pass to avaoid another include and new. * @return int <=0 if KO, >0 if OK */ -function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='') +function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='', $object=null) { global $db, $langs; + $error = 0; + if (empty($objectname)) return -1; if (empty($readdir)) $readdir=$destdir; @@ -200,11 +224,15 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='') return -1; } + // Load object from myobject.class.php try { - include_once $pathoffiletoclasssrc; - if (class_exists($objectname)) $object=new $objectname($db); - else return -1; + if (! is_object($object)) + { + include_once $pathoffiletoclasssrc; + if (class_exists($objectname)) $object=new $objectname($db); + else return -1; + } } catch(Exception $e) { @@ -235,9 +263,15 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='') $contentsql = preg_replace('/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims', $texttoinsert, $contentsql); - file_put_contents($pathoffiletoedittarget, $contentsql); - @chmod($pathoffiletoedittarget, octdec($newmask)); - + $result = file_put_contents($pathoffiletoedittarget, $contentsql); + if ($result) + { + @chmod($pathoffiletoedittarget, octdec($newmask)); + } + else + { + $error++; + } // Edit .key.sql file $pathoffiletoeditsrc=$destdir.'/sql/llx_'.strtolower($objectname).'.key.sql'; @@ -265,10 +299,17 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='') dol_mkdir(dirname($pathoffiletoedittarget)); - file_put_contents($pathoffiletoedittarget, $contentsql); - @chmod($pathoffiletoedittarget, octdec($newmask)); + $result2 = file_put_contents($pathoffiletoedittarget, $contentsql); + if ($result) + { + @chmod($pathoffiletoedittarget, octdec($newmask)); + } + else + { + $error++; + } - return 1; + return $error ? -1 : 1; } diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 0f62870b299..891faa8e134 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -51,6 +51,8 @@ DatabaseIndex=Database index FileAlreadyExists=File %s already exists TriggersFile=File for triggers code HooksFile=File for hooks code +ArrayOfKeyValues=Array of key-val +ArrayOfKeyValuesDesc=Array of keys and values if field is a combo list with fixed values WidgetFile=Widget file ReadmeFile=Readme file ChangeLog=ChangeLog file diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 48bfb1731ae..5ff69549182 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -337,13 +337,13 @@ if ($dirins && $action == 'initobject' && $module && $objectname) if (! $error) { // Edit the class file to write properties - $result=rebuildObjectClass($destdir, $module, $objectname, $newmask); - if ($result < 0) $error++; + $object=rebuildObjectClass($destdir, $module, $objectname, $newmask); + if (is_numeric($object) && $object < 0) $error++; } if (! $error) { // Edit sql with new properties - $result=rebuildObjectSql($destdir, $module, $objectname, $newmask); + $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, '', $object); if ($result < 0) $error++; } @@ -362,25 +362,28 @@ if ($dirins && $action == 'addproperty' && !empty($module) && ! empty($tabobj)) dol_mkdir($destdir); $addfieldentry = array( - 'name'=>GETPOST('propname','aZ09'),'type'=>GETPOST('proptype','alpha'),'label'=>GETPOST('proplabel','alpha'),'visible'=>GETPOST('propvisible','int'),'enabled'=>GETPOST('propenabled','int'), + 'name'=>GETPOST('propname','aZ09'),'label'=>GETPOST('proplabel','alpha'),'type'=>GETPOST('proptype','alpha'), + 'arrayofkeyval'=>GETPOST('proparrayofkeyval','none'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}' + 'visible'=>GETPOST('propvisible','int'),'enabled'=>GETPOST('propenabled','int'), 'position'=>GETPOST('propposition','int'),'notnull'=>GETPOST('propnotnull','int'),'index'=>GETPOST('propindex','int'),'searchall'=>GETPOST('propsearchall','int'), 'isameasure'=>GETPOST('propisameasure','int'), 'comment'=>GETPOST('propcomment','alpha'),'help'=>GETPOST('prophelp')); + if (! empty($addfieldentry['arrayofkeyval']) && ! is_array($addfieldentry['arrayofkeyval'])) + { + $addfieldentry['arrayofkeyval'] = dol_json_decode($addfieldentry['arrayofkeyval'], true); + } + // Edit the class file to write properties if (! $error) { - $result=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry); - // var_dump($result);exit; - if ($result <= 0) - { - $error++; - } + $object=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry); + if (is_numeric($result) && $result <= 0) $error++; } // Edit sql with new properties if (! $error) { - $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir); + $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object); if ($result <= 0) { $error++; @@ -412,14 +415,14 @@ if ($dirins && $action == 'confirm_deleteproperty' && $propertykey) // Edit the class file to write properties if (! $error) { - $result=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, array(), $propertykey); - if ($result <= 0) $error++; + $object=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, array(), $propertykey); + if (is_numeric($object) && $object <= 0) $error++; } // Edit sql with new properties if (! $error) { - $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir); + $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object); if ($result <= 0) $error++; } @@ -1410,28 +1413,28 @@ elseif (! empty($module)) print '
'; print ' '.$langs->trans("ClassFile").' : '.($realpathtoclass?'':'').$pathtoclass.($realpathtoclass?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print ' '.$langs->trans("ApiClassFile").' : '.($realpathtoapi?'':'').$pathtoapi.($realpathtoapi?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '   '.$langs->trans("GoToApiExplorer").''; print '
'; print ' '.$langs->trans("TestClassFile").' : '.($realpathtophpunit?'':'').$pathtophpunit.($realpathtophpunit?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print '
'; print ' '.$langs->trans("SqlFile").' : '.($realpathtosql?'':'').$pathtosql.($realpathtosql?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '   '.$langs->trans("DropTableIfEmpty").''; //print '   '.$langs->trans("RunSql").''; print '
'; print ' '.$langs->trans("SqlFileExtraFields").' : '.($realpathtosqlextra?'':'').$pathtosqlextra.($realpathtosqlextra?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; //print '   '.$langs->trans("RunSql").''; print '
'; print ' '.$langs->trans("SqlFileKey").' : '.($realpathtosqlkey?'':'').$pathtosqlkey.($realpathtosqlkey?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; //print '   '.$langs->trans("RunSql").''; print '
'; @@ -1443,19 +1446,19 @@ elseif (! empty($module)) print '
'; print ' '.$langs->trans("PageForList").' : '.($realpathtosql?'':'').$pathtolist.($realpathtosql?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print ' '.$langs->trans("PageForCreateEditView").' : '.($realpathtocard?'':'').$pathtocard.($realpathtocard?'':'').'?action=create'; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print ' '.$langs->trans("PageForAgendaTab").' : '.($realpathtoagenda?'':'').$pathtoagenda.($realpathtoagenda?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print ' '.$langs->trans("PageForDocumentTab").' : '.($realpathtodocument?'':'').$pathtodocument.($realpathtodocument?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print ' '.$langs->trans("PageForNoteTab").' : '.($realpathtonote?'':'').$pathtonote.($realpathtonote?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print '


'; @@ -1506,6 +1509,7 @@ elseif (! empty($module)) print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey")); print ''; print ''.$langs->trans("Type").''; + print ''.$form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")).''; print ''.$langs->trans("NotNull").''; //print ''.$langs->trans("DefaultValue").''; print ''.$langs->trans("DatabaseIndex").''; @@ -1524,18 +1528,19 @@ elseif (! empty($module)) { // Line to add a property print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; //print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; print ''; print ''; print ''; @@ -1559,6 +1564,7 @@ elseif (! empty($module)) $propname=$propkey; $proplabel=$propval['label']; $proptype=$propval['type']; + $proparrayofkeyval=$propval['arrayofkeyval']; $propnotnull=$propval['notnull']; $propsearchall=$propval['searchall']; //$propdefault=$propval['default']; @@ -1580,6 +1586,12 @@ elseif (! empty($module)) print ''; print $proptype; print ''; + print ''; + if ($proparrayofkeyval) + { + print json_encode($proparrayofkeyval); + } + print ''; print ''; print $propnotnull; print ''; @@ -1652,6 +1664,7 @@ elseif (! empty($module)) print ''; print ''; print ''; + print ''; print ''; $doleditor=new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%'); diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 546c404eb49..259db698024 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -78,19 +78,19 @@ class MyObject extends CommonObject * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. */ public $fields=array( - 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'index'=>1, 'position'=>1, 'comment'=>'Id'), - 'ref' =>array('type'=>'varchar(64)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'), - 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'index'=>1, 'position'=>20), + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'index'=>1, 'position'=>1, 'comment'=>'Id'), + 'ref' =>array('type'=>'varchar(64)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'index'=>1, 'position'=>20), 'label' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1), 'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Amount'), - 'status' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'index'=>1, 'position'=>1000), - 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), - 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), + 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), //'date_valid' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>500), - 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), + 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), 'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-1, 'notnull'=>-1, 'position'=>500), //'fk_user_valid' =>array('type'=>'integer', 'label'=>'UserValid', 'enabled'=>1, 'visible'=>-1, 'position'=>500), 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'notnull'=>-1, 'index'=>1, 'position'=>1000), + 'status' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', -1=>'Cancel')), ); public $rowid; diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 97662c150da..c4826cf2792 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -270,22 +270,30 @@ if ($action == 'create') foreach($object->fields as $key => $val) { if (in_array($key, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat', 'fk_user_modif', 'import_key'))) continue; - print ''; + print ''.$langs->trans($val['label']).''; + print '>'; + print $langs->trans($val['label']); + print ''; print ''; if ($val['type'] == 'text') { print ''; + } + elseif (is_array($val['arrayofkeyval'])) + { + print $form->selectarray($key, $val['arrayofkeyval'], GETPOST($key, 'int')); } else { - print ''; + $cssforinput = 'minwidth100'; + print ''; } print ''; print ''; @@ -329,10 +337,15 @@ if (($id || $ref) && $action == 'edit') print ''; + } + elseif (is_array($val['arrayofkeyval'])) + { + print $form->selectarray($key, $val['arrayofkeyval'], GETPOST($key, 'int')); } else { - print ''; + $cssforinput = 'minwidth100'; + print ''; } print ''; print ''; From b9f2a53b3672eb80815fc29813c7445f3a8cb53e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 23 Sep 2017 23:51:49 +0200 Subject: [PATCH 115/177] Debug modulebuilder --- htdocs/modulebuilder/index.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 5ff69549182..02150274fda 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -1398,6 +1398,8 @@ elseif (! empty($module)) $pathtosql = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.sql'; $pathtosqlextra = strtolower($module).'/sql/llx_'.strtolower($tabobj).'_extrafields.sql'; $pathtosqlkey = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.key.sql'; + $pathtolib = strtolower($module).'/lib/'.strtolower($tabobj).'.lib.php'; + $pathtopicto = strtolower($module).'/img/object_'.strtolower($tabobj).'.png'; $realpathtoclass = dol_buildpath($pathtoclass, 0, 1); $realpathtoapi = dol_buildpath($pathtoapi, 0, 1); @@ -1410,6 +1412,8 @@ elseif (! empty($module)) $realpathtosql = dol_buildpath($pathtosql, 0, 1); $realpathtosqlextra = dol_buildpath($pathtosqlextra, 0, 1); $realpathtosqlkey = dol_buildpath($pathtosqlkey, 0, 1); + $realpathtolib = dol_buildpath($pathtolib, 0, 1); + $realpathtopicto = dol_buildpath($pathtopicto, 0, 1); print '
'; print ' '.$langs->trans("ClassFile").' : '.($realpathtoclass?'':'').$pathtoclass.($realpathtoclass?'':'').''; @@ -1459,6 +1463,16 @@ elseif (! empty($module)) print '
'; print ' '.$langs->trans("PageForNoteTab").' : '.($realpathtonote?'':'').$pathtonote.($realpathtonote?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; + + print '
'; + + print ' '.$langs->trans("PageForLib").' : '.($realpathtolib?'':'').$pathtolib.($realpathtodocument?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; + print ' '.$langs->trans("PageForPicto").' : '.($realpathtopicto?'':'').$pathtopicto.($realpathtopicto?'':'').''; + //print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; print '


'; From 91d303465dca47d1f2ca67f23ed6b0122aa15786 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 01:36:20 +0200 Subject: [PATCH 116/177] NEW Can add html content on right of tabs --- htdocs/admin/dolistore/ajax/image.php | 3 ++- htdocs/admin/ihm.php | 14 ++++++------- htdocs/compta/bank/bankentries.php | 2 +- htdocs/compta/facture/card.php | 4 ++-- htdocs/core/class/html.form.class.php | 4 ++-- htdocs/core/lib/functions.lib.php | 19 +++++++++++------- htdocs/core/search_page.php | 2 +- htdocs/core/tpl/objectline_create.tpl.php | 2 +- htdocs/core/tpl/objectline_edit.tpl.php | 8 ++++---- htdocs/fourn/facture/card.php | 4 ++-- htdocs/langs/en_US/modulebuilder.lang | 3 ++- htdocs/modulebuilder/index.php | 20 +++++++++++-------- .../product/class/html.formproduct.class.php | 3 +-- htdocs/projet/element.php | 2 -- htdocs/theme/eldy/style.css.php | 4 +++- htdocs/theme/md/style.css.php | 8 ++++++-- 16 files changed, 57 insertions(+), 45 deletions(-) diff --git a/htdocs/admin/dolistore/ajax/image.php b/htdocs/admin/dolistore/ajax/image.php index 6d63dd3e08b..14d05a036e8 100644 --- a/htdocs/admin/dolistore/ajax/image.php +++ b/htdocs/admin/dolistore/ajax/image.php @@ -64,4 +64,5 @@ try { if ($trace[0]['args'][0] == 404) die('Bad ID'); else if ($trace[0]['args'][0] == 401) die('Bad auth key'); else die('Can not access to '.$conf->global->MAIN_MODULE_DOLISTORE_API_SRV); -} \ No newline at end of file +} + diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 7a336e6d4e7..2322ae7a057 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -230,14 +230,14 @@ if ($action == 'edit') // Edit print ''; // Default language - print ''.$langs->trans("DefaultLanguage").''; + print ''.$langs->trans("DefaultLanguage").''; print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'MAIN_LANG_DEFAULT', 1, 0, 0, 0, 0, 'minwidth300'); print ''; print ' '; print ''; // Multilingual GUI - print ''.$langs->trans("EnableMultilangInterface").''; + print ''.$langs->trans("EnableMultilangInterface").''; print $form->selectyesno('MAIN_MULTILANGS',$conf->global->MAIN_MULTILANGS,1); print ''; print ' '; @@ -349,9 +349,8 @@ if ($action == 'edit') // Edit print ''; // Message of the day on home page - $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object')); + $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','objectamount')); complete_substitutions_array($substitutionarray, $langs); - $substitutionarray['__(AnyTranslationKey)__']=$langs->trans('TranslationKey'); print ''; $texthelp=$langs->trans("FollowingConstantsWillBeSubstituted").'
'; @@ -359,7 +358,7 @@ if ($action == 'edit') // Edit { $texthelp.=$key.'
'; } - print $form->textwithpicto($langs->trans("MessageOfDay"), $texthelp, 1, 'help', '', 0, 2, ''); + print $form->textwithpicto($langs->trans("MessageOfDay"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessageofday'); print ''; @@ -379,16 +378,15 @@ if ($action == 'edit') // Edit print ''; // Message on login page - $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','user')); + $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','objectamount','user')); complete_substitutions_array($substitutionarray, $langs); - $substitutionarray['__(AnyTranslationKey)__']=$langs->trans('TranslationKey'); print ''; $texthelp=$langs->trans("FollowingConstantsWillBeSubstituted").'
'; foreach($substitutionarray as $key => $val) { $texthelp.=$key.'
'; } - print $form->textwithpicto($langs->trans("MessageLogin"), $texthelp, 1, 'help', '', 0, 2, ''); + print $form->textwithpicto($langs->trans("MessageLogin"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessagelogin'); print ''; $doleditor = new DolEditor('main_home', (isset($conf->global->MAIN_HOME)?$conf->global->MAIN_HOME:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); $doleditor->Create(); diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index cd4d659d743..40d2f5c8ffc 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -743,7 +743,7 @@ if ($resql) // Title $bankcateg=new BankCateg($db); - $morehtml='
'; + $morehtml='
'; $morehtml.= ' "; // ' Page '; $morehtml.=''; $morehtml.='/'.$nbtotalofpages.' '; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index b3a21f9af31..8006a120996 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2550,8 +2550,8 @@ if ($action == 'create') print $desc; print '
'; - print '    0 ? 'checked':'').' /> "; - print '
    0 ? 'checked':'').' /> "; + print '    0 ? 'checked':'').' /> "; + print '
    0 ? 'checked':'').' /> "; print '
'; print '
'; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 931c3c5d1ce..f2427056fb5 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -544,7 +544,7 @@ class Form $disabled=0; $ret='
'; - $ret.=''; // Complete list with data from external modules. THe module can use $_SERVER['PHP_SELF'] to know on which page we are, or use the $parameters['currentcontext'] completed by executeHooks. $parameters=array(); @@ -561,7 +561,7 @@ class Form $ret.=''; // Warning: if you set submit button to disabled, post using 'Enter' will no more work. - $ret.=''; + $ret.=''; $ret.='
'; if (! empty($conf->use_javascript_ajax)) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 41cd039d1e6..f5b4b755b8d 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1016,11 +1016,12 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename=' * @param int $notab -1 or 0=Add tab header, 1=no tab header. If you set this to 1, using dol_fiche_end() to close tab is not required. * @param string $picto Add a picto on tab title * @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto. + * @param string $morehtmlright Add more html content on right of tabs title * @return void */ -function dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0) +function dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='') { - print dol_get_fiche_head($links, $active, $title, $notab, $picto, $pictoisfullpath); + print dol_get_fiche_head($links, $active, $title, $notab, $picto, $pictoisfullpath, $morehtmlright); } /** @@ -1032,14 +1033,17 @@ function dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto * @param int $notab -1 or 0=Add tab header, 1=no tab header. If you set this to 1, using dol_fiche_end() to close tab is not required. * @param string $picto Add a picto on tab title * @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto. + * @param string $morehtmlright Add more html content on right of tabs title * @return string */ -function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0) +function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='') { global $conf, $langs, $hookmanager; $out="\n".'
'."\n"; + if ($morehtmlright) $out.='
'.$morehtmlright.'
'; // Output right area first so when space is missing, text is in front of tabs and not under. + // Show title $showtitle=1; if (! empty($conf->dol_optimize_smallscreen)) $showtitle=0; @@ -1060,6 +1064,8 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi if (count($keys)) $maxkey=max($keys); } + //$conf->global->MAIN_MAXTABS_IN_CARD=3; + // Show tabs $bactive=false; // if =0 we don't use the feature @@ -1147,7 +1153,7 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi { $tabsname=str_replace("@", "", $picto); $out.='\n"; @@ -5213,9 +5219,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob if (empty($exclude) || ! in_array('system', $exclude)) { - $substitutionarray=array_merge($substitutionarray, array( - '__DOL_MAIN_URL_ROOT__'=>DOL_MAIN_URL_ROOT - )); + $substitutionarray['__(AnyTranslationKey)__']=$outputlangs->trans('TranslationKey'); + $substitutionarray['__DOL_MAIN_URL_ROOT__']=DOL_MAIN_URL_ROOT; } if (empty($exclude) || ! in_array('mycompany', $exclude)) { diff --git a/htdocs/core/search_page.php b/htdocs/core/search_page.php index 494dddbdff3..61d39af045e 100644 --- a/htdocs/core/search_page.php +++ b/htdocs/core/search_page.php @@ -73,7 +73,7 @@ if ($conf->use_javascript_ajax && 1 == 2) // select2 is ko with jmobile { if (! is_object($form)) $form=new Form($db); $selected=-1; - $searchform.='

'.$form->selectArrayAjax('searchselectcombo', DOL_URL_ROOT.'/core/ajax/selectsearchbox.php', $selected, 'data-role="none"', '', 0, 1, 'minwidth300', 1, $langs->trans("Search"), 0); + $searchform.='

'.$form->selectArrayAjax('searchselectcombo', DOL_URL_ROOT.'/core/ajax/selectsearchbox.php', $selected, '', '', 0, 1, 'minwidth300', 1, $langs->trans("Search"), 0); } else { diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 9969740ff35..84b2413f396 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -317,7 +317,7 @@ else { product->enabled) || ! empty($conf->service->enabled)) { ?> - + "> diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index 2f839e06281..de1649225ee 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -179,7 +179,7 @@ $coldisplay=-1; // We remove first td product->enabled) || ! empty($conf->service->enabled)) { ?> - + @@ -266,21 +266,21 @@ jQuery(document).ready(function() if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#price_ht").val() != '') { jQuery("#price_ttc").val(''); jQuery("#multicurrency_subprice").val(''); - } + } }); jQuery("#price_ttc").keyup(function(event) { // console.log(event.which); // discard event tag and arrows if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') { jQuery("#price_ht").val(''); jQuery("#multicurrency_subprice").val(''); - } + } }); jQuery("#multicurrency_subprice").keyup(function(event) { // console.log(event.which); // discard event tag and arrows if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') { jQuery("#price_ht").val(''); jQuery("#price_ttc").val(''); - } + } }); '; - print '    0 ? 'checked':'').' /> "; - print '
    0 ? 'checked':'').' /> "; + print '    0 ? 'checked':'').' /> "; + print '
    0 ? 'checked':'').' /> "; print '
'; print '
'; diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 891faa8e134..e5e662a7852 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -3,7 +3,8 @@ ModuleBuilderDesc=This tools must be used by experienced users or developers. It EnterNameOfModuleDesc=Enter name of the module/application to create with no spaces. Use uppercase to separate words (For example: MyModule, EcommerceForShop, SyncWithMySystem...) EnterNameOfObjectDesc=Enter name of the object to create with no spaces. Use uppercase to separate words (For example: MyObject, Student, Teacher...). The CRUD class file, but also API file, pages to list/add/edit/delete object and SQL files will be generated. ModuleBuilderDesc2=Path where modules are generated/edited (first alternative directory defined into %s): %s -ModuleBuilderDesc3=Generated/editable modules found: %s (they are detected as editable when the file %s exists in root of module directory). +ModuleBuilderDesc3=Generated/editable modules found: %s +ModuleBuilderDesc4=A module is detected as 'editable' when the file %s exists in root of module directory NewModule=New module NewObject=New object ModuleKey=Module key diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 02150274fda..da5bbfaf1cd 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -851,7 +851,8 @@ if ($message) print $message; } -print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).'
'; +//print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).'
'; +$infomodulesfound = '
'.$form->textwithpicto($langs->trans("ModuleBuilderDesc3", count($listofmodules)), $langs->trans("ModuleBuilderDesc4", $FILEFLAG)).'
'; // Load module descriptor @@ -911,7 +912,7 @@ $head[$h][2] = 'deletemodule'; $h++; -dol_fiche_head($head, $module, $langs->trans("Modules"), -1, 'generic'); // Modules +dol_fiche_head($head, $module, $langs->trans("Modules"), -1, 'generic', 0, $infomodulesfound); // Modules if ($module == 'initmodule') { @@ -1427,6 +1428,15 @@ elseif (! empty($module)) print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; + print '
'; + + print ' '.$langs->trans("PageForLib").' : '.($realpathtolib?'':'').$pathtolib.($realpathtodocument?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; + print ' '.$langs->trans("PageForPicto").' : '.($realpathtopicto?'':'').$pathtopicto.($realpathtopicto?'':'').''; + //print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; + print '
'; print ' '.$langs->trans("SqlFile").' : '.($realpathtosql?'':'').$pathtosql.($realpathtosql?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; @@ -1467,12 +1477,6 @@ elseif (! empty($module)) print '
'; - print ' '.$langs->trans("PageForLib").' : '.($realpathtolib?'':'').$pathtolib.($realpathtodocument?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - print ' '.$langs->trans("PageForPicto").' : '.($realpathtopicto?'':'').$pathtopicto.($realpathtopicto?'':'').''; - //print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print ''; print '


'; diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php index 1c4c3249791..8d4ddc4705d 100644 --- a/htdocs/product/class/html.formproduct.class.php +++ b/htdocs/product/class/html.formproduct.class.php @@ -219,10 +219,9 @@ class FormProduct include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlname, $events); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } - $out.=''; if ($empty) $out.=''; foreach($this->cache_warehouses as $id => $arraytypes) { diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index f76b6f9f0cc..8dd7f6bbed5 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -1133,13 +1133,11 @@ foreach ($listofreferent as $key => $value) } // Enhance with select2 -$nodatarole=''; if ($conf->use_javascript_ajax) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox('.elementselect'); $out.=$comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); print $comboenhancement; } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 1fbd4e44037..fa85d0825e7 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2039,7 +2039,9 @@ div.tabs { div.tabsElem { margin-top: 1px; } /* To avoid overlap of tabs when not browser */ - +div.tabsElem a { + font-weight: normal !important; +} div.tabBar { color: #; padding-top: 16px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 4d46f2e781e..1273d819f3c 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2064,8 +2064,12 @@ div.tabs { clear:both; height:100%; } -div.tabsElem { margin-top: 6px; } /* To avoid overlap of tabs when not browser */ - +div.tabsElem { + margin-top: 6px; +} /* To avoid overlap of tabs when not browser */ +div.tabsElem a { + font-weight: normal !important; +} div.tabBar { color: #; padding-top: 16px; From 87a75a0ad73b4c5436eccda96a0ff32dd187c62c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 01:46:00 +0200 Subject: [PATCH 117/177] CSS not bold on jnotify messages --- htdocs/theme/eldy/style.css.php | 6 ++++++ htdocs/theme/md/style.css.php | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index fa85d0825e7..505038023ca 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -3991,6 +3991,12 @@ div#ecm-layout-center { padding-left: 10px !important; padding-right: 10px !important; } +.jnotify-container .jnotify-notification .jnotify-message { + font-weight: normal; +} +.jnotify-container .jnotify-notification-warning .jnotify-close, .jnotify-container .jnotify-notification-warning .jnotify-message { + color: #a28918 !important; +} /* use or not ? */ div.jnotify-background { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 1273d819f3c..64d852b0395 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -4043,6 +4043,12 @@ div#ecm-layout-center { padding-left: 10px !important; padding-right: 10px !important; } +.jnotify-container .jnotify-notification .jnotify-message { + font-weight: normal; +} +.jnotify-container .jnotify-notification-warning .jnotify-close, .jnotify-container .jnotify-notification-warning .jnotify-message { + color: #a28918 !important; +} /* use or not ? */ div.jnotify-background { From 97ece5fda949292c37f438e3df9ea82895fd7a15 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 01:49:59 +0200 Subject: [PATCH 118/177] CSS --- htdocs/theme/eldy/style.css.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 505038023ca..c1841f6cb9a 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -3138,12 +3138,11 @@ td.legendLabel { padding: 2px 2px 2px 0 !important; } div.titre { font-family: ; font-size: 14px; - font-weight: bold; + /* font-weight: bold; */ color: rgb(); text-decoration: none; padding-top: 5px; padding-bottom: 5px; - /* text-shadow: 1px 1px 2px #FFFFFF; */ } #dolpaymenttable { min-width: 310px; font-size: 16px; } /* Width must have min to make stripe input area visible */ From f4b35a304b4d552be8607e7425e3650dea83507c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 02:32:21 +0200 Subject: [PATCH 119/177] Update doc --- .../template/doc/Specifications.asciidoc | 128 +++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-) diff --git a/htdocs/modulebuilder/template/doc/Specifications.asciidoc b/htdocs/modulebuilder/template/doc/Specifications.asciidoc index d2150c0865d..adfaeb4e9b5 100644 --- a/htdocs/modulebuilder/template/doc/Specifications.asciidoc +++ b/htdocs/modulebuilder/template/doc/Specifications.asciidoc @@ -1,3 +1,127 @@ -# SPECIFICATIONS OF MODULE MYMODULE FOR DOLIBARR ERP CRM += MYMODULE = +Copyright (C) ---Put here your own copyright and developer email--- +:subtitle: MYMODULE SPECIFICATIONS + + + +== Topic of document + +This document was build from following input: + +* Date 1 +... + +* Date 2 +... + + +The document includes an introductory chapter of functional specifications, presenting the different actors involved in the rebuild of the definitions +of business terms that will be used (some of which may be new or different). +The main following chapter will present the entire process, also known as *uses cases*, according to a principle of a description, in chronological sequence if possible, +to present the actor and the action performed, as in the following example: + +* *X* Actor realizes Action A. +* *Y* Actor communicates Info B to Actor *Z* +* *Automaton* performs update of data for... +* Etc ... + +Functional requirements are complemented by a chapter of technical requirements. +The chapter on data lists key information specific to Presto that were identified at the time of writing specification. It will be enriched as +iterations occurs. + +Finally, in the Appendix, the documents known when writing this document are centralized to illustrate the existing document or inspire the new expected one. +These documents have their content directly integrated in this specification or have a reference to +external documents stored in the *Appendices* directory accompanying this document. + + + +*Log of versions* + +[options="header",format="csv"] +|=== +Author, Date, Version +John Doe, Date YYY-MM-DD, Version 1.0 +|=== + + + +<<< + + +== BUSINESS SPECIFICATIONS - INTRODUCTION + +=== List of actors [[actors]] + +Actors are physical people or moral entities working on at least one process. +The following chart prensts list of actors or partners identified by the project for the defined scope of project. We will use then the name defined into first column to speak about roles in the rest of documents. + +[options="header",format="csv"] +|=== +Actor/profil/role, Description of role, Access to system or not, Example of actor +Customer Service, Receive and create Sales orders (SO), Yes, Mr Smith +Purchase, Make puchase order (PO), Yes, 5 people +Administrator - IT, Administration of users/groups and IT services, Yes, John Doe +Automaton, Execute automatic data processing, Yes, NA +|=== + + +=== Definitions [[definitions]] + +To understand the descriptions of the target process, it was necessary to define or redefine some vocabulary concepts. We must see these definitions as defined in the +new system. Indeed, some terms are already being used but have either not a definition in line with standards, or even differs between services. To bring everyone, +and to consolidate the process, these terms are redefined here, and with their definition in the target objective. + +*Definition ABC* + +... + +*Definition DEF* + +... + + +[NOTE] +============== +Important information will be noticed with a notice like this one. + +* Main information 1 +* Main information 2 +============== + + + +== BUSINESS SPECIFICATION - PROCESS + +Specifications were cut into different business process. We call a business process a workflow with a starting situation and ending situation. Between start and end, we will find actions +done by actors to bring the value of the company. This actions are described using the syntax rule: +*Actor X* do action Y, *Actor Z* do action W. + +_Each process/use case is described into a separate chapter._ + + +=== Use case / Process 1 [[process_1]] + +==== Title and goals + +... + +==== Actors or roles + +* Members of group *...* + +==== Standard flow + +* Members of Groupe *...*: Do ... +* Members of Groupe *...*: Do ... +* Members of Groupe *...*: Do ... + +==== Alternative flow + +* A user without role *...*: Can't do ... + +==== Business rules + +* Business rule 1 +* Business rule 2 + -There is no detailed specification available yet. From fac4ebec22bad9b7f550e72f5bb6ff7f4e404008 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 10:26:43 +0200 Subject: [PATCH 120/177] Code comment --- htdocs/modulebuilder/template/myobject_card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index c4826cf2792..515768b8011 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -27,8 +27,8 @@ //if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); //if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); //if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test done when option MAIN_SECURITY_CSRF_WITH_TOKEN is on. //if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data //if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test //if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu From c65f794f87b8804d57a7eafdc4a20b391aef59d4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 10:29:48 +0200 Subject: [PATCH 121/177] Code comment --- htdocs/modulebuilder/index.php | 2 +- htdocs/modulebuilder/template/myobject_list.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index da5bbfaf1cd..dade8847aa6 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -23,7 +23,7 @@ * \brief Home page for module builder module */ -if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test +if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti SQL+XSS injection attack test require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index ad8c8b317eb..475716114fa 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -27,8 +27,8 @@ //if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); //if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); //if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test done when option MAIN_SECURITY_CSRF_WITH_TOKEN is on. //if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data //if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test //if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu From 0cdca6f3ebae336a29398e463856529ba9c6d910 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sun, 24 Sep 2017 11:10:33 +0200 Subject: [PATCH 122/177] Fix: phpcs error --- htdocs/core/class/html.form.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index f2427056fb5..dd9e643e74c 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2987,12 +2987,12 @@ class Form * Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want. * See instead to force the default value by the caller. * - * @param int $selected Id of payment term to preselect by default - * @param string $htmlname Nom de la zone select - * @param int $filtertype Not used + * @param int $selected Id of payment term to preselect by default + * @param string $htmlname Nom de la zone select + * @param int $filtertype Not used * @param int $addempty Add an empty entry - * @param int $noadmininfo 0=Add admin info, 1=Disable admin info - * @param string $morecss Add more CSS on select tag + * @param int $noinfoadmin 0=Add admin info, 1=Disable admin info + * @param string $morecss Add more CSS on select tag * @return void */ function select_conditions_paiements($selected=0, $htmlname='condid', $filtertype=-1, $addempty=0, $noinfoadmin=0, $morecss='') From b48fe684d358c9cecaa793b51c51a95dde0eed60 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sun, 24 Sep 2017 17:43:01 +0200 Subject: [PATCH 123/177] Fix: wrong return when cancel --- htdocs/adherents/card.php | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 479af36a134..0ef0a4e3dc3 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -121,17 +121,6 @@ $hookmanager->initHooks(array('membercard','globalcard')); * Actions */ -if ($cancel) { - - $action=''; - - if (! empty($backtopage)) - { - header("Location: ".$backtopage); - exit; - } -} - $parameters=array('id'=>$id, 'rowid'=>$id, 'objcanvas'=>$objcanvas); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); @@ -986,11 +975,18 @@ else dol_fiche_end(); - print '
'; - print ''; - print '     '; - print ''; - print '
'; + print '
'; + print ''; + print '  '; + if (! empty($backtopage)) + { + print ''; + } + else + { + print ''; + } + print '
'; print "\n"; } From 49e9326a6d4b81e446b40b2143b47af145b23145 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 19:50:32 +0200 Subject: [PATCH 124/177] Code comment --- htdocs/core/lib/security2.lib.php | 2 +- htdocs/main.inc.php | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index 3876dc0e2cd..4d79b87122e 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -184,7 +184,7 @@ function dol_loginfunction($langs,$conf,$mysoc) // Set cookie for timeout management $prefix=dol_getprefix(); $sessiontimeout='DOLSESSTIMEOUT_'.$prefix; - if (! empty($conf->global->MAIN_SESSION_TIMEOUT)) setcookie($sessiontimeout, $conf->global->MAIN_SESSION_TIMEOUT, 0, "/", '', 0); + if (! empty($conf->global->MAIN_SESSION_TIMEOUT)) setcookie($sessiontimeout, $conf->global->MAIN_SESSION_TIMEOUT, 0, "/", null, false, true); if (GETPOST('urlfrom','alpha')) $_SESSION["urlfrom"]=GETPOST('urlfrom','alpha'); else unset($_SESSION["urlfrom"]); diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 675c82aa499..27168349f22 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -179,7 +179,9 @@ if (! empty($_SERVER['DOCUMENT_ROOT']) && substr($_SERVER['DOCUMENT_ROOT'], -6) // Include the conf.php and functions.lib.php require_once 'filefunc.inc.php'; -// If there is a POST parameter to tell to save automatically some POST parameters into cookies, we do it +// If there is a POST parameter to tell to save automatically some POST parameters into cookies, we do it. +// This is used for example by form of boxes to save personalization of some options. +// DOL_AUTOSET_COOKIE=cookiename:val1,val2 and cookiename_val1=aaa cookiename_val2=bbb will set cookie_name with value json_encode(array('val1'=> , )) if (! empty($_POST["DOL_AUTOSET_COOKIE"])) { $tmpautoset=explode(':',$_POST["DOL_AUTOSET_COOKIE"],2); @@ -194,7 +196,7 @@ if (! empty($_POST["DOL_AUTOSET_COOKIE"])) $cookiename=$tmpautoset[0]; $cookievalue=json_encode($cookiearrayvalue); //var_dump('setcookie cookiename='.$cookiename.' cookievalue='.$cookievalue); - setcookie($cookiename, empty($cookievalue)?'':$cookievalue, empty($cookievalue)?0:(time()+(86400*354)), '/'); // keep cookie 1 year + setcookie($cookiename, empty($cookievalue)?'':$cookievalue, empty($cookievalue)?0:(time()+(86400*354)), '/', null, false, true); // keep cookie 1 year and add tag httponly if (empty($cookievalue)) unset($_COOKIE[$cookiename]); } @@ -204,7 +206,7 @@ $sessionname='DOLSESSID_'.$prefix; $sessiontimeout='DOLSESSTIMEOUT_'.$prefix; if (! empty($_COOKIE[$sessiontimeout])) ini_set('session.gc_maxlifetime',$_COOKIE[$sessiontimeout]); session_name($sessionname); -session_set_cookie_params(0, '/', null, false, true); // Add tag httponly on session cookie +session_set_cookie_params(0, '/', null, false, true); // Add tag httponly on session cookie (same as setting session.cookie_httponly into php.ini). Must be called before the session_start. // This create lock released until session_write_close() or end of page. // We need this lock as long as we read/write $_SESSION ['vars']. We can close released when finished. if (! defined('NOSESSION')) From 4246cf24f3ea4b296647f57267dbd5b417691d57 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 20:36:27 +0200 Subject: [PATCH 125/177] Perf enhancement: Remove one include of js. --- htdocs/core/class/html.form.class.php | 11 +++-- htdocs/core/js/lib_head.js.php | 29 ++++++++++++ htdocs/core/js/select2_locale.js.php | 67 --------------------------- htdocs/core/lib/ajax.lib.php | 5 +- htdocs/main.inc.php | 3 +- 5 files changed, 39 insertions(+), 76 deletions(-) delete mode 100644 htdocs/core/js/select2_locale.js.php diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index f2427056fb5..d5ada748c1f 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5215,15 +5215,16 @@ class Form */ static function selectArrayAjax($htmlname, $url, $id='', $moreparam='', $moreparamtourl='', $disabled=0, $minimumInputLength=1, $morecss='', $callurlonselect=0, $placeholder='', $acceptdelayedhtml=0) { - global $langs; + global $conf, $langs; global $delayedhtmlcontent; - $tmpplugin='select2'; + // TODO Use an internal dolibarr component instead of select2 + if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && ! defined('REQUIRE_JQUERY_MULTISELECT')) return ''; $out=''; - // TODO Use an internal dolibarr component instead of select2 - $outdelayed=' + $tmpplugin='select2'; + $outdelayed="\n".' '."\n"; - print ''."\n"; } } @@ -1321,7 +1320,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs // Global js function print ''."\n"; - print ''."\n"; + print ''."\n"; // Add datepicker default options /*if (! defined('DISABLE_DATE_PICKER')) From 3482b1293321e134a7b45afdab6ad5a9fae7cf3f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 20:55:48 +0200 Subject: [PATCH 126/177] Comment deprecated js code --- htdocs/core/js/lib_head.js.php | 157 +++++++++++++++++---------------- 1 file changed, 81 insertions(+), 76 deletions(-) diff --git a/htdocs/core/js/lib_head.js.php b/htdocs/core/js/lib_head.js.php index 46219f1b50e..57a6c4f7005 100644 --- a/htdocs/core/js/lib_head.js.php +++ b/htdocs/core/js/lib_head.js.php @@ -82,6 +82,7 @@ else header('Cache-Control: no-cache'); * SimpleDateFormat a utiliser pour retour * ================================================================== */ + /* function showDP(base,dateFieldID,format,codelang) { // check to see if another box is already showing @@ -165,7 +166,7 @@ function resetDP(base,dateFieldID,format,codelang) function loadMonth(base,month,year,ymd,codelang) { - /* showDP.box.innerHTML="Loading..."; */ + // showDP.box.innerHTML="Loading..."; // alert(codelang); var theURL=base+"datepicker.php?cm=shw&lang="+codelang; theURL+="&m="+encodeURIComponent(month); @@ -192,37 +193,6 @@ function closeDPBox() showDP.datefieldID=null; } -function dpChangeDay(dateFieldID,format) -{ - showDP.datefieldID=dateFieldID; - console.log("Call dpChangeDay, we save date into detailed fields."); - - var thefield=getObjectFromID(showDP.datefieldID); - var thefieldday=getObjectFromID(showDP.datefieldID+"day"); - var thefieldmonth=getObjectFromID(showDP.datefieldID+"month"); - var thefieldyear=getObjectFromID(showDP.datefieldID+"year"); - - var date=getDateFromFormat(thefield.value,format); - if (date) - { - thefieldday.value=date.getDate(); - if(thefieldday.onchange) thefieldday.onchange.call(thefieldday); - thefieldmonth.value=date.getMonth()+1; - if(thefieldmonth.onchange) thefieldmonth.onchange.call(thefieldmonth); - thefieldyear.value=date.getFullYear(); - if(thefieldyear.onchange) thefieldyear.onchange.call(thefieldyear); - } - else - { - thefieldday.value=''; - if(thefieldday.onchange) thefieldday.onchange.call(thefieldday); - thefieldmonth.value=''; - if(thefieldmonth.onchange) thefieldmonth.onchange.call(thefieldmonth); - thefieldyear.value=''; - if(thefieldyear.onchange) thefieldyear.onchange.call(thefieldyear); - } -} - function dpClickDay(year,month,day,format) { var thefield=getObjectFromID(showDP.datefieldID); @@ -250,16 +220,6 @@ function dpHighlightDay(year,month,day,months){ displayinfo.innerHTML=months[month-1]+" "+day+", "+year; } -// Returns an object given an id -function getObjectFromID(id){ - var theObject; - if(document.getElementById) - theObject=document.getElementById(id); - else - theObject=document.all[id]; - return theObject; -} - // This Function returns the top position of an object function getTop(theitem){ var offsetTrail = theitem; @@ -286,6 +246,85 @@ function getLeft(theitem){ return offsetLeft; } +// To hide/show select Boxes with IE6 (and only IE6 because IE6 has a bug and +// not put popup completely on the front) +// Used only bu popup calendar +function hideSelectBoxes() { + var brsVersion = parseInt(window.navigator.appVersion.charAt(0), 10); + if (brsVersion <= 6 && window.navigator.userAgent.indexOf("MSIE 6") > -1) + { + for(var i = 0; i < document.all.length; i++) + { + if(document.all[i].tagName) + if(document.all[i].tagName == "SELECT") + document.all[i].style.visibility="hidden"; + } + } +} +// To hide/show select Boxes with IE6 (and only IE6 because IE6 has a bug and +// not put popup completely on the front) +// Used only bu popup calendar +function displaySelectBoxes() { + var brsVersion = parseInt(window.navigator.appVersion.charAt(0), 10); + if (brsVersion <= 6 && window.navigator.userAgent.indexOf("MSIE 6") > -1) + { + for(var i = 0; i < document.all.length; i++) + { + if(document.all[i].tagName) + if(document.all[i].tagName == "SELECT") + document.all[i].style.visibility="visible"; + } + } +} + +*/ + + +// Returns an object given an id +function getObjectFromID(id){ + var theObject; + if(document.getElementById) + theObject=document.getElementById(id); + else + theObject=document.all[id]; + return theObject; +} + +// Called after selection of a date to save details into detailed fields +function dpChangeDay(dateFieldID,format) +{ + //showDP.datefieldID=dateFieldID; + console.log("Call dpChangeDay, we save date into detailed fields."); + + var thefield=getObjectFromID(dateFieldID); + var thefieldday=getObjectFromID(dateFieldID+"day"); + var thefieldmonth=getObjectFromID(dateFieldID+"month"); + var thefieldyear=getObjectFromID(dateFieldID+"year"); + + var date=getDateFromFormat(thefield.value,format); + if (date) + { + thefieldday.value=date.getDate(); + if(thefieldday.onchange) thefieldday.onchange.call(thefieldday); + thefieldmonth.value=date.getMonth()+1; + if(thefieldmonth.onchange) thefieldmonth.onchange.call(thefieldmonth); + thefieldyear.value=date.getFullYear(); + if(thefieldyear.onchange) thefieldyear.onchange.call(thefieldyear); + } + else + { + thefieldday.value=''; + if(thefieldday.onchange) thefieldday.onchange.call(thefieldday); + thefieldmonth.value=''; + if(thefieldmonth.onchange) thefieldmonth.onchange.call(thefieldmonth); + thefieldyear.value=''; + if(thefieldyear.onchange) thefieldyear.onchange.call(thefieldyear); + } +} + + + + // Create XMLHttpRequest object and load url // Used by calendar or other ajax processes @@ -345,40 +384,6 @@ function loadXMLDoc(url,readyStateFunction,async) return req; } -/* To hide/show select Boxes with IE6 (and only IE6 because IE6 has a bug and - * not put popup completely on the front) - * Used only bu popup calendar - */ -function hideSelectBoxes() { - var brsVersion = parseInt(window.navigator.appVersion.charAt(0), 10); - if (brsVersion <= 6 && window.navigator.userAgent.indexOf("MSIE 6") > -1) - { - for(var i = 0; i < document.all.length; i++) - { - if(document.all[i].tagName) - if(document.all[i].tagName == "SELECT") - document.all[i].style.visibility="hidden"; - } - } -} -/* To hide/show select Boxes with IE6 (and only IE6 because IE6 has a bug and - * not put popup completely on the front) - * Used only bu popup calendar - */ -function displaySelectBoxes() { - var brsVersion = parseInt(window.navigator.appVersion.charAt(0), 10); - if (brsVersion <= 6 && window.navigator.userAgent.indexOf("MSIE 6") > -1) - { - for(var i = 0; i < document.all.length; i++) - { - if(document.all[i].tagName) - if(document.all[i].tagName == "SELECT") - document.all[i].style.visibility="visible"; - } - } -} - - /* * ================================================================= From 2e511badf99f321ecd1a9c86b0dbb05662cb3fd6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 21:02:20 +0200 Subject: [PATCH 127/177] Code comment --- htdocs/core/js/lib_head.js.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/js/lib_head.js.php b/htdocs/core/js/lib_head.js.php index 57a6c4f7005..7ed49d004d2 100644 --- a/htdocs/core/js/lib_head.js.php +++ b/htdocs/core/js/lib_head.js.php @@ -44,7 +44,7 @@ top_httphead('text/javascript; charset=UTF-8'); if (empty($dolibarr_nocache)) header('Cache-Control: max-age=3600, public, must-revalidate'); else header('Cache-Control: no-cache'); ?> - +// Javascript libraries for Dolibarr ERP CRM (https://www.dolibarr.org) /** From 7a6180858e9d37a2d8442a9a72d9428554b95514 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 21:12:50 +0200 Subject: [PATCH 128/177] Fix phpunit --- test/phpunit/AdherentTest.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/phpunit/AdherentTest.php b/test/phpunit/AdherentTest.php index 34ec0a80917..b29f8508a8e 100644 --- a/test/phpunit/AdherentTest.php +++ b/test/phpunit/AdherentTest.php @@ -196,7 +196,6 @@ class AdherentTest extends PHPUnit_Framework_TestCase $result=$localobject->fetch($id); print __METHOD__." id=".$id." result=".$result."\n"; $this->assertLessThan($result, 0); - return $localobject; } @@ -318,14 +317,13 @@ class AdherentTest extends PHPUnit_Framework_TestCase $langs=$this->savlangs; $db=$this->savdb; - $template = '%DOL_MAIN_URL_ROOT%,%ID%,%CIVILITY%,%FIRSTNAME%,%LASTNAME%,%FULLNAME%,%COMPANY%,'. - '%ADDRESS%,%ZIP%,%TOWN%,%COUNTRY%,%EMAIL%,%BIRTH%,%PHOTO%,%LOGIN%,%PASSWORD%,%PRENOM%,'. - '%NOM%,%SOCIETE%,%ADDRESS%,%ZIP%,%TOWN%,%COUNTRY%'; + $template = '__CIVILITY__,__FIRSTNAME__,__LASTNAME__,__FULLNAME__,__COMPANY__,'. + '__ADDRESS__,__ZIP__,__TOWN__,__COUNTRY__,__EMAIL__,__BIRTH__,__PHOTO__,__LOGIN__'; // If option to store clear password has been set, we get 'dolibspec' into PASSWORD field. - $expected = DOL_MAIN_URL_ROOT.','.$localobject->id.',,New firstname,New name,New firstname New name,'. + $expected = ',New firstname,New name,New firstname New name,'. 'New company,New address,New zip,New town,Belgium,newemail@newemail.com,'.dol_print_date($localobject->birth,'day').',,'. - 'newlogin,dolibspec,New firstname,New name,New company,New address,New zip,New town,Belgium'; + 'newlogin'; $result = $localobject->makeSubstitution($template); print __METHOD__." result=".$result."\n"; From 971e59395c78e2527510d35d76627a50e917eebf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 21:46:14 +0200 Subject: [PATCH 129/177] Fix phpcs --- htdocs/core/class/html.form.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index d5ada748c1f..b75cde6d9e3 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2991,7 +2991,7 @@ class Form * @param string $htmlname Nom de la zone select * @param int $filtertype Not used * @param int $addempty Add an empty entry - * @param int $noadmininfo 0=Add admin info, 1=Disable admin info + * @param int $noinfoadmin 0=Add admin info, 1=Disable admin info * @param string $morecss Add more CSS on select tag * @return void */ From 5776a948c44309402f9c462a85766084c0e2e833 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 21:54:26 +0200 Subject: [PATCH 130/177] Update card.php --- htdocs/holiday/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index 6d6eb15e856..51ad2277ab5 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -39,7 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/holiday/common.inc.php'; $myparam = GETPOST("myparam"); $action=GETPOST('action', 'alpha'); $id=GETPOST('id', 'int'); -$fuserid = (GETPOST('fuserid')?:$user->id); +$fuserid = (GETPOST('fuserid','int')?GETPOST('fuserid','int'):$user->id); // Protection if external user if ($user->societe_id > 0) accessforbidden(); From 1bb5408d837feea388d9abd1959a1df33fd9cb70 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 22:18:10 +0200 Subject: [PATCH 131/177] FIX #7464 --- htdocs/install/mysql/migration/5.0.0-6.0.0.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 3a5810d19e4..cd955b0416b 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -338,6 +338,7 @@ UPDATE llx_const SET value = __ENCRYPT('moono-lisa')__ WHERE value = __ENCRYPT DELETE FROM llx_document_model where nom = 'fsfe.fr.php' and type='donation'; ALTER TABLE llx_product_price ADD COLUMN default_vat_code varchar(10) AFTER tva_tx; +ALTER TABLE llx_product_customer_price ADD COLUMN default_vat_code varchar(10) AFTER tva_tx; ALTER TABLE llx_product_fournisseur_price ADD COLUMN default_vat_code varchar(10) AFTER tva_tx; ALTER TABLE llx_user ADD COLUMN model_pdf varchar(255); From 3a7aea48d76d82f2a4de61785b13caa014d641be Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 22:38:18 +0200 Subject: [PATCH 132/177] FIX #7475 --- htdocs/comm/propal/class/propal.class.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index f007cbdbf81..359695d883b 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3366,8 +3366,8 @@ class Propal extends CommonObject $this->lines = array(); $sql = 'SELECT pt.rowid, pt.label as custom_label, pt.description, pt.fk_product, pt.fk_remise_except,'; - $sql.= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.remise_percent, pt.subprice, pt.info_bits,'; - $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code, pt.localtax1_tx, pt.localtax2_tx,'; + $sql.= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.localtax1_tx, pt.localtax2_tx, pt.remise_percent, pt.subprice, pt.info_bits,'; + $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.total_localtax1, pt.total_localtax2, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code,'; $sql.= ' pt.date_start, pt.date_end, pt.product_type, pt.rang, pt.fk_parent_line,'; $sql.= ' pt.fk_unit,'; $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.description as product_desc, p.tobatch as product_tobatch,'; @@ -3411,11 +3411,15 @@ class Propal extends CommonObject $this->lines[$i]->vat_src_code = $obj->vat_src_code; $this->lines[$i]->tva_tx = $obj->tva_tx; + $this->lines[$i]->localtax1_tx = $obj->localtax1_tx; + $this->lines[$i]->localtax2_tx = $obj->localtax2_tx; $this->lines[$i]->info_bits = $obj->info_bits; $this->lines[$i]->total_ht = $obj->total_ht; $this->lines[$i]->total_tva = $obj->total_tva; $this->lines[$i]->total_ttc = $obj->total_ttc; - $this->lines[$i]->fk_fournprice = $obj->fk_fournprice; + $this->lines[$i]->total_localtax1 = $obj->total_localtax1; + $this->lines[$i]->total_localtax2 = $obj->total_localtax2; + $this->lines[$i]->fk_fournprice = $obj->fk_fournprice; $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht); $this->lines[$i]->pa_ht = $marginInfos[0]; $this->lines[$i]->marge_tx = $marginInfos[1]; From adb3827d1eeb3c6ce963155b776b35f922f2417d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 22:55:27 +0200 Subject: [PATCH 133/177] FIX #7475 --- htdocs/comm/propal/class/propal.class.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 359695d883b..f2ecb877a9a 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1404,7 +1404,7 @@ class Propal extends CommonObject { $this->lines=array(); - $sql = 'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,'; + $sql = 'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,'; $sql.= ' d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,'; $sql.= ' d.fk_unit,'; $sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label,'; @@ -1443,6 +1443,8 @@ class Propal extends CommonObject $line->tva_tx = $objp->tva_tx; $line->localtax1_tx = $objp->localtax1_tx; $line->localtax2_tx = $objp->localtax2_tx; + $line->localtax1_type = $objp->localtax1_type; + $line->localtax2_type = $objp->localtax2_type; $line->subprice = $objp->subprice; $line->fk_remise_except = $objp->fk_remise_except; $line->remise_percent = $objp->remise_percent; @@ -3366,7 +3368,7 @@ class Propal extends CommonObject $this->lines = array(); $sql = 'SELECT pt.rowid, pt.label as custom_label, pt.description, pt.fk_product, pt.fk_remise_except,'; - $sql.= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.localtax1_tx, pt.localtax2_tx, pt.remise_percent, pt.subprice, pt.info_bits,'; + $sql.= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.localtax1_tx, pt.localtax2_tx, pt.localtax1_type, pt.localtax2_type, pt.remise_percent, pt.subprice, pt.info_bits,'; $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.total_localtax1, pt.total_localtax2, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code,'; $sql.= ' pt.date_start, pt.date_end, pt.product_type, pt.rang, pt.fk_parent_line,'; $sql.= ' pt.fk_unit,'; @@ -3413,6 +3415,8 @@ class Propal extends CommonObject $this->lines[$i]->tva_tx = $obj->tva_tx; $this->lines[$i]->localtax1_tx = $obj->localtax1_tx; $this->lines[$i]->localtax2_tx = $obj->localtax2_tx; + $this->lines[$i]->localtax1_type = $obj->localtax1_type; + $this->lines[$i]->localtax2_type = $obj->localtax2_type; $this->lines[$i]->info_bits = $obj->info_bits; $this->lines[$i]->total_ht = $obj->total_ht; $this->lines[$i]->total_tva = $obj->total_tva; From 270aba99faabfd561fddfa8f7e94a8b413db2508 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 23:28:48 +0200 Subject: [PATCH 134/177] FIX #7471 --- .../class/fournisseur.commande.class.php | 9 +++- .../fourn/class/fournisseur.facture.class.php | 4 +- htdocs/fourn/commande/card.php | 52 ++++++++++++------- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 528e32fd4a4..d328a66cef3 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -279,11 +279,12 @@ class CommandeFournisseur extends CommonOrder $this->fetchObjectLinked(); + //$result=$this->fetch_lines(); $this->lines=array(); $sql = "SELECT l.rowid, l.ref as ref_supplier, l.fk_product, l.product_type, l.label, l.description, l.qty,"; $sql.= " l.vat_src_code, l.tva_tx, l.remise_percent, l.subprice,"; - $sql.= " l.localtax1_tx, l. localtax2_tx, l.total_localtax1, l.total_localtax2,"; + $sql.= " l.localtax1_tx, l. localtax2_tx, l.localtax1_type, l. localtax2_type, l.total_localtax1, l.total_localtax2,"; $sql.= " l.total_ht, l.total_tva, l.total_ttc, l.special_code, l.fk_parent_line, l.rang,"; $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.description as product_desc,"; $sql.= " l.fk_unit,"; @@ -315,6 +316,8 @@ class CommandeFournisseur extends CommonOrder $line->tva_tx = $objp->tva_tx; $line->localtax1_tx = $objp->localtax1_tx; $line->localtax2_tx = $objp->localtax2_tx; + $line->localtax1_type = $objp->localtax1_type; + $line->localtax2_type = $objp->localtax2_type; $line->subprice = $objp->subprice; $line->pu_ht = $objp->subprice; $line->remise_percent = $objp->remise_percent; @@ -2977,7 +2980,7 @@ class CommandeFournisseurLigne extends CommonOrderLine public function fetch($rowid) { $sql = 'SELECT cd.rowid, cd.fk_commande, cd.fk_product, cd.product_type, cd.description, cd.qty, cd.tva_tx,'; - $sql.= ' cd.localtax1_tx, cd.localtax2_tx, cd.ref,'; + $sql.= ' cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.ref,'; $sql.= ' cd.remise, cd.remise_percent, cd.subprice,'; $sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_ttc,'; $sql.= ' cd.total_localtax1, cd.total_localtax2,'; @@ -3003,6 +3006,8 @@ class CommandeFournisseurLigne extends CommonOrderLine $this->tva_tx = $objp->tva_tx; $this->localtax1_tx = $objp->localtax1_tx; $this->localtax2_tx = $objp->localtax2_tx; + $this->localtax1_type = $objp->localtax1_type; + $this->localtax2_type = $objp->localtax2_type; $this->remise = $objp->remise; $this->remise_percent = $objp->remise_percent; $this->fk_product = $objp->fk_product; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 022b5f7c15d..6e5e7fce66a 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -640,7 +640,7 @@ class FactureFournisseur extends CommonInvoice function fetch_lines() { $sql = 'SELECT f.rowid, f.ref as ref_supplier, f.description, f.pu_ht, f.pu_ttc, f.qty, f.remise_percent, f.vat_src_code, f.tva_tx'; - $sql.= ', f.localtax1_tx, f.localtax2_tx, f.total_localtax1, f.total_localtax2, f.fk_facture_fourn '; + $sql.= ', f.localtax1_tx, f.localtax2_tx, f.localtax1_type, f.localtax2_type, f.total_localtax1, f.total_localtax2, f.fk_facture_fourn '; $sql.= ', f.total_ht, f.tva as total_tva, f.total_ttc, f.fk_product, f.product_type, f.info_bits, f.rang, f.special_code, f.fk_parent_line, f.fk_unit'; $sql.= ', p.rowid as product_id, p.ref as product_ref, p.label as label, p.description as product_desc'; $sql.= ', f.fk_multicurrency, f.multicurrency_code, f.multicurrency_subprice, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc'; @@ -681,6 +681,8 @@ class FactureFournisseur extends CommonInvoice $line->tva_tx = $obj->tva_tx; $line->localtax1_tx = $obj->localtax1_tx; $line->localtax2_tx = $obj->localtax2_tx; + $line->localtax1_type = $obj->localtax1_type; + $line->localtax2_type = $obj->localtax2_type; $line->qty = $obj->qty; $line->remise_percent = $obj->remise_percent; $line->tva = $obj->total_tva; diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 48a2e72661b..43ce10ba2f6 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -544,19 +544,7 @@ if (empty($reshook)) */ if ($action == 'updateline' && $user->rights->fournisseur->commande->creer && ! GETPOST('cancel')) { - $tva_tx = GETPOST('tva_tx'); - - if (GETPOST('price_ht') != '') - { - $price_base_type = 'HT'; - $ht = price2num(GETPOST('price_ht')); - } - else - { - $ttc = price2num(GETPOST('price_ttc')); - $ht = $ttc / (1 + ($tva_tx / 100)); - $price_base_type = 'HT'; - } + $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); if ($lineid) { @@ -568,10 +556,36 @@ if (empty($reshook)) $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $localtax1_tx=get_localtax($tva_tx,1,$mysoc,$object->thirdparty); - $localtax2_tx=get_localtax($tva_tx,2,$mysoc,$object->thirdparty); + // Define info_bits + $info_bits = 0; + if (preg_match('/\*/', $vat_rate)) + $info_bits |= 0x01; - $pu_ht_devise = GETPOST('multicurrency_subprice'); + // Define vat_rate + $vat_rate = str_replace('*', '', $vat_rate); + $localtax1_rate = get_localtax($vat_rate, 1, $mysoc, $object->thirdparty); + $localtax2_rate = get_localtax($vat_rate, 2, $mysoc, $object->thirdparty); + + if (GETPOST('price_ht') != '') + { + $price_base_type = 'HT'; + $ht = price2num(GETPOST('price_ht')); + } + else + { + $vatratecleaned = $vat_rate; + if (preg_match('/^(.*)\s*\((.*)\)$/', $vat_rate, $reg)) // If vat is "xx (yy)" + { + $vatratecleaned = trim($reg[1]); + $vatratecode = $reg[2]; + } + + $ttc = price2num(GETPOST('price_ttc')); + $ht = $ttc / (1 + ($vatratecleaned / 100)); + $price_base_type = 'HT'; + } + + $pu_ht_devise = GETPOST('multicurrency_subprice'); // Extrafields Lines $extrafieldsline = new ExtraFields($db); @@ -590,9 +604,9 @@ if (empty($reshook)) $ht, $_POST['qty'], $_POST['remise_percent'], - $tva_tx, - $localtax1_tx, - $localtax2_tx, + $vat_rate, + $localtax1_rate, + $localtax2_rate, $price_base_type, 0, isset($_POST["type"])?$_POST["type"]:$line->product_type, From af384f14ae5833b1cb914d740dd0ce963f009727 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 23:40:42 +0200 Subject: [PATCH 135/177] FIX #7477 --- htdocs/compta/facture/fiche-rec.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index 58fed19d103..66c964212db 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -360,7 +360,7 @@ if (empty($reshook)) // For triggers $line->id = $lineid; - if ($line->delete() > 0) + if ($line->delete($user) > 0) { $result=$object->update_price(1); From 4b92e2a705f4b25c8dc2e6c89aa8518d619fbafb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Sep 2017 23:55:44 +0200 Subject: [PATCH 136/177] Fix localtax --- htdocs/contrat/class/contrat.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 52bc7efd860..937cce82474 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -728,7 +728,7 @@ class Contrat extends CommonObject } // Selectionne les lignes contrat liees a aucun produit - $sql = "SELECT d.rowid, d.fk_contrat, d.statut, d.qty, d.description, d.price_ht, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.rowid, d.remise_percent, d.subprice,"; + $sql = "SELECT d.rowid, d.fk_contrat, d.statut, d.qty, d.description, d.price_ht, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.rowid, d.remise_percent, d.subprice,"; $sql.= " d.total_ht,"; $sql.= " d.total_tva,"; $sql.= " d.total_localtax1,"; @@ -766,6 +766,8 @@ class Contrat extends CommonObject $line->tva_tx = $objp->tva_tx; $line->localtax1_tx = $objp->localtax1_tx; $line->localtax2_tx = $objp->localtax2_tx; + $line->localtax1_type = $objp->localtax1_type; + $line->localtax2_type = $objp->localtax2_type; $line->subprice = $objp->subprice; $line->remise_percent = $objp->remise_percent; $line->price_ht = $objp->price_ht; @@ -2628,6 +2630,8 @@ class ContratLigne extends CommonObjectLine $sql.= " t.vat_src_code,"; $sql.= " t.localtax1_tx,"; $sql.= " t.localtax2_tx,"; + $sql.= " t.localtax1_type,"; + $sql.= " t.localtax2_type,"; $sql.= " t.qty,"; $sql.= " t.remise_percent,"; $sql.= " t.remise,"; @@ -2681,6 +2685,8 @@ class ContratLigne extends CommonObjectLine $this->vat_src_code = $obj->vat_src_code; $this->localtax1_tx = $obj->localtax1_tx; $this->localtax2_tx = $obj->localtax2_tx; + $this->localtax1_type = $obj->localtax1_type; + $this->localtax2_type = $obj->localtax2_type; $this->qty = $obj->qty; $this->remise_percent = $obj->remise_percent; $this->remise = $obj->remise; From cef7b9c92dd42ab468b51a3ef9b89c3cff452ee3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 25 Sep 2017 00:08:26 +0200 Subject: [PATCH 137/177] FIX #7435 Can't add payment term --- htdocs/admin/dict.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 52e90b21956..ce87f507cc6 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -600,7 +600,8 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($value == 'localtax2' && empty($_POST['localtax2_type'])) continue; if ($value == 'color' && empty($_POST['color'])) continue; if ($value == 'formula' && empty($_POST['formula'])) continue; - if ((! isset($_POST[$value]) || $_POST[$value]=='') + if ($value == 'sortorder') continue; // For a column name 'sortorder', we use the field name 'position' + if ((! isset($_POST[$value]) || $_POST[$value]=='') && (! in_array($listfield[$f], array('decalage','module','accountancy_code','accountancy_code_sell','accountancy_code_buy')) // Fields that are not mandatory && (! ($id == 10 && $listfield[$f] == 'code')) // Code is mandatory fir table 10 ) @@ -715,7 +716,11 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) $_POST[$listfieldvalue[$i]] = $conf->entity; } if ($i) $sql.=","; - if ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' + if ($listfieldvalue[$i] == 'sortorder') // For column name 'sortorder', we use the field name 'position' + { + $sql.="'".(int) $db->escape($_POST['position'])."'"; + } + elseif ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $i++; } @@ -764,7 +769,11 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) } if ($i) $sql.=","; $sql.= $field."="; - if ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' + if ($listfieldvalue[$i] == 'sortorder') // For column name 'sortorder', we use the field name 'position' + { + $sql.="'".(int) $db->escape($_POST['position'])."'"; + } + elseif ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $i++; } @@ -1839,6 +1848,8 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') } else { + if ($fieldlist[$field]=='sortorder') $fieldlist[$field]='position'; + $classtd=''; $class=''; if ($fieldlist[$field]=='code') $classtd='width100'; if ($fieldlist[$field]=='affect') $class='maxwidth50'; From e3da4188e2fabb92b8e3302f081aab275aa86ff0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 25 Sep 2017 00:16:52 +0200 Subject: [PATCH 138/177] GETPOST must not clean data for text input. --- htdocs/comm/action/card.php | 2 +- htdocs/comm/propal/card.php | 10 +++++----- htdocs/comm/remx.php | 2 +- htdocs/commande/card.php | 6 +++--- htdocs/compta/facture/card.php | 2 +- htdocs/compta/facture/class/facture.class.php | 4 ++-- htdocs/compta/facture/fiche-rec.php | 10 +++++----- htdocs/compta/paiement/card.php | 2 +- htdocs/contrat/card.php | 2 +- htdocs/cron/card.php | 4 ++-- htdocs/expedition/card.php | 4 ++-- htdocs/expensereport/card.php | 8 ++++---- htdocs/fichinter/card.php | 10 +++++----- htdocs/fourn/commande/card.php | 8 ++++---- htdocs/fourn/commande/orderstoinvoice.php | 4 ++-- htdocs/fourn/facture/card.php | 12 ++++++------ htdocs/fourn/paiement/card.php | 2 +- htdocs/loan/card.php | 4 ++-- htdocs/loan/payment/payment.php | 4 ++-- htdocs/product/card.php | 12 ++++++------ htdocs/public/members/new.php | 2 +- htdocs/supplier_proposal/card.php | 8 ++++---- htdocs/user/note.php | 2 +- 23 files changed, 62 insertions(+), 62 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index b491c9007cb..02a16af3c17 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -824,7 +824,7 @@ if ($action == 'create') // Description print ''.$langs->trans("Description").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('note',(GETPOST('note')?GETPOST('note'):$object->note),'',180,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_5,'90%'); + $doleditor=new DolEditor('note',(GETPOST('note','none')?GETPOST('note','none'):$object->note),'',180,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_5,'90%'); $doleditor->Create(); print ''; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 8fb2a102c22..4fc1eebb66d 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -358,8 +358,8 @@ if (empty($reshook)) $object->fk_project = GETPOST('projectid'); $object->modelpdf = GETPOST('model'); $object->author = $user->id; // deprecated - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->statut = Propal::STATUS_DRAFT; $object->fk_incoterms = GETPOST('incoterm_id', 'int'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); @@ -386,8 +386,8 @@ if (empty($reshook)) $object->fk_project = GETPOST('projectid'); $object->modelpdf = GETPOST('model'); $object->author = $user->id; // deprecated - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->fk_incoterms = GETPOST('incoterm_id', 'int'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); @@ -979,7 +979,7 @@ if (empty($reshook)) $info_bits |= 0x01; // Clean parameters - $description = dol_htmlcleanlastbr(GETPOST('product_desc')); + $description = dol_htmlcleanlastbr(GETPOST('product_desc','none')); // Define vat_rate $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 332181922d2..7a34d1a3a76 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -292,7 +292,7 @@ if ($socid > 0) print $form->load_tva('tva_tx',GETPOST('tva_tx'),$mysoc,$object); print ''; print ''.$langs->trans("NoteReason").''; - print ''; + print ''; print ""; } diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index eb510b53333..53082499a9a 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -256,8 +256,8 @@ if (empty($reshook)) $db->begin(); $object->date_commande = $datecommande; - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->source = GETPOST('source_id'); $object->fk_project = GETPOST('projectid'); $object->ref_client = GETPOST('ref_client'); @@ -927,7 +927,7 @@ if (empty($reshook)) $date_end=''; $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description=dol_htmlcleanlastbr(GETPOST('product_desc')); + $description=dol_htmlcleanlastbr(GETPOST('product_desc','none')); $pu_ht=GETPOST('price_ht'); $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); $pu_ht_devise = GETPOST('multicurrency_subprice'); diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 949e36f8ec3..2535d8e7442 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1816,7 +1816,7 @@ if (empty($reshook)) $date_end = ''; $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description = dol_htmlcleanlastbr(GETPOST('product_desc') ? GETPOST('product_desc') : GETPOST('desc')); + $description = dol_htmlcleanlastbr(GETPOST('product_desc','none') ? GETPOST('product_desc','none') : GETPOST('desc','none')); $pu_ht = GETPOST('price_ht'); $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); $qty = GETPOST('qty'); diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 41cc8042144..b6d294c6e18 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -293,8 +293,8 @@ class Facture extends CommonInvoice // Fields coming from GUI (priority on template). TODO Value of template should be used as default value on GUI so we can use here always value from GUI $this->fk_project = GETPOST('projectid','int') > 0 ? GETPOST('projectid','int') : $_facrec->fk_project; - $this->note_public = GETPOST('note_public') ? GETPOST('note_public') : $_facrec->note_public; - $this->note_private = GETPOST('note_private') ? GETPOST('note_private') : $_facrec->note_private; + $this->note_public = GETPOST('note_public','none') ? GETPOST('note_public','none') : $_facrec->note_public; + $this->note_private = GETPOST('note_private','none') ? GETPOST('note_private','none') : $_facrec->note_private; $this->modelpdf = GETPOST('model') ? GETPOST('model') : $_facrec->modelpdf; $this->cond_reglement_id = GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $_facrec->cond_reglement_id; $this->mode_reglement_id = GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $_facrec->mode_reglement_id; diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index 66c964212db..80912bffbad 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -209,8 +209,8 @@ if (empty($reshook)) if (! $error) { $object->titre = GETPOST('titre', 'alpha'); - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->usenewprice = GETPOST('usenewprice'); $object->frequency = $frequency; @@ -723,7 +723,7 @@ if (empty($reshook)) $date_end = ''; //$date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); //$date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description = dol_htmlcleanlastbr(GETPOST('product_desc') ? GETPOST('product_desc') : GETPOST('desc')); + $description = dol_htmlcleanlastbr(GETPOST('product_desc','none') ? GETPOST('product_desc','none') : GETPOST('desc','none')); $pu_ht = GETPOST('price_ht'); $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); $qty = GETPOST('qty'); @@ -965,8 +965,8 @@ if ($action == 'create') print ''.$langs->trans("Customer").''.$object->thirdparty->getNomUrl(1,'customer').''; print ''; - $note_public=GETPOST('note_public')?GETPOST('note_public'):$object->note_public; - $note_private=GETPOST('note_private')?GETPOST('note_private'):$object->note_private; + $note_public=GETPOST('note_public','none')?GETPOST('note_public','none'):$object->note_public; + $note_private=GETPOST('note_private','none')?GETPOST('note_private','none'):$object->note_private; // Help of substitution key $substitutionarray=array( diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php index 523d5256816..da38e9fb47a 100644 --- a/htdocs/compta/paiement/card.php +++ b/htdocs/compta/paiement/card.php @@ -60,7 +60,7 @@ if ($action == 'setnote' && $user->rights->facture->paiement) $db->begin(); $object->fetch($id); - $result = $object->update_note(GETPOST('note')); + $result = $object->update_note(GETPOST('note','none')); if ($result > 0) { $db->commit(); diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 6d2181886a0..46fa2b3ca87 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -676,7 +676,7 @@ if (empty($reshook)) $fk_unit = GETPOST('unit', 'alpha'); - $objectline->description=GETPOST('product_desc'); + $objectline->description=GETPOST('product_desc','none'); $objectline->price_ht=GETPOST('elprice'); $objectline->subprice=GETPOST('elprice'); $objectline->qty=GETPOST('elqty'); diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php index a1255954014..8e540c799fe 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -148,7 +148,7 @@ if ($action=='add') $object->params=GETPOST('params'); $object->md5params=GETPOST('md5params'); $object->module_name=GETPOST('module_name','alpha'); - $object->note=GETPOST('note'); + $object->note=GETPOST('note','none'); $object->datestart=dol_mktime(GETPOST('datestarthour','int'), GETPOST('datestartmin','int'), 0, GETPOST('datestartmonth','int'), GETPOST('datestartday','int'), GETPOST('datestartyear','int')); $object->dateend=dol_mktime(GETPOST('dateendhour','int'), GETPOST('dateendmin','int'), 0, GETPOST('dateendmonth','int'), GETPOST('dateendday','int'), GETPOST('dateendyear','int')); $object->datenextrun=dol_mktime(GETPOST('datenextrunhour','int'), GETPOST('datenextrunmin','int'), 0, GETPOST('datenextrunmonth','int'), GETPOST('datenextrunday','int'), GETPOST('datenextrunyear','int')); @@ -184,7 +184,7 @@ if ($action=='update') $object->params=GETPOST('params'); $object->md5params=GETPOST('md5params'); $object->module_name=GETPOST('module_name','alpha'); - $object->note=GETPOST('note'); + $object->note=GETPOST('note','none'); $object->datestart=dol_mktime(GETPOST('datestarthour','int'), GETPOST('datestartmin','int'), 0, GETPOST('datestartmonth','int'), GETPOST('datestartday','int'), GETPOST('datestartyear','int')); $object->dateend=dol_mktime(GETPOST('dateendhour','int'), GETPOST('dateendmin','int'), 0, GETPOST('dateendmonth','int'), GETPOST('dateendday','int'), GETPOST('dateendyear','int')); $object->datenextrun=dol_mktime(GETPOST('datenextrunhour','int'), GETPOST('datenextrunmin','int'), 0, GETPOST('datenextrunmonth','int'), GETPOST('datenextrunday','int'), GETPOST('datenextrunyear','int')); diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index e8748d3a9af..17777e6e228 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -219,8 +219,8 @@ if (empty($reshook)) $object->shipping_method_id = GETPOST('shipping_method_id','int'); $object->tracking_number = GETPOST('tracking_number','alpha'); $object->ref_int = GETPOST('ref_int','alpha'); - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->fk_incoterms = GETPOST('incoterm_id', 'int'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 561f1ecd082..1460d97323c 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -213,8 +213,8 @@ if (empty($reshook)) $object->fk_statut = 1; $object->fk_c_paiement = GETPOST('fk_c_paiement','int'); $object->fk_user_validator = GETPOST('fk_user_validator','int'); - $object->note_public = GETPOST('note_public'); - $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public','none'); + $object->note_private = GETPOST('note_private','none'); // Fill array 'array_options' with data from add form if (! $error) { @@ -264,8 +264,8 @@ if (empty($reshook)) } $object->fk_c_paiement = GETPOST('fk_c_paiement','int'); - $object->note_public = GETPOST('note_public'); - $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public','none'); + $object->note_private = GETPOST('note_private','none'); $object->fk_user_modif = $user->id; $result = $object->update($user); diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 32fcf3c9973..680ab2b6a7e 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -64,7 +64,7 @@ $confirm = GETPOST('confirm','alpha'); $mesg = GETPOST('msg','alpha'); $origin=GETPOST('origin','alpha'); $originid=(GETPOST('originid','int')?GETPOST('originid','int'):GETPOST('origin_id','int')); // For backward compatibility -$note_public = GETPOST('note_public'); +$note_public = GETPOST('note_public','none'); $lineid = GETPOST('line_id','int'); //PDF @@ -208,8 +208,8 @@ if (empty($reshook)) $object->description = GETPOST('description'); $object->ref = $ref; $object->modelpdf = GETPOST('model','alpha'); - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); if ($object->socid > 0) { @@ -877,8 +877,8 @@ if ($action == 'create') $soc = $objectsrc->client; - $note_private = (! empty($objectsrc->note) ? $objectsrc->note : (! empty($objectsrc->note_private) ? $objectsrc->note_private : GETPOST('note_private'))); - $note_public = (! empty($objectsrc->note_public) ? $objectsrc->note_public : GETPOST('note_public')); + $note_private = (! empty($objectsrc->note) ? $objectsrc->note : (! empty($objectsrc->note_private) ? $objectsrc->note_private : GETPOST('note_private','none'))); + $note_public = (! empty($objectsrc->note_public) ? $objectsrc->note_public : GETPOST('note_public','none')); // Object source contacts list $srccontactslist = $objectsrc->liste_contact(-1,'external',1); diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index ffe55f1315e..210e93adf14 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -988,8 +988,8 @@ if (empty($reshook)) $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $object->fk_account = GETPOST('fk_account', 'int'); - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->date_livraison = $datelivraison; $object->fk_incoterms = GETPOST('incoterm_id', 'int'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); @@ -1534,7 +1534,7 @@ if ($action=='create') print ''.$langs->trans('NotePublic').''; print ''; - $doleditor = new DolEditor('note_public', isset($note_public) ? $note_public : GETPOST('note_public'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); + $doleditor = new DolEditor('note_public', isset($note_public) ? $note_public : GETPOST('note_public','none'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); print ''; //print ''; @@ -1542,7 +1542,7 @@ if ($action=='create') print ''.$langs->trans('NotePrivate').''; print ''; - $doleditor = new DolEditor('note_private', isset($note_private) ? $note_private : GETPOST('note_private'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); + $doleditor = new DolEditor('note_private', isset($note_private) ? $note_private : GETPOST('note_private','none'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); print ''; //print ''; diff --git a/htdocs/fourn/commande/orderstoinvoice.php b/htdocs/fourn/commande/orderstoinvoice.php index b1a8c0c08c1..012574915ab 100644 --- a/htdocs/fourn/commande/orderstoinvoice.php +++ b/htdocs/fourn/commande/orderstoinvoice.php @@ -155,8 +155,8 @@ if (($action == 'create' || $action == 'add') && ! $error) { $object->libelle = GETPOST('libelle'); $object->date = $datefacture; $object->date_echeance = $datedue; - $object->note_public = GETPOST('note_public'); - $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public','none'); + $object->note_private = GETPOST('note_private','none'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $projectid = GETPOST('projectid'); diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index d632081fd9e..9f747b07197 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -443,8 +443,8 @@ if (empty($reshook)) $object->libelle = GETPOST('label'); $object->date = $datefacture; $object->date_echeance = $datedue; - $object->note_public = GETPOST('note_public'); - $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public','none'); + $object->note_private = GETPOST('note_private','none'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $object->fk_account = GETPOST('fk_account', 'int'); @@ -507,8 +507,8 @@ if (empty($reshook)) $object->libelle = $_POST['label']; $object->date = $datefacture; $object->date_echeance = $datedue; - $object->note_public = GETPOST('note_public'); - $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public','none'); + $object->note_private = GETPOST('note_private','none'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $object->fk_account = GETPOST('fk_account', 'int'); @@ -616,8 +616,8 @@ if (empty($reshook)) $object->libelle = $_POST['label']; $object->date = $datefacture; $object->date_echeance = $datedue; - $object->note_public = GETPOST('note_public'); - $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public','none'); + $object->note_private = GETPOST('note_private','none'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $object->fk_account = GETPOST('fk_account', 'int'); diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index f42cc1db110..a1104eeaceb 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -57,7 +57,7 @@ if ($action == 'setnote' && $user->rights->fournisseur->facture->creer) $db->begin(); $object->fetch($id); - $result = $object->update_note(GETPOST('note')); + $result = $object->update_note(GETPOST('note','none')); if ($result > 0) { $db->commit(); diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 4f61aa833bf..1f76d705305 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -133,8 +133,8 @@ if (empty($reshook)) $object->dateend = $dateend; $object->nbterm = GETPOST('nbterm'); $object->rate = $rate; - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->fk_project = GETPOST('projectid','int'); $accountancy_account_capital = GETPOST('accountancy_account_capital'); diff --git a/htdocs/loan/payment/payment.php b/htdocs/loan/payment/payment.php index dc927035954..bea15f288a0 100644 --- a/htdocs/loan/payment/payment.php +++ b/htdocs/loan/payment/payment.php @@ -101,8 +101,8 @@ if ($action == 'add_payment') $payment->amount_interest = GETPOST('amount_interest'); $payment->paymenttype = GETPOST('paymenttype'); $payment->num_payment = GETPOST('num_payment'); - $payment->note_private = GETPOST('note_private'); - $payment->note_public = GETPOST('note_public'); + $payment->note_private = GETPOST('note_private','none'); + $payment->note_public = GETPOST('note_public','none'); if (! $error) { diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 143b375f5b3..f5e6c906e7d 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -281,9 +281,9 @@ if (empty($reshook)) $object->barcode_type_coder = $stdobject->barcode_type_coder; $object->barcode_type_label = $stdobject->barcode_type_label; - $object->description = dol_htmlcleanlastbr(GETPOST('desc')); + $object->description = dol_htmlcleanlastbr(GETPOST('desc','none')); $object->url = GETPOST('url'); - $object->note_private = dol_htmlcleanlastbr(GETPOST('note_private')); + $object->note_private = dol_htmlcleanlastbr(GETPOST('note_private','none')); $object->note = $object->note_private; // deprecated $object->customcode = GETPOST('customcode'); $object->country_id = GETPOST('country_id'); @@ -370,11 +370,11 @@ if (empty($reshook)) $object->ref = $ref; $object->label = GETPOST('label'); - $object->description = dol_htmlcleanlastbr(GETPOST('desc')); + $object->description = dol_htmlcleanlastbr(GETPOST('desc','none')); $object->url = GETPOST('url'); if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) { - $object->note_private = dol_htmlcleanlastbr(GETPOST('note_private')); + $object->note_private = dol_htmlcleanlastbr(GETPOST('note_private','none')); $object->note = $object->note_private; } $object->customcode = GETPOST('customcode'); @@ -977,7 +977,7 @@ else // Description (used in invoice, propal...) print ''.$langs->trans("Description").''; - $doleditor = new DolEditor('desc', GETPOST('desc'), '', 160, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_PRODUCTDESC, ROWS_4, '90%'); + $doleditor = new DolEditor('desc', GETPOST('desc','none'), '', 160, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_PRODUCTDESC, ROWS_4, '90%'); $doleditor->Create(); print ""; @@ -1092,7 +1092,7 @@ else print ''.$langs->trans("NoteNotVisibleOnBill").''; // We use dolibarr_details as type of DolEditor here, because we must not accept images as description is included into PDF and not accepted by TCPDF. - $doleditor = new DolEditor('note_private', GETPOST('note_private'), '', 140, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_PRODUCTDESC, ROWS_8, '90%'); + $doleditor = new DolEditor('note_private', GETPOST('note_private','none'), '', 140, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_PRODUCTDESC, ROWS_8, '90%'); $doleditor->Create(); print ""; diff --git a/htdocs/public/members/new.php b/htdocs/public/members/new.php index 2869d2254e7..6a5fcbdfc62 100644 --- a/htdocs/public/members/new.php +++ b/htdocs/public/members/new.php @@ -572,7 +572,7 @@ foreach($extrafields->attribute_label as $key=>$value) // Comments print ''; print ''.$langs->trans("Comments").''; -print ''; +print ''; print ''."\n"; // Add specific fields used by Dolibarr foundation for example diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 1b3857fdbf1..a997b5f4b96 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -268,7 +268,7 @@ if (empty($reshook)) $object->fk_project = GETPOST('projectid'); $object->modelpdf = GETPOST('model'); $object->author = $user->id; // deprecated - $object->note = GETPOST('note'); + $object->note = GETPOST('note','none'); $object->statut = SupplierProposal::STATUS_DRAFT; $id = $object->create_from($user); @@ -286,7 +286,7 @@ if (empty($reshook)) $object->fk_project = GETPOST('projectid'); $object->modelpdf = GETPOST('model'); $object->author = $user->id; // deprecated - $object->note = GETPOST('note'); + $object->note = GETPOST('note','none'); $object->origin = GETPOST('origin'); $object->origin_id = GETPOST('originid'); @@ -465,7 +465,7 @@ if (empty($reshook)) } else { // prevent browser refresh from closing proposal several times if ($object->statut == SupplierProposal::STATUS_VALIDATED) { - $object->cloture($user, GETPOST('statut'), GETPOST('note')); + $object->cloture($user, GETPOST('statut'), GETPOST('note','none')); } } } @@ -774,7 +774,7 @@ if (empty($reshook)) $info_bits |= 0x01; // Clean parameters - $description = dol_htmlcleanlastbr(GETPOST('product_desc')); + $description = dol_htmlcleanlastbr(GETPOST('product_desc','none')); // Define vat_rate $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); diff --git a/htdocs/user/note.php b/htdocs/user/note.php index 1734e7286d4..78fe25adfe9 100644 --- a/htdocs/user/note.php +++ b/htdocs/user/note.php @@ -65,7 +65,7 @@ if (empty($reshook)) { if ($action == 'update' && $user->rights->user->user->creer && !$_POST["cancel"]) { $db->begin(); - $res = $object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $res = $object->update_note(dol_html_entity_decode(GETPOST('note_private','none'), ENT_QUOTES)); if ($res < 0) { $mesg = '
'.$adh->error.'
'; $db->rollback(); From 6ee15f1c45dcf13a36c1ff39688207c23f12cb70 Mon Sep 17 00:00:00 2001 From: dolibarr95 Date: Mon, 25 Sep 2017 09:01:47 +0200 Subject: [PATCH 139/177] Fix 7470 php warning when MAIN_MODULE_xxxxx_DIR exists but the module does not have a directory. --- htdocs/core/class/conf.class.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index ad224fec97d..1b8709f1330 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -287,15 +287,18 @@ class Conf { foreach($this->modules_parts['dir'] as $module => $dirs) { - foreach($dirs as $type => $name) + if (! empty($this->$module->enabled)) { - $subdir=($type=='temp'?'/temp':''); - // For multicompany sharings - $varname = 'multidir_'.$type; - $this->$module->$varname = array($this->entity => $rootfordata."/".$name.$subdir); - // For backward compatibility - $varname = 'dir_'.$type; - $this->$module->$varname = $rootfordata."/".$name.$subdir; + foreach($dirs as $type => $name) + { + $subdir=($type=='temp'?'/temp':''); + // For multicompany sharings + $varname = 'multidir_'.$type; + $this->$module->$varname = array($this->entity => $rootfordata."/".$name.$subdir); + // For backward compatibility + $varname = 'dir_'.$type; + $this->$module->$varname = $rootfordata."/".$name.$subdir; + } } } } From d3d6fca350ed1ac4e3c07fc1d1a754748c346468 Mon Sep 17 00:00:00 2001 From: Inovea Conseil Date: Mon, 25 Sep 2017 10:49:56 +0200 Subject: [PATCH 140/177] Missing space in request Fix bug in request --- htdocs/core/boxes/box_services_contracts.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php index 1795f7c6f2f..0cc4e68682b 100644 --- a/htdocs/core/boxes/box_services_contracts.php +++ b/htdocs/core/boxes/box_services_contracts.php @@ -2,6 +2,7 @@ /* Copyright (C) 2003 Rodolphe Quiedeville * Copyright (C) 2005-2017 Laurent Destailleur * Copyright (C) 2005-2011 Regis Houssin + * Copyright (C) 2017 Nicolas Zabouri * * 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 @@ -91,7 +92,7 @@ class box_services_contracts extends ModeleBoxes $sql.= " INNER JOIN ".MAIN_DB_PREFIX."contrat as c ON s.rowid = c.fk_soc"; $sql.= " INNER JOIN ".MAIN_DB_PREFIX."contratdet as cd ON c.rowid = cd.fk_contrat"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid"; - if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= "INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; $sql.= ")"; $sql.= " WHERE c.entity = ".$conf->entity; if($user->societe_id) $sql.= " AND s.rowid = ".$user->societe_id; From a9fabf117ee3be11b9ed84814330403dc069db4c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 25 Sep 2017 11:42:59 +0200 Subject: [PATCH 141/177] Code comment --- htdocs/core/class/html.form.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 9ebcb295792..009f1f0dcd3 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1256,6 +1256,7 @@ class Form * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param bool $options_only Return options only (for ajax treatment) * @return int <0 if KO, Nb of contact in list if OK + * @deprected You can use selectcontacts directly (warning order of param was changed) */ function select_contacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $showsoc=0, $forcecombo=0, $events=array(), $options_only=false) { @@ -1264,7 +1265,8 @@ class Form } /** - * Return list of all contacts (for a third party or all) + * Return HTML code of the SELECT of list of all contacts (for a third party or all). + * This also set the number of contacts found into $this->num * * @param int $socid Id ot third party or 0 for all * @param string $selected Id contact pre-selectionne From 0ffffa3019b51e92fc1c6b20a6b98a055a900c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Peccatte?= Date: Mon, 25 Sep 2017 12:05:12 +0200 Subject: [PATCH 142/177] Add a parameter to specify variant identifier separator --- htdocs/variants/admin/admin.php | 13 +++++++++++++ htdocs/variants/class/ProductCombination.class.php | 10 +++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/htdocs/variants/admin/admin.php b/htdocs/variants/admin/admin.php index eedacb086b3..f3752469538 100644 --- a/htdocs/variants/admin/admin.php +++ b/htdocs/variants/admin/admin.php @@ -37,6 +37,12 @@ if ($_POST) { setEventMessage($langs->trans('CoreErrorMessage'), 'errors'); } + if (dolibarr_set_const($db, 'PRODUIT_ATTRIBUTES_SEPARATOR', GETPOST('PRODUIT_ATTRIBUTES_SEPARATOR'), 'chaine', 0, '', $conf->entity)) { + setEventMessage($langs->trans('RecordSaved')); + } else { + setEventMessage($langs->trans('CoreErrorMessage'), 'errors'); + } + } $title = $langs->trans('ModuleSetup').' '.$langs->trans('ProductAttributes'); @@ -55,6 +61,13 @@ print ''.$langs->trans("Value").''."\n"; print ' '."\n"; print ''.$langs->trans('HideProductCombinations').''; print $form->selectyesno("PRODUIT_ATTRIBUTES_HIDECHILD",$conf->global->PRODUIT_ATTRIBUTES_HIDECHILD,1).''; +print ''.$langs->trans('CombinationsSeparator').''; +if(isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) { + $separator = $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR; +} else { + $separator = "_"; +} +print ''; print ''; print '
'; print ''; diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index d3e6964aea6..04b987192e1 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -476,7 +476,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; */ public function createProductCombination(Product $product, array $combinations, array $variations, $price_var_percent = false, $forced_pricevar = false, $forced_weightvar = false) { - global $db, $user; + global $db, $user, $conf; require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttribute.class.php'; require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttributeValue.class.php'; @@ -542,7 +542,11 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $price_impact += (float) price2num($variations[$currcombattr][$currcombval]['price']); } - $newproduct->ref .= '_'.$prodattrval->ref; + if (isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) { + $newproduct->ref .= $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR . $prodattrval->ref; + } else { + $newproduct->ref .= '_'.$prodattrval->ref; + } //The first one should not contain a linebreak if ($newproduct->description) { @@ -660,4 +664,4 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; return 1; } -} \ No newline at end of file +} From 35ae0e435d8ace1670af9981a6074c4568dc6e3b Mon Sep 17 00:00:00 2001 From: Inovea Conseil Date: Mon, 25 Sep 2017 16:14:14 +0200 Subject: [PATCH 143/177] Fix quote in input Delete a quote in input field --- htdocs/core/class/extrafields.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 6a7659cd925..b539a02654f 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -8,6 +8,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2015 Charles-Fr BENKE * Copyright (C) 2016 RaphaĂ«l Doursenaud + * Copyright (C) 2017 Nicolas ZABOURI * * 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 @@ -832,7 +833,7 @@ class ExtraFields { $tmp=explode(',',$size); $newsize=$tmp[0]; - $out=''; + $out=''; } elseif ($type == 'varchar') { From 16941f1d9d65f6c67aea354035c4e292b84519c0 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 25 Sep 2017 16:46:13 +0200 Subject: [PATCH 144/177] Fix: uniformize code --- htdocs/product/inventory/card.php | 40 ++++------------------------- htdocs/product/inventory/list.php | 42 +++++-------------------------- 2 files changed, 11 insertions(+), 71 deletions(-) diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index c5eca27b348..7ef847855e5 100644 --- a/htdocs/product/inventory/card.php +++ b/htdocs/product/inventory/card.php @@ -1,6 +1,5 @@ - * Copyright (C) ---Put here your own copyright and developer email--- * * 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 @@ -17,43 +16,14 @@ */ /** - * \file product/inventory/card.php + * \file htdocs/product/inventory/card.php * \ingroup inventory - * \brief This file is an example of a php page - * Put here some comments + * \brief Inventory card */ -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); -//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library -//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) - -// Load Dolibarr environment -$res=0; -// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"); -// Try main.inc.php into web root detected using web root caluclated from SCRIPT_FILENAME -$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1; -while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; } -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php"); -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php"); -// Try main.inc.php using relative path -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php"); -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php"); -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php"); -if (! $res) die("Include of main fails"); - -include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); -dol_include_once('/inventory/class/inventory.class.php'); +require '../../main.inc.php'; +include_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +include_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; // Load traductions files requiredby by page $langs->loadLangs(array("inventory","other")); diff --git a/htdocs/product/inventory/list.php b/htdocs/product/inventory/list.php index 6f443324f6b..a8ce9c404e6 100644 --- a/htdocs/product/inventory/list.php +++ b/htdocs/product/inventory/list.php @@ -1,6 +1,5 @@ - * Copyright (C) ---Put here your own copyright and developer email--- * * 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 @@ -17,45 +16,16 @@ */ /** - * \file product/inventory/list.php + * \file htdocs/product/inventory/list.php * \ingroup inventory - * \brief List page for monmodule + * \brief List page for inventory */ -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); -//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library -//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) - - -// Load Dolibarr environment -$res=0; -// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"); -// Try main.inc.php into web root detected using web root caluclated from SCRIPT_FILENAME -$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1; -while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; } -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php"); -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php"); -// Try main.inc.php using relative path -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php"); -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php"); -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php"); -if (! $res) die("Include of main fails"); - -require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; -dol_include_once('/inventory/class/inventory.class.php'); +require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; // Load traductions files requiredby by page $langs->loadLangs(array("inventory","other")); @@ -177,7 +147,7 @@ if (empty($reshook)) $permtoread = $user->rights->inventory->read; $permtodelete = $user->rights->inventory->delete; $uploaddir = $conf->inventory->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + //include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; // TODO to fix for product module } From dc362fcd30d6484e098ad50df8005f7de79c07cc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 25 Sep 2017 18:11:03 +0200 Subject: [PATCH 145/177] NEW Can show currency in list of bank accounts --- htdocs/compta/bank/bankentries.php | 10 ++--- htdocs/compta/bank/index.php | 63 +++++++++++++++++---------- htdocs/compta/bank/transfer.php | 11 +++-- htdocs/core/class/html.form.class.php | 18 ++++---- htdocs/langs/en_US/multicurrency.lang | 1 + 5 files changed, 61 insertions(+), 42 deletions(-) diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index 40d2f5c8ffc..8cb5b878dc0 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -104,9 +104,9 @@ if (! $sortfield) $sortfield='b.datev, b.dateo, b.rowid'; $mode_balance_ok=false; //if (($sortfield == 'b.datev' || $sortfield == 'b.datev, b.dateo, b.rowid')) // TODO Manage balance when account not selected -if (($sortfield == 'b.datev' || $sortfield == 'b.datev, b.dateo, b.rowid')) +if (($sortfield == 'b.datev' || $sortfield == 'b.datev,b.dateo,b.rowid')) { - $sortfield = 'b.datev, b.dateo, b.rowid'; + $sortfield = 'b.datev,b.dateo,b.rowid'; if ($id > 0 || ! empty($ref) || $account > 0) $mode_balance_ok = true; } if (strtolower($sortorder) == 'desc') $mode_balance_ok = false; @@ -887,7 +887,7 @@ if ($resql) if (! empty($arrayfields['b.rowid']['checked'])) print_liste_field_titre($arrayfields['b.rowid']['label'],$_SERVER['PHP_SELF'],'b.rowid','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['description']['checked'])) print_liste_field_titre($arrayfields['description']['label'],$_SERVER['PHP_SELF'],'','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['b.dateo']['checked'])) print_liste_field_titre($arrayfields['b.dateo']['label'],$_SERVER['PHP_SELF'],'b.dateo','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['b.datev']['checked'])) print_liste_field_titre($arrayfields['b.datev']['label'],$_SERVER['PHP_SELF'],'b.datev, b.dateo, b.rowid','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['b.datev']['checked'])) print_liste_field_titre($arrayfields['b.datev']['label'],$_SERVER['PHP_SELF'],'b.datev,b.dateo,b.rowid','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['type']['checked'])) print_liste_field_titre($arrayfields['type']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['b.num_chq']['checked'])) print_liste_field_titre($arrayfields['b.num_chq']['label'],$_SERVER['PHP_SELF'],'b.num_chq','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['bu.label']['checked'])) print_liste_field_titre($arrayfields['bu.label']['label'],$_SERVER['PHP_SELF'],'bu.label','',$param,'',$sortfield,$sortorder); @@ -1065,7 +1065,7 @@ if ($resql) $bankstatic->id=$banklinestatic->fk_account; $bankstatic->label=$banklinestatic->bank_account_ref; print ' ('.$langs->trans("TransferFrom").' '; - print $bankstatic->getNomUrl(1,'transactions'); + print $bankstatic->getNomUrl(1); print ' '.$langs->trans("toward").' '; $bankstatic->id=$objp->bankid; $bankstatic->label=$objp->bankref; @@ -1082,7 +1082,7 @@ if ($resql) $banklinestatic->fetch($links[$key]['url_id']); $bankstatic->id=$banklinestatic->fk_account; $bankstatic->label=$banklinestatic->bank_account_ref; - print $bankstatic->getNomUrl(1,'transactions'); + print $bankstatic->getNomUrl(1); print ')'; } //var_dump($links); diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 5a0ab062b29..4485680a4e9 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -92,7 +92,8 @@ $arrayfields=array( 'b.account_number'=>array('label'=>$langs->trans("AccountAccounting"), 'checked'=>$conf->accountancy->enabled), 'b.fk_accountancy_journal'=>array('label'=>$langs->trans("AccountancyJournal"), 'checked'=>$conf->accountancy->enabled), 'toreconcile'=>array('label'=>$langs->trans("TransactionsToConciliate"), 'checked'=>1), - 'b.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), + 'b.currency_code'=>array('label'=>$langs->trans("Currency"), 'checked'=>0), + 'b.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), 'b.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), 'b.clos'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), 'balance'=>array('label'=>$langs->trans("Balance"), 'checked'=>1, 'position'=>1010), @@ -121,7 +122,7 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; // Purge search criteria -if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All test are required to be compatible with all browsers +if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { $search_ref=''; $search_label=''; @@ -142,7 +143,7 @@ $title=$langs->trans('BankAccounts'); // Load array of financial accounts (opened by default) $accounts = array(); -$sql = "SELECT rowid, label, courant, rappro, account_number, fk_accountancy_journal, datec as date_creation, tms as date_update"; +$sql = "SELECT rowid, label, courant, rappro, account_number, fk_accountancy_journal, currency_code, datec as date_creation, tms as date_update"; // Add fields from extrafields foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : ''); // Add fields from hooks @@ -337,6 +338,12 @@ if (! empty($arrayfields['toreconcile']['checked'])) print ''; print ''; } +// Currency +if (! empty($arrayfields['b.currency_code']['checked'])) +{ + print ''; + print ''; +} // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { @@ -407,6 +414,7 @@ if (! empty($arrayfields['accountype']['checked'])) print_liste_field_titr if (! empty($arrayfields['b.number']['checked'])) print_liste_field_titre($arrayfields['b.number']['label'],$_SERVER["PHP_SELF"],'b.number','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['b.account_number']['checked'])) print_liste_field_titre($arrayfields['b.account_number']['label'],$_SERVER["PHP_SELF"],'b.account_number','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['b.fk_accountancy_journal']['checked'])) print_liste_field_titre($arrayfields['b.fk_accountancy_journal']['label'],$_SERVER["PHP_SELF"],'b.fk_accountancy_journal','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['b.currency_code']['checked'])) print_liste_field_titre($arrayfields['b.currency_code']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['toreconcile']['checked'])) print_liste_field_titre($arrayfields['toreconcile']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) @@ -442,19 +450,19 @@ foreach ($accounts as $key=>$type) $found++; - $acc = new Account($db); - $acc->fetch($key); + $obj = new Account($db); + $obj->fetch($key); $var = !$var; - $solde = $acc->solde(1); + $solde = $obj->solde(1); - if (! empty($lastcurrencycode) && $lastcurrencycode != $acc->currency_code) + if (! empty($lastcurrencycode) && $lastcurrencycode != $obj->currency_code) { $lastcurrencycode='various'; // We found several different currencies } if ($lastcurrencycode != 'various') { - $lastcurrencycode=$acc->currency_code; + $lastcurrencycode=$obj->currency_code; } print ''; @@ -462,14 +470,14 @@ foreach ($accounts as $key=>$type) // Ref if (! empty($arrayfields['b.ref']['checked'])) { - print ''.$acc->getNomUrl(1).''; + print ''.$obj->getNomUrl(1).''; if (! $i) $totalarray['nbfield']++; } // Label if (! empty($arrayfields['b.label']['checked'])) { - print ''.$acc->label.''; + print ''.$obj->label.''; if (! $i) $totalarray['nbfield']++; } @@ -477,7 +485,7 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['accountype']['checked'])) { print ''; - print $acc->type_lib[$acc->type]; + print $obj->type_lib[$obj->type]; print ''; if (! $i) $totalarray['nbfield']++; } @@ -485,7 +493,7 @@ foreach ($accounts as $key=>$type) // Number if (! empty($arrayfields['b.number']['checked'])) { - print ''.$acc->number.''; + print ''.$obj->number.''; if (! $i) $totalarray['nbfield']++; } @@ -496,12 +504,12 @@ foreach ($accounts as $key=>$type) if (! empty($conf->accounting->enabled)) { $accountingaccount = new AccountingAccount($db); - $accountingaccount->fetch('',$acc->account_number); + $accountingaccount->fetch('',$obj->account_number); print $accountingaccount->getNomUrl(0,1,1,'',1); } else { - print $acc->account_number; + print $obj->account_number; } print ''; if (! $i) $totalarray['nbfield']++; @@ -514,7 +522,7 @@ foreach ($accounts as $key=>$type) if (! empty($conf->accounting->enabled)) { $accountingjournal = new AccountingJournal($db); - $accountingjournal->fetch($acc->fk_accountancy_journal); + $accountingjournal->fetch($obj->fk_accountancy_journal); print $accountingjournal->getNomUrl(0,1,1,'',1); } else @@ -525,15 +533,24 @@ foreach ($accounts as $key=>$type) if (! $i) $totalarray['nbfield']++; } + // Currency + if (! empty($arrayfields['b.currency_code']['checked'])) + { + print ''; + print $obj->currency_code; + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Transactions to reconcile if (! empty($arrayfields['toreconcile']['checked'])) { print ''; - if ($acc->rappro) + if ($obj->rappro) { - $result=$acc->load_board($user,$acc->id); + $result=$obj->load_board($user,$obj->id); if ($result<0) { - setEventMessages($acc->error, $acc->errors, 'errors'); + setEventMessages($obj->error, $obj->errors, 'errors'); } else { print $result->nbtodo; if ($result->nbtodolate) print '   ('.$result->nbtodolate.img_warning($langs->trans("Late")).')'; @@ -570,7 +587,7 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['b.datec']['checked'])) { print ''; - print dol_print_date($acc->date_creation, 'dayhour'); + print dol_print_date($obj->date_creation, 'dayhour'); print ''; if (! $i) $totalarray['nbfield']++; } @@ -578,7 +595,7 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['b.tms']['checked'])) { print ''; - print dol_print_date($acc->date_update, 'dayhour'); + print dol_print_date($obj->date_update, 'dayhour'); print ''; if (! $i) $totalarray['nbfield']++; } @@ -586,7 +603,7 @@ foreach ($accounts as $key=>$type) // Status if (! empty($arrayfields['b.clos']['checked'])) { - print ''.$acc->getLibStatut(5).''; + print ''.$obj->getLibStatut(5).''; if (! $i) $totalarray['nbfield']++; } @@ -594,7 +611,7 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['balance']['checked'])) { print ''; - print ''.price($solde, 0, $langs, 0, 0, -1, $acc->currency_code).''; + print ''.price($solde, 0, $langs, 0, 0, -1, $obj->currency_code).''; print ''; if (! $i) $totalarray['nbfield']++; if (! $i) $totalarray['totalbalancefield']=$totalarray['nbfield']; @@ -614,7 +631,7 @@ foreach ($accounts as $key=>$type) print ''; - $total[$acc->currency_code] += $solde; + $total[$obj->currency_code] += $solde; $i++; } diff --git a/htdocs/compta/bank/transfer.php b/htdocs/compta/bank/transfer.php index a0f5fdea27b..7696427b059 100644 --- a/htdocs/compta/bank/transfer.php +++ b/htdocs/compta/bank/transfer.php @@ -30,8 +30,7 @@ require('../../main.inc.php'); require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; -$langs->load("banks"); -$langs->load("categories"); +$langs->loadLangs(array("banks", "categories", "multicurrency")); if (! $user->rights->banque->transfer) accessforbidden(); @@ -123,7 +122,7 @@ if ($action == 'add') if (! $error) { - $mesgs = $langs->trans("TransferFromToDone","id."\">".$accountfrom->label."","id."\">".$accountto->label."",$amount,$langs->transnoentities("Currency".$conf->currency)); + $mesgs = $langs->trans("TransferFromToDone",''.$accountfrom->label."",''.$accountto->label."",$amount,$langs->transnoentities("Currency".$conf->currency)); setEventMessages($mesgs, null, 'mesgs'); $db->commit(); } @@ -229,16 +228,16 @@ print ''; print ''; print ''; print ''; -print ''; +print ''; print ''; $var=false; print '"; print "\n"; print "\n"; From ceb868493e5782fb8e1b67a3af91d817146c3608 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 26 Sep 2017 10:12:42 +0200 Subject: [PATCH 152/177] NEW get payement types using the REST API Adds the ability to get payments types using the REST API --- .../class/api_dictionarypayments.class.php | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 htdocs/api/class/api_dictionarypayments.class.php diff --git a/htdocs/api/class/api_dictionarypayments.class.php b/htdocs/api/class/api_dictionarypayments.class.php new file mode 100644 index 00000000000..4c9aa8a948b --- /dev/null +++ b/htdocs/api/class/api_dictionarypayments.class.php @@ -0,0 +1,97 @@ + + * + * 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 . + */ + +use Luracast\Restler\RestException; + +require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; + +/** + * API class for payment type (content of the paiement dictionary) + * + * @access protected + * @class DolibarrApiAccess {@requires user,external} + */ +class DictionaryPayments extends DolibarrApi +{ + /** + * Constructor + */ + function __construct() + { + global $db; + $this->db = $db; + } + + /** + * Get the list of payments types. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number {@min 0} + * @param int $active Payment type is active or not {@min 0} {@max 1} + * @param string $sqlfilters SQL criteria to filter. Syntax example "(t.code:=:'CHQ')" + * @return List of payment types + * + * @throws RestException + */ + function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT id, code, type, libelle as label, module"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_paiement as t"; + $sql.= " WHERE t.active = ".$active; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + + $sql.= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(503, 'Error when retrieving list of payment types : '.$this->db->lasterror()); + } + + return $list; + } + +} From 59571b1ce1780e7230a29ef798e208fee8bc4fe6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 25 Sep 2017 21:41:53 +0200 Subject: [PATCH 153/177] FIX #7473 Mass update of vat rates and other bugs on localtax --- htdocs/core/lib/functions.lib.php | 2 +- htdocs/core/tpl/objectline_view.tpl.php | 2 +- .../fourn/class/fournisseur.product.class.php | 47 +++++- htdocs/product/admin/product_tools.php | 62 ++++++-- .../class/productcustomerprice.class.php | 4 + htdocs/product/price.php | 146 +++++++++++++++--- 6 files changed, 215 insertions(+), 48 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 33ad6a48ca3..bfddc4b4921 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3711,7 +3711,7 @@ function vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0) if (! preg_match('/\//', $rate)) $ret=price($rate,0,'',0,0).($addpercent?'%':''); else { - // TODO Split on / and output with a price2num to have clean numbers with ton of 000. + // TODO Split on / and output with a price2num to have clean numbers without ton of 000. $ret=$rate.($addpercent?'%':''); } if ($info_bits & 1) $ret.=' *'; diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index f968fdcbfc7..94c05fd9ffe 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -145,7 +145,7 @@ if (empty($outputalsopricetotalwithtax)) $outputalsopricetotalwithtax=0; '."\n"; print ''."\n"; - + print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; - + print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; /* - + print ''."\n"; print ''."\n"; print '
'.$langs->trans("TransferFrom").''.$langs->trans("TransferTo").''.$langs->trans("Date").''.$langs->trans("Description").''.$langs->trans("Amount").'
'; -$form->select_comptes($account_from,'account_from',0,'',1); +$form->select_comptes($account_from, 'account_from', 0, '', 1, '', empty($conf->multicurrency->enabled)?0:1); print "\n"; -$form->select_comptes($account_to,'account_to',0,'',1); +$form->select_comptes($account_to, 'account_to', 0, '', 1, '', empty($conf->multicurrency->enabled)?0:1); print ""; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 009f1f0dcd3..8db18e2c748 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3306,21 +3306,22 @@ class Form /** * Return a HTML select list of bank accounts * - * @param string $selected Id account pre-selected - * @param string $htmlname Name of select zone - * @param int $statut Status of searched accounts (0=open, 1=closed, 2=both) - * @param string $filtre To filter list - * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. - * @param string $moreattrib To add more attribute on select + * @param string $selected Id account pre-selected + * @param string $htmlname Name of select zone + * @param int $statut Status of searched accounts (0=open, 1=closed, 2=both) + * @param string $filtre To filter list + * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. + * @param string $moreattrib To add more attribute on select + * @param int $showcurrency Show currency in label * @return void */ - function select_comptes($selected='',$htmlname='accountid',$statut=0,$filtre='',$useempty=0,$moreattrib='') + function select_comptes($selected='',$htmlname='accountid',$statut=0,$filtre='',$useempty=0,$moreattrib='',$showcurrency=0) { global $langs, $conf; $langs->load("admin"); - $sql = "SELECT rowid, label, bank, clos as status"; + $sql = "SELECT rowid, label, bank, clos as status, currency_code"; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; $sql.= " WHERE entity IN (".getEntity('bank_account').")"; if ($statut != 2) $sql.= " AND clos = '".$statut."'"; @@ -3353,6 +3354,7 @@ class Form print ''; $i++; diff --git a/htdocs/langs/en_US/multicurrency.lang b/htdocs/langs/en_US/multicurrency.lang index fcf84791a1f..bd19ab1b0e9 100644 --- a/htdocs/langs/en_US/multicurrency.lang +++ b/htdocs/langs/en_US/multicurrency.lang @@ -17,3 +17,4 @@ rate=rate MulticurrencyReceived=Received, original currency MulticurrencyRemainderToTake=Remaining amout, original currency MulticurrencyPaymentAmount=Payment amount, original currency +AmountToOthercurrency=Amount To (in currency of receiving account) \ No newline at end of file From 845a33653aac9a228f9680afd9c0acca8afdb6be Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 25 Sep 2017 19:07:57 +0200 Subject: [PATCH 146/177] Fix translation --- htdocs/langs/en_US/products.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 6bc5d842a8e..b324154e9d0 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -152,7 +152,7 @@ BuyingPrices=Buying prices CustomerPrices=Customer prices SuppliersPrices=Supplier prices SuppliersPricesOfProductsOrServices=Supplier prices (of products or services) -CustomCode=Customs code +CustomCode=Customs/Commodity/HS code CountryOrigin=Origin country Nature=Nature ShortLabel=Short label From 58bc30ae9a50a2618c32d2123ff21e0c011a2768 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 25 Sep 2017 19:08:17 +0200 Subject: [PATCH 147/177] Add indian vat --- htdocs/install/mysql/data/llx_c_tva.sql | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/install/mysql/data/llx_c_tva.sql b/htdocs/install/mysql/data/llx_c_tva.sql index cce279d79da..ac8513ef95c 100644 --- a/htdocs/install/mysql/data/llx_c_tva.sql +++ b/htdocs/install/mysql/data/llx_c_tva.sql @@ -138,8 +138,14 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (11 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1173, 117, '1','0','VAT super-reduced rate',0); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1174, 117, '0','0','VAT Rate 0', 0); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'CGST+SGST', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'IGST' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1178, 117, 'C+S-5', 0, 2.5, '1', 2.5, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1179, 117, 'I-5' , 5, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1180, 117, 'C+S-12', 0, 6, '1', 6, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1181, 117, 'I-12' , 12, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'C+S-18', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'I-18' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1182, 117, 'C+S-28', 0, 14, '1', 14, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1183, 117, 'I-28' , 28, 0, '0', 0, '0', 0, 'IGST', 1); -- IRELAND (id country=8) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (81, 8, '0','0','VAT Rate 0',1); From 4c7b39f49e3b4636f0f321940e5204b82ce4c970 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 25 Sep 2017 19:22:41 +0200 Subject: [PATCH 148/177] FIX #7486 Empty value for multicurrency rate must be forbidden --- htdocs/admin/multicurrency.php | 36 ++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index 0229f4fc150..ce6a04fab30 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -78,34 +78,54 @@ if (preg_match('/del_(.*)/',$action,$reg)) if ($action == 'add_currency') { + $error=0; + $langs->loadCacheCurrencies(''); $code = GETPOST('code', 'alpha'); - $rate = GETPOST('rate', 'alpha'); + $rate = price2num(GETPOST('rate', 'alpha')); $currency = new MultiCurrency($db); $currency->code = $code; $currency->name = !empty($langs->cache_currencies[$code]['label']) ? $langs->cache_currencies[$code]['label'].' ('.$langs->getCurrencySymbol($code).')' : $code; - if ($currency->create($user) > 0) + if (empty($rate)) { - if ($currency->addRate($rate)) setEventMessages($langs->trans('RecordSaved'), array()); - else setEventMessages($langs->trans('ErrorAddRateFail'), array(), 'errors'); + setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Rate")), null, 'errors'); + $error++; + } + if (! $error) + { + if ($currency->create($user) > 0) + { + if ($currency->addRate($rate)) setEventMessages($langs->trans('RecordSaved'), array()); + else setEventMessages($langs->trans('ErrorAddRateFail'), array(), 'errors'); + } + else setEventMessages($langs->trans('ErrorAddCurrencyFail'), $currency->errors, 'errors'); } - else setEventMessages($langs->trans('ErrorAddCurrencyFail'), $currency->errors, 'errors'); } elseif ($action == 'update_currency') { + $error = 0; + $submit = GETPOST('submit', 'alpha'); if ($submit == $langs->trans('Modify')) { $fk_multicurrency = GETPOST('fk_multicurrency', 'int'); - $rate = GETPOST('rate', 'float'); + $rate = price2num(GETPOST('rate', 'alpha')); $currency = new MultiCurrency($db); - if ($currency->fetch($fk_multicurrency) > 0) + if (empty($rate)) { - $currency->updateRate($rate); + setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Rate")), null, 'errors'); + $error++; + } + if (! $error) + { + if ($currency->fetch($fk_multicurrency) > 0) + { + $currency->updateRate($rate); + } } } elseif ($submit == $langs->trans('Delete')) From fe55feb82f39c57a77864d1f72693bbf0f53a673 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 25 Sep 2017 19:45:01 +0200 Subject: [PATCH 149/177] FIX #7461 --- htdocs/core/class/commonobject.class.php | 12 ++++++------ htdocs/fourn/facture/card.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index d222d1ab268..f1002d86f80 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1562,22 +1562,22 @@ abstract class CommonObject switch ($this->element) { case 'propal': - $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->desc, 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, ($line->description?$line->description:$line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; case 'commande': - $this->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; case 'facture': - $this->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit, $line->multicurrency_subprice); break; case 'supplier_proposal': - $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->desc, 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->array_options, $line->ref_fourn, $line->multicurrency_subprice); + $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, ($line->description?$line->description:$line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->array_options, $line->ref_fourn, $line->multicurrency_subprice); break; case 'order_supplier': - $this->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; case 'invoice_supplier': - $this->updateline($line->id, $line->desc, $line->subprice, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->qty, 0, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->qty, 0, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; default: dol_syslog(get_class($this).'::setMulticurrencyRate no updateline defined', LOG_DEBUG); diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index a3d396e75a1..ca9689292b4 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -320,7 +320,7 @@ if (empty($reshook)) // Multicurrency rate else if ($action == 'setmulticurrencyrate' && $user->rights->facture->creer) { - $result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx'))); + $result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx', 'alpha'))); } // bank account From f1791b5bf4e91e7f5864b1094e3fd7b5ae0af25f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 25 Sep 2017 19:58:38 +0200 Subject: [PATCH 150/177] Better translation --- htdocs/langs/en_US/supplier_proposal.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/supplier_proposal.lang b/htdocs/langs/en_US/supplier_proposal.lang index dc3eae23672..d5b51978920 100644 --- a/htdocs/langs/en_US/supplier_proposal.lang +++ b/htdocs/langs/en_US/supplier_proposal.lang @@ -1,7 +1,7 @@ # Dolibarr language file - Source file is en_US - supplier_proposal SupplierProposal=Supplier commercial proposals supplier_proposalDESC=Manage price requests to suppliers -SupplierProposalNew=New request +SupplierProposalNew=New price request CommRequest=Price request CommRequests=Price requests SearchRequest=Find a request From a350a067550970fcb6934ff780f58eb45403bbda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= Date: Mon, 25 Sep 2017 21:15:35 +0200 Subject: [PATCH 151/177] Solve bug with alias name display The bug display the alias name on the following name between brackets after name column. --- htdocs/societe/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index f280a9db89c..5009a668ba3 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -1024,6 +1024,7 @@ while ($i < min($num, $limit)) $companystatic->id=$obj->rowid; $companystatic->name=$obj->name; + $companystatic->name_alias=$obj->name_alias; $companystatic->canvas=$obj->canvas; $companystatic->client=$obj->client; $companystatic->status=$obj->status; @@ -1053,7 +1054,6 @@ while ($i < min($num, $limit)) } if (! empty($arrayfields['s.name_alias']['checked'])) { - $companystatic->name_alias=$obj->name_alias; // Added after the getNomUrl print ''; print $companystatic->name_alias; print "tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); + if (price2num($line->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); if (price2num($line->total_localtax1)) $positiverates.=($positiverates?'/':'').price2num($line->localtax1_tx); if (price2num($line->total_localtax2)) $positiverates.=($positiverates?'/':'').price2num($line->localtax2_tx); if (empty($positiverates)) $positiverates='0'; diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 5184c8ffe80..17f8b2615ee 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -180,16 +180,18 @@ class ProductFournisseur extends Product * @param Societe $fourn Supplier * @param int $availability Product availability * @param string $ref_fourn Supplier ref - * @param float $tva_tx VAT rate + * @param float $tva_tx New VAT Rate (For example 8.5. Should not be a string) * @param string $charges costs affering to product * @param float $remise_percent Discount regarding qty (percent) * @param float $remise Discount regarding qty (amount) * @param int $newnpr Set NPR or not * @param int $delivery_time_days Delay in days for delivery (max). May be '' if not defined. * @param string $supplier_reputation Reputation with this product to the defined supplier (empty, FAVORITE, DONOTORDER) + * @param array $localtaxes_array Array with localtaxes info array('0'=>type1,'1'=>rate1,'2'=>type2,'3'=>rate2) (loaded by getLocalTaxesFromRate(vatrate, 0, ...) function). + * @param string $newdefaultvatcode Default vat code * @return int <0 if KO, >=0 if OK */ - function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges=0, $remise_percent=0, $remise=0, $newnpr=0, $delivery_time_days=0, $supplier_reputation='') + function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges=0, $remise_percent=0, $remise=0, $newnpr=0, $delivery_time_days=0, $supplier_reputation='', $localtaxes_array=array(), $newdefaultvatcode='') { global $conf, $langs; //global $mysoc; @@ -217,6 +219,25 @@ class ProductFournisseur extends Product $now=dol_now(); + $newvat = $tva_tx; + + if (count($localtaxes_array) > 0) + { + $localtaxtype1=$localtaxes_array['0']; + $localtax1=$localtaxes_array['1']; + $localtaxtype2=$localtaxes_array['2']; + $localtax2=$localtaxes_array['3']; + } + else // old method. deprecated because ot can't retreive type + { + $localtaxtype1='0'; + $localtax1=get_localtax($newvat,1); + $localtaxtype2='0'; + $localtax2=get_localtax($newvat,2); + } + if (empty($localtax1)) $localtax1=0; // If = '' then = 0 + if (empty($localtax2)) $localtax2=0; // If = '' then = 0 + $this->db->begin(); if ($this->product_fourn_price_id > 0) @@ -230,9 +251,15 @@ class ProductFournisseur extends Product $sql.= " remise = ".$remise.","; $sql.= " unitprice = ".$unitBuyPrice.","; $sql.= " unitcharges = ".$unitCharges.","; // deprecated - $sql.= " tva_tx = ".$tva_tx.","; $sql.= " fk_availability = ".$availability.","; $sql.= " entity = ".$conf->entity.","; + $sql.= " tva_tx = ".price2num($tva_tx).","; + // TODO Add localtax1 and localtax2 + //$sql.= " localtax1_tx=".($localtax1>=0?$localtax1:'NULL').","; + //$sql.= " localtax2_tx=".($localtax2>=0?$localtax2:'NULL').","; + //$sql.= " localtax1_type=".($localtaxtype1!=''?"'".$localtaxtype1."'":"'0'").","; + //$sql.= " localtax2_type=".($localtaxtype2!=''?"'".$localtaxtype2."'":"'0'").","; + $sql.= " default_vat_code=".($newdefaultvatcode?"'".$this->db->escape($newdefaultvatcode)."'":"null").","; $sql.= " info_bits = ".$newnpr.","; $sql.= " charges = ".$charges.","; // deprecated $sql.= " delivery_time_days = ".($delivery_time_days != '' ? $delivery_time_days : 'null').","; @@ -279,7 +306,7 @@ class ProductFournisseur extends Product if ($resql) { // Add price for this quantity to supplier $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_fournisseur_price("; - $sql .= "datec, fk_product, fk_soc, ref_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, unitcharges, fk_availability, info_bits, entity, delivery_time_days,supplier_reputation)"; + $sql .= "datec, fk_product, fk_soc, ref_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, unitcharges, fk_availability, default_vat_code, info_bits, entity, delivery_time_days, supplier_reputation)"; $sql .= " values('" . $this->db->idate($now) . "',"; $sql .= " " . $this->id . ","; $sql .= " " . $fourn->id . ","; @@ -294,6 +321,7 @@ class ProductFournisseur extends Product $sql .= " " . $charges . ","; $sql .= " " . $unitCharges . ","; $sql .= " " . $availability . ","; + $sql .= " ".($newdefaultvatcode?"'".$this->db->escape($newdefaultvatcode)."'":"null").","; $sql .= " " . $newnpr . ","; $sql .= $conf->entity . ","; $sql .= $delivery_time_days . ","; @@ -364,9 +392,9 @@ class ProductFournisseur extends Product function fetch_product_fournisseur_price($rowid, $ignore_expression = 0) { global $conf; - $sql = "SELECT pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.fk_availability,"; + $sql = "SELECT pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.default_vat_code, pfp.fk_availability,"; $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.fk_product, pfp.charges, pfp.unitcharges, pfp.fk_supplier_price_expression, pfp.delivery_time_days,"; // , pfp.recuperableonly as fourn_tva_npr"; FIXME this field not exist in llx_product_fournisseur_price - $sql.=" pfp.supplier_reputation"; + $sql.= " pfp.supplier_reputation"; $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; $sql.= " WHERE pfp.rowid = ".$rowid; @@ -392,11 +420,14 @@ class ProductFournisseur extends Product $this->fourn_unitprice = $obj->unitprice; $this->fourn_unitcharges = $obj->unitcharges; // deprecated $this->fourn_tva_tx = $obj->tva_tx; - //$this->fourn_tva_npr = $obj->fourn_tva_npr; // TODO this field not exist in llx_product_fournisseur_price. We should add it ? + // TODO + // $this->fourn_tva_npr = $obj->fourn_tva_npr; // TODO this field not exist in llx_product_fournisseur_price. We should add it ? + // Add also localtaxes $this->fk_availability = $obj->fk_availability; $this->delivery_time_days = $obj->delivery_time_days; $this->fk_supplier_price_expression = $obj->fk_supplier_price_expression; - $this->supplier_reputation = $obj->supplier_reputation; + $this->supplier_reputation = $obj->supplier_reputation; + $this->default_vat_code = $obj->default_vat_code; if (empty($ignore_expression) && !empty($this->fk_supplier_price_expression)) { diff --git a/htdocs/product/admin/product_tools.php b/htdocs/product/admin/product_tools.php index 85351a0fb2a..f19f672a25e 100644 --- a/htdocs/product/admin/product_tools.php +++ b/htdocs/product/admin/product_tools.php @@ -38,8 +38,8 @@ $langs->load("products"); if (! $user->admin) accessforbidden(); $action = GETPOST('action','alpha'); -$oldvatrate=GETPOST('oldvatrate'); -$newvatrate=GETPOST('newvatrate'); +$oldvatrate=GETPOST('oldvatrate', 'alpha'); +$newvatrate=GETPOST('newvatrate', 'alpha'); //$price_base_type=GETPOST('price_base_type'); @@ -67,13 +67,31 @@ if ($action == 'convert') $db->begin(); + // Clean vat code old + $vat_src_code_old=''; + if (preg_match('/\((.*)\)/', $oldvatrate, $reg)) + { + $vat_src_code_old = $reg[1]; + $oldvatrateclean = preg_replace('/\s*\(.*\)/', '', $oldvatrate); // Remove code into vatrate. + } + + // Clean vat code new + $vat_src_code_new=''; + if (preg_match('/\((.*)\)/', $newvatrate, $reg)) + { + $vat_src_code_new = $reg[1]; + $newvatrateclean = preg_replace('/\s*\(.*\)/', '', $newvatrate); // Remove code into vatrate. + } + // If country to edit is my country, so we change customer prices if ($country_id == $mysoc->country_id) { $sql = 'SELECT rowid'; $sql.= ' FROM '.MAIN_DB_PREFIX.'product'; $sql.= ' WHERE entity IN ('.getEntity('product').')'; - $sql.= " AND tva_tx = '".$db->escape($oldvatrate)."'"; + $sql.= " AND tva_tx = '".$db->escape($oldvatrateclean)."'"; + if ($vat_src_code_old) $sql.= " AND default_vat_code = '".$vat_src_code_old."'"; + else " AND default_vat_code = IS NULL"; $resql=$db->query($sql); if ($resql) @@ -109,12 +127,15 @@ if ($action == 'convert') $newminprice=$objectstatic->multiprices_min[$level]; } if ($newminprice > $newprice) $newminprice=$newprice; + $newvat=str_replace('*','',$newvatrate); + $localtaxes_type=getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc); $newnpr=$objectstatic->multiprices_recuperableonly[$level]; + $newdefaultvatcode=$vat_src_code_new; $newlevel=$level; //print "$objectstatic->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr
\n"; - $retm=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvat, $newminprice, $newlevel, $newnpr); + $retm=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvatratclean, $newminprice, $newlevel, $newnpr, 0, 0, $localtaxes_type, $newdefaultvatcode); if ($retm < 0) { $error++; @@ -138,19 +159,21 @@ if ($action == 'convert') } if ($newminprice > $newprice) $newminprice=$newprice; $newvat=str_replace('*','',$newvatrate); + $localtaxes_type=getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc); $newnpr=$objectstatic->recuperableonly; + $newdefaultvatcode=$vat_src_code_new; $newlevel=0; if (! empty($price_base_type) && ! $updatelevel1) { //print "$objectstatic->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr
\n"; - $ret=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvat, $newminprice, $newlevel, $newnpr); + $ret=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvatrateclean, $newminprice, $newlevel, $newnpr, 0, 0, $localtaxes_type, $newdefaultvatcode); } if ($ret < 0 || $retm < 0) $error++; else $nbrecordsmodified++; } unset($objectstatic); - + $i++; } } @@ -164,6 +187,8 @@ if ($action == 'convert') $sql.= ' FROM '.MAIN_DB_PREFIX.'product_fournisseur_price as pfp, '.MAIN_DB_PREFIX.'societe as s'; $sql.= ' WHERE pfp.fk_soc = s.rowid AND pfp.entity IN ('.getEntity('product').')'; $sql.= " AND tva_tx = '".$db->escape($oldvatrate)."'"; + if ($vat_src_code_old) $sql.= " AND default_vat_code = '".$vat_src_code_old."'"; + else " AND default_vat_code = IS NULL"; $sql.= " AND s.fk_pays = '".$country_id."'"; //print $sql; $resql=$db->query($sql); @@ -196,26 +221,33 @@ if ($action == 'convert') //} //if ($newminprice > $newprice) $newminprice=$newprice; $newvat=str_replace('*','',$newvatrate); + $localtaxes_type=getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc); //$newnpr=$objectstatic2->recuperableonly; + $newnpr=0; + $newdefaultvatcode=$vat_src_code_new; + + $newpercent = $objectstatic2->fourn_remise_percent; + $newdeliverydelay = $objectstatic2->delivery_time_days; + $newsupplierreputation = $objectstatic2->supplier_reputation; + $newlevel=0; if (! empty($price_base_type) && ! $updatelevel1) { //print "$objectstatic2->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr
\n"; $fourn->id=$obj->fk_soc; - $ret=$objectstatic2->update_buyprice($obj->qty, $newprice, $user, $price_base_type, $fourn, $obj->fk_availability, $obj->ref_fourn, $newvat); + $ret=$objectstatic2->update_buyprice($obj->qty, $newprice, $user, $price_base_type, $fourn, $obj->fk_availability, $obj->ref_fourn, $newvat, '', $newpercent, 0, $newnpr, $newdeliverydelay, $newsupplierreputation, $localtaxes_type, $newdefaultvatcode); } if ($ret < 0 || $retm < 0) $error++; else $nbrecordsmodified++; } unset($objectstatic2); - + $i++; } } else dol_print_error($db); - if (! $error) { $db->commit(); @@ -274,24 +306,24 @@ else print '
'.$langs->trans("Value").'
'.$langs->trans("OldVATRates").''."\n"; - print $form->load_tva('oldvatrate', $oldvatrate, $mysoc); + print $form->load_tva('oldvatrate', $oldvatrate, $mysoc, null, 0, 0, '', false, 1); print '
'.$langs->trans("NewVATRates").''."\n"; - print $form->load_tva('newvatrate', $newvatrate, $mysoc); + print $form->load_tva('newvatrate', $newvatrate, $mysoc, null, 0, 0, '', false, 1); print '
'.$langs->trans("PriceBaseTypeToChange").''."\n"; @@ -303,7 +335,7 @@ else print '
'; print '
'; - + // Boutons actions print '
'; print ''; diff --git a/htdocs/product/class/productcustomerprice.class.php b/htdocs/product/class/productcustomerprice.class.php index 441b865e255..4ff018bf031 100644 --- a/htdocs/product/class/productcustomerprice.class.php +++ b/htdocs/product/class/productcustomerprice.class.php @@ -329,6 +329,8 @@ class Productcustomerprice extends CommonObject $sql .= " t.recuperableonly,"; $sql .= " t.localtax1_tx,"; $sql .= " t.localtax2_tx,"; + $sql .= " t.localtax1_type,"; + $sql .= " t.localtax2_type,"; $sql .= " t.fk_user,"; $sql .= " t.import_key,"; $sql .= " soc.nom as socname,"; @@ -386,6 +388,8 @@ class Productcustomerprice extends CommonObject $line->recuperableonly = $obj->recuperableonly; $line->localtax1_tx = $obj->localtax1_tx; $line->localtax2_tx = $obj->localtax2_tx; + $line->localtax1_type = $obj->localtax1_type; + $line->localtax2_type = $obj->localtax2_type; $line->fk_user = $obj->fk_user; $line->import_key = $obj->import_key; $line->socname = $obj->socname; diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 949711b4a1b..f16b716c9cc 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -107,8 +107,15 @@ if (empty($reshook)) $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' // We must define tva_tx, npr and local taxes + $tva_tx = $tva_tx_txt; $vatratecode = ''; - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -217,8 +224,15 @@ if (empty($reshook)) $tva_tx_txt = $newvattx[$i]; + $tva_tx = $tva_tx_txt; $vatratecode = ''; - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = $newlocaltax1_tx[$i]; $localtax1_type = $newlocaltax1_type[$i]; @@ -266,9 +280,15 @@ if (empty($reshook)) { $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' + $tva_tx = $tva_tx_txt; $vatratecode = ''; - // We must define tva_tx, npr and local taxes - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -280,7 +300,7 @@ if (empty($reshook)) $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; - $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; + $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) @@ -469,11 +489,17 @@ if (empty($reshook)) $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU'); $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha'); - $tva_tx_txt = GETPOST("tva_tx"); + $tva_tx_txt = GETPOST("tva_tx",'alpha'); + $tva_tx = $tva_tx_txt; $vatratecode = ''; - // We must define tva_tx, npr and local taxes - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -485,7 +511,7 @@ if (empty($reshook)) $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; - $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; + $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) @@ -565,9 +591,15 @@ if (empty($reshook)) $tva_tx_txt = GETPOST("tva_tx"); - $vatratecode=''; - // We must define tva_tx, npr and local taxes - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + $tva_tx = $tva_tx_txt; + $vatratecode = ''; + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -579,7 +611,7 @@ if (empty($reshook)) $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; - $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; + $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) @@ -712,17 +744,34 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) // using this option is a bug. kept for backward compatibility { // TVA - print '' . $langs->trans("VATRate") . '' . vatrate($object->multiprices_tva_tx[$soc->price_level], true) . ''; + print '' . $langs->trans("VATRate") . ''; + + $positiverates=''; + if (price2num($object->multiprices_tva_tx[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_tva_tx[$soc->price_level]); + if (price2num($object->multiprices_localtax1_type[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_localtax1_tx[$soc->price_level]); + if (price2num($object->multiprices_localtax2_type[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_localtax2_tx[$soc->price_level]); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + //print vatrate($object->multiprices_tva_tx[$soc->price_level], true); + print ''; } else { // TVA print '' . $langs->trans("VATRate") . ''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } - else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true); + else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true);*/ print ''; } @@ -740,11 +789,19 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) { // TVA print '' . $langs->trans("VATRate") . ''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } - else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true); + else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true);*/ print ''; } print ''; @@ -889,11 +946,19 @@ else { // TVA print '' . $langs->trans("VATRate") . ''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } - else print vatrate($object->tva_tx, true, $object->tva_npr, true); + else print vatrate($object->tva_tx, true, $object->tva_npr, true);*/ print ''; // Price @@ -1314,7 +1379,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_price') && ! in_array($action, array('edit_price','edit_vat'))) { - $sql = "SELECT p.rowid, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.default_vat_code, p.recuperableonly,"; + $sql = "SELECT p.rowid, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.default_vat_code, p.recuperableonly, p.localtax1_tx, p.localtax1_type, p.localtax2_tx, p.localtax2_type,"; $sql .= " p.price_level, p.price_min, p.price_min_ttc,p.price_by_qty,"; $sql .= " p.date_price as dp, p.fk_price_expression, u.rowid as user_id, u.login"; $sql .= " FROM " . MAIN_DB_PREFIX . "product_price as p,"; @@ -1410,11 +1475,19 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_ if (empty($conf->global->PRODUIT_MULTIPRICES)) { print ''; + + $positiverates=''; + if (price2num($objp->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($objp->tva_tx); + if (price2num($objp->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax1_tx); + if (price2num($objp->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($objp->default_vat_code?' ('.$objp->default_vat_code.')':''), '%', $objp->tva_npr); + /* if ($objp->default_vat_code) { print vatrate($objp->tva_tx, true) . ' ('.$objp->default_vat_code.')'; } - else print vatrate($objp->tva_tx, true, $objp->recuperableonly); + else print vatrate($objp->tva_tx, true, $objp->recuperableonly);*/ print ""; } @@ -1769,7 +1842,17 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print "" . $staticsoc->getNomUrl(1) . ""; print "" . dol_print_date($line->datec, "dayhour") . ""; print '' . $langs->trans($line->price_base_type) . ""; - print '' . vatrate($tva_tx, true, $line->recuperableonly) . ""; + print ''; +var_dump($prodcustprice);exit; + $positiverates=''; + if (price2num($objp->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($objp->tva_tx); + if (price2num($objp->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax1_tx); + if (price2num($objp->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($objp->default_vat_code?' ('.$objp->default_vat_code.')':''), '%', $objp->tva_npr); + + //. vatrate($tva_tx, true, $line->recuperableonly) . + print ""; print '' . price($line->price) . ""; print '' . price($line->price_ttc) . ""; @@ -1873,8 +1956,16 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print '' . $langs->trans($object->price_base_type) . ""; print ''; - print vatrate($object->tva_tx, true, $object->recuperableonly); - print $object->default_vat_code?' ('.$object->default_vat_code.')':''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + + //print vatrate($object->tva_tx, true, $object->tva_npr); + //print $object->default_vat_code?' ('.$object->default_vat_code.')':''; print ""; print '' . price($object->price) . ""; @@ -1939,7 +2030,16 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print "" . dol_print_date($line->datec, "dayhour") . ""; print '' . $langs->trans($line->price_base_type) . ""; - print '' . vatrate($tva_tx, true, $line->recuperableonly) . ""; + print ''; + + $positiverates=''; + if (price2num($line->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); + if (price2num($line->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax1_tx); + if (price2num($line->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($line->default_vat_code?' ('.$line->default_vat_code.')':''), '%', $line->tva_npr); + + print ""; print '' . price($line->price) . ""; print '' . price($line->price_ttc) . ""; From 4f76545b628e9641a99e15b3054e7be2c7e03c47 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 10:47:08 +0200 Subject: [PATCH 154/177] Add missing fields to manage localtax on supplier products --- .../install/mysql/migration/6.0.0-7.0.0.sql | 5 ++++ .../tables/llx_product_fournisseur_price.sql | 4 +++ htdocs/langs/en_US/main.lang | 1 + htdocs/product/price.php | 26 +++++++++---------- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index c8f2142684c..0d2a6a7baed 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -41,6 +41,11 @@ ALTER TABLE llx_website_page ADD COLUMN fk_user_modif integer; -- For 7.0 +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax1_tx double(6,3) DEFAULT 0; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax1_type varchar(10) NOT NULL DEFAULT '0'; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax2_tx double(6,3) DEFAULT 0; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax2_type varchar(10) NOT NULL DEFAULT '0'; + insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_SENTBYMAIL','Mails sent from member card','Executed when you send email from member card','member',23); diff --git a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql index f341b103edb..1c86bfe04f8 100755 --- a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql +++ b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql @@ -38,6 +38,10 @@ create table llx_product_fournisseur_price unitcharges double(24,8) DEFAULT 0, -- deprecated default_vat_code varchar(10), tva_tx double(6,3) NOT NULL, + localtax1_tx double(6,3) DEFAULT 0, + localtax1_type varchar(10) NOT NULL DEFAULT '0', + localtax2_tx double(6,3) DEFAULT 0, + localtax2_type varchar(10) NOT NULL DEFAULT '0', info_bits integer NOT NULL DEFAULT 0, fk_user integer, fk_supplier_price_expression integer, -- Link to the rule for dynamic price calculation diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 7475d1194eb..93d2542ea69 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -382,6 +382,7 @@ LT2ES=IRPF LT1IN=CGST LT2IN=SGST VATRate=Tax Rate +DefaultTaxRate=Default tax rate Average=Average Sum=Sum Delta=Delta diff --git a/htdocs/product/price.php b/htdocs/product/price.php index f3d61b26f81..af9fa2a927f 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -744,7 +744,7 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) // using this option is a bug. kept for backward compatibility { // TVA - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; $positiverates=''; if (price2num($object->multiprices_tva_tx[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_tva_tx[$soc->price_level]); @@ -758,7 +758,7 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) else { // TVA - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; $positiverates=''; if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); @@ -781,14 +781,14 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) // using this option is a bug. kept for backward compatibility { // We show only vat for level 1 - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; print '' . vatrate($object->multiprices_tva_tx[1], true) . ''; print ''; } else { // TVA - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; $positiverates=''; if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); @@ -945,7 +945,7 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) else { // TVA - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; $positiverates=''; if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); @@ -1123,7 +1123,7 @@ if ($action == 'edit_vat' && ($user->rights->produit->creer || $user->rights->se print ''; // VAT - print ''; @@ -1157,7 +1157,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) print '
' . $langs->trans("VATRate") . ''; + print '
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
'; // VAT - print ''; @@ -1298,7 +1298,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) print ''; - if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) print ''; + if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) print ''; else print ''; print ''; @@ -1439,7 +1439,7 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_ print ''; print $conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL; - if (empty($conf->global->PRODUIT_MULTIPRICES)) print ''; + if (empty($conf->global->PRODUIT_MULTIPRICES)) print ''; print ''; print ''; if (! empty($conf->dynamicprices->enabled)) { @@ -1606,7 +1606,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; // VAT - print ''; @@ -1695,7 +1695,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; // VAT - print ''; @@ -1799,7 +1799,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; @@ -1920,7 +1920,7 @@ var_dump($prodcustprice);exit; print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; From f5be144bebe72be6e36af481d837b868e00e6de0 Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Tue, 26 Sep 2017 10:48:35 +0200 Subject: [PATCH 155/177] NEW Consolidates REST dictionary APIs into a single tree and a single file The php code of the files "htdocs / api / class / api_dictionary * .class.php" has been integrated into a single file: "htdocs / api / class / api_dictionary.class.php". --- htdocs/api/class/api_dictionary.class.php | 452 ++++++++++++++++++ .../class/api_dictionarycountries.class.php | 184 ------- .../api/class/api_dictionaryevents.class.php | 100 ---- .../class/api_dictionaryextrafields.class.php | 112 ----- .../class/api_dictionarypayments.class.php | 97 ---- .../api/class/api_dictionarytowns.class.php | 102 ---- 6 files changed, 452 insertions(+), 595 deletions(-) create mode 100644 htdocs/api/class/api_dictionary.class.php delete mode 100644 htdocs/api/class/api_dictionarycountries.class.php delete mode 100644 htdocs/api/class/api_dictionaryevents.class.php delete mode 100644 htdocs/api/class/api_dictionaryextrafields.class.php delete mode 100644 htdocs/api/class/api_dictionarypayments.class.php delete mode 100644 htdocs/api/class/api_dictionarytowns.class.php diff --git a/htdocs/api/class/api_dictionary.class.php b/htdocs/api/class/api_dictionary.class.php new file mode 100644 index 00000000000..93f16d44377 --- /dev/null +++ b/htdocs/api/class/api_dictionary.class.php @@ -0,0 +1,452 @@ + + * + * 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 . + */ + +use Luracast\Restler\RestException; + +require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php'; + +/** + * API class for payment type (content of the paiement dictionary) + * + * @access protected + * @class DolibarrApiAccess {@requires user,external} + */ +class Dictionary extends DolibarrApi +{ + private $translations = null; + + /** + * Constructor + */ + function __construct() + { + global $db; + $this->db = $db; + } + + /** + * Get the list of payments types. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number {@min 0} + * @param int $active Payment type is active or not {@min 0} {@max 1} + * @param string $sqlfilters SQL criteria to filter. Syntax example "(t.code:=:'CHQ')" + * + * @url GET payments + * + * @return List of payment types + * + * @throws RestException + */ + function getPaymentTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT id, code, type, libelle as label, module"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_paiement as t"; + $sql.= " WHERE t.active = ".$active; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + + $sql.= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(503, 'Error when retrieving list of payment types : '.$this->db->lasterror()); + } + + return $list; + } + + /** + * Get the list of countries. + * + * The names of the countries will be translated to the given language if + * the $lang parameter is provided. The value of $lang must be a language + * code supported by Dolibarr, for example 'en_US' or 'fr_FR'. + * The returned list is sorted by country ID. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number (starting from zero) + * @param string $filter To filter the countries by name + * @param string $lang Code of the language the label of the countries must be translated to + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return List of countries + * + * @url GET countries + * + * @throws RestException + */ + function getListOfCountries($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '', $sqlfilters = '') + { + $list = array(); + + // Note: The filter is not applied in the SQL request because it must + // be applied to the translated names, not to the names in database. + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country as t"; + $sql.=" WHERE 1 = 1"; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql.= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $obj = $this->db->fetch_object($result); + $country = new Ccountry($this->db); + if ($country->fetch($obj->rowid) > 0) { + // Translate the name of the country if needed + // and then apply the filter if there is one. + $this->translateLabel($country, $lang); + + if (empty($filter) || stripos($country->label, $filter) !== FALSE) { + $list[] = $this->_cleanObjectDatas($country); + } + } + } + } else { + throw new RestException(503, 'Error when retrieving list of countries : '.$country->error); + } + + return $list; + } + + /** + * Get country by ID. + * + * @param int $id ID of country + * @param string $lang Code of the language the name of the + * country must be translated to + * + * @url GET countries/{id} + * + * @throws RestException + */ + function getCountryByID($id, $lang = '') + { + $country = new Ccountry($this->db); + + if ($country->fetch($id) < 0) { + throw new RestException(503, 'Error when retrieving country : '.$country->error); + } + else if ($country->fetch($id) == 0) { + throw new RestException(404, 'country not found'); + } + + $this->translateLabel($country, $lang); + + return $this->_cleanObjectDatas($country); + } + + /** + * Clean sensible object datas + * + * @param object $object Object to clean + * @return array Array of cleaned object properties + */ + function _cleanObjectDatas($object) + { + $object = parent::_cleanObjectDatas($object); + + unset($object->error); + unset($object->errors); + + return $object; + } + + /** + * Translate the name of the country to the given language. + * + * @param Ccountry $country Country + * @param string $lang Code of the language the name of the + * country must be translated to + */ + private function translateLabel($country, $lang) + { + if (!empty($lang)) { + // Load the translations if this is a new language. + if ($this->translations == null || $this->translations->getDefaultLang() !== $lang) { + global $conf; + $this->translations = new Translate('', $conf); + $this->translations->setDefaultLang($lang); + $this->translations->load('dict'); + } + if ($country->code) { + $key = 'Country'.$country->code; + $translation = $this->translations->trans($key); + if ($translation != $key) { + $country->label = html_entity_decode($translation); + } + } + } + } + + /** + * Get the list of events types. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number (starting from zero) + * @param string $type To filter on type of event + * @param string $module To filter on module events + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return List of events types + * + * @url GET events + * + * @throws RestException + */ + function getListOfEvents($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT id, code, type, libelle as label, module"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_actioncomm as t"; + $sql.= " WHERE t.active = 1"; + if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'"; + if ($module) $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'"; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + + $sql.= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(503, 'Error when retrieving list of events types : '.$this->db->lasterror()); + } + + return $list; + } + + + /** + * Get the list of extra fields. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param string $type Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...) + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'SO-%')" + * @return List of events types + * + * @url GET extrafields + * + * @throws RestException + */ + function getListOfExtrafields($sortfield = "t.pos", $sortorder = 'ASC', $type = '', $sqlfilters = '') + { + $list = array(); + + if ($type == 'thirdparty') $type='societe'; + if ($type == 'contact') $type='socpeople'; + + $sql = "SELECT t.rowid, t.name, t.label, t.type, t.size, t.elementtype, t.fieldunique, t.fieldrequired, t.param, t.pos, t.alwayseditable, t.perms, t.list, t.ishidden, t.fielddefault, t.fieldcomputed"; + $sql.= " FROM ".MAIN_DB_PREFIX."extrafields as t"; + $sql.= " WHERE t.entity IN (".getEntity('extrafields').")"; + if (! empty($type)) $sql.= " AND t.elementtype = '".$this->db->escape($type)."'"; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql.= $this->db->order($sortfield, $sortorder); + + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + while ($tab = $this->db->fetch_object($resql)) + { + // New usage + $list[$tab->elementtype][$tab->name]['type']=$tab->type; + $list[$tab->elementtype][$tab->name]['label']=$tab->label; + $list[$tab->elementtype][$tab->name]['size']=$tab->size; + $list[$tab->elementtype][$tab->name]['elementtype']=$tab->elementtype; + $list[$tab->elementtype][$tab->name]['default']=$tab->fielddefault; + $list[$tab->elementtype][$tab->name]['computed']=$tab->fieldcomputed; + $list[$tab->elementtype][$tab->name]['unique']=$tab->fieldunique; + $list[$tab->elementtype][$tab->name]['required']=$tab->fieldrequired; + $list[$tab->elementtype][$tab->name]['param']=($tab->param ? unserialize($tab->param) : ''); + $list[$tab->elementtype][$tab->name]['pos']=$tab->pos; + $list[$tab->elementtype][$tab->name]['alwayseditable']=$tab->alwayseditable; + $list[$tab->elementtype][$tab->name]['perms']=$tab->perms; + $list[$tab->elementtype][$tab->name]['list']=$tab->list; + $list[$tab->elementtype][$tab->name]['ishidden']=$tab->ishidden; + } + } + } + else + { + throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror()); + } + + if (! count($list)) + { + throw new RestException(404, 'No extrafield found'); + } + + return $list; + } + + + /** + * Get the list of towns. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number (starting from zero) + * @param string $zipcode To filter on zipcode + * @param string $town To filter on city name + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return List of towns + * + * @url GET towns + * + * @throws RestException + */ + function getListOfTowns($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '', $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_ziptown as t"; + $sql.= " WHERE t.active = 1"; + if ($zipcode) $sql.=" AND t.zip LIKE '%" . $this->db->escape($zipcode) . "%'"; + if ($town) $sql.=" AND t.town LIKE '%" . $this->db->escape($town) . "%'"; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + + $sql.= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(503, 'Error when retrieving list of towns : '.$this->db->lasterror()); + } + + return $list; + } + +} diff --git a/htdocs/api/class/api_dictionarycountries.class.php b/htdocs/api/class/api_dictionarycountries.class.php deleted file mode 100644 index 070be509a8a..00000000000 --- a/htdocs/api/class/api_dictionarycountries.class.php +++ /dev/null @@ -1,184 +0,0 @@ - - * Copyright (C) 2016 Laurent Destailleur - * - * 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 . - */ - -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php'; - -/** - * API class for countries - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryCountries extends DolibarrApi -{ - private $translations = null; - - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of countries. - * - * The names of the countries will be translated to the given language if - * the $lang parameter is provided. The value of $lang must be a language - * code supported by Dolibarr, for example 'en_US' or 'fr_FR'. - * The returned list is sorted by country ID. - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Number of items per page - * @param int $page Page number (starting from zero) - * @param string $filter To filter the countries by name - * @param string $lang Code of the language the label of the countries must be translated to - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return List of countries - * - * @throws RestException - */ - function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '', $sqlfilters = '') - { - $list = array(); - - // Note: The filter is not applied in the SQL request because it must - // be applied to the translated names, not to the names in database. - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country as t"; - $sql.=" WHERE 1 = 1"; - // Add sql filters - if ($sqlfilters) - { - if (! DolibarrApi::_checkFilters($sqlfilters)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - $sql.= $this->db->order($sortfield, $sortorder); - - if ($limit) { - if ($page < 0) { - $page = 0; - } - $offset = $limit * $page; - - $sql .= $this->db->plimit($limit, $offset); - } - - $result = $this->db->query($sql); - - if ($result) { - $num = $this->db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - for ($i = 0; $i < $min; $i++) { - $obj = $this->db->fetch_object($result); - $country = new Ccountry($this->db); - if ($country->fetch($obj->rowid) > 0) { - // Translate the name of the country if needed - // and then apply the filter if there is one. - $this->translateLabel($country, $lang); - - if (empty($filter) || stripos($country->label, $filter) !== FALSE) { - $list[] = $this->_cleanObjectDatas($country); - } - } - } - } else { - throw new RestException(503, 'Error when retrieving list of countries : '.$country->error); - } - - return $list; - } - - /** - * Get country by ID. - * - * @param int $id ID of country - * @param string $lang Code of the language the name of the - * country must be translated to - * - * @throws RestException - */ - function get($id, $lang = '') - { - $country = new Ccountry($this->db); - - if ($country->fetch($id) < 0) { - throw new RestException(503, 'Error when retrieving country : '.$country->error); - } - else if ($country->fetch($id) == 0) { - throw new RestException(404, 'country not found'); - } - - $this->translateLabel($country, $lang); - - return $this->_cleanObjectDatas($country); - } - - /** - * Clean sensible object datas - * - * @param object $object Object to clean - * @return array Array of cleaned object properties - */ - function _cleanObjectDatas($object) - { - $object = parent::_cleanObjectDatas($object); - - unset($object->error); - unset($object->errors); - - return $object; - } - - /** - * Translate the name of the country to the given language. - * - * @param Ccountry $country Country - * @param string $lang Code of the language the name of the - * country must be translated to - */ - private function translateLabel($country, $lang) - { - if (!empty($lang)) { - // Load the translations if this is a new language. - if ($this->translations == null || $this->translations->getDefaultLang() !== $lang) { - global $conf; - $this->translations = new Translate('', $conf); - $this->translations->setDefaultLang($lang); - $this->translations->load('dict'); - } - if ($country->code) { - $key = 'Country'.$country->code; - $translation = $this->translations->trans($key); - if ($translation != $key) { - $country->label = html_entity_decode($translation); - } - } - } - } -} diff --git a/htdocs/api/class/api_dictionaryevents.class.php b/htdocs/api/class/api_dictionaryevents.class.php deleted file mode 100644 index 23d7e8e5dba..00000000000 --- a/htdocs/api/class/api_dictionaryevents.class.php +++ /dev/null @@ -1,100 +0,0 @@ - - * - * 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 . - */ - -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; - -/** - * API class for events type (content of the actioncomm dictionary) - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryEvents extends DolibarrApi -{ - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of events types. - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Number of items per page - * @param int $page Page number (starting from zero) - * @param string $type To filter on type of event - * @param string $module To filter on module events - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return List of events types - * - * @throws RestException - */ - function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $sqlfilters = '') - { - $list = array(); - - $sql = "SELECT id, code, type, libelle as label, module"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_actioncomm as t"; - $sql.= " WHERE t.active = 1"; - if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'"; - if ($module) $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'"; - // Add sql filters - if ($sqlfilters) - { - if (! DolibarrApi::_checkFilters($sqlfilters)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - - $sql.= $this->db->order($sortfield, $sortorder); - - if ($limit) { - if ($page < 0) { - $page = 0; - } - $offset = $limit * $page; - - $sql .= $this->db->plimit($limit, $offset); - } - - $result = $this->db->query($sql); - - if ($result) { - $num = $this->db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - for ($i = 0; $i < $min; $i++) { - $list[] = $this->db->fetch_object($result); - } - } else { - throw new RestException(503, 'Error when retrieving list of events types : '.$this->db->lasterror()); - } - - return $list; - } - -} diff --git a/htdocs/api/class/api_dictionaryextrafields.class.php b/htdocs/api/class/api_dictionaryextrafields.class.php deleted file mode 100644 index 69f574797c7..00000000000 --- a/htdocs/api/class/api_dictionaryextrafields.class.php +++ /dev/null @@ -1,112 +0,0 @@ - - * - * 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 . - */ - -use Luracast\Restler\RestException; - -//require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; - -/** - * API class for extra fields (content of the extrafields) - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryExtraFields extends DolibarrApi -{ - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of extra fields. - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param string $type Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...) - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'SO-%')" - * @return List of events types - * - * @throws RestException - */ - function index($sortfield = "t.pos", $sortorder = 'ASC', $type = '', $sqlfilters = '') - { - $list = array(); - - if ($type == 'thirdparty') $type='societe'; - if ($type == 'contact') $type='socpeople'; - - $sql = "SELECT t.rowid, t.name, t.label, t.type, t.size, t.elementtype, t.fieldunique, t.fieldrequired, t.param, t.pos, t.alwayseditable, t.perms, t.list, t.ishidden, t.fielddefault, t.fieldcomputed"; - $sql.= " FROM ".MAIN_DB_PREFIX."extrafields as t"; - $sql.= " WHERE t.entity IN (".getEntity('extrafields').")"; - if (! empty($type)) $sql.= " AND t.elementtype = '".$this->db->escape($type)."'"; - // Add sql filters - if ($sqlfilters) - { - if (! DolibarrApi::_checkFilters($sqlfilters)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - $sql.= $this->db->order($sortfield, $sortorder); - - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - while ($tab = $this->db->fetch_object($resql)) - { - // New usage - $list[$tab->elementtype][$tab->name]['type']=$tab->type; - $list[$tab->elementtype][$tab->name]['label']=$tab->label; - $list[$tab->elementtype][$tab->name]['size']=$tab->size; - $list[$tab->elementtype][$tab->name]['elementtype']=$tab->elementtype; - $list[$tab->elementtype][$tab->name]['default']=$tab->fielddefault; - $list[$tab->elementtype][$tab->name]['computed']=$tab->fieldcomputed; - $list[$tab->elementtype][$tab->name]['unique']=$tab->fieldunique; - $list[$tab->elementtype][$tab->name]['required']=$tab->fieldrequired; - $list[$tab->elementtype][$tab->name]['param']=($tab->param ? unserialize($tab->param) : ''); - $list[$tab->elementtype][$tab->name]['pos']=$tab->pos; - $list[$tab->elementtype][$tab->name]['alwayseditable']=$tab->alwayseditable; - $list[$tab->elementtype][$tab->name]['perms']=$tab->perms; - $list[$tab->elementtype][$tab->name]['list']=$tab->list; - $list[$tab->elementtype][$tab->name]['ishidden']=$tab->ishidden; - } - } - } - else - { - throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror()); - } - - if (! count($list)) - { - throw new RestException(404, 'No extrafield found'); - } - - return $list; - } - -} diff --git a/htdocs/api/class/api_dictionarypayments.class.php b/htdocs/api/class/api_dictionarypayments.class.php deleted file mode 100644 index 4c9aa8a948b..00000000000 --- a/htdocs/api/class/api_dictionarypayments.class.php +++ /dev/null @@ -1,97 +0,0 @@ - - * - * 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 . - */ - -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; - -/** - * API class for payment type (content of the paiement dictionary) - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryPayments extends DolibarrApi -{ - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of payments types. - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Number of items per page - * @param int $page Page number {@min 0} - * @param int $active Payment type is active or not {@min 0} {@max 1} - * @param string $sqlfilters SQL criteria to filter. Syntax example "(t.code:=:'CHQ')" - * @return List of payment types - * - * @throws RestException - */ - function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') - { - $list = array(); - - $sql = "SELECT id, code, type, libelle as label, module"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_paiement as t"; - $sql.= " WHERE t.active = ".$active; - // Add sql filters - if ($sqlfilters) - { - if (! DolibarrApi::_checkFilters($sqlfilters)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - - $sql.= $this->db->order($sortfield, $sortorder); - - if ($limit) { - if ($page < 0) { - $page = 0; - } - $offset = $limit * $page; - - $sql .= $this->db->plimit($limit, $offset); - } - - $result = $this->db->query($sql); - - if ($result) { - $num = $this->db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - for ($i = 0; $i < $min; $i++) { - $list[] = $this->db->fetch_object($result); - } - } else { - throw new RestException(503, 'Error when retrieving list of payment types : '.$this->db->lasterror()); - } - - return $list; - } - -} diff --git a/htdocs/api/class/api_dictionarytowns.class.php b/htdocs/api/class/api_dictionarytowns.class.php deleted file mode 100644 index 0ebcfbe0b17..00000000000 --- a/htdocs/api/class/api_dictionarytowns.class.php +++ /dev/null @@ -1,102 +0,0 @@ - - * Copyright (C) 2016 Laurent Destailleur - * - * 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 . - */ - -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php'; - -/** - * API class for towns (content of the ziptown dictionary) - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryTowns extends DolibarrApi -{ - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of towns. - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Number of items per page - * @param int $page Page number (starting from zero) - * @param string $zipcode To filter on zipcode - * @param string $town To filter on city name - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return List of towns - * - * @throws RestException - */ - function index($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '', $sqlfilters = '') - { - $list = array(); - - $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_ziptown as t"; - $sql.= " WHERE t.active = 1"; - if ($zipcode) $sql.=" AND t.zip LIKE '%" . $this->db->escape($zipcode) . "%'"; - if ($town) $sql.=" AND t.town LIKE '%" . $this->db->escape($town) . "%'"; - // Add sql filters - if ($sqlfilters) - { - if (! DolibarrApi::_checkFilters($sqlfilters)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - - $sql.= $this->db->order($sortfield, $sortorder); - - if ($limit) { - if ($page < 0) { - $page = 0; - } - $offset = $limit * $page; - - $sql .= $this->db->plimit($limit, $offset); - } - - $result = $this->db->query($sql); - - if ($result) { - $num = $this->db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - for ($i = 0; $i < $min; $i++) { - $list[] = $this->db->fetch_object($result); - } - } else { - throw new RestException(503, 'Error when retrieving list of towns : '.$this->db->lasterror()); - } - - return $list; - } - -} From 7f420f32463700bf3a499cdd57454e9681feb9d3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 10:53:24 +0200 Subject: [PATCH 156/177] Complete vat rates for india --- htdocs/install/mysql/data/llx_c_tva.sql | 15 +++++++++------ htdocs/install/mysql/migration/5.0.0-6.0.0.sql | 10 ++++++++-- htdocs/product/fournisseurs.php | 4 +++- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/htdocs/install/mysql/data/llx_c_tva.sql b/htdocs/install/mysql/data/llx_c_tva.sql index b4389ca8397..b805b9f8014 100644 --- a/htdocs/install/mysql/data/llx_c_tva.sql +++ b/htdocs/install/mysql/data/llx_c_tva.sql @@ -135,13 +135,16 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 3 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 34, 3, '0','0','VAT Rate 0',1); -- INDIA (id country=117) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1171, 117, '12.5','0','VAT standard rate', 0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1172, 117, '4','0','VAT reduced rate', 0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1173, 117, '1','0','VAT super-reduced rate',0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1174, 117, '0','0','VAT Rate 0', 0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1171, 117, '0','0','VAT Rate 0', 0); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'CGST+SGST', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'IGST' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1178, 117, 'C+S-5', 0, 2.5, '1', 2.5, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1179, 117, 'I-5' , 5, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1180, 117, 'C+S-12', 0, 6, '1', 6, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1181, 117, 'I-12' , 12, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'C+S-18', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'I-18' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1182, 117, 'C+S-28', 0, 14, '1', 14, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1183, 117, 'I-28' , 28, 0, '0', 0, '0', 0, 'IGST', 1); -- IRELAND (id country=8) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (81, 8, '0','0','VAT Rate 0',1); diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index cd955b0416b..a2534728683 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -597,5 +597,11 @@ ALTER TABLE llx_mailing_cibles MODIFY COLUMN source_url varchar(255); -- VPGSQL8.2 CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_website FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -- VPGSQL8.2 CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_website_page FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'CGST+SGST', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'IGST' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1178, 117, 'C+S-5', 0, 2.5, '1', 2.5, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1179, 117, 'I-5' , 5, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1180, 117, 'C+S-12', 0, 6, '1', 6, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1181, 117, 'I-12' , 12, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'C+S-18', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'I-18' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1182, 117, 'C+S-28', 0, 14, '1', 14, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1183, 117, 'I-28' , 28, 0, '0', 0, '0', 0, 'IGST', 1); diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index ed53163615d..cb295012795 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -472,7 +472,9 @@ if ($id > 0 || $ref) $default_vat=$object->tva_tx; } } - print ''; + $vattosuggest=(GETPOST("tva_tx")?vatrate(GETPOST("tva_tx")):($default_vat!=''?vatrate($default_vat):'')); + $vattosuggest=preg_replace('/\s*\(.*\)$/','', $vattosuggest); + print ''; print ''; if (! empty($conf->dynamicprices->enabled)) //Only show price mode and expression selector if module is enabled From 1002923dea899c1caf700d81f0e029e1587d2dbe Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 10:58:24 +0200 Subject: [PATCH 157/177] Fix css --- htdocs/product/composition/card.php | 2 +- htdocs/product/traduction.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index fc8ae32fb38..946ce1be7a8 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -208,7 +208,7 @@ if ($id > 0 || ! empty($ref)) $shownav = 1; if ($user->societe_id && ! in_array('product', explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL))) $shownav=0; - dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref', '', '', '', 0, '', '', 1); + dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref', '', '', '', 0, '', '', 0); if ($object->type!=Product::TYPE_SERVICE || empty($conf->global->PRODUIT_MULTIPRICES)) { diff --git a/htdocs/product/traduction.php b/htdocs/product/traduction.php index 004662972c4..791da80c05d 100644 --- a/htdocs/product/traduction.php +++ b/htdocs/product/traduction.php @@ -205,7 +205,7 @@ $linkback = ''.$langs->trans("BackTo $shownav = 1; if ($user->societe_id && ! in_array('product', explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL))) $shownav=0; -dol_banner_tab($object, 'ref', $linkback, shownav, 'ref'); +dol_banner_tab($object, 'ref', $linkback, shownav, 'ref', '', '', '', 0, '', '', 1); dol_fiche_end(); From d2c55ea07bd7d4ea65013d15588038736fab6eae Mon Sep 17 00:00:00 2001 From: Papoteur Date: Tue, 26 Sep 2017 11:27:53 +0200 Subject: [PATCH 158/177] Factorize code between payments reports client/provider --- .../modules/rapport/pdf_paiement.class.php | 129 ++++-- .../rapport/pdf_paiement_fourn.class.php | 387 +----------------- 2 files changed, 100 insertions(+), 416 deletions(-) diff --git a/htdocs/core/modules/rapport/pdf_paiement.class.php b/htdocs/core/modules/rapport/pdf_paiement.class.php index da1223526db..606419e9a2a 100644 --- a/htdocs/core/modules/rapport/pdf_paiement.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement.class.php @@ -77,6 +77,8 @@ class pdf_paiement $this->posxinvoiceamount-=10; $this->posxpaymentamount-=20; } + // which type of document will be generated: clients (client) or providers (fourn) invoices + $this->doc_type = "client"; } @@ -105,7 +107,7 @@ class pdf_paiement $this->month=$month; $this->year=$year; - +dol_syslog(get_class($this)."::write_file".$year." ".$month, LOG_DEBUG); $dir=$_dir.'/'.$year; if (! is_dir($dir)) @@ -120,7 +122,15 @@ class pdf_paiement $month = sprintf("%02d",$month); $year = sprintf("%04d",$year); - $file = $dir . "/payments-".$year."-".$month.".pdf"; + switch ($this->doc_type) { + case "client": + $file = $dir . "/payments-".$year."-".$month.".pdf"; + break; + case "fourn": + $file = $dir . "/supplier_payments-".$year."-".$month.".pdf"; + break; + } + // Add pdfgeneration hook if (! is_object($hookmanager)) @@ -147,8 +157,19 @@ class pdf_paiement $lines=array(); // count number of lines of payment +dol_syslog(get_class($this)."::write_file".$year." ".$month." ".dol_get_first_day($year,$month), LOG_DEBUG); +dol_syslog(get_class($this)."::write_file".$year." ".$month." ".$this->db->idate(dol_get_first_day($year,$month)), LOG_DEBUG); +dol_syslog(get_class($this)."::write_file".$year." ".$month." ".dol_get_last_day($year,$month), LOG_DEBUG); +dol_syslog(get_class($this)."::write_file".$year." ".$month." ".$this->db->idate(dol_get_last_day($year,$month)), LOG_DEBUG); $sql = "SELECT p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p"; + switch ($this->doc_type) { + case "client": + $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p"; + break; + case "fourn": + $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p"; + break; + } $sql.= " WHERE p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; $sql.= " AND p.entity = " . $conf->entity; $result = $this->db->query($sql); @@ -158,35 +179,70 @@ class pdf_paiement } // number of bill - $sql = "SELECT p.datep as dp, f.facnumber"; - //$sql .= ", c.libelle as paiement_type, p.num_paiement"; - $sql.= ", c.code as paiement_code, p.num_paiement"; - $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; - $sql.= ", pf.amount as pf_amount"; - if (! empty($conf->banque->enabled)) - $sql.= ", ba.ref as bankaccount"; - $sql.= ", p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p, ".MAIN_DB_PREFIX."facture as f,"; - $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiement_facture as pf,"; - if (! empty($conf->banque->enabled)) - $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facture = f.rowid AND pf.fk_paiement = p.rowid"; - if (! empty($conf->banque->enabled)) - $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; - $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND p.fk_paiement = c.id "; - $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - } - if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; - $sql.= " ORDER BY p.datep ASC, pf.fk_paiement ASC"; + switch ($this->doc_type) { + case "client": + $sql = "SELECT p.datep as dp, f.facnumber"; + //$sql .= ", c.libelle as paiement_type, p.num_paiement"; + $sql.= ", c.code as paiement_code, p.num_paiement"; + $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; + $sql.= ", pf.amount as pf_amount"; + if (! empty($conf->banque->enabled)) + $sql.= ", ba.ref as bankaccount"; + $sql.= ", p.rowid as prowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p, ".MAIN_DB_PREFIX."facture as f,"; + $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiement_facture as pf,"; + if (! empty($conf->banque->enabled)) + $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; + $sql.= " ".MAIN_DB_PREFIX."societe as s"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + } + $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facture = f.rowid AND pf.fk_paiement = p.rowid"; + if (! empty($conf->banque->enabled)) + $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " AND p.fk_paiement = c.id "; + $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + } + if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; + $sql.= " ORDER BY p.datep ASC, pf.fk_paiement ASC"; + break; + case "fourn": + $sql = "SELECT p.datep as dp, f.ref as facnumber"; + //$sql .= ", c.libelle as paiement_type, p.num_paiement"; + $sql.= ", c.code as paiement_code, p.num_paiement"; + $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; + $sql.= ", pf.amount as pf_amount"; + if (! empty($conf->banque->enabled)) + $sql.= ", ba.ref as bankaccount"; + $sql.= ", p.rowid as prowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p, ".MAIN_DB_PREFIX."facture_fourn as f,"; + $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf,"; + if (! empty($conf->banque->enabled)) + $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; + $sql.= " ".MAIN_DB_PREFIX."societe as s"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + } + $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facturefourn = f.rowid AND pf.fk_paiementfourn = p.rowid"; + if (! empty($conf->banque->enabled)) + $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " AND p.fk_paiement = c.id "; + $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + } + if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; + $sql.= " ORDER BY p.datep ASC, pf.fk_paiementfourn ASC"; + break; + } dol_syslog(get_class($this)."::write_file", LOG_DEBUG); $result = $this->db->query($sql); @@ -300,7 +356,14 @@ class pdf_paiement $default_font_size = pdf_getPDFFontSize($outputlangs); $title=$conf->global->MAIN_INFO_SOCIETE_NOM; - $title.=' - '.$outputlangs->transnoentities("ListOfCustomerPayments"); + switch($this->doc_type) { + case "client": + $title.=' - '.$outputlangs->transnoentities("ListOfCustomerPayments"); + break; + case "fourn": + $title.=' - '.$outputlangs->transnoentities("ListOfSupplierPayments"); + break; + } $title.=' - '.dol_print_date(dol_mktime(0,0,0,$this->month,1,$this->year),"%B %Y",false,$outputlangs,true); $pdf->SetFont('','B',$default_font_size + 1); $pdf->SetXY($this->marge_gauche,10); diff --git a/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php b/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php index 108b3bd6ce6..c7cb11ad31f 100644 --- a/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php @@ -23,12 +23,12 @@ */ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; - +require_once DOL_DOCUMENT_ROOT.'/core/modules/rapport/pdf_paiement.class.php'; /** * Classe permettant de generer les rapports de paiement */ -class pdf_paiement_fourn +class pdf_paiement_fourn extends pdf_paiement { /** * Constructor @@ -37,389 +37,10 @@ class pdf_paiement_fourn */ function __construct($db) { - global $langs,$conf; - $langs->load("bills"); - $langs->load("compta"); - - $this->db = $db; - $this->description = $langs->transnoentities("ListOfCustomerPayments"); - - // Dimension page pour format A4 - $this->type = 'pdf'; - $formatarray=pdf_getFormat(); - $this->page_largeur = $formatarray['width']; - $this->page_hauteur = $formatarray['height']; - $this->format = array($this->page_largeur,$this->page_hauteur); - $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10; - $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10; - $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10; - $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10; - - $this->tab_top = 30; - - $this->line_height = 5; - $this->line_per_page = 40; - $this->tab_height = $this->page_hauteur - $this->marge_haute - $this->marge_basse - $this->tab_top - 5; // must be > $this->line_height * $this->line_per_page and < $this->page_hauteur - $this->marge_haute - $this->marge_basse - $this->tab_top - 5; - - $this->posxdate=$this->marge_gauche+2; - $this->posxpaymenttype=42; - $this->posxinvoice=82; - $this->posxbankaccount=110; - $this->posxinvoiceamount=132; - $this->posxpaymentamount=162; - if ($this->page_largeur < 210) // To work with US executive format - { - $this->line_per_page = 35; - $this->posxpaymenttype-=10; - $this->posxinvoice-=0; - $this->posxinvoiceamount-=10; - $this->posxpaymentamount-=20; + parent::__construct($db); + $this->doc_type = "fourn"; } } - /** - * Fonction generant la rapport sur le disque - * - * @param string $_dir repertoire - * @param int $month mois du rapport - * @param int $year annee du rapport - * @param string $outputlangs Lang output object - * @return int <0 if KO, >0 if OK - */ - function write_file($_dir, $month, $year, $outputlangs) - { - include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; - - global $conf, $hookmanager, $langs, $user; - - $socid=0; - if ($user->societe_id) $socid=$user->societe_id; - - if (! is_object($outputlangs)) $outputlangs=$langs; - // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO - if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1'; - - $this->month=$month; - $this->year=$year; - - $dir=$_dir.'/'.$year; - - if (! is_dir($dir)) - { - $result=dol_mkdir($dir); - if ($result < 0) - { - $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); - return -1; - } - } - - $month = sprintf("%02d",$month); - $year = sprintf("%04d",$year); - $file = $dir . "/supplier_payments-".$year."-".$month.".pdf"; - - // Add pdfgeneration hook - if (! is_object($hookmanager)) - { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('pdfgeneration')); - $parameters=array('file'=>$file,'outputlangs'=>$outputlangs); - global $action; - $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks - - $pdf=pdf_getInstance($this->format); - $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance - - if (class_exists('TCPDF')) - { - $pdf->setPrintHeader(false); - $pdf->setPrintFooter(false); - } - $pdf->SetFont(pdf_getPDFFont($outputlangs)); - - $num=0; - $lines=array(); - - // count number of lines of payment - $sql = "SELECT p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p"; - $sql.= " WHERE p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; - $sql.= " AND p.entity = " . $conf->entity; - $result = $this->db->query($sql); - if ($result) - { - $numpaiement = $this->db->num_rows($result); - } - - // number of bill - $sql = "SELECT p.datep as dp, f.ref"; - //$sql .= ", c.libelle as paiement_type, p.num_paiement"; - $sql.= ", c.code as paiement_code, p.num_paiement"; - $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; - $sql.= ", pf.amount as pf_amount"; - if (! empty($conf->banque->enabled)) - $sql.= ", ba.ref as bankaccount"; - $sql.= ", p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p, ".MAIN_DB_PREFIX."facture_fourn as f,"; - $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf,"; - if (! empty($conf->banque->enabled)) - $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facturefourn = f.rowid AND pf.fk_paiementfourn = p.rowid"; - if (! empty($conf->banque->enabled)) - $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; - $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND p.fk_paiement = c.id "; - $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - } - if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; - $sql.= " ORDER BY p.datep ASC, pf.fk_paiementfourn ASC"; - - dol_syslog(get_class($this)."::write_file", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - $i = 0; - $var=True; - - while ($i < $num) - { - $objp = $this->db->fetch_object($result); - - - $lines[$i][0] = $objp->ref; - $lines[$i][1] = dol_print_date($this->db->jdate($objp->dp),"day",false,$outputlangs,true); - $lines[$i][2] = $langs->transnoentities("PaymentTypeShort".$objp->paiement_code); - $lines[$i][3] = $objp->num_paiement; - $lines[$i][4] = price($objp->paiement_amount); - $lines[$i][5] = price($objp->facture_amount); - $lines[$i][6] = price($objp->pf_amount); - $lines[$i][7] = $objp->prowid; - $lines[$i][8] = $objp->bankaccount; - $i++; - } - } - else - { - dol_print_error($this->db); - } - - $pages = intval(($num + $numpaiement) / $this->line_per_page); - - if ((($num + $numpaiement) % $this->line_per_page)>0) - { - $pages++; - } - - if ($pages == 0) - { - // force to build at least one page if report has no line - $pages = 1; - } - - $pdf->Open(); - $pagenb=0; - $pdf->SetDrawColor(128,128,128); - - $pdf->SetTitle($outputlangs->transnoentities("Payments")); - $pdf->SetSubject($outputlangs->transnoentities("Payments")); - $pdf->SetCreator("Dolibarr ".DOL_VERSION); - $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); - //$pdf->SetKeyWords(); - if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); - - $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right - $pdf->SetAutoPageBreak(1,0); - - // New page - $pdf->AddPage(); - $pagenb++; - $this->_pagehead($pdf, $pagenb, 1, $outputlangs); - $pdf->SetFont('','', 9); - $pdf->MultiCell(0, 3, ''); // Set interline to 3 - $pdf->SetTextColor(0,0,0); - - - $this->Body($pdf, 1, $lines, $outputlangs); - - if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages(); - - $pdf->Close(); - - $pdf->Output($file,'F'); - - // Add pdfgeneration hook - if (! is_object($hookmanager)) - { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('pdfgeneration')); - $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); - global $action; - $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - - if (! empty($conf->global->MAIN_UMASK)) - @chmod($file, octdec($conf->global->MAIN_UMASK)); - - $this->result = array('fullpath'=>$file); - - return 1; - } - - /** - * Show top header of page. - * - * @param PDF $pdf Object PDF - * @param int $page Object to show - * @param int $showaddress 0=no, 1=yes - * @param Translate $outputlangs Object lang for output - * @return void - */ - function _pagehead(&$pdf, $page, $showaddress, $outputlangs) - { - global $langs; - - // Do not add the BACKGROUND as this is a report - //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); - - $default_font_size = pdf_getPDFFontSize($outputlangs); - - $title=$conf->global->MAIN_INFO_SOCIETE_NOM; - $title.=' - '.$outputlangs->transnoentities("ListOfSupplierPayments"); - $title.=' - '.dol_print_date(dol_mktime(0,0,0,$this->month,1,$this->year),"%B %Y",false,$outputlangs,true); - $pdf->SetFont('','B',$default_font_size + 1); - $pdf->SetXY($this->marge_gauche,10); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->marge_gauche, 2, $title, 0, 'C'); - - $pdf->SetFont('','',$default_font_size); - - $pdf->SetXY($this->posxdate, 16); - $pdf->MultiCell(80, 2, $outputlangs->transnoentities("DateBuild")." : ".dol_print_date(time(),"day",false,$outputlangs,true), 0, 'L'); - - $pdf->SetXY($this->posxdate+100, 16); - $pdf->MultiCell(80, 2, $outputlangs->transnoentities("Page")." : ".$page, 0, 'R'); - - - // Title line - $pdf->SetXY($this->posxdate, $this->tab_top+2); - $pdf->MultiCell($this->posxpaymenttype - $this->posxdate, 2, 'Date'); - - $pdf->line($this->posxpaymenttype - 1, $this->tab_top, $this->posxpaymenttype - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxpaymenttype, $this->tab_top+2); - $pdf->MultiCell($this->posxinvoice - $this->posxpaymenttype, 2, $outputlangs->transnoentities("PaymentMode"), 0, 'L'); - - $pdf->line($this->posxinvoice - 1, $this->tab_top, $this->posxinvoice - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxinvoice, $this->tab_top+2); - $pdf->MultiCell($this->posxbankaccount - $this->posxinvoice, 2, $outputlangs->transnoentities("Invoice"), 0, 'L'); - - $pdf->line($this->posxbankaccount - 1, $this->tab_top, $this->posxbankaccount - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxbankaccount, $this->tab_top+2); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxbankaccount, 2, $outputlangs->transnoentities("Account"), 0, 'L'); - - - $pdf->line($this->posxinvoiceamount - 1, $this->tab_top, $this->posxinvoiceamount - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxinvoiceamount, $this->tab_top+2); - $pdf->MultiCell($this->posxpaymentamount - $this->posxinvoiceamount - 1, 2, $outputlangs->transnoentities("AmountInvoice"), 0, 'R'); - - $pdf->line($this->posxpaymentamount - 1, $this->tab_top, $this->posxpaymentamount - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxpaymentamount, $this->tab_top+2); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount - 1, 2, $outputlangs->transnoentities("AmountPayment"), 0, 'R'); - - $pdf->line($this->marge_gauche, $this->tab_top + 10, $this->page_largeur - $this->marge_droite, $this->tab_top + 10); - - $pdf->Rect($this->marge_gauche, $this->tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $this->tab_height + 10); - } - - - /** - * Output body - * - * @param PDF $pdf PDF object - * @param string $page Page - * @param array $lines Array of lines - * @param Translate $outputlangs Object langs - * @return void - */ - function Body(&$pdf, $page, $lines, $outputlangs) - { - $default_font_size = pdf_getPDFFontSize($outputlangs); - - $pdf->SetFont('','', $default_font_size - 1); - $oldprowid = 0; - $pdf->SetFillColor(220,220,220); - $yp = 0; - $numlines=count($lines); - for ($j = 0 ; $j < $numlines ; $j++) - { - $i = $j; - if ($yp > $this->tab_height -5) - { - $page++; - $pdf->AddPage(); - $this->_pagehead($pdf, $page, 0, $outputlangs); - $pdf->SetFont('','', $default_font_size - 1); - $yp = 0; - } - if ($oldprowid <> $lines[$j][7]) - { - if ($yp > $this->tab_height -10) - { - $page++; - $pdf->AddPage(); - $this->_pagehead($pdf, $page, 0, $outputlangs); - $pdf->SetFont('','', $default_font_size - 1); - $yp = 0; - } - - $pdf->SetXY($this->posxdate - 1, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxpaymenttype - $this->posxdate + 1, $this->line_height, $lines[$j][1], 0, 'L', 1); - - $pdf->SetXY($this->posxpaymenttype, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxpaymenttype, $this->line_height, $lines[$j][2].' '.$lines[$j][3], 0, 'L', 1); - - $pdf->SetXY($this->posxinvoiceamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxpaymentamount- $this->posxinvoiceamount, $this->line_height, '', 0, 'R', 1); - - $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $lines[$j][4], 0, 'R', 1); - $yp = $yp + 5; - } - - // Invoice number - $pdf->SetXY($this->posxinvoice, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxbankaccount, $this->line_height, $lines[$j][0], 0, 'L', 0); - - // BankAccount - $pdf->SetXY($this->posxbankaccount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxbankaccount - $this->posxdate, $this->line_height, $lines[$j][8], 0, 'L', 0); - - // Invoice amount - $pdf->SetXY($this->posxinvoiceamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxpaymentamount- $this->posxinvoiceamount - 1, $this->line_height, $lines[$j][5], 0, 'R', 0); - - // Payment amount - $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $lines[$j][6], 0, 'R', 0); - $yp = $yp + 5; - - if ($oldprowid <> $lines[$j][7]) - { - $oldprowid = $lines[$j][7]; - } - } - } -} - From cbe1683fe736557bd52be585b29016c790b4fe92 Mon Sep 17 00:00:00 2001 From: Papoteur Date: Tue, 26 Sep 2017 11:30:28 +0200 Subject: [PATCH 159/177] Invoice number on one line instead of two (issue#7487) --- htdocs/core/modules/rapport/pdf_paiement.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/rapport/pdf_paiement.class.php b/htdocs/core/modules/rapport/pdf_paiement.class.php index 606419e9a2a..6cd8e7aa655 100644 --- a/htdocs/core/modules/rapport/pdf_paiement.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement.class.php @@ -465,7 +465,7 @@ dol_syslog(get_class($this)."::write_file".$year." ".$month." ".$this->db->idate // Invoice number $pdf->SetXY($this->posxinvoice, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxbankaccount, $this->line_height, $lines[$j][0], 0, 'L', 0); + $pdf->MultiCell($this->posxinvoice - $this->posxbankaccount, $this->line_height, $lines[$j][0], 0, 'L', 0); // BankAccount $pdf->SetXY($this->posxbankaccount, $this->tab_top + 10 + $yp); From 49982b36accdd8c8c7491b5bd2cc2eb4a5a47733 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 11:55:19 +0200 Subject: [PATCH 160/177] FIX #7490 --- htdocs/compta/facture/list.php | 13 +++++---- htdocs/core/actions_massactions.inc.php | 29 ++++++++++--------- .../fourn/class/fournisseur.facture.class.php | 2 +- htdocs/fourn/facture/list.php | 23 +++++++-------- 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 3ffd0af9cd3..67ef9c96973 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -95,8 +95,10 @@ $month_lim = GETPOST('month_lim','int'); $year_lim = GETPOST('year_lim','int'); $option = GETPOST('option'); -if ($option == 'late') $filter = 'paye:0'; -$filtre = GETPOST('filtre'); +if ($option == 'late') { + $search_status = '1'; +} +$filtre = GETPOST('filtre','alpha'); $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); @@ -386,7 +388,7 @@ if ($search_user > 0) $sql.= ' WHERE f.fk_soc = s.rowid'; $sql.= ' AND f.entity IN ('.getEntity('facture').')'; if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; -if ($search_product_category > 0) $sql.=" AND cp.fk_categorie = ".$search_product_category; +if ($search_product_category > 0) $sql.=" AND cp.fk_categorie = ".$db->escape($search_product_category); if ($socid > 0) $sql.= ' AND s.rowid = '.$socid; if ($userid) { @@ -399,7 +401,7 @@ if ($filtre) foreach ($aFilter as $filter) { $filt = explode(':', $filter); - $sql .= ' AND ' . trim($filt[0]) . ' = ' . trim($filt[1]); + $sql .= ' AND ' . $db->escape(trim($filt[0])) . ' = ' . $db->escape(trim($filt[1])); } } if ($search_ref) $sql .= natural_search('f.facnumber', $search_ref); @@ -433,7 +435,7 @@ if ($search_status != '' && $search_status >= 0) if ($search_status == '2') $sql.=" AND f.fk_statut = 2"; // payed Not that some corrupted data may contains f.fk_statut = 1 AND f.paye = 1 (it means payed too but should not happend. If yes, reopen and reclassify billed) if ($search_status == '3') $sql.=" AND f.fk_statut = 3"; // abandonned } -if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$search_paymentmode; +if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$db->escape($search_paymentmode); if ($month > 0) { if ($year > 0 && empty($day)) @@ -461,7 +463,6 @@ else if ($year_lim > 0) $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_get_first_day($year_lim,1,false))."' AND '".$db->idate(dol_get_last_day($year_lim,12,false))."'"; } if ($option == 'late') $sql.=" AND f.date_lim_reglement < '".$db->idate(dol_now() - $conf->facture->client->warning_delay)."'"; -if ($filter == 'paye:0') $sql.= " AND f.fk_statut = 1"; if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$search_sale; if ($search_user > 0) { diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index d03fb5df214..6dc6fed25f1 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -463,22 +463,23 @@ if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_se $outputlangs->setDefaultLang($newlang); } - if(!empty($conf->global->USE_PDFTK_FOR_PDF_CONCAT)) { + if(!empty($conf->global->USE_PDFTK_FOR_PDF_CONCAT)) + { // Create output dir if not exists - dol_mkdir($diroutputmassaction); + dol_mkdir($diroutputmassaction); - // Defined name of merged file - $filename=strtolower(dol_sanitizeFileName($langs->transnoentities($objectlabel))); - $filename=preg_replace('/\s/','_',$filename); + // Defined name of merged file + $filename=strtolower(dol_sanitizeFileName($langs->transnoentities($objectlabel))); + $filename=preg_replace('/\s/','_',$filename); - // Save merged file - if ($filter=='paye:0') - { - if ($option=='late') $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))).'_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Late"))); - else $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))); - } - if ($year) $filename.='_'.$year; - if ($month) $filename.='_'.$month; + // Save merged file + if (in_array($object->element, array('facture', 'facture_fournisseur')) && $search_status == Facture::STATUS_VALIDATED) + { + if ($option=='late') $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))).'_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Late"))); + else $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))); + } + if ($year) $filename.='_'.$year; + if ($month) $filename.='_'.$month; if (count($files)>0) { @@ -546,7 +547,7 @@ if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_se $filename=preg_replace('/\s/','_',$filename); // Save merged file - if ($filter=='paye:0') + if (in_array($object->element, array('facture', 'facture_fournisseur')) && $search_status == Facture::STATUS_VALIDATED) { if ($option=='late') $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))).'_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Late"))); else $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))); diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 6e5e7fce66a..8b573679f82 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1799,7 +1799,7 @@ class FactureFournisseur extends CommonInvoice $response->warning_delay=$conf->facture->fournisseur->warning_delay/60/60/24; $response->label=$langs->trans("SupplierBillsToPay"); - $response->url=DOL_URL_ROOT.'/fourn/facture/list.php?filtre=fac.fk_statut:1,paye:0&mainmenu=accountancy&leftmenu=suppliers_bills'; + $response->url=DOL_URL_ROOT.'/fourn/facture/list.php?search_status=1&mainmenu=accountancy&leftmenu=suppliers_bills'; $response->img=img_object($langs->trans("Bills"),"bill"); $facturestatic = new FactureFournisseur($this->db); diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index e4b18202d7b..6d388540053 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -54,6 +54,7 @@ $massaction=GETPOST('massaction','alpha'); $show_files=GETPOST('show_files','int'); $confirm=GETPOST('confirm','alpha'); $toselect = GETPOST('toselect', 'array'); +$optioncss = GETPOST('optioncss','alpha'); $socid = GETPOST('socid','int'); @@ -67,6 +68,11 @@ if ($user->societe_id > 0) $mode=GETPOST("mode"); +$search_all = GETPOST('sall', 'alphanohtml'); +$search_label = GETPOST("search_label","alpha"); +$search_company = GETPOST("search_company","alpha"); +$search_amount_no_tax = GETPOST("search_amount_no_tax","alpha"); +$search_amount_all_tax = GETPOST("search_amount_all_tax","alpha"); $search_product_category=GETPOST('search_product_category','int'); $search_ref=GETPOST('sf_ref')?GETPOST('sf_ref','alpha'):GETPOST('search_ref','alpha'); $search_refsupplier=GETPOST('search_refsupplier','alpha'); @@ -93,20 +99,12 @@ $day_lim = GETPOST('day_lim','int'); $month_lim = GETPOST('month_lim','int'); $year_lim = GETPOST('year_lim','int'); $toselect = GETPOST('toselect', 'array'); -$filter = GETPOST('filtre','alpha'); $option = GETPOST('option'); if ($option == 'late') { - $filter = 'paye:0'; + $search_status = '1'; } - -$search_all = GETPOST('sall', 'alphanohtml'); -$search_label = GETPOST("search_label","alpha"); -$search_company = GETPOST("search_company","alpha"); -$search_amount_no_tax = GETPOST("search_amount_no_tax","alpha"); -$search_amount_all_tax = GETPOST("search_amount_all_tax","alpha"); -$search_status=GETPOST('search_status','alpha'); -$optioncss = GETPOST('optioncss','alpha'); +$filter = GETPOST('filtre','alpha'); $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); @@ -348,7 +346,6 @@ else if ($year_lim > 0) $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_get_first_day($year_lim,1,false))."' AND '".$db->idate(dol_get_last_day($year_lim,12,false))."'"; } if ($option == 'late') $sql.=" AND f.date_lim_reglement < '".$db->idate(dol_now() - $conf->facture->fournisseur->warning_delay)."'"; -if ($filter == 'paye:0') $sql.= " AND f.fk_statut = 1"; if ($search_label) $sql .= natural_search('f.libelle', $search_label); if ($search_status != '' && $search_status >= 0) { @@ -360,10 +357,10 @@ if ($filter && $filter != -1) foreach ($aFilter as $fil) { $filt = explode(':', $fil); - $sql .= ' AND ' . trim($filt[0]) . ' = ' . trim($filt[1]); + $sql .= ' AND ' . $db->escape(trim($filt[0])) . ' = ' . $db->escape(trim($filt[1])); } } -if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$search_sale; +if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$db->escape($search_sale); if ($search_user > 0) { $sql.= " AND ec.fk_c_type_contact = tc.rowid AND tc.element='invoice_supplier' AND tc.source='internal' AND ec.element_id = f.rowid AND ec.fk_socpeople = ".$search_user; From 50d639f1fa868be2f74b52edf39101076954e59e Mon Sep 17 00:00:00 2001 From: Papoteur Date: Tue, 26 Sep 2017 12:10:51 +0200 Subject: [PATCH 161/177] Add total and subtotal in payments reports --- .../core/modules/rapport/pdf_paiement.class.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/rapport/pdf_paiement.class.php b/htdocs/core/modules/rapport/pdf_paiement.class.php index 6cd8e7aa655..007057819f8 100644 --- a/htdocs/core/modules/rapport/pdf_paiement.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement.class.php @@ -42,6 +42,7 @@ class pdf_paiement global $langs,$conf; $langs->load("bills"); $langs->load("compta"); + $langs->load("main"); $this->db = $db; $this->description = $langs->transnoentities("ListOfCustomerPayments"); @@ -266,6 +267,7 @@ dol_syslog(get_class($this)."::write_file".$year." ".$month." ".$this->db->idate $lines[$i][6] = price($objp->pf_amount); $lines[$i][7] = $objp->prowid; $lines[$i][8] = $objp->bankaccount; + $lines[$i][9] = $objp->paiement_amount; $i++; } } @@ -420,10 +422,13 @@ dol_syslog(get_class($this)."::write_file".$year." ".$month." ".$this->db->idate */ function Body(&$pdf, $page, $lines, $outputlangs) { + global $langs; $default_font_size = pdf_getPDFFontSize($outputlangs); $pdf->SetFont('','', $default_font_size - 1); $oldprowid = 0; + $total_page = 0; + $total = 0; $pdf->SetFillColor(220,220,220); $yp = 0; $numlines=count($lines); @@ -440,13 +445,17 @@ dol_syslog(get_class($this)."::write_file".$year." ".$month." ".$this->db->idate } if ($oldprowid <> $lines[$j][7]) { - if ($yp > $this->tab_height -10) + if ($yp > $this->tab_height -15) { + $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); + $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $langs->transnoentities('SubTotal')." : ".price($total_page), 0, 'R', 0); $page++; $pdf->AddPage(); $this->_pagehead($pdf, $page, 0, $outputlangs); $pdf->SetFont('','', $default_font_size - 1); $yp = 0; + $total += $total_page; + $total_page = 0; } $pdf->SetXY($this->posxdate - 1, $this->tab_top + 10 + $yp); @@ -461,6 +470,7 @@ dol_syslog(get_class($this)."::write_file".$year." ".$month." ".$this->db->idate $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $lines[$j][4], 0, 'R', 1); $yp = $yp + 5; + $total_page += $lines[$j][9]; } // Invoice number @@ -485,6 +495,9 @@ dol_syslog(get_class($this)."::write_file".$year." ".$month." ".$this->db->idate $oldprowid = $lines[$j][7]; } } + $total += $total_page; + $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); + $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $langs->transnoentities('Total')." : ".price($total), 0, 'R', 0); } } From 76f1dbe16b6e748bfc4cd04a4502a66a48fdc5e0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 12:25:26 +0200 Subject: [PATCH 162/177] FIX #7288 --- htdocs/societe/class/societe.class.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 523ab31c8f9..b950b2f2c46 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1021,7 +1021,7 @@ class Societe extends CommonObject $sql = 'SELECT s.rowid, s.nom as name, s.name_alias, s.entity, s.ref_ext, s.ref_int, s.address, s.datec as date_creation, s.prefix_comm'; $sql .= ', s.status'; $sql .= ', s.price_level'; - $sql .= ', s.tms as date_modification'; + $sql .= ', s.tms as date_modification, s.fk_user_creat, s.fk_user_modif'; $sql .= ', s.phone, s.fax, s.email, s.skype, s.url, s.zip, s.town, s.note_private, s.note_public, s.model_pdf, s.client, s.fournisseur'; $sql .= ', s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6'; $sql .= ', s.capital, s.tva_intra'; @@ -1087,8 +1087,10 @@ class Societe extends CommonObject $this->ref_ext = $obj->ref_ext; $this->ref_int = $obj->ref_int; - $this->date_creation = $this->db->jdate($obj->date_creation); + $this->date_creation = $this->db->jdate($obj->date_creation); $this->date_modification = $this->db->jdate($obj->date_modification); + $this->user_creation = $obj->fk_user_creat; + $this->user_modification = $obj->fk_user_modif; $this->address = $obj->address; $this->zip = $obj->zip; From 74a2a4c257dd11948453d52b3f0b07dc2bdbb7e6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 12:34:18 +0200 Subject: [PATCH 163/177] Better translation --- htdocs/langs/en_US/admin.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 7d96aba7d8f..3c10edc86ca 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1400,7 +1400,7 @@ CompressionOfResources=Compression of HTTP responses CompressionOfResourcesDesc=For exemple using the Apache directive "AddOutputFilterByType DEFLATE" TestNotPossibleWithCurrentBrowsers=Such an automatic detection is not possible with current browsers DefaultValuesDesc=You can define/force here the default value you want to get when your create a new record, and/or defaut filters or sort order when your list record. -DefaultCreateForm=Default values for new objects +DefaultCreateForm=Default values for creation form DefaultSearchFilters=Default search filters DefaultSortOrder=Default sort orders DefaultFocus=Default focus fields From cc9954e95e1d1ddc830e141bf714f8f0c8a20e07 Mon Sep 17 00:00:00 2001 From: Papoteur Date: Tue, 26 Sep 2017 12:51:14 +0200 Subject: [PATCH 164/177] Clean debug messages --- htdocs/core/modules/rapport/pdf_paiement.class.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/htdocs/core/modules/rapport/pdf_paiement.class.php b/htdocs/core/modules/rapport/pdf_paiement.class.php index 007057819f8..35ffc399372 100644 --- a/htdocs/core/modules/rapport/pdf_paiement.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement.class.php @@ -108,7 +108,6 @@ class pdf_paiement $this->month=$month; $this->year=$year; -dol_syslog(get_class($this)."::write_file".$year." ".$month, LOG_DEBUG); $dir=$_dir.'/'.$year; if (! is_dir($dir)) @@ -158,10 +157,6 @@ dol_syslog(get_class($this)."::write_file".$year." ".$month, LOG_DEBUG); $lines=array(); // count number of lines of payment -dol_syslog(get_class($this)."::write_file".$year." ".$month." ".dol_get_first_day($year,$month), LOG_DEBUG); -dol_syslog(get_class($this)."::write_file".$year." ".$month." ".$this->db->idate(dol_get_first_day($year,$month)), LOG_DEBUG); -dol_syslog(get_class($this)."::write_file".$year." ".$month." ".dol_get_last_day($year,$month), LOG_DEBUG); -dol_syslog(get_class($this)."::write_file".$year." ".$month." ".$this->db->idate(dol_get_last_day($year,$month)), LOG_DEBUG); $sql = "SELECT p.rowid as prowid"; switch ($this->doc_type) { case "client": From e14087845883657bcf4e9469480d4c7ac9845fb0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 13:00:09 +0200 Subject: [PATCH 165/177] NEW Can import local tax rates in prices --- htdocs/core/modules/modProduct.class.php | 9 +++++++-- htdocs/langs/en_US/main.lang | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index f51e69039e9..79541c10105 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -260,10 +260,12 @@ class modProduct extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('p'=>MAIN_DB_PREFIX.'product','extra'=>MAIN_DB_PREFIX.'product_extrafields'); $this->import_tables_creator_array[$r]=array('p'=>'fk_user_author'); // Fields to store import user id - $this->import_fields_array[$r]=array('p.ref'=>"Ref*",'p.label'=>"Label*",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.weight'=>"Weight",'p.duration'=>"Duration",'p.customcode'=>'CustomCode','p.price'=>"SellingPriceHT",'p.price_ttc'=>"SellingPriceTTC",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell*",'p.tobuy'=>"OnBuy*",'p.fk_product_type'=>"Type*",'p.finished'=>'Nature','p.datec'=>'DateCreation'); + $this->import_fields_array[$r]=array('p.ref'=>"Ref*",'p.label'=>"Label*",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.weight'=>"Weight",'p.duration'=>"Duration",'p.customcode'=>'CustomCode','p.price'=>"SellingPriceHT",'p.price_ttc'=>"SellingPriceTTC", 'p.tva_tx'=>'VATRate', 'p.tosell'=>"OnSell*",'p.tobuy'=>"OnBuy*",'p.fk_product_type'=>"Type*",'p.finished'=>'Nature','p.datec'=>'DateCreation'); if (! empty($conf->stock->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.cost_price'=>'CostPrice')); if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.recuperableonly'=>'NPR')); + if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax1_tx'=>'LT1', 'p.localtax1_type'=>'LT1Type')); + if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax2_tx'=>'LT2', 'p.localtax2_type'=>'LT2Type')); if (! empty($conf->barcode->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.barcode'=>'BarCode')); if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->import_fields_array[$r]['p.fk_unit'] = 'Unit'; // Add extra fields @@ -300,9 +302,12 @@ class modProduct extends DolibarrModules $this->import_fields_array[$r]=array('sp.fk_product'=>"ProductOrService*", 'sp.fk_soc'=>"Supplier*", 'sp.ref_fourn'=>'SupplierRef', 'sp.quantity'=>"QtyMin*", 'sp.tva_tx'=>'VATRate', 'sp.price'=>"PriceQtyMinHT*", - 'sp.unitprice'=>'UnitPriceHT*', // TODO Make this file not required and calculate it from price and qty + 'sp.unitprice'=>'UnitPriceHT*', // TODO Make this field not required and calculate it from price and qty 'sp.remise_percent'=>'DiscountQtyMin' ); + if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.recuperableonly'=>'NPR')); + if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.localtax1_tx'=>'LT1', 'sp.localtax1_type'=>'LT1Type')); + if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.localtax2_tx'=>'LT2', 'sp.localtax2_type'=>'LT2Type')); $this->import_convertvalue_array[$r]=array( 'sp.fk_soc'=>array('rule'=>'fetchidfromref','classfile'=>'/societe/class/societe.class.php','class'=>'Societe','method'=>'fetch','element'=>'ThirdParty'), diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 93d2542ea69..93616b6151c 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -376,7 +376,9 @@ VATIN=IGST VATs=Sales taxes VATINs=IGST taxes LT1=Sales tax 2 +LT1Type=Sales tax 2 type LT2=Sales tax 3 +LT2Type=Sales tax 3 type LT1ES=RE LT2ES=IRPF LT1IN=CGST From d1bee67b40a1f1bcf2a56e0b47c7cb5636f590c6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 13:09:19 +0200 Subject: [PATCH 166/177] FIX #3991 --- htdocs/core/class/html.formmail.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 3e09c1a83e8..dab36ec250d 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -907,8 +907,8 @@ class FormMail extends Form /** - * Return templates of email with type = $type_template or type = 'all' - * This search into table c_email_templates. + * Return templates of email with type = $type_template or type = 'all'. + * This search into table c_email_templates. Used by the get_form function. * * @param DoliDB $db Database handler * @param string $type_template Get message for type=$type_template, type='all' also included. @@ -918,7 +918,7 @@ class FormMail extends Form * @param int $active 1=Only active template, 0=Only disabled, -1=All * @return array array('topic'=>,'content'=>,..) */ - private function getEMailTemplate($db, $type_template, $user, $outputlangs, $id=0, $active=1) + public function getEMailTemplate($db, $type_template, $user, $outputlangs, $id=0, $active=1) { $ret=array(); From 7b106bc6426872e2f39df651564a7d01432d042b Mon Sep 17 00:00:00 2001 From: dolibarr95 Date: Tue, 26 Sep 2017 14:13:11 +0200 Subject: [PATCH 167/177] Try to fix 7492 check if enough quantity --- htdocs/fourn/commande/card.php | 230 +++++++++++++++++---------------- 1 file changed, 119 insertions(+), 111 deletions(-) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index f121a9e371f..c955d7b98d3 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -560,123 +560,131 @@ if (empty($reshook)) $res = $line->fetch($lineid); if (!$res) dol_print_error($db); } + + if( $productsupplier->get_buyprice(0, price2num($_POST['qty']), $line->fk_product, 'none', GETPOST('socid','int')) < 0 ) + { + setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'errors'); + } + else + { - $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); - $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); + $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - // Define info_bits - $info_bits = 0; - if (preg_match('/\*/', $vat_rate)) - $info_bits |= 0x01; + // Define info_bits + $info_bits = 0; + if (preg_match('/\*/', $vat_rate)) + $info_bits |= 0x01; - // Define vat_rate - $vat_rate = str_replace('*', '', $vat_rate); - $localtax1_rate = get_localtax($vat_rate, 1, $mysoc, $object->thirdparty); - $localtax2_rate = get_localtax($vat_rate, 2, $mysoc, $object->thirdparty); + // Define vat_rate + $vat_rate = str_replace('*', '', $vat_rate); + $localtax1_rate = get_localtax($vat_rate, 1, $mysoc, $object->thirdparty); + $localtax2_rate = get_localtax($vat_rate, 2, $mysoc, $object->thirdparty); - if (GETPOST('price_ht') != '') - { - $price_base_type = 'HT'; - $ht = price2num(GETPOST('price_ht')); - } - else - { - $vatratecleaned = $vat_rate; - if (preg_match('/^(.*)\s*\((.*)\)$/', $vat_rate, $reg)) // If vat is "xx (yy)" - { - $vatratecleaned = trim($reg[1]); - $vatratecode = $reg[2]; - } - - $ttc = price2num(GETPOST('price_ttc')); - $ht = $ttc / (1 + ($vatratecleaned / 100)); - $price_base_type = 'HT'; - } - - $pu_ht_devise = GETPOST('multicurrency_subprice'); - - // Extrafields Lines - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline); - // Unset extrafield POST Data - if (is_array($extralabelsline)) { - foreach ($extralabelsline as $key => $value) { - unset($_POST["options_" . $key]); + if (GETPOST('price_ht') != '') + { + $price_base_type = 'HT'; + $ht = price2num(GETPOST('price_ht')); + } + else + { + $vatratecleaned = $vat_rate; + if (preg_match('/^(.*)\s*\((.*)\)$/', $vat_rate, $reg)) // If vat is "xx (yy)" + { + $vatratecleaned = trim($reg[1]); + $vatratecode = $reg[2]; } + + $ttc = price2num(GETPOST('price_ttc')); + $ht = $ttc / (1 + ($vatratecleaned / 100)); + $price_base_type = 'HT'; + } + + $pu_ht_devise = GETPOST('multicurrency_subprice'); + + // Extrafields Lines + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield POST Data + if (is_array($extralabelsline)) { + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + $result = $object->updateline( + $lineid, + $_POST['product_desc'], + $ht, + $_POST['qty'], + $_POST['remise_percent'], + $vat_rate, + $localtax1_rate, + $localtax2_rate, + $price_base_type, + 0, + isset($_POST["type"])?$_POST["type"]:$line->product_type, + false, + $date_start, + $date_end, + $array_options, + $_POST['units'], + $pu_ht_devise + ); + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['idprodfournprice']); + unset($_POST['remmise_percent']); + unset($_POST['dp_desc']); + unset($_POST['np_desc']); + unset($_POST['pu']); + unset($_POST['tva_tx']); + unset($_POST['date_start']); + unset($_POST['date_end']); + unset($_POST['units']); + unset($localtax1_tx); + unset($localtax2_tx); + + unset($_POST['date_starthour']); + unset($_POST['date_startmin']); + unset($_POST['date_startsec']); + unset($_POST['date_startday']); + unset($_POST['date_startmonth']); + unset($_POST['date_startyear']); + unset($_POST['date_endhour']); + unset($_POST['date_endmin']); + unset($_POST['date_endsec']); + unset($_POST['date_endday']); + unset($_POST['date_endmonth']); + unset($_POST['date_endyear']); + + if ($result >= 0) + { + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + + $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result < 0) dol_print_error($db,$result); + } + } + else + { + dol_print_error($db,$object->error); + exit; + } } - - $result = $object->updateline( - $lineid, - $_POST['product_desc'], - $ht, - $_POST['qty'], - $_POST['remise_percent'], - $vat_rate, - $localtax1_rate, - $localtax2_rate, - $price_base_type, - 0, - isset($_POST["type"])?$_POST["type"]:$line->product_type, - false, - $date_start, - $date_end, - $array_options, - $_POST['units'], - $pu_ht_devise - ); - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['idprodfournprice']); - unset($_POST['remmise_percent']); - unset($_POST['dp_desc']); - unset($_POST['np_desc']); - unset($_POST['pu']); - unset($_POST['tva_tx']); - unset($_POST['date_start']); - unset($_POST['date_end']); - unset($_POST['units']); - unset($localtax1_tx); - unset($localtax2_tx); - - unset($_POST['date_starthour']); - unset($_POST['date_startmin']); - unset($_POST['date_startsec']); - unset($_POST['date_startday']); - unset($_POST['date_startmonth']); - unset($_POST['date_startyear']); - unset($_POST['date_endhour']); - unset($_POST['date_endmin']); - unset($_POST['date_endsec']); - unset($_POST['date_endday']); - unset($_POST['date_endmonth']); - unset($_POST['date_endyear']); - - if ($result >= 0) - { - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model=$object->modelpdf; - $ret = $object->fetch($id); // Reload to get new records - - $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result < 0) dol_print_error($db,$result); - } - } - else - { - dol_print_error($db,$object->error); - exit; - } } // Remove a product line From eacb221ffea90cc6706983d608dc799d7515838f Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Tue, 26 Sep 2017 15:15:39 +0200 Subject: [PATCH 168/177] fix : add missing column into service's contract lines --- htdocs/contrat/services.php | 76 ++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/htdocs/contrat/services.php b/htdocs/contrat/services.php index aaf0d0cd796..2662f6f33f4 100644 --- a/htdocs/contrat/services.php +++ b/htdocs/contrat/services.php @@ -115,6 +115,11 @@ $companystatic=new Societe($db); $arrayfields=array( 'c.ref'=>array('label'=>$langs->trans("Contract"), 'checked'=>1, 'position'=>80), 'p.description'=>array('label'=>$langs->trans("Service"), 'checked'=>1, 'position'=>80), + 'cd.qty'=>array('label'=>$langs->trans("Qty"), 'checked'=>0, 'position'=>100), + 'cd.total_ht'=>array('label'=>$langs->trans("TotalHT"), 'checked'=>0, 'position'=>100), + 'cd.total_tva'=>array('label'=>$langs->trans("TotalVAT"), 'checked'=>0, 'position'=>100), + 'cd.tva_tx'=>array('label'=>$langs->trans("VAT"), 'checked'=>0, 'position'=>100), + 'cd.subprice'=>array('label'=>$langs->trans("PriceUHT"), 'checked'=>0, 'position'=>100), 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1, 'position'=>100), 'cd.date_ouverture_prevue'=>array('label'=>$langs->trans("DateStartPlannedShort"), 'checked'=>(($mode == "" || $mode == -1) || $mode == "0")), 'cd.date_ouverture'=>array('label'=>$langs->trans("DateStartRealShort"), 'checked'=>(($mode == "" || $mode == -1) || $mode > 0)), @@ -199,7 +204,11 @@ if (!$user->rights->societe->client->voir && !$socid) $sql .= " sc.fk_soc, sc.fk $sql.= " cd.date_ouverture_prevue,"; $sql.= " cd.date_ouverture,"; $sql.= " cd.date_fin_validite,"; -$sql.= " cd.date_cloture,"; +$sql.= " cd.qty,"; +$sql.= " cd.total_ht,"; +$sql.= " cd.total_tva,"; +$sql.= " cd.tva_tx,"; +$sql.= " cd.subprice,"; //$sql.= " cd.date_c as date_creation,"; $sql.= " cd.tms as date_update"; // Add fields from extrafields @@ -362,6 +371,11 @@ print '
' . $langs->trans("VATRate") . ''; + print '
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
'.$langs->trans("PriceLevel").''.$langs->trans("VATRate").''.$langs->trans("DefaultTaxRate").''.$langs->trans("SellingPrice").'' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '
' . $langs->trans("VATRate") . ''; + print '
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
' . $langs->trans("VATRate") . ''; + print '
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $prodcustprice->default_vat_code ? $prodcustprice->tva_tx.' ('.$prodcustprice->default_vat_code.')' : $prodcustprice->tva_tx, $mysoc, '', $object->id, $prodcustprice->recuperableonly, $object->type, false, 1); print '
' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("INCT") . '' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("INCT") . '
'; if (! empty($arrayfields['c.ref']['checked'])) print_liste_field_titre($arrayfields['c.ref']['label'],$_SERVER["PHP_SELF"],"c.ref","",$param,"",$sortfield,$sortorder); if (! empty($arrayfields['p.description']['checked'])) print_liste_field_titre($arrayfields['p.description']['label'],$_SERVER["PHP_SELF"],"p.description","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['cd.qty']['checked'])) print_liste_field_titre($arrayfields['cd.qty']['label'],$_SERVER["PHP_SELF"],"cd.qty","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.total_ht']['checked'])) print_liste_field_titre($arrayfields['cd.total_ht']['label'],$_SERVER["PHP_SELF"],"cd.total_ht","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.total_tva']['checked'])) print_liste_field_titre($arrayfields['cd.total_tva']['label'],$_SERVER["PHP_SELF"],"cd.total_tva","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.tva_tx']['checked'])) print_liste_field_titre($arrayfields['cd.tva_tx']['label'],$_SERVER["PHP_SELF"],"cd.tva_tx","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.subprice']['checked'])) print_liste_field_titre($arrayfields['cd.subprice']['label'],$_SERVER["PHP_SELF"],"cd.subprice","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); if (! empty($arrayfields['cd.date_ouverture_prevue']['checked'])) print_liste_field_titre($arrayfields['cd.date_ouverture_prevue']['label'],$_SERVER["PHP_SELF"],"cd.date_ouverture_prevue","",$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['cd.date_ouverture']['checked'])) print_liste_field_titre($arrayfields['cd.date_ouverture']['label'],$_SERVER["PHP_SELF"],"cd.date_ouverture","",$param,'align="center"',$sortfield,$sortorder); @@ -407,6 +421,32 @@ if (! empty($arrayfields['p.description']['checked'])) print ''; print ''; } +// detail lines +if (! empty($arrayfields['cd.qty']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.total_ht']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.total_tva']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.tva_tx']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.subprice']['checked'])) +{ + print ''; +} // Third party if (! empty($arrayfields['s.nom']['checked'])) { @@ -414,6 +454,8 @@ if (! empty($arrayfields['s.nom']['checked'])) print ''; print ''; } + + if (! empty($arrayfields['cd.date_ouverture_prevue']['checked'])) { print ''; } + if (! empty($arrayfields['cd.qty']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.total_ht']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.total_tva']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.tva_tx']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.subprice']['checked'])) + { + print ''; + } + + // Third party if (! empty($arrayfields['s.nom']['checked'])) { From 0dfbc8d72fa3be023ed3a4fd82b2b45939463ca6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 16:03:08 +0200 Subject: [PATCH 169/177] doxygen --- htdocs/core/modules/modApi.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/modApi.class.php b/htdocs/core/modules/modApi.class.php index fc1821fde53..34c8e62a03f 100644 --- a/htdocs/core/modules/modApi.class.php +++ b/htdocs/core/modules/modApi.class.php @@ -20,7 +20,7 @@ /** * \defgroup api Module Api * \brief Descriptor file for Api modulee - * \file htdocs/api/core/modules/modApi.class.php + * \file htdocs/core/modules/modApi.class.php * \ingroup api * \brief Description and activation file for module Api */ @@ -67,7 +67,7 @@ class modApi extends DolibarrModules // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module' $this->picto='technic'; - + $this->module_parts = array(); // Data directories to create when module is enabled. From d7dd6ed3344a79fa8ec10063f1d9f6f71404df1b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 16:07:46 +0200 Subject: [PATCH 170/177] Fix undefined var --- htdocs/core/class/html.formmail.class.php | 7 ++++--- htdocs/core/lib/functions.lib.php | 4 +++- htdocs/expedition/card.php | 2 +- htdocs/product/inventory/card.php | 2 +- htdocs/societe/card.php | 2 +- htdocs/user/card.php | 2 +- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index dab36ec250d..e1df1156239 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -329,6 +329,7 @@ class FormMail extends Form $out.= ''."\n"; } + $modelmail_array=array(); if ($this->param['models'] != 'none') { $result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs); @@ -336,7 +337,6 @@ class FormMail extends Form { setEventMessages($this->error, $this->errors, 'errors'); } - $modelmail_array=array(); foreach($this->lines_model as $line) { $langs->trans("members"); @@ -1076,11 +1076,11 @@ class FormMail extends Form * @return void * @see getCommonSubstitutionArray */ - function setSubstitFromObject($object, $outputlangs=null) + function setSubstitFromObject($object, $outputlangs) { global $conf, $user; - $parameters=array('mode'=>$mode); + $parameters=array(); $tmparray=getCommonSubstitutionArray($outputlangs, 0, null, $object); complete_substitutions_array($tmparray, $outputlangs, null, $parameters); @@ -1135,6 +1135,7 @@ class FormMail extends Form { global $conf, $langs; + $tmparray=array(); if ($mode == 'formemail' || $mode == 'formemailwithlines' || $mode == 'formemailforlines') { $parameters=array('mode'=>$mode); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c3c80a3c54a..ba8e9f4d085 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5280,10 +5280,12 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob // TODO USe this ? $msgishtml = 0; + $birthday = dol_print_date($object->birth,'day'); + if (method_exists($object, 'getCivilityLabel')) $substitutionarray['__MEMBER_CIVILITY__'] = $object->getCivilityLabel(); $substitutionarray['__MEMBER_FIRSTNAME__']=$msgishtml?dol_htmlentitiesbr($object->firstname):$object->firstname; $substitutionarray['__MEMBER_LASTNAME__']=$msgishtml?dol_htmlentitiesbr($object->lastname):$object->lastname; - if (method_exists($object, 'getFullName')) $substitutionarray['__MEMBER_FULLNAME__']=$msgishtml?dol_htmlentitiesbr($object->getFullName($langs)):$object->getFullName($langs); + if (method_exists($object, 'getFullName')) $substitutionarray['__MEMBER_FULLNAME__']=$msgishtml?dol_htmlentitiesbr($object->getFullName($outputlangs)):$object->getFullName($outputlangs); $substitutionarray['__MEMBER_COMPANY__']=$msgishtml?dol_htmlentitiesbr($object->societe):$object->societe; $substitutionarray['__MEMBER_ADDRESS__']=$msgishtml?dol_htmlentitiesbr($object->address):$object->address; $substitutionarray['__MEMBER_ZIP__']=$msgishtml?dol_htmlentitiesbr($object->zip):$object->zip; diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 17777e6e228..ef4bf2a9a70 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -2221,7 +2221,7 @@ else if ($id || $ref) $formmail->withdeliveryreceipt=1; $formmail->withcancel=1; // Tableau des substitutions - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object, $outputlangs); $formmail->substit['__SHIPPINGREF__']=$object->ref; $formmail->substit['__SHIPPINGTRACKNUM__']=$object->tracking_number; $formmail->substit['__SHIPPINGTRACKNUMURL__']=$object->tracking_url; diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index 7ef847855e5..dae399a9907 100644 --- a/htdocs/product/inventory/card.php +++ b/htdocs/product/inventory/card.php @@ -542,7 +542,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formmail->withdeliveryreceipt = 1; $formmail->withcancel = 1; // Tableau des substitutions - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object, $outputlangs); $formmail->substit ['__ORDERREF__'] = $object->ref; $custcontact = ''; diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 3b56046e55f..236faaaa232 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -2485,7 +2485,7 @@ else $formmail->withdeliveryreceipt=1; $formmail->withcancel=1; // Array of substitutions - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object, $outputlangs); $formmail->substit['__THIRDPARTY_ID__']=$object->id; // substit in setSubstitFromObject was wrong for this one $formmail->substit['__THIRDPARTY_NAME__']=$object->name; // substit in setSubstitFromObject was wrong for this one $formmail->substit['__PERSONALIZED__']=''; // deprecated diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 273c71d8e8c..40fa4db7a37 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -1760,7 +1760,7 @@ else $formmail->withdeliveryreceipt=1; $formmail->withcancel=1; // Tableau des substitutions - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object, $outputlangs); $formmail->substit['__LASTNAME__']=$object->lastname; $formmail->substit['__FIRSTNAME__']=$object->firstname; From 7d965f58d6d1d8eb24ba46b2e8c64f27b5c109da Mon Sep 17 00:00:00 2001 From: fappels Date: Tue, 26 Sep 2017 16:21:28 +0200 Subject: [PATCH 171/177] Clean code --- htdocs/fourn/commande/dispatch.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index f4f05f96b78..67b22c6767c 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -547,6 +547,9 @@ if ($id > 0 || ! empty($ref)) { print "\n"; print '' . "\n"; + // hidden fields for js function + print ''; + print ''; print ''; $linktoprod = '' . img_object($langs->trans("ShowProduct"), 'product') . ' ' . $objp->ref . ''; @@ -607,9 +610,6 @@ if ($id > 0 || ! empty($ref)) { print ''; } - // hidden fields for js function - print ''; - print ''; print ''; print ''; } // Qty to dispatch print ''; + print ''; print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; @@ -557,6 +599,38 @@ while ($i < min($num,$limit)) print ''; + print $obj->qty; + print ''; + print price($obj->total_ht); + print ''; + print price($obj->total_tva); + print ''; + print price2num($obj->tva_tx).'%'; + print ''; + print price($obj->subprice); + print '
'; @@ -649,16 +649,13 @@ if ($id > 0 || ! empty($ref)) { print ''; } - // hidden fields for js function - print ''; - print ''; print ''; print ''; - print ''; if (! empty($conf->productbatch->enabled) && $objp->tobatch == 1) { From ca6ad909e7cb9afe929618d728435e65155c0b51 Mon Sep 17 00:00:00 2001 From: fappels Date: Tue, 26 Sep 2017 16:23:00 +0200 Subject: [PATCH 172/177] remove deprecated file --- htdocs/core/js/lib_batch.js | 50 ------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 htdocs/core/js/lib_batch.js diff --git a/htdocs/core/js/lib_batch.js b/htdocs/core/js/lib_batch.js deleted file mode 100644 index 54ddb8fa77d..00000000000 --- a/htdocs/core/js/lib_batch.js +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2014 Cedric GROSS -// -// 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 . -// or see http://www.gnu.org/ - -// -// \file htdocs/core/js/lib_batch.js -// \brief File that include javascript functions used when dispatching batch-enabled product -// - -/** - * addLineBatch - * @deprecated replaced by addDispatchLine and moved to module folder and file fourn/js/lib_dispatch.js - * - * @param index int number of produt. 0 = first product line - */ -function addLineBatch(index) -{ - var nme = 'dluo_0_'+index; - $row=$("tr[name='"+nme+"']").clone(true); - $row.find("input[name^='qty']").val(''); - var trs = $("tr[name^='dluo_'][name$='_"+index+"']"); /* trs.length = position of line for batch */ - var newrow=$row.html().replace(/_0_/g,"_"+(trs.length)+"_"); - $row.html(newrow); - //clear value - $row.find("input[name^='qty']").val(''); - //change name of row - $row.attr('name','dluo_'+trs.length+'_'+index); - $("tr[name^='dluo_'][name$='_"+index+"']:last").after($row); - - /* Suffix of lines are: _ trs.length _ index */ - jQuery("#lot_number_"+trs.length+"_"+index).focus(); - nb = jQuery("#qty_"+(trs.length - 1)+"_"+index).val(); - if (nb > 0) - { - jQuery("#qty_"+(trs.length - 1)+"_"+index).val(1); - jQuery("#qty_"+trs.length+"_"+index).val(nb - 1); - } -} From 7178bf013271fcf374cb01c90b920a30a9bc0e7b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 16:56:33 +0200 Subject: [PATCH 173/177] Work on direct external link for dolibarr objects --- htdocs/compta/facture/class/facture.class.php | 11 +++++++++-- htdocs/document.php | 2 +- .../modulebuilder/template/class/myobject.class.php | 11 +++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index b6d294c6e18..b7603400c61 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1059,13 +1059,20 @@ class Facture extends CommonInvoice */ function getDirectExternalLink($withpicto=0) { + global $dolibarr_main_url_root; + // Define $urlwithroot $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - $url='eee'; - return ''.$this->ref.''; + // TODO Read into ecmfile table to get entry and hash exists (PS: If not found, add it) + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($this->db); + //$result = $ecmfile->get(); + + $hashp='todo'; + return ''.$this->ref.''; } /** diff --git a/htdocs/document.php b/htdocs/document.php index 11017f52cc2..0b2db2323cd 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -25,7 +25,7 @@ * \file htdocs/document.php * \brief Wrapper to download data files * \remarks Call of this wrapper is made with URL: - * document.php?modulepart=repfichierconcerne&file=pathrelatifdufichier + * document.php?modulepart=repfichierconcerne&file=relativepathoffile * document.php?modulepart=logs&file=dolibarr.log */ diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 259db698024..4a5f349215b 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -324,6 +324,17 @@ class MyObject extends CommonObject return $result; } + /** + * Return link to download file from a direct external access + * + * @param int $withpicto Add download picto into link + * @return string HTML link to file + */ + function getDirectExternalLink($withpicto=0) + { + return 'todo'; + } + /** * Retourne le libelle du status d'un user (actif, inactif) * From 15c8515d5356ec3ca41481a0c55b033124f4d2a6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 19:08:04 +0200 Subject: [PATCH 174/177] Fix default --- htdocs/install/mysql/migration/3.0.0-3.1.0.sql | 2 +- htdocs/install/mysql/tables/llx_societe.sql | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/install/mysql/migration/3.0.0-3.1.0.sql b/htdocs/install/mysql/migration/3.0.0-3.1.0.sql index fa94a5deeed..a4ab666299d 100644 --- a/htdocs/install/mysql/migration/3.0.0-3.1.0.sql +++ b/htdocs/install/mysql/migration/3.0.0-3.1.0.sql @@ -63,7 +63,7 @@ ALTER TABLE llx_facturedet ADD UNIQUE INDEX uk_fk_remise_except (fk_remise_excep ALTER TABLE llx_societe ADD COLUMN fk_currency integer DEFAULT 0 AFTER fk_forme_juridique; ALTER TABLE llx_societe ADD COLUMN status tinyint DEFAULT 1; -ALTER TABLE llx_societe ADD COLUMN logo varchar(255); +ALTER TABLE llx_societe ADD COLUMN logo varchar(255) DEFAULT NULL; ALTER TABLE llx_societe_remise MODIFY remise_client double(6,3) DEFAULT 0 NOT NULL; diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index 20440b692d7..0f0cb437750 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -95,13 +95,13 @@ create table llx_societe barcode varchar(255), -- barcode fk_barcode_type integer NULL DEFAULT 0, -- barcode type price_level integer NULL, -- level of price for multiprices - outstanding_limit double(24,8) DEFAULT NULL, -- allowed outstanding limit + outstanding_limit double(24,8) DEFAULT NULL, -- allowed outstanding limit default_lang varchar(6), -- default language - logo varchar(255), - canvas varchar(32), -- type of canvas if used (null by default) + logo varchar(255) DEFAULT NULL, + canvas varchar(32) DEFAULT NULL, -- type of canvas if used (null by default) import_key varchar(14), -- import key - webservices_url varchar(255), -- supplier webservice url - webservices_key varchar(128), -- supplier webservice key + webservices_url varchar(255), -- supplier webservice url + webservices_key varchar(128), -- supplier webservice key fk_multicurrency integer, multicurrency_code varchar(255) From 938989d2e4fcb18445afd18cbfa5a46eefdeca72 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 20:31:39 +0200 Subject: [PATCH 175/177] Update doc --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 7823d4cefb1..d75938891f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ Following changes may create regressions for some external modules, but were nec * The methode "cloture" on contact were renamed into "closeAll". * The substitution key for reference of object is now __REF__ whatever is the object (it replaces __ORDERREF__, __PROPALREF__, ...) +* Some REST API to access the dictionary (country, town, ...) were moved into a common API. ***** ChangeLog for 6.0.1 compared to 6.0.* ***** From 7cf1a418537d5f5c0dc01d866f1b634a9f7f41c0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 20:57:09 +0200 Subject: [PATCH 176/177] Try to replace error into warning, so we can still make the order if qty too low --- htdocs/fourn/commande/card.php | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index c955d7b98d3..a7568f446ca 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -555,18 +555,16 @@ if (empty($reshook)) $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); if ($lineid) - { - $line = new CommandeFournisseurLigne($db); - $res = $line->fetch($lineid); - if (!$res) dol_print_error($db); - } + { + $line = new CommandeFournisseurLigne($db); + $res = $line->fetch($lineid); + if (!$res) dol_print_error($db); + } - if( $productsupplier->get_buyprice(0, price2num($_POST['qty']), $line->fk_product, 'none', GETPOST('socid','int')) < 0 ) - { - setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'errors'); - } - else - { + if ($productsupplier->get_buyprice(0, price2num($_POST['qty']), $line->fk_product, 'none', GETPOST('socid','int')) < 0 ) + { + setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'warnings'); + } $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); @@ -684,7 +682,7 @@ if (empty($reshook)) dol_print_error($db,$object->error); exit; } - } + } // Remove a product line From 04f4a81736385d61ca91300898c545b967fe4eb9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Sep 2017 22:06:59 +0200 Subject: [PATCH 177/177] FIX #7505 --- htdocs/fichinter/card.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index fc634bed9ff..297e6097fe2 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -1685,18 +1685,11 @@ else if ($id > 0 || ! empty($ref)) * Built documents */ $filename=dol_sanitizeFileName($object->ref); - $filedir=$conf->ficheinter->dir_output . "/".$object->ref; + $filedir=$conf->ficheinter->dir_output . "/".$filename; $urlsource=$_SERVER["PHP_SELF"]."?id=".$object->id; $genallowed=$user->rights->ficheinter->creer; $delallowed=$user->rights->ficheinter->supprimer; - $genallowed=1; - $delallowed=1; - - $var=true; - - //print "
\n"; - print $somethingshown=$formfile->showdocuments('ficheinter',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); - + print $formfile->showdocuments('ficheinter',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, array('fichinter'));