From 4c3f9d6d5e1b5f86cfbe2cf2016e626b6387f580 Mon Sep 17 00:00:00 2001 From: gauthier Date: Fri, 18 May 2018 15:20:16 +0200 Subject: [PATCH 01/72] FIX : test is_erasable() must be done before call function delete() too to avoid delete invoice with &action=delete in url --- htdocs/compta/facture/card.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index d79b8d0bae5..9d5cc64c2a4 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -186,13 +186,17 @@ if (empty($reshook)) $qualified_for_stock_change = $object->hasProductsOrServices(1); } - $result = $object->delete($user, 0, $idwarehouse); - if ($result > 0) { - header('Location: ' . DOL_URL_ROOT . '/compta/facture/list.php'); - exit(); - } else { - setEventMessages($object->error, $object->errors, 'errors'); - $action=''; + if($object->is_erasable()) { + + $result = $object->delete($user, 0, $idwarehouse); + if ($result > 0) { + header('Location: ' . DOL_URL_ROOT . '/compta/facture/list.php'); + exit(); + } else { + setEventMessages($object->error, $object->errors, 'errors'); + $action=''; + } + } } From c9222adf6d0cc70bd562324d3f1486c9472bb3d9 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio Date: Mon, 21 May 2018 16:22:06 +0200 Subject: [PATCH 02/72] FIX: shipment: fk_proje(c)t not handled in fetch() and update() methods --- htdocs/expedition/class/expedition.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index bccfba4446d..0c4232fabee 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -481,7 +481,7 @@ class Expedition extends CommonObject // Check parameters if (empty($id) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1; - $sql = "SELECT e.rowid, e.ref, e.fk_soc as socid, e.date_creation, e.ref_customer, e.ref_ext, e.ref_int, e.fk_user_author, e.fk_statut"; + $sql = "SELECT e.rowid, e.ref, e.fk_soc as socid, e.date_creation, e.ref_customer, e.ref_ext, e.ref_int, e.fk_user_author, e.fk_statut, e.fk_projet"; $sql.= ", e.weight, e.weight_units, e.size, e.size_units, e.width, e.height"; $sql.= ", e.date_expedition as date_expedition, e.model_pdf, e.fk_address, e.date_delivery"; $sql.= ", e.fk_shipping_method, e.tracking_number"; @@ -513,6 +513,7 @@ class Expedition extends CommonObject $this->ref_ext = $obj->ref_ext; $this->ref_int = $obj->ref_int; $this->statut = $obj->fk_statut; + $this->fk_project = $obj->fk_projet; $this->user_author_id = $obj->fk_user_author; $this->date_creation = $this->db->jdate($obj->date_creation); $this->date = $this->db->jdate($obj->date_expedition); // TODO deprecated @@ -1052,6 +1053,7 @@ class Expedition extends CommonObject $sql.= " fk_shipping_method=".((isset($this->shipping_method_id) && $this->shipping_method_id > 0)?$this->shipping_method_id:"null").","; $sql.= " tracking_number=".(isset($this->tracking_number)?"'".$this->db->escape($this->tracking_number)."'":"null").","; $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").","; + $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").","; $sql.= " height=".(($this->trueHeight != '')?$this->trueHeight:"null").","; $sql.= " width=".(($this->trueWidth != '')?$this->trueWidth:"null").","; $sql.= " size_units=".(isset($this->size_units)?$this->size_units:"null").","; From be21405d219d04cd286c653f7490b9d1d1a89a1e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 22 May 2018 19:24:56 +0200 Subject: [PATCH 03/72] Fix missing error message --- htdocs/societe/card.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 204eff383d5..d0aa719e08c 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -296,7 +296,7 @@ if (empty($reshook)) if (! $error) { $result = $object->insertExtraFields(); - if ($result < 0) + if ($result < 0) { $error++; $errors = $object->errors; @@ -524,8 +524,8 @@ if (empty($reshook)) $error=$object->error; $errors=$object->errors; } } - - + + // Customer categories association $custcats = GETPOST( 'custcats', 'array' ); $object->setCategories($custcats, 'customer'); @@ -533,7 +533,7 @@ if (empty($reshook)) // Supplier categories association $suppcats = GETPOST('suppcats', 'array'); $object->setCategories($suppcats, 'supplier'); - + // Logo/Photo save $dir = $conf->societe->multidir_output[$conf->entity]."/".$object->id."/logos/"; $file_OK = is_uploaded_file($_FILES['photo']['tmp_name']); @@ -638,10 +638,13 @@ if (empty($reshook)) $result = $object->update($socid, $user, 1, $object->oldcopy->codeclient_modifiable(), $object->oldcopy->codefournisseur_modifiable(), 'update', 0); if ($result <= 0) { - $error = $object->error; $errors = $object->errors; + $error++; + $errors = $object->errors; + setEventMessages($object->error, $object->errors, 'errors'); } + // Prevent thirdparty's emptying if a user hasn't rights $user->rights->categorie->lire (in such a case, post of 'custcats' is not defined) - if(!empty($user->rights->categorie->lire)){ + if(!empty($user->rights->categorie->lire)){ // Customer categories association $categories = GETPOST( 'custcats', 'array' ); $object->setCategories($categories, 'customer'); @@ -718,6 +721,7 @@ if (empty($reshook)) { $error++; $object->error .= $object->db->lasterror(); + setEventMessages($object->error, $object->errors, 'errors'); } } From 734ecbc9b5051aff233f73cdc8910e94a791dc6b Mon Sep 17 00:00:00 2001 From: ATM-Nicolas Date: Wed, 23 May 2018 09:47:29 +0200 Subject: [PATCH 04/72] FIX : Fetch shipping will now fetch project id --- htdocs/expedition/class/expedition.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index bccfba4446d..fa16f7f6ae5 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -487,7 +487,7 @@ class Expedition extends CommonObject $sql.= ", e.fk_shipping_method, e.tracking_number"; $sql.= ", el.fk_source as origin_id, el.sourcetype as origin"; $sql.= ", e.note_private, e.note_public"; - $sql.= ', e.fk_incoterms, e.location_incoterms'; + $sql.= ', e.fk_incoterms, e.location_incoterms, e.fk_projet'; $sql.= ', i.libelle as libelle_incoterms'; $sql.= " FROM ".MAIN_DB_PREFIX."expedition as e"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->db->escape($this->element)."'"; @@ -526,6 +526,7 @@ class Expedition extends CommonObject $this->origin = ($obj->origin?$obj->origin:'commande'); // For compatibility $this->origin_id = $obj->origin_id; $this->billed = ($obj->fk_statut==2?1:0); + $this->fk_project = $obj->fk_projet; $this->trueWeight = $obj->weight; $this->weight_units = $obj->weight_units; From eb224e43a5d67d3656f547da822704e802a04b4d Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Thu, 24 May 2018 10:41:24 +0200 Subject: [PATCH 05/72] FIX missing filters during ordering --- htdocs/comm/propal/list.php | 1 + htdocs/commande/list.php | 7 +++++++ htdocs/compta/facture/list.php | 3 +++ htdocs/expedition/list.php | 6 ++++++ 4 files changed, 17 insertions(+) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 480ad7f4fda..72491e90e3e 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -384,6 +384,7 @@ if ($resql) if ($search_zip) $param.='&search_zip='.urlencode($search_zip); if ($socid > 0) $param.='&socid='.urlencode($socid); if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss); + if ($search_product_category != '') $param.='&search_product_category='.$search_product_category; // Add $param from extra fields foreach ($search_array_options as $key => $val) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 86a5f463840..6284e53aa5c 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -627,6 +627,13 @@ if ($resql) if ($show_files) $param.='&show_files=' .$show_files; if ($optioncss != '') $param.='&optioncss='.$optioncss; if ($billed != '') $param.='&billed='.$billed; + if ($search_town != '')$param .= '&search_town='.$search_town; + if ($search_zip != '')$param .= '&search_zip='.$search_zip; + if ($search_state != '')$param .= '&search_state='.$search_state; + if ($search_country != '')$param .= '&search_country='.$search_country; + if ($search_type_thirdparty != '')$param .= '&search_type_thirdparty='.$search_type_thirdparty; + if ($search_product_category != '')$param .= '&search_product_category='.$search_product_category; + // Add $param from extra fields foreach ($search_array_options as $key => $val) { diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index d7f9384399f..994f1d93569 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -563,6 +563,9 @@ if ($resql) if ($show_files) $param.='&show_files=' .$show_files; if ($option) $param.="&option=".$option; if ($optioncss != '') $param.='&optioncss='.$optioncss; + if ($search_town)$param .= '&search_town='.urlencode($search_town); + if ($search_zip)$param .= '&search_zip='.urlencode($search_zip); + // Add $param from extra fields foreach ($search_array_options as $key => $val) { diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 1a712b66650..819d4337788 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -51,6 +51,7 @@ $search_type_thirdparty=GETPOST("search_type_thirdparty",'int'); $search_billed=GETPOST("search_billed",'int'); $sall = GETPOST('sall', 'alphanohtml'); $optioncss = GETPOST('optioncss','alpha'); +$search_ref_customer=GETPOST("search_ref_customer"); $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST('sortfield','alpha'); @@ -141,6 +142,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x', $search_billed=''; $viewstatut=''; $search_array_options=array(); + $search_ref_customer=''; } if (empty($reshook)) @@ -267,6 +269,10 @@ if ($resql) if ($search_ref_liv) $param.= "&search_ref_liv=".$search_ref_liv; if ($search_company) $param.= "&search_company=".$search_company; if ($optioncss != '') $param.='&optioncss='.$optioncss; + if ($search_town)$param .= '&search_town='.urlencode($search_town); + if ($search_zip)$param .= '&search_zip='.urlencode($search_zip); + if ($search_ref_customer)$param .= '&search_ref_customer='.$search_ref_customer; + if ($viewstatut != '')$param .= '&viewstatut='.$viewstatut; // Add $param from extra fields foreach ($search_array_options as $key => $val) { From 0a581e48d47cb8c0a5aa565006beae35a753b4a3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 25 May 2018 11:04:04 +0200 Subject: [PATCH 06/72] Update card.php --- htdocs/compta/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 9d5cc64c2a4..06330de7682 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -186,7 +186,7 @@ if (empty($reshook)) $qualified_for_stock_change = $object->hasProductsOrServices(1); } - if($object->is_erasable()) { + if ($object->is_erasable()) { $result = $object->delete($user, 0, $idwarehouse); if ($result > 0) { From 6b0b975ffda214f73c65a5679c2730025e2400b5 Mon Sep 17 00:00:00 2001 From: ATM-Nicolas Date: Tue, 29 May 2018 10:50:20 +0200 Subject: [PATCH 07/72] FIX : Keep supplier proposal price for supplier order --- htdocs/fourn/class/fournisseur.commande.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 4eccc21cd93..3edb70b1ed6 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1430,7 +1430,7 @@ class CommandeFournisseur extends CommonOrder // We use 'none' instead of $fourn_ref, because fourn_ref may not exists anymore. So we will take the first supplier price ok. // If we want a dedicated supplier price, we must provide $fk_prod_fourn_price. $result=$prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', ($this->fk_soc?$this->fk_soc:$this->socid)); // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$fourn_ref/$this->fk_soc - if ($result > 0) + if ($result > 0 && $origin !== 'supplier_proposal') { $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice $ref_supplier = $prod->ref_supplier; // Ref supplier price set by get_buyprice From 95e3c5a4b15b4e3c646100f59a896ba0aa76956b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 29 May 2018 12:13:58 +0200 Subject: [PATCH 08/72] Backport fix of file list check generation --- build/generate_filelist_xml.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/build/generate_filelist_xml.php b/build/generate_filelist_xml.php index e6336e30e97..5f54c95d7e0 100755 --- a/build/generate_filelist_xml.php +++ b/build/generate_filelist_xml.php @@ -17,7 +17,7 @@ */ /** - * \file build/generate_filecheck_xml.php + * \file build/generate_filelist_xml.php * \ingroup dev * \brief This script create a xml checksum file */ @@ -45,7 +45,7 @@ $includeconstants=array(); if (empty($argv[1])) { - print "Usage: ".$script_file." release=x.y.z[-...] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n"; + print "Usage: ".$script_file." release=auto|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n"; print "Example: ".$script_file." release=6.0.0 includecustom=1 includeconstant=FR:INVOICE_CAN_ALWAYS_BE_REMOVED:0 includeconstant=all:MAILING_NO_USING_PHPMAIL:1\n"; exit -1; } @@ -68,11 +68,20 @@ while ($i < $argc) $i++; } +// If release is auto, we take current version +$tmpver=explode('-', $release, 2); +if ($tmpver[0] == 'auto') +{ + $release=DOL_VERSION; + if ($tmpver[1]) $release.='-'.$tmpver[1]; +} + if (empty($includecustom)) { - if (DOL_VERSION != $release) + $tmpver=explode('-', $release, 2); + if (DOL_VERSION != $tmpver[0]) { - print 'Error: When parameter "includecustom" is not set, version declared into filefunc.in.php ('.DOL_VERSION.') must be exact same value than "release" parameter ('.$release.')'."\n"; + print 'Error: When parameter "includecustom" is not set and there is no suffix in release parameter, version declared into filefunc.in.php ('.DOL_VERSION.') must be exact same value than "release" parameter ('.$tmpver[0].')'."\n"; print "Usage: ".$script_file." release=x.y.z[-...] [includecustom=1]\n"; exit -1; } From 2e2cc553505f51ae86a4965a5428691005553476 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 29 May 2018 12:15:28 +0200 Subject: [PATCH 09/72] Backport fix of file checker generation --- build/generate_filelist_xml.php | 137 +++++++++++++++++++++++++------- 1 file changed, 109 insertions(+), 28 deletions(-) diff --git a/build/generate_filelist_xml.php b/build/generate_filelist_xml.php index b227b544bab..5f54c95d7e0 100755 --- a/build/generate_filelist_xml.php +++ b/build/generate_filelist_xml.php @@ -1,6 +1,6 @@ #!/usr/bin/env php +/* Copyright (C) 2015-2017 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 @@ -17,7 +17,7 @@ */ /** - * \file build/generate_filecheck_xml.php + * \file build/generate_filelist_xml.php * \ingroup dev * \brief This script create a xml checksum file */ @@ -40,55 +40,128 @@ require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); * Main */ +$includecustom=0; +$includeconstants=array(); + if (empty($argv[1])) { - print "Usage: ".$script_file." release=x.y.z\n"; + print "Usage: ".$script_file." release=auto|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n"; + print "Example: ".$script_file." release=6.0.0 includecustom=1 includeconstant=FR:INVOICE_CAN_ALWAYS_BE_REMOVED:0 includeconstant=all:MAILING_NO_USING_PHPMAIL:1\n"; exit -1; } parse_str($argv[1]); -if ($release != DOL_VERSION) +$i=0; +while ($i < $argc) { - print 'Error: release is not version declared into filefunc.in.php.'."\n"; - exit -1; + if (! empty($argv[$i])) parse_str($argv[$i]); + if (preg_match('/includeconstant=/',$argv[$i])) + { + $tmp=explode(':', $includeconstant, 3); + if (count($tmp) != 3) + { + print "Error: Bad parameter includeconstant ".$includeconstant."\n"; + exit -1; + } + $includeconstants[$tmp[0]][$tmp[1]] = $tmp[2]; + } + $i++; } +// If release is auto, we take current version +$tmpver=explode('-', $release, 2); +if ($tmpver[0] == 'auto') +{ + $release=DOL_VERSION; + if ($tmpver[1]) $release.='-'.$tmpver[1]; +} + +if (empty($includecustom)) +{ + $tmpver=explode('-', $release, 2); + if (DOL_VERSION != $tmpver[0]) + { + print 'Error: When parameter "includecustom" is not set and there is no suffix in release parameter, version declared into filefunc.in.php ('.DOL_VERSION.') must be exact same value than "release" parameter ('.$tmpver[0].')'."\n"; + print "Usage: ".$script_file." release=x.y.z[-...] [includecustom=1]\n"; + exit -1; + } +} +else +{ + if (! preg_match('/'.preg_quote(DOL_VERSION,'/').'-/',$release)) + { + print 'Error: When parameter "includecustom" is set, version declared into filefunc.inc.php ('.DOL_VERSION.') must be used with a suffix into "release" parmater (ex: '.DOL_VERSION.'-mydistrib).'."\n"; + print "Usage: ".$script_file." release=x.y.z[-...] [includecustom=1]\n"; + exit -1; + } +} + +print "Release : ".$release."\n"; +print "Include custom in signature : ".$includecustom."\n"; +print "Include constants in signature : "; +foreach ($includeconstants as $countrycode => $tmp) +{ + foreach($tmp as $constname => $constvalue) + { + print $constname.'='.$constvalue." "; + } +} +print "\n"; + //$outputfile=dirname(__FILE__).'/../htdocs/install/filelist-'.$release.'.xml'; $outputdir=dirname(dirname(__FILE__)).'/htdocs/install'; print 'Delete current files '.$outputdir.'/filelist*.xml'."\n"; dol_delete_file($outputdir.'/filelist*.xml',0,1,1); +$checksumconcat=array(); + $outputfile=$outputdir.'/filelist-'.$release.'.xml'; $fp = fopen($outputfile,'w'); fputs($fp, ''."\n"); -fputs($fp, ''."\n"); +fputs($fp, ''."\n"); -fputs($fp, ''."\n"); +foreach ($includeconstants as $countrycode => $tmp) +{ + fputs($fp, ''."\n"); + foreach($tmp as $constname => $constvalue) + { + $valueforchecksum=(empty($constvalue)?'0':$constvalue); + $checksumconcat[]=$valueforchecksum; + fputs($fp, ' '.$valueforchecksum.''."\n"); + } + fputs($fp, ''."\n"); +} -$checksumconcat=array(); +fputs($fp, ''."\n"); -$dir_iterator1 = new RecursiveDirectoryIterator(dirname(__FILE__).'/../htdocs/'); +/*$dir_iterator1 = new RecursiveDirectoryIterator(dirname(__FILE__).'/../htdocs/'); $iterator1 = new RecursiveIteratorIterator($dir_iterator1); -// need to ignore document custom etc -$files = new RegexIterator($iterator1, '#^(?:[A-Z]:)?(?:/(?!(?:custom|documents|conf|install|nltechno))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i'); +// Need to ignore document custom etc. Note: this also ignore natively symbolic links. +$files = new RegexIterator($iterator1, '#^(?:[A-Z]:)?(?:/(?!(?:'.($includecustom?'':'custom\/|').'documents\/|conf\/|install\/))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i'); +*/ +$regextoinclude='\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$'; +$regextoexclude='('.($includecustom?'':'custom|').'documents|conf|install|public\/test|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs +$files = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude, 'fullname'); $dir=''; $needtoclose=0; -foreach ($files as $file) { - $newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file)); - if ($newdir!=$dir) { +foreach ($files as $filetmp) { + $file = $filetmp['fullname']; + //$newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file)); + $newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file)); + if ($newdir!=$dir) { if ($needtoclose) - fputs($fp, ''."\n"); - fputs($fp, ''."\n"); + fputs($fp, ' '."\n"); + fputs($fp, ' '."\n"); $dir = $newdir; $needtoclose=1; } if (filetype($file)=="file") { $md5=md5_file($file); $checksumconcat[]=$md5; - fputs($fp, ''.$md5.''."\n"); + fputs($fp, ' '.$md5.''."\n"); } } -fputs($fp, ''."\n"); +fputs($fp, ' '."\n"); fputs($fp, ''."\n"); asort($checksumconcat); // Sort list of checksum @@ -102,28 +175,36 @@ $checksumconcat=array(); fputs($fp, ''."\n"); -$dir_iterator2 = new RecursiveDirectoryIterator(dirname(__FILE__).'/../scripts/'); +// TODO Replace RecursiveDirectoryIterator with dol_dir_list +/*$dir_iterator2 = new RecursiveDirectoryIterator(dirname(__FILE__).'/../scripts/'); $iterator2 = new RecursiveIteratorIterator($dir_iterator2); -// need to ignore document custom etc -$files = new RegexIterator($iterator2, '#^(?:[A-Z]:)?(?:/(?!(?:custom|documents|conf|install|nltechno))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i'); +// Need to ignore document custom etc. Note: this also ignore natively symbolic links. +$files = new RegexIterator($iterator2, '#^(?:[A-Z]:)?(?:/(?!(?:custom|documents|conf|install))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i'); +*/ +$regextoinclude='\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$'; +$regextoexclude='(custom|documents|conf|install)$'; // Exclude dirs +$files = dol_dir_list(dirname(__FILE__).'/../scripts/', 'files', 1, $regextoinclude, $regextoexclude, 'fullname'); $dir=''; $needtoclose=0; -foreach ($files as $file) { - $newdir = str_replace(dirname(__FILE__).'/../scripts', '', dirname($file)); +foreach ($files as $filetmp) { + $file = $filetmp['fullname']; + //$newdir = str_replace(dirname(__FILE__).'/../scripts', '', dirname($file)); + $newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file)); + $newdir = str_replace(dirname(__FILE__).'/../scripts', '', dirname($file)); if ($newdir!=$dir) { if ($needtoclose) - fputs($fp, ''."\n"); - fputs($fp, ''."\n"); + fputs($fp, ' '."\n"); + fputs($fp, ' '."\n"); $dir = $newdir; $needtoclose=1; } if (filetype($file)=="file") { $md5=md5_file($file); $checksumconcat[]=$md5; - fputs($fp, ''.$md5.''."\n"); + fputs($fp, ' '.$md5.''."\n"); } } -fputs($fp, ''."\n"); +fputs($fp, ' '."\n"); fputs($fp, ''."\n"); asort($checksumconcat); // Sort list of checksum From b65b545e0f498c5bd46d1c3c098ba6ff30410ed4 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Tue, 29 May 2018 16:29:14 +0200 Subject: [PATCH 10/72] add hook on balence pages --- htdocs/compta/recap-compta.php | 47 ++++++++++++++++++---------------- htdocs/fourn/recap-fourn.php | 8 +++--- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/htdocs/compta/recap-compta.php b/htdocs/compta/recap-compta.php index c3231ecccdd..07dfa0d738e 100644 --- a/htdocs/compta/recap-compta.php +++ b/htdocs/compta/recap-compta.php @@ -54,9 +54,12 @@ if (! $sortorder) $sortorder="DESC"; $arrayfields=array( 'f.datef'=>array('label'=>"Date", 'checked'=>1), - //... + //... ); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('supplierbalencelist','globalcard')); + /* * Actions */ @@ -87,13 +90,13 @@ if ($id > 0) dol_fiche_head($head, 'customer', $langs->trans("ThirdParty"), 0, 'company'); dol_banner_tab($object, 'socid', '', ($user->societe_id?0:1), 'rowid', 'nom', '', '', 0, '', '', 1); dol_fiche_end(); - + if (! empty($conf->facture->enabled) && $user->rights->facture->lire) { // Invoice list print load_fiche_titre($langs->trans("CustomerPreview")); - print ''; + print '
'; print ''; if (! empty($arrayfields['f.datef']['checked'])) print_liste_field_titre($arrayfields['f.datef']['label'],$_SERVER["PHP_SELF"],"f.datef","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); print ''; @@ -103,7 +106,7 @@ if ($id > 0) print ''; print ''; print ''; - + $TData = array(); $TDataSort = array(); @@ -135,10 +138,10 @@ if ($id > 0) continue; } $totalpaye = $fac->getSommePaiement(); - + $userstatic->id=$objf->userid; $userstatic->login=$objf->login; - + $TData[] = array( 'date' => $fac->date, 'link' => $fac->getNomUrl(1), @@ -168,13 +171,13 @@ if ($id > 0) while ($j < $nump) { $objp = $db->fetch_object($resqlp); - + $paymentstatic = new Paiement($db); $paymentstatic->id = $objp->rowid; - + $userstatic->id=$objp->userid; $userstatic->login=$objp->login; - + $TData[] = array( 'date' => $db->jdate($objp->dp), 'link' => $langs->trans("Payment") .' '. $paymentstatic->getNomUrl(1), @@ -199,11 +202,11 @@ if ($id > 0) { dol_print_error($db); } - + if(empty($TData)) { print ''; } else { - + // Sort array by date asort($TDataSort); array_multisort($TData,$TDataSort); @@ -213,37 +216,37 @@ if ($id > 0) $balance += $data1['amount']; $data1['balance'] += $balance; } - + // Reverse array to have last elements on top $TData = dol_sort_array($TData, 'date', $sortorder); - - + + $totalDebit = 0; $totalCredit = 0; - + // Display array foreach($TData as $data) { - + print ''; - + print "\n"; print '\n"; - + print ''; print '\n"; $totalDebit += ($data['amount'] > 0) ? abs($data['amount']) : 0; print '\n"; $totalCredit += ($data['amount'] > 0) ? 0 : abs($data['amount']); print '\n"; - + // Author print ''; - + print "\n"; } - + print ''; print ''; print ''; @@ -252,7 +255,7 @@ if ($id > 0) print ''; print "\n"; } - + print "
'.$langs->trans("Element").''.$langs->trans("Balance").''.$langs->trans("Author").'
'.$langs->trans("NoInvoice").'
".dol_print_date($data['date'],'day')."'.$data['link']."'.$data['status'].''.(($data['amount'] > 0) ? price(abs($data['amount'])) : '')."'.(($data['amount'] > 0) ? '' : price(abs($data['amount'])))."'.price($data['balance'])."'; print $data['author']; print '
 '.price($totalDebit).'
"; } } diff --git a/htdocs/fourn/recap-fourn.php b/htdocs/fourn/recap-fourn.php index 470e6c64cc4..fc5821b96f8 100644 --- a/htdocs/fourn/recap-fourn.php +++ b/htdocs/fourn/recap-fourn.php @@ -38,6 +38,8 @@ if ($user->societe_id > 0) } +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('supplierbalencelist','globalcard')); /* * View @@ -67,7 +69,7 @@ if ($socid > 0) // Invoice list print load_fiche_titre($langs->trans("SupplierPreview")); - print ''; + print '
'; $sql = "SELECT s.nom, s.rowid as socid, f.ref_supplier, f.amount, f.datef as df,"; $sql.= " f.paye as paye, f.fk_statut as statut, f.rowid as facid,"; @@ -114,7 +116,7 @@ if ($socid > 0) } $totalpaye = $fac->getSommePaiement(); - + print ''; print "\n"; @@ -182,7 +184,7 @@ if ($socid > 0) { dol_print_error($db); } - + print "
".dol_print_date($fac->date)."
"; } } From e57ceab5de4fad7a54c6f8b613cf0dfdd2ce8857 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 30 May 2018 10:45:06 +0200 Subject: [PATCH 11/72] Update fournisseur.commande.class.php --- htdocs/fourn/class/fournisseur.commande.class.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 3edb70b1ed6..e84815a828e 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1430,15 +1430,13 @@ class CommandeFournisseur extends CommonOrder // We use 'none' instead of $fourn_ref, because fourn_ref may not exists anymore. So we will take the first supplier price ok. // If we want a dedicated supplier price, we must provide $fk_prod_fourn_price. $result=$prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', ($this->fk_soc?$this->fk_soc:$this->socid)); // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$fourn_ref/$this->fk_soc - if ($result > 0 && $origin !== 'supplier_proposal') + if ($result > 0 && $origin == 'commande') // If supplier order created from customer order, we take best supplier price { $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice $ref_supplier = $prod->ref_supplier; // Ref supplier price set by get_buyprice // is remise percent not keyed but present for the product we add it 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 { From 60321aabd89e38b77cfbf68cc4793b2970d5cb4d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 30 May 2018 11:59:23 +0200 Subject: [PATCH 12/72] Fix regression --- htdocs/fourn/class/fournisseur.commande.class.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index e84815a828e..f00392f1377 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1374,7 +1374,7 @@ class CommandeFournisseur extends CommonOrder $error = 0; - dol_syslog(get_class($this)."::addline $desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $fk_prod_fourn_price, $fourn_ref, $remise_percent, $price_base_type, $pu_ttc, $type, $fk_unit"); + dol_syslog(get_class($this)."::addline $desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $fk_prod_fourn_price, $fourn_ref, $remise_percent, $price_base_type, $pu_ttc, $type, $fk_unit, $pu_ht_devise, $origin, $origin_id"); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; // Clean parameters @@ -1430,13 +1430,14 @@ class CommandeFournisseur extends CommonOrder // We use 'none' instead of $fourn_ref, because fourn_ref may not exists anymore. So we will take the first supplier price ok. // If we want a dedicated supplier price, we must provide $fk_prod_fourn_price. $result=$prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', ($this->fk_soc?$this->fk_soc:$this->socid)); // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$fourn_ref/$this->fk_soc - if ($result > 0 && $origin == 'commande') // If supplier order created from customer order, we take best supplier price + // If supplier order created from customer order, we take best supplier price + // If $pu (defined previously from pu_ht or pu_ttc) is not defined at all, we also take the best supplier price + if ($result > 0 && ($origin == 'commande' || $pu === '')) { - $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice - $ref_supplier = $prod->ref_supplier; // Ref supplier price set by get_buyprice - // is remise percent not keyed but present for the product we add it - if ($remise_percent == 0 && $prod->remise_percent !=0) - $remise_percent =$prod->remise_percent; + $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice + $ref_supplier = $prod->ref_supplier; // Ref supplier price set by get_buyprice + // is remise percent not keyed but present for the product we add it + 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 { From b996237142d6bc26aca90af038e230d1ba8f9054 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Wed, 30 May 2018 13:37:17 +0200 Subject: [PATCH 13/72] fix: when agenda is filterd with "todo" event, do not display "not applicable" event --- htdocs/comm/action/index.php | 4 ++-- htdocs/comm/action/listactions.php | 6 +++--- htdocs/comm/action/pertype.php | 4 ++-- htdocs/comm/action/peruser.php | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index e2bb57c3ce4..381c3e7cc28 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -534,8 +534,8 @@ if ($type) $sql.= " AND ca.id = ".$type; if ($status == '0') { $sql.= " AND a.percent = 0"; } if ($status == '-1') { $sql.= " AND a.percent = -1"; } // Not applicable if ($status == '50') { $sql.= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started -if ($status == 'done' || $status == '100') { $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep2 <= '".$db->idate($now)."'))"; } -if ($status == 'todo') { $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep2 > '".$db->idate($now)."'))"; } +if ($status == 'done' || $status == '100') { $sql.= " AND (a.percent = 100)"; } +if ($status == 'todo') { $sql.= " AND (a.percent >= 0 AND a.percent < 100)"; } // We must filter on assignement table if ($filtert > 0 || $usergroup > 0) { diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php index 4540580fed8..ccdcc5f7412 100644 --- a/htdocs/comm/action/listactions.php +++ b/htdocs/comm/action/listactions.php @@ -238,7 +238,7 @@ if (! empty($actioncode)) else { $sql.=" AND c.code IN ('".implode("','", explode(',', $actioncode))."')"; - } + } } } } @@ -253,8 +253,8 @@ if ($status == '0') { $sql.= " AND a.percent = 0"; } if ($status == '-1') { $sql.= " AND a.percent = -1"; } // Not applicable if ($status == '50') { $sql.= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started if ($status == '100') { $sql.= " AND a.percent = 100"; } -if ($status == 'done' || $status == '100') { $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep2 <= '".$db->idate($now)."'))"; } -if ($status == 'todo') { $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep2 > '".$db->idate($now)."'))"; } +if ($status == 'done' || $status == '100') { $sql.= " AND (a.percent = 100)"; } +if ($status == 'todo') { $sql.= " AND (a.percent >= 0 AND a.percent < 100)"; } if ($search_title) $sql.=natural_search("a.label", $search_title); // We must filter on assignement table if ($filtert > 0 || $usergroup > 0) diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php index b10ab8dc05b..742797284b2 100644 --- a/htdocs/comm/action/pertype.php +++ b/htdocs/comm/action/pertype.php @@ -427,8 +427,8 @@ if ($type) $sql.= " AND ca.id = ".$type; if ($status == '0') { $sql.= " AND a.percent = 0"; } if ($status == '-1') { $sql.= " AND a.percent = -1"; } // Not applicable if ($status == '50') { $sql.= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started -if ($status == 'done' || $status == '100') { $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep2 <= '".$db->idate($now)."'))"; } -if ($status == 'todo') { $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep2 > '".$db->idate($now)."'))"; } +if ($status == 'done' || $status == '100') { $sql.= " AND (a.percent = 100)"; } +if ($status == 'todo') { $sql.= " AND (a.percent >= 0 AND a.percent < 100)"; } // We must filter on assignement table if ($filtert > 0 || $usergroup > 0) { diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 05eba093cfd..d818dda493f 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -446,8 +446,8 @@ if ($type) $sql.= " AND ca.id = ".$type; if ($status == '0') { $sql.= " AND a.percent = 0"; } if ($status == '-1') { $sql.= " AND a.percent = -1"; } // Not applicable if ($status == '50') { $sql.= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started -if ($status == 'done' || $status == '100') { $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep2 <= '".$db->idate($now)."'))"; } -if ($status == 'todo') { $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep2 > '".$db->idate($now)."'))"; } +if ($status == 'done' || $status == '100') { $sql.= " AND (a.percent = 100)"; } +if ($status == 'todo') { $sql.= " AND (a.percent >= 0 AND a.percent < 100)"; } // We must filter on assignement table if ($filtert > 0 || $usergroup > 0) { From 77e793267116a7cf6a4df703b9c1db5f621aec68 Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 5 Jun 2018 11:33:58 +0200 Subject: [PATCH 14/72] FIX : sometimes amounts are identical but php find them different. --- htdocs/compta/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 06330de7682..993194e0f91 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -406,7 +406,7 @@ if (empty($reshook)) //var_dump($object->getRemainToPay(0)); //var_dump($discount->amount_ttc);exit; - if ($discount->amount_ttc > $object->getRemainToPay(0)) + if (price2num($discount->amount_ttc) > price2num($object->getRemainToPay(0))) { // TODO Split the discount in 2 automatically $error++; From 45ecb0258b23dafa400fb33e4e6d0a9c2b0ffd90 Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 5 Jun 2018 12:41:38 +0200 Subject: [PATCH 15/72] FIX : entity test must be on product_fourn_price table and not product table --- 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 2c5e41ce75a..634071791e3 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2581,7 +2581,7 @@ class Form $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON pfp.fk_soc = s.rowid"; - $sql.= " WHERE p.entity IN (".getEntity('productprice').")"; + $sql.= " WHERE pfp.entity IN (".getEntity('productprice').")"; $sql.= " AND p.tobuy = 1"; $sql.= " AND s.fournisseur = 1"; $sql.= " AND p.rowid = ".$productid; From 4c21ad4e4e331c64bebcce76da018f5cd49dd883 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 5 Jun 2018 18:05:33 +0200 Subject: [PATCH 16/72] FIX: dol_delete_file must work in a context without db handler loaded Conflicts: htdocs/core/lib/files.lib.php --- htdocs/core/lib/files.lib.php | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 5bf386e1fac..b7e69b243cf 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1031,7 +1031,7 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n if (preg_match('/\.\./',$file) || preg_match('/[<>|]/',$file)) { dol_syslog("Refused to delete file ".$file, LOG_WARNING); - return False; + return false; } if (empty($nohook)) @@ -1080,18 +1080,21 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n { $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete); - dol_syslog("Try to remove also entries in database for full relative path = ".$rel_filetodelete, LOG_DEBUG); - include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; - $ecmfile=new EcmFiles($db); - $result = $ecmfile->fetch(0, '', $rel_filetodelete); - if ($result >= 0 && $ecmfile->id > 0) - { - $result = $ecmfile->delete($user); - } - if ($result < 0) - { - setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); - } + if (is_object($db)) // $db may not be defined when lib is in a context with define('NOREQUIREDB',1) + { + dol_syslog("Try to remove also entries in database for full relative path = ".$rel_filetodelete, LOG_DEBUG); + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(0, '', $rel_filetodelete); + if ($result >= 0 && $ecmfile->id > 0) + { + $result = $ecmfile->delete($user); + } + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + } } } else dol_syslog("Failed to remove file ".$filename, LOG_WARNING); @@ -1130,7 +1133,7 @@ function dol_delete_dir($dir,$nophperrors=0) if (preg_match('/\.\./',$dir) || preg_match('/[<>|]/',$dir)) { dol_syslog("Refused to delete dir ".$dir, LOG_WARNING); - return False; + return false; } $dir_osencoded=dol_osencode($dir); @@ -1711,7 +1714,7 @@ function dol_uncompress($inputfile,$outputdir) dol_syslog("Class ZipArchive is set so we unzip using ZipArchive to unzip into ".$outputdir); $zip = new ZipArchive; $res = $zip->open($inputfile); - if ($res === TRUE) + if ($res === true) { $zip->extractTo($outputdir.'/'); $zip->close(); From 8785d6954858a4679c30e100586bc18581a703de Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 5 Jun 2018 18:21:56 +0200 Subject: [PATCH 17/72] Do not load database handler --- build/generate_filelist_xml.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/generate_filelist_xml.php b/build/generate_filelist_xml.php index 5f54c95d7e0..5f71ff54072 100755 --- a/build/generate_filelist_xml.php +++ b/build/generate_filelist_xml.php @@ -22,6 +22,8 @@ * \brief This script create a xml checksum file */ +if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Do not create database handler $db + $sapi_type = php_sapi_name(); $script_file = basename(__FILE__); $path=dirname(__FILE__).'/'; From baf9d4a806702dd3cdf040319ad7e60551790741 Mon Sep 17 00:00:00 2001 From: gauthier Date: Fri, 8 Jun 2018 17:11:59 +0200 Subject: [PATCH 18/72] FIX : If we enable 3 steps for supplier order approbation, we must not delete all fourn rights def. --- htdocs/admin/supplier_order.php | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php index 6b99bb1c39c..5848c0533b0 100644 --- a/htdocs/admin/supplier_order.php +++ b/htdocs/admin/supplier_order.php @@ -179,24 +179,30 @@ else if ($action == 'set_SUPPLIER_ORDER_OTHER') // TODO We add/delete permission here until permission can have a condition on a global var include_once DOL_DOCUMENT_ROOT.'/core/modules/modFournisseur.class.php'; $newmodule=new modFournisseur($db); - // clear default rights array - $newmodule->rights=array(); - // add new right - $r=0; - $newmodule->rights[$r][0] = 1190; - $newmodule->rights[$r][1] = $langs->trans("Permission1190"); - $newmodule->rights[$r][2] = 'w'; - $newmodule->rights[$r][3] = 0; - $newmodule->rights[$r][4] = 'commande'; - $newmodule->rights[$r][5] = 'approve2'; - + if ($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) { + // clear default rights array + $newmodule->rights=array(); + // add new right + $r=0; + $newmodule->rights[$r][0] = 1190; + $newmodule->rights[$r][1] = $langs->trans("Permission1190"); + $newmodule->rights[$r][2] = 'w'; + $newmodule->rights[$r][3] = 0; + $newmodule->rights[$r][4] = 'commande'; + $newmodule->rights[$r][5] = 'approve2'; + + // Insert $newmodule->insert_permissions(1); } else { + // Remove all rights with Permission1190 $newmodule->delete_permissions(); + + // Add all right without Permission1190 + $newmodule->insert_permissions(1); } } From d42f00bca961a0f0d70f9b3acc703fbd2890c346 Mon Sep 17 00:00:00 2001 From: altatof Date: Wed, 13 Jun 2018 16:35:52 +0200 Subject: [PATCH 19/72] FIX : pu_ht_devise was not converted to numeric so decimals were lost when clculating total_ht_devise --- htdocs/comm/propal/class/propal.class.php | 2 ++ htdocs/commande/class/commande.class.php | 2 ++ htdocs/compta/facture/class/facture.class.php | 2 ++ htdocs/fourn/class/fournisseur.commande.class.php | 2 ++ 4 files changed, 8 insertions(+) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index ffeda27da42..ca5935af0a8 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -417,6 +417,7 @@ class Propal extends CommonObject $remise_percent=price2num($remise_percent); $qty=price2num($qty); $pu_ht=price2num($pu_ht); + $pu_ht_devise=price2num($pu_ht_devise); $pu_ttc=price2num($pu_ttc); $txtva=price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' $txlocaltax1=price2num($txlocaltax1); @@ -638,6 +639,7 @@ class Propal extends CommonObject $remise_percent=price2num($remise_percent); $qty=price2num($qty); $pu = price2num($pu); + $pu_ht_devise=price2num($pu_ht_devise); $txtva = price2num($txtva); $txlocaltax1=price2num($txlocaltax1); $txlocaltax2=price2num($txlocaltax2); diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 429566e054d..d2f915406f8 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -1269,6 +1269,7 @@ class Commande extends CommonOrder $remise_percent=price2num($remise_percent); $qty=price2num($qty); $pu_ht=price2num($pu_ht); + $pu_ht_devise=price2num($pu_ht_devise); $pu_ttc=price2num($pu_ttc); $pa_ht=price2num($pa_ht); $txtva = price2num($txtva); @@ -2815,6 +2816,7 @@ class Commande extends CommonOrder $qty=price2num($qty); $pu = price2num($pu); $pa_ht=price2num($pa_ht); + $pu_ht_devise=price2num($pu_ht_devise); $txtva=price2num($txtva); $txlocaltax1=price2num($txlocaltax1); $txlocaltax2=price2num($txlocaltax2); diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 5c0fc379584..3de5ae96458 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2512,6 +2512,7 @@ class Facture extends CommonInvoice $remise_percent=price2num($remise_percent); $qty=price2num($qty); $pu_ht=price2num($pu_ht); + $pu_ht_devise=price2num($pu_ht_devise); $pu_ttc=price2num($pu_ttc); $pa_ht=price2num($pa_ht); $txtva=price2num($txtva); @@ -2735,6 +2736,7 @@ class Facture extends CommonInvoice $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu = price2num($pu); + $pu_ht_devise = price2num($pu_ht_devise); $pa_ht = price2num($pa_ht); $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index f00392f1377..d07c3347146 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1388,6 +1388,7 @@ class CommandeFournisseur extends CommonOrder $remise_percent=price2num($remise_percent); $qty=price2num($qty); $pu_ht=price2num($pu_ht); + $pu_ht_devise=price2num($pu_ht_devise); $pu_ttc=price2num($pu_ttc); $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); @@ -2336,6 +2337,7 @@ class CommandeFournisseur extends CommonOrder $qty=price2num($qty); if (! $qty) $qty=1; $pu = price2num($pu); + $pu_ht_devise=price2num($pu_ht_devise); $txtva=price2num($txtva); $txlocaltax1=price2num($txlocaltax1); $txlocaltax2=price2num($txlocaltax2); From e9d65ea751cf068b04a2e1f333c74da7462e8e5f Mon Sep 17 00:00:00 2001 From: gauthier Date: Thu, 14 Jun 2018 11:56:22 +0200 Subject: [PATCH 20/72] FIX : need to filter on aa.entity for same accounting accounts available in several entities --- htdocs/accountancy/customer/list.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index f675c010b37..d5d828ef626 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -235,6 +235,7 @@ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_STANDARD . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_DEPOSIT . "," . Facture::TYPE_SITUATION . ")"; } $sql .= " AND f.entity IN (" . getEntity('facture', 0) . ")"; // We don't share object for accountancy +$sql .= " AND aa.entity = " . $conf->entity; // Add where from hooks $parameters=array(); @@ -439,4 +440,4 @@ if ($result) { } llxFooter(); -$db->close(); \ No newline at end of file +$db->close(); From 5d6cd381b9999c6f615904c54217c4721965f6d5 Mon Sep 17 00:00:00 2001 From: altatof Date: Fri, 15 Jun 2018 15:59:14 +0200 Subject: [PATCH 21/72] Fix
detection --- htdocs/core/lib/functions.lib.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 6e9261fdd81..c0fbfb68010 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5067,6 +5067,7 @@ function dol_textishtml($msg,$option=0) { if (preg_match('//i',$msg)) return true; elseif (preg_match('/<(br|div|font|li|p|span|strong|table)>/i',$msg)) return true; elseif (preg_match('/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*>/i',$msg)) return true; From 63fb82931cb0d8427503cb27f437ac6eb6704082 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 18 Jun 2018 10:41:11 +0200 Subject: [PATCH 22/72] Update functions.lib.php --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c0fbfb68010..8c3bea14dae 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5067,8 +5067,8 @@ function dol_textishtml($msg,$option=0) { if (preg_match('//i',$msg)) return true; + elseif (preg_match('//i',$msg)) return true; elseif (preg_match('/<(br|div|font|li|p|span|strong|table)>/i',$msg)) return true; elseif (preg_match('/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*>/i',$msg)) return true; elseif (preg_match('/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*\/>/i',$msg)) return true; From fed61930d5e50916eaed657211b2ba943032db3b Mon Sep 17 00:00:00 2001 From: gauthier Date: Mon, 18 Jun 2018 11:37:15 +0200 Subject: [PATCH 23/72] FIX : clause must not be there --- htdocs/accountancy/customer/list.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index d5d828ef626..850e5cae6a9 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -198,7 +198,7 @@ $sql.=$hookmanager->resPrint; $sql .= " FROM " . MAIN_DB_PREFIX . "facture as f"; $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "facturedet as l ON f.rowid = l.fk_facture"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = l.fk_product"; -$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON p.accountancy_code_sell = aa.account_number"; +$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON (p.accountancy_code_sell = aa.account_number AND aa.entity = ".$conf->entity.")"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_system as accsys ON accsys.pcg_version = aa.fk_pcg_version"; $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql .= " AND product_type <= 2"; @@ -235,7 +235,6 @@ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_STANDARD . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_DEPOSIT . "," . Facture::TYPE_SITUATION . ")"; } $sql .= " AND f.entity IN (" . getEntity('facture', 0) . ")"; // We don't share object for accountancy -$sql .= " AND aa.entity = " . $conf->entity; // Add where from hooks $parameters=array(); From 8fc2f7441cf340ae2dae1e77b89e7ad82b05d3b1 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 20 Jun 2018 09:06:16 +0200 Subject: [PATCH 24/72] Fix: to avoid deleting line breaks --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8c3bea14dae..0b0f74c1a09 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -449,7 +449,7 @@ function GETPOST($paramname, $check='', $method=0, $filter=NULL, $options=NULL, if (! is_array($out) || empty($out)) $out=array(); break; case 'nohtml': - $out=dol_string_nohtmltag($out); + $out=dol_string_nohtmltag($out, 0); break; case 'alphanohtml': // Recommended for search params $out=trim($out); From 86a58def3b659676dd9c7483e05df7d3ddd6faef Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 27 Jun 2018 17:13:50 +0200 Subject: [PATCH 25/72] FIX : getEntity project and not projet --- htdocs/projet/class/project.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 551bdcb9d5f..d42c67a09dc 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1750,7 +1750,7 @@ class Project extends CommonObject $sql = "SELECT count(p.rowid) as nb"; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql.= " WHERE"; - $sql.= " p.entity IN (".getEntity('projet').")"; + $sql.= " p.entity IN (".getEntity('project').")"; if (! $user->rights->projet->all->lire) { $projectsListId = $this->getProjectsAuthorizedForUser($user,0,1); From d8ca9f2947cc3928bc02b10c5176bd9b3015d08e Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 27 Jun 2018 17:26:04 +0200 Subject: [PATCH 26/72] FIX : we must see number of all shared projects --- htdocs/projet/class/project.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index d42c67a09dc..5dce267d965 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1674,7 +1674,7 @@ class Project extends CommonObject // For external user, no check is done on company permission because readability is managed by public status of project and assignement. //if (! $user->rights->societe->client->voir && ! $socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid"; $sql.= " WHERE p.fk_statut = 1"; - $sql.= " AND p.entity IN (".getEntity('project', 0).')'; + $sql.= " AND p.entity IN (".getEntity('project').')'; if (! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")"; // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser //if ($socid || ! $user->rights->societe->client->voir) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; From 2d13b5b59d4a1db3b0c6ff30493fe57ed09aaa5d Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 29 Jun 2018 15:57:34 +0200 Subject: [PATCH 27/72] Fix: broken feature with edit in place --- htdocs/core/class/html.form.class.php | 2 +- htdocs/core/tpl/notes.tpl.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 634071791e3..f782da206da 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -282,7 +282,7 @@ class Form $out=''; // Check parameters - if ($inputType == 'textarea') $value = dol_nl2br($value); + if (preg_match('/^text/',$inputType)) $value = dol_nl2br($value); else if (preg_match('/^numeric/',$inputType)) $value = price($value); else if ($inputType == 'day' || $inputType == 'datepicker') $value = dol_print_date($value, 'day'); diff --git a/htdocs/core/tpl/notes.tpl.php b/htdocs/core/tpl/notes.tpl.php index da3ad8fb234..7fe5a5b1c77 100644 --- a/htdocs/core/tpl/notes.tpl.php +++ b/htdocs/core/tpl/notes.tpl.php @@ -71,7 +71,7 @@ elseif ($module == 'shipping') { $permission=$user->rights->expedition->cr elseif ($module == 'product') { $permission=$user->rights->produit->creer;} //else dol_print_error('','Bad value '.$module.' for param module'); -if (! empty($conf->global->FCKEDITOR_ENABLE_SOCIETE)) $typeofdata='ckeditor:dolibarr_notes:100%:200::1:12:95%'; // Rem: This var is for all notes, not only thirdparties note. +if (! empty($conf->fckeditor->enabled) && ! empty($conf->global->FCKEDITOR_ENABLE_SOCIETE)) $typeofdata='ckeditor:dolibarr_notes:100%:200::1:12:95%'; // Rem: This var is for all notes, not only thirdparties note. else $typeofdata='textarea:12:95%'; ?> From 41709f07d0aef384723164877395ed081b44b810 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 29 Jun 2018 18:18:10 +0200 Subject: [PATCH 28/72] Fix: #9032 Vulnerability --- htdocs/install/step1.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/install/step1.php b/htdocs/install/step1.php index 14695f914cb..c53a5996a67 100644 --- a/htdocs/install/step1.php +++ b/htdocs/install/step1.php @@ -47,16 +47,16 @@ $main_data_dir = GETPOST('main_data_dir') ? GETPOST('main_data_dir') : $main_dir // Dolibarr root URL $main_url = GETPOST('main_url'); // Database login informations -$userroot=GETPOST('db_user_root'); -$passroot=GETPOST('db_pass_root'); +$userroot=GETPOST('db_user_root','aZ09'); +$passroot=GETPOST('db_pass_root'); // FIXME protect for injection // Database server -$db_type=GETPOST('db_type','alpha'); -$db_host=GETPOST('db_host','alpha'); -$db_name=GETPOST('db_name','alpha'); -$db_user=GETPOST('db_user','alpha'); -$db_pass=GETPOST('db_pass'); +$db_type=GETPOST('db_type','aZ09'); +$db_host=GETPOST('db_host','aZ09'); +$db_name=GETPOST('db_name','aZ09'); +$db_user=GETPOST('db_user','aZ09'); +$db_pass=GETPOST('db_pass'); // FIXME protect for injection $db_port=GETPOST('db_port','int'); -$db_prefix=GETPOST('db_prefix','alpha'); +$db_prefix=GETPOST('db_prefix','aZ09'); $db_create_database = GETPOST('db_create_database','none'); $db_create_user = GETPOST('db_create_user','none'); // Force https From c4143763beb511f2f8dc3d61152c2530956caa05 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jun 2018 19:23:17 +0200 Subject: [PATCH 29/72] Update step1.php --- htdocs/install/step1.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/install/step1.php b/htdocs/install/step1.php index c53a5996a67..ee30534f438 100644 --- a/htdocs/install/step1.php +++ b/htdocs/install/step1.php @@ -47,14 +47,14 @@ $main_data_dir = GETPOST('main_data_dir') ? GETPOST('main_data_dir') : $main_dir // Dolibarr root URL $main_url = GETPOST('main_url'); // Database login informations -$userroot=GETPOST('db_user_root','aZ09'); -$passroot=GETPOST('db_pass_root'); // FIXME protect for injection +$userroot=GETPOST('db_user_root','alpha'); +$passroot=GETPOST('db_pass_root','none'); // Database server $db_type=GETPOST('db_type','aZ09'); -$db_host=GETPOST('db_host','aZ09'); -$db_name=GETPOST('db_name','aZ09'); -$db_user=GETPOST('db_user','aZ09'); -$db_pass=GETPOST('db_pass'); // FIXME protect for injection +$db_host=GETPOST('db_host','alpha'); +$db_name=GETPOST('db_name','alpha'); +$db_user=GETPOST('db_user','alpha'); +$db_pass=GETPOST('db_pass','none'); $db_port=GETPOST('db_port','int'); $db_prefix=GETPOST('db_prefix','aZ09'); $db_create_database = GETPOST('db_create_database','none'); From 3f2b3c08404ed3b99d038b966ce5ab5d90177f66 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jun 2018 19:38:12 +0200 Subject: [PATCH 30/72] FIX #9032 --- htdocs/install/step1.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/step1.php b/htdocs/install/step1.php index ee30534f438..7aab5d2f1a2 100644 --- a/htdocs/install/step1.php +++ b/htdocs/install/step1.php @@ -52,7 +52,7 @@ $passroot=GETPOST('db_pass_root','none'); // Database server $db_type=GETPOST('db_type','aZ09'); $db_host=GETPOST('db_host','alpha'); -$db_name=GETPOST('db_name','alpha'); +$db_name=GETPOST('db_name','aZ09'); $db_user=GETPOST('db_user','alpha'); $db_pass=GETPOST('db_pass','none'); $db_port=GETPOST('db_port','int'); From 1daba56bbc665f666bad0af7a56dca80cfd68fc8 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Mon, 9 Jul 2018 10:05:53 +0200 Subject: [PATCH 31/72] Fix count(): Parameter must be an array or an object that implements Countable --- htdocs/comm/action/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 381c3e7cc28..e178bcdd468 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1243,7 +1243,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $i=0; $nummytasks=0; $numother=0; $numbirthday=0; $numical=0; $numicals=array(); $ymd=sprintf("%04d",$year).sprintf("%02d",$month).sprintf("%02d",$day); - $nextindextouse=count($colorindexused); // At first run this is 0, so fist user has 0, next 1, ... + $nextindextouse=is_array($colorindexused)?count($colorindexused):0; // At first run this is 0, so fist user has 0, next 1, ... //print $nextindextouse; foreach ($eventarray as $daykey => $notused) From 2ba7c075742c299131ba1e86a73dea6577125cc5 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio Date: Mon, 9 Jul 2018 17:34:31 +0200 Subject: [PATCH 32/72] FIX: propal: correctly preset project when creating with origin/originid --- htdocs/comm/propal/card.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index e0a4c19c9cb..9a1c2dcb54f 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -74,6 +74,7 @@ $originid = GETPOST('originid', 'int'); $confirm = GETPOST('confirm', 'alpha'); $lineid = GETPOST('lineid', 'int'); $contactid = GETPOST('contactid','int'); +$projectid = GETPOST('projectid','int'); // PDF $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); @@ -1310,7 +1311,7 @@ if ($action == 'create') } $objectsrc->fetch_thirdparty(); - $projectid = (! empty($objectsrc->fk_project) ? $objectsrc->fk_project : ''); + $projectid = (! empty($objectsrc->fk_project) ? $objectsrc->fk_project : 0); $ref_client = (! empty($objectsrc->ref_client) ? $objectsrc->ref_client : ''); $ref_int = (! empty($objectsrc->ref_int) ? $objectsrc->ref_int : ''); @@ -1478,9 +1479,6 @@ if ($action == 'create') // Project if (! empty($conf->projet->enabled) && $socid > 0) { - $projectid = GETPOST('projectid')?GETPOST('projectid'):0; - if ($origin == 'project') $projectid = ($originid ? $originid : 0); - $langs->load("projects"); print ''; print '' . $langs->trans("Project") . ''; From 103c7e6d066ad7a0754e6db85a93e8ac4b7252e6 Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 11 Jul 2018 09:51:36 +0200 Subject: [PATCH 33/72] FIX : page must always be 0 when we search (to avoid case : when we're on page 3 and we're looking for a precise thirdparty, we stay on page 3 and nothing's displaied) --- htdocs/comm/propal/list.php | 4 +++- htdocs/commande/list.php | 4 +++- htdocs/compta/facture/list.php | 4 +++- htdocs/fourn/commande/list.php | 4 +++- htdocs/fourn/facture/list.php | 4 +++- htdocs/societe/list.php | 4 +++- htdocs/supplier_proposal/list.php | 4 +++- 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 72491e90e3e..fe35c2bc4e8 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -83,12 +83,14 @@ $mesg=(GETPOST("msg") ? GETPOST("msg") : GETPOST("mesg")); $search_day=GETPOST("search_day","int"); $search_month=GETPOST("search_month","int"); $search_year=GETPOST("search_year","int"); +$search_btn=GETPOST('button_search','alpha'); +$search_remove_btn=GETPOST('button_removefilter','alpha'); $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page",'int'); -if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 6284e53aa5c..6e57b55b2c7 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -74,6 +74,8 @@ $search_total_ht=GETPOST('search_total_ht','alpha'); $optioncss = GETPOST('optioncss','alpha'); $billed = GETPOST('billed','int'); $viewstatut=GETPOST('viewstatut'); +$search_btn=GETPOST('button_search','alpha'); +$search_remove_btn=GETPOST('button_removefilter','alpha'); // Security check $id = (GETPOST('orderid')?GETPOST('orderid','int'):GETPOST('id','int')); @@ -86,7 +88,7 @@ $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page",'int'); -if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 994f1d93569..1e857abfa7e 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -93,6 +93,8 @@ $year = GETPOST('year','int'); $day_lim = GETPOST('day_lim','int'); $month_lim = GETPOST('month_lim','int'); $year_lim = GETPOST('year_lim','int'); +$search_btn=GETPOST('button_search','alpha'); +$search_remove_btn=GETPOST('button_removefilter','alpha'); $option = GETPOST('option'); if ($option == 'late') { @@ -104,7 +106,7 @@ $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page",'int'); -if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; if (! $sortorder && ! empty($conf->global->INVOICE_DEFAULT_UNPAYED_SORT_ORDER) && $search_status == 1) $sortorder=$conf->global->INVOICE_DEFAULT_UNPAYED_SORT_ORDER; if (! $sortorder) $sortorder='DESC'; diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 4d5f2999943..1bb52d8ae48 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -85,6 +85,8 @@ $search_total_ttc=GETPOST('search_total_ttc','alpha'); $optioncss = GETPOST('optioncss','alpha'); $billed = GETPOST('billed','int'); $search_project_ref=GETPOST('search_project_ref','alpha'); +$search_btn=GETPOST('button_search','alpha'); +$search_remove_btn=GETPOST('button_removefilter','alpha'); $page = GETPOST('page','int'); $sortorder = GETPOST('sortorder','alpha'); @@ -105,7 +107,7 @@ $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page",'int'); -if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index a602badfb05..960fac83216 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -99,6 +99,8 @@ $day_lim = GETPOST('day_lim','int'); $month_lim = GETPOST('month_lim','int'); $year_lim = GETPOST('year_lim','int'); $toselect = GETPOST('toselect', 'array'); +$search_btn=GETPOST('button_search','alpha'); +$search_remove_btn=GETPOST('button_removefilter','alpha'); $option = GETPOST('option'); if ($option == 'late') { @@ -110,7 +112,7 @@ $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page=GETPOST("page",'int'); -if ($page == -1 || $page == null) { $page = 0 ; } +if ($page == -1 || $page == null || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0 ; } $offset = $limit * $page ; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 3d56fa9401a..b3f070124a6 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -82,6 +82,8 @@ $search_type=GETPOST('search_type','alpha'); $search_level_from = GETPOST("search_level_from","alpha"); $search_level_to = GETPOST("search_level_to","alpha"); $search_stcomm=GETPOST('search_stcomm','int'); +$search_btn=GETPOST('button_search','alpha'); +$search_remove_btn=GETPOST('button_removefilter','alpha'); $type=GETPOST('type'); $optioncss=GETPOST('optioncss','alpha'); @@ -95,7 +97,7 @@ $sortorder=GETPOST("sortorder",'alpha'); $page=GETPOST("page",'int'); if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="s.nom"; -if (empty($page) || $page == -1) { $page = 0; } +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index 4240ca72a08..c1267fce72a 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -73,6 +73,8 @@ $search_montant_vat=GETPOST('search_montant_vat','alpha'); $search_montant_ttc=GETPOST('search_montant_ttc','alpha'); $search_status=GETPOST('viewstatut','alpha')?GETPOST('viewstatut','alpha'):GETPOST('search_status','int'); $object_statut=$db->escape(GETPOST('supplier_proposal_statut')); +$search_btn=GETPOST('button_search','alpha'); +$search_remove_btn=GETPOST('button_removefilter','alpha'); $sall=GETPOST('sall', 'alphanohtml'); $mesg=(GETPOST("msg") ? GETPOST("msg") : GETPOST("mesg")); @@ -85,7 +87,7 @@ $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page",'int'); -if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; From 80ff7fa86f34d11c9facedac8bab3b3250b91b53 Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 11 Jul 2018 15:18:30 +0200 Subject: [PATCH 34/72] FIX : case when we valid form with keyboard --- htdocs/comm/propal/list.php | 2 +- htdocs/commande/list.php | 2 +- htdocs/compta/facture/list.php | 2 +- htdocs/fourn/commande/list.php | 2 +- htdocs/fourn/facture/list.php | 2 +- htdocs/societe/list.php | 2 +- htdocs/supplier_proposal/list.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index fe35c2bc4e8..52a712ab043 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -90,7 +90,7 @@ $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page",'int'); -if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } // If $page is not defined, or '' or -1 +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 6e57b55b2c7..db1b7554e4f 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -88,7 +88,7 @@ $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 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } // If $page is not defined, or '' or -1 +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 1e857abfa7e..859889966eb 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -106,7 +106,7 @@ $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page",'int'); -if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } // If $page is not defined, or '' or -1 +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; if (! $sortorder && ! empty($conf->global->INVOICE_DEFAULT_UNPAYED_SORT_ORDER) && $search_status == 1) $sortorder=$conf->global->INVOICE_DEFAULT_UNPAYED_SORT_ORDER; if (! $sortorder) $sortorder='DESC'; diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 1bb52d8ae48..d1b8cdcdcaf 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -107,7 +107,7 @@ $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 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } // If $page is not defined, or '' or -1 +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 960fac83216..5ba2a2b9779 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -112,7 +112,7 @@ $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page=GETPOST("page",'int'); -if ($page == -1 || $page == null || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0 ; } +if ($page == -1 || $page == null || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { $page = 0 ; } $offset = $limit * $page ; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index b3f070124a6..3f011d588f5 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -97,7 +97,7 @@ $sortorder=GETPOST("sortorder",'alpha'); $page=GETPOST("page",'int'); if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="s.nom"; -if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { $page = 0; } $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index c1267fce72a..cf492137330 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -87,7 +87,7 @@ $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page",'int'); -if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn)) { $page = 0; } // If $page is not defined, or '' or -1 +if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; From 1e986bc39a54f73d336ff8e5da0e98e13905690c Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Fri, 20 Jul 2018 11:49:38 +0200 Subject: [PATCH 35/72] Fix: Warning: Use of undefined constant MYSQL_NUM - assumed 'MYSQL_NUM' (this will throw an Error in a future version of PHP) --- htdocs/core/class/html.form.class.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index f782da206da..4efedc2544e 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3231,21 +3231,21 @@ class Form if ($resql && $this->db->num_rows($resql) > 0) { // Last seen cycle $ref = 0; - while ($res = $this->db->fetch_array($resql, MYSQL_NUM)) { + while ($obj = $this->db->fetch_object($resql)){ //Same company ? - if ($socid == $res[5]) { + if ($socid == $obj->fk_soc) { //Same cycle ? - if ($res[2] != $ref) { + if ($obj->situation_cycle_ref != $ref) { // Just seen this cycle - $ref = $res[2]; + $ref = $obj->situation_cycle_ref; //not final ? - if ($res[4] != 1) { + if ($obj->situation_final != 1) { //Not prov? - if (substr($res[1], 1, 4) != 'PROV') { - if ($selected == $res[0]) { - $opt .= ''; + if (substr($obj->facnumber, 1, 4) != 'PROV') { + if ($selected == $obj->situation_final) { + $opt .= ''; } else { - $opt .= ''; + $opt .= ''; } } } From d582f72bd95fd290b2ab1efa8fb0b29b74d003d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 22 Jul 2018 17:27:02 +0200 Subject: [PATCH 36/72] __NEXT_MONTH __PREVIOUS_MONTH give day instead month --- htdocs/core/lib/functions.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 0b0f74c1a09..9cbd8562949 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5159,9 +5159,9 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob { $tmp=dol_getdate(dol_now(), true); $tmp2=dol_get_prev_day($tmp['mday'], $tmp['mon'], $tmp['year']); - $tmp3=dol_get_prev_month($tmp['mday'], $tmp['mon'], $tmp['year']); + $tmp3=dol_get_prev_month($tmp['mon'], $tmp['year']); $tmp4=dol_get_next_day($tmp['mday'], $tmp['mon'], $tmp['year']); - $tmp5=dol_get_next_month($tmp['mday'], $tmp['mon'], $tmp['year']); + $tmp5=dol_get_next_month($tmp['mon'], $tmp['year']); } $substitutionarray=array_merge($substitutionarray, array( '__DAY__' => $tmp['mday'], From 4341e367d26e5136b05128a8e95e3a32a5025a69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 23 Jul 2018 10:30:28 +0200 Subject: [PATCH 37/72] remove % in supplier order pdf --- htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php index b70a299fa03..196d1f0c6a2 100644 --- a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php +++ b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php @@ -430,7 +430,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders if ($object->lines[$i]->remise_percent) { $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); - $pdf->MultiCell($this->postotalht-$this->posxdiscount-1, 3, $remise_percent."%", 0, 'R'); + $pdf->MultiCell($this->postotalht-$this->posxdiscount-1, 3, $remise_percent, 0, 'R'); } // Total HT line From bde30b85ad7a493d9421379dfff3c467b7ac48e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 24 Jul 2018 17:06:12 +0200 Subject: [PATCH 38/72] use defaut currency for supplier order --- htdocs/fourn/commande/card.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index fa1cef8fe0e..7a1d80daa28 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1342,6 +1342,8 @@ if ($action=='create') dol_htmloutput_events(); + $currency_code = $conf->currency; + $societe=''; if ($socid>0) { From 7dada7ae8e2c020cda81d614c96d694c7d1f99da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 29 Jul 2018 09:15:42 +0200 Subject: [PATCH 39/72] fix #8820 --- htdocs/product/reassort.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index e3983344cff..70dce7470cd 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -134,7 +134,7 @@ if (dol_strlen($type)) $sql.= " AND p.fk_product_type <> '1'"; } } -if ($sref) $sql.= natural_search('p.ref', $ref); +if ($sref) $sql.= natural_search('p.ref', $sref); if ($sbarcode) $sql.= natural_search('p.barcode', $sbarcode); if ($snom) $sql.= natural_search('p.label', $snom); if (! empty($tosell)) $sql.= " AND p.tosell = ".$tosell; From 4ddca02bb9d86d3e6abfdfe2cb4a75359e9e3582 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Tue, 31 Jul 2018 14:58:33 +0200 Subject: [PATCH 40/72] fix situation line's total --- htdocs/compta/facture/class/facture.class.php | 2 +- htdocs/core/lib/pdf.lib.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 3de5ae96458..e0b6d1d81bc 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4834,7 +4834,7 @@ class FactureLigne extends CommonInvoiceLine $resql = $this->db->query($sql); if ($resql && $resql->num_rows > 0) { $res = $this->db->fetch_array($resql); - return $res['situation_percent']; + return floatval($res['situation_percent']); } else { $this->error = $this->db->error(); dol_syslog(get_class($this) . "::select Error " . $this->error, LOG_ERR); diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index cb061bc9f2e..234c0cc7e34 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1899,13 +1899,13 @@ function pdf_getlinetotalexcltax($object,$i,$outputlangs,$hidedetails=0) { $prev_progress = 0; $progress = 1; - if (method_exists($object, 'get_prev_progress')) + if (method_exists($object->lines[$i], 'get_prev_progress')) { $prev_progress = $object->lines[$i]->get_prev_progress($object->id); $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100; } $result.=price($sign * ($total_ht/($object->lines[$i]->situation_percent/100)) * $progress, 0, $outputlangs); - } + } else $result.=price($sign * $total_ht, 0, $outputlangs); } From ceb85cfa45d60cb987a3ef5271cd11fef844d99d Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Tue, 31 Jul 2018 17:29:08 +0200 Subject: [PATCH 41/72] fix : odt project and task extrafields management --- .../doc/doc_generic_project_odt.modules.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php index e050bf8e3eb..c2258f9ba97 100644 --- a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php +++ b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php @@ -130,12 +130,9 @@ class doc_generic_project_odt extends ModelePDFProjects $array_key.'_statut'=>$object->getLibStatut() ); - // Retrieve extrafields - $extrafieldkey=$object->element; - require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields = new ExtraFields($this->db); - $extralabels = $extrafields->fetch_name_optionals_label($extrafieldkey,true); + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element,true); $object->fetch_optionals($object->id,$extralabels); $resarray = $this->fill_substitutionarray_with_extrafields($object,$resarray,$extrafields,$array_key,$outputlangs); @@ -154,7 +151,7 @@ class doc_generic_project_odt extends ModelePDFProjects { global $conf; - return array( + $resarray = array( 'task_ref'=>$task->ref, 'task_fk_project'=>$task->fk_project, 'task_projectref'=>$task->projectref, @@ -170,6 +167,16 @@ class doc_generic_project_odt extends ModelePDFProjects 'task_note_private'=>$task->note_private, 'task_note_public'=>$task->note_public ); + + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields = new ExtraFields($this->db); + $extralabels = $extrafields->fetch_name_optionals_label($task->table_element,true); + $task->fetch_optionals($task->id,$extralabels); + + $resarray = $this->fill_substitutionarray_with_extrafields($task,$resarray,$extrafields,'task',$outputlangs); + + return $resarray; + } /** From 4e16f64af0a95f0968cbdb37a8f6ec79fc18bdb7 Mon Sep 17 00:00:00 2001 From: atm-greg Date: Thu, 9 Aug 2018 12:13:06 +0200 Subject: [PATCH 42/72] Fix project::delete to delete children tasks before parent tasks --- htdocs/projet/class/project.class.php | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 5dce267d965..6710aa98ffc 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -633,9 +633,7 @@ class Project extends CommonObject $this->getLinesArray($user); // Delete tasks - foreach($this->lines as &$task) { - $task->delete($user); - } + $this->deleteTasks($this->lines); // Delete project if (! $error) @@ -711,6 +709,25 @@ class Project extends CommonObject return -1; } } + + /** + * Reoder tasks to delete children tasks first + * + * @param array $arr Array of tasks + */ + function deleteTasks($arr) + { + global $user; + + $arrParents = array(); + foreach($arr as $task) + { + if($task->hasChildren() < 0) $task->delete($user); + else $arrParents[] = $task; + } + + if (count($arrParents)) $this->deleteTasks($arrParents); + } /** * Validate a project From 3d84adbd7635e772d9d38da435a6e00c9c37d6cd Mon Sep 17 00:00:00 2001 From: atm-greg Date: Thu, 9 Aug 2018 12:21:48 +0200 Subject: [PATCH 43/72] fix recurcivity --- htdocs/projet/class/project.class.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 6710aa98ffc..2292487898d 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -719,14 +719,12 @@ class Project extends CommonObject { global $user; - $arrParents = array(); foreach($arr as $task) { - if($task->hasChildren() < 0) $task->delete($user); - else $arrParents[] = $task; + if($task->hasChildren() <= 0) $task->delete($user); } - - if (count($arrParents)) $this->deleteTasks($arrParents); + $this->getLinesArray($user); + if (count($this->lines)) $this->deleteTasks($this->lines); } /** From ba6f7d4b0a1daba4ab391e76fc39d30eefe84699 Mon Sep 17 00:00:00 2001 From: atm-greg Date: Tue, 14 Aug 2018 09:32:43 +0200 Subject: [PATCH 44/72] fix infinite loop --- htdocs/projet/class/project.class.php | 32 ++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 2292487898d..4413e9b3361 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -633,7 +633,8 @@ class Project extends CommonObject $this->getLinesArray($user); // Delete tasks - $this->deleteTasks($this->lines); + $ret = $this->deleteTasks($user); + if ($ret < 0) $error++; // Delete project if (! $error) @@ -715,16 +716,31 @@ class Project extends CommonObject * * @param array $arr Array of tasks */ - function deleteTasks($arr) + function deleteTasks($user) { - global $user; - - foreach($arr as $task) - { - if($task->hasChildren() <= 0) $task->delete($user); + $countTasks = count($this->lines); + $deleted = false; + if ($countTasks){ + foreach($this->lines as $task) + { + if($task->hasChildren() <= 0) { + $deleted = true; + $ret = $task->delete($user); + if ($ret < 1) + { + $this->errors[] = $this->db->lasterror(); + return -1; + } + } + } } $this->getLinesArray($user); - if (count($this->lines)) $this->deleteTasks($this->lines); + if($deleted && count($this->lines) < $countTasks) + { + if (count($this->lines)) $this->deleteTasks($this->lines); + } + + return 1; } /** From 20309665e60ea50ff3f1050ffcc91a934f21e025 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Tue, 14 Aug 2018 10:45:08 +0200 Subject: [PATCH 45/72] fix : ODT project substitution --- .../doc/doc_generic_project_odt.modules.php | 209 +++++++++++++----- .../projects/template_project.odt | Bin 29375 -> 22487 bytes 2 files changed, 153 insertions(+), 56 deletions(-) diff --git a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php index c2258f9ba97..d2f5a859197 100644 --- a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php +++ b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php @@ -160,6 +160,7 @@ class doc_generic_project_odt extends ModelePDFProjects 'task_description'=>$task->description, 'task_fk_parent'=>$task->fk_parent, 'task_duration'=>$task->duration, + 'task_duration_hour'=>convertSecondToTime($task->duration,'all'), 'task_progress'=>$task->progress, 'task_public'=>$task->public, 'task_date_start'=>dol_print_date($task->date_start,'day'), @@ -317,7 +318,10 @@ class doc_generic_project_odt extends ModelePDFProjects 'tasktime_fk_user'=>$tasktime['fk_user'], 'tasktime_user_name'=>$tasktime['name'], 'tasktime_user_first'=>$tasktime['firstname'], - 'tasktime_fullcivname'=>$tasktime['fullcivname'] + 'tasktime_fullcivname'=>$tasktime['fullcivname'], + 'tasktime_amountht'=>$tasktime['amountht'], + 'tasktime_amountttc'=>$tasktime['amountttc'], + 'tasktime_thm'=>$tasktime['thm'], ); } @@ -698,7 +702,7 @@ class doc_generic_project_odt extends ModelePDFProjects //Time ressources $sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note"; - $sql.= ", u.lastname, u.firstname"; + $sql.= ", u.lastname, u.firstname, t.thm"; $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; $sql .= " , ".MAIN_DB_PREFIX."user as u"; $sql .= " WHERE t.fk_task =".$task->id; @@ -712,6 +716,35 @@ class doc_generic_project_odt extends ModelePDFProjects $i = 0; $tasks = array(); $listlinestasktime = $listlines->__get('taskstimes'); + if (empty($num)) { + $row['rowid']=''; + $row['task_date']=''; + $row['task_duration']=''; + $row['$tasktime']=''; + $row['note']=''; + $row['fk_user']=''; + $row['name']=''; + $row['firstname']=''; + $row['fullcivname']=''; + $row['amountht']=''; + $row['amountttc']=''; + $row['thm']=''; + $tmparray=$this->get_substitutionarray_taskstime($row,$outputlangs); + foreach($tmparray as $key => $val) + { + try + { + $listlinestasktime->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlinestasktime->merge(); + } while ($i < $num) { $row = $this->db->fetch_array($resql); @@ -723,6 +756,16 @@ class doc_generic_project_odt extends ModelePDFProjects $row['fullcivname']=''; } + if (!empty($row['thm'])) { + $row['amountht']=($row['task_duration'] / 3600) * $row['thm']; + $defaultvat = get_default_tva($mysoc, $mysoc); + $row['amountttc']=price2num($row['amountht'] * (1 + ($defaultvat / 100)),'MT');; + } else { + $row['amountht']=0; + $row['amountttc']=0; + $row['thm']=0; + } + $tmparray=$this->get_substitutionarray_taskstime($row,$outputlangs); foreach($tmparray as $key => $val) @@ -884,60 +927,114 @@ class doc_generic_project_odt extends ModelePDFProjects //List of referent - $listofreferent=array( - 'propal'=>array( - 'title'=>"ListProposalsAssociatedProject", - 'class'=>'Propal', - 'table'=>'propal', - 'test'=>$conf->propal->enabled && $user->rights->propale->lire), - 'order'=>array( - 'title'=>"ListOrdersAssociatedProject", - 'class'=>'Commande', - 'table'=>'commande', - 'test'=>$conf->commande->enabled && $user->rights->commande->lire), - 'invoice'=>array( - 'title'=>"ListInvoicesAssociatedProject", - 'class'=>'Facture', - 'table'=>'facture', - 'test'=>$conf->facture->enabled && $user->rights->facture->lire), - 'invoice_predefined'=>array( - 'title'=>"ListPredefinedInvoicesAssociatedProject", - 'class'=>'FactureRec', - 'table'=>'facture_rec', - 'test'=>$conf->facture->enabled && $user->rights->facture->lire), - 'order_supplier'=>array( - 'title'=>"ListSupplierOrdersAssociatedProject", - 'table'=>'commande_fournisseur', - 'class'=>'CommandeFournisseur', - 'test'=>$conf->fournisseur->enabled && $user->rights->fournisseur->commande->lire), - 'invoice_supplier'=>array( - 'title'=>"ListSupplierInvoicesAssociatedProject", - 'table'=>'facture_fourn', - 'class'=>'FactureFournisseur', - 'test'=>$conf->fournisseur->enabled && $user->rights->fournisseur->facture->lire), - 'contract'=>array( - 'title'=>"ListContractAssociatedProject", - 'class'=>'Contrat', - 'table'=>'contrat', - 'test'=>$conf->contrat->enabled && $user->rights->contrat->lire), - 'intervention'=>array( - 'title'=>"ListFichinterAssociatedProject", - 'class'=>'Fichinter', - 'table'=>'fichinter', - 'disableamount'=>1, - 'test'=>$conf->ficheinter->enabled && $user->rights->ficheinter->lire), - 'trip'=>array( - 'title'=>"ListTripAssociatedProject", - 'class'=>'Deplacement', - 'table'=>'deplacement', - 'disableamount'=>1, - 'test'=>$conf->deplacement->enabled && $user->rights->deplacement->lire), - 'agenda'=>array( - 'title'=>"ListActionsAssociatedProject", - 'class'=>'ActionComm', - 'table'=>'actioncomm', - 'disableamount'=>1, - 'test'=>$conf->agenda->enabled && $user->rights->agenda->allactions->lire) + $listofreferent = array( + 'propal' => array( + 'title' => "ListProposalsAssociatedProject", + 'class' => 'Propal', + 'table' => 'propal', + 'test' => $conf->propal->enabled && $user->rights->propale->lire + ), + 'order' => array( + 'title' => "ListOrdersAssociatedProject", + 'class' => 'Commande', + 'table' => 'commande', + 'test' => $conf->commande->enabled && $user->rights->commande->lire + ), + 'invoice' => array( + 'title' => "ListInvoicesAssociatedProject", + 'class' => 'Facture', + 'table' => 'facture', + 'test' => $conf->facture->enabled && $user->rights->facture->lire + ), + 'invoice_predefined' => array( + 'title' => "ListPredefinedInvoicesAssociatedProject", + 'class' => 'FactureRec', + 'table' => 'facture_rec', + 'test' => $conf->facture->enabled && $user->rights->facture->lire + ), + 'proposal_supplier' => array( + 'title' => "ListSupplierProposalsAssociatedProject", + 'class' => 'SupplierProposal', + 'table' => 'supplier_proposal', + 'test' => $conf->supplier_proposal->enabled && $user->rights->supplier_proposal->lire + ), + 'order_supplier' => array( + 'title' => "ListSupplierOrdersAssociatedProject", + 'table' => 'commande_fournisseur', + 'class' => 'CommandeFournisseur', + 'test' => $conf->fournisseur->enabled && $user->rights->fournisseur->commande->lire + ), + 'invoice_supplier' => array( + 'title' => "ListSupplierInvoicesAssociatedProject", + 'table' => 'facture_fourn', + 'class' => 'FactureFournisseur', + 'test' => $conf->fournisseur->enabled && $user->rights->fournisseur->facture->lire + ), + 'contract' => array( + 'title' => "ListContractAssociatedProject", + 'class' => 'Contrat', + 'table' => 'contrat', + 'test' => $conf->contrat->enabled && $user->rights->contrat->lire + ), + 'intervention' => array( + 'title' => "ListFichinterAssociatedProject", + 'class' => 'Fichinter', + 'table' => 'fichinter', + 'disableamount' => 1, + 'test' => $conf->ficheinter->enabled && $user->rights->ficheinter->lire + ), + 'shipping' => array( + 'title' => "ListShippingAssociatedProject", + 'class' => 'Expedition', + 'table' => 'expedition', + 'disableamount' => 1, + 'test' => $conf->expedition->enabled && $user->rights->expedition->lire + ), + 'trip' => array( + 'title' => "ListTripAssociatedProject", + 'class' => 'Deplacement', + 'table' => 'deplacement', + 'disableamount' => 1, + 'test' => $conf->deplacement->enabled && $user->rights->deplacement->lire + ), + 'expensereport' => array( + 'title' => "ListExpenseReportsAssociatedProject", + 'class' => 'ExpenseReportLine', + 'table' => 'expensereport_det', + 'test' => $conf->expensereport->enabled && $user->rights->expensereport->lire + ), + 'donation' => array( + 'title' => "ListDonationsAssociatedProject", + 'class' => 'Don', + 'table' => 'don', + 'test' => $conf->don->enabled && $user->rights->don->lire + ), + 'loan' => array( + 'title' => "ListLoanAssociatedProject", + 'class' => 'Loan', + 'table' => 'loan', + 'test' => $conf->loan->enabled && $user->rights->loan->read + ), + 'chargesociales' => array( + 'title' => "ListSocialContributionAssociatedProject", + 'class' => 'ChargeSociales', + 'table' => 'chargesociales', + 'urlnew' => DOL_URL_ROOT . '/compta/sociales/card.php?action=create&projectid=' . $id, + 'test' => $conf->tax->enabled && $user->rights->tax->charges->lire + ), + 'stock_mouvement' => array( + 'title' => "ListMouvementStockProject", + 'class' => 'MouvementStock', + 'table' => 'stock_mouvement', + 'test' => ($conf->stock->enabled && $user->rights->stock->mouvement->lire && ! empty($conf->global->STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW)) + ), + 'agenda' => array( + 'title' => "ListActionsAssociatedProject", + 'class' => 'ActionComm', + 'table' => 'actioncomm', + 'disableamount' => 1, + 'test' => $conf->agenda->enabled && $user->rights->agenda->allactions->lire + ) ); //Insert reference diff --git a/htdocs/install/doctemplates/projects/template_project.odt b/htdocs/install/doctemplates/projects/template_project.odt index fca796a26ddcd9d7990b80782bed00a32db09aa8..b6fd0349ea43e1223bdb9ec01343dd1a3895963a 100644 GIT binary patch delta 21028 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 W?N|%a$Kvc+vDwaa6s!isBmV=yfD)Mi literal 29375 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 PHsq%O!d$mjcUS)hQNnij From bb09bcece4b5b877cca6f2d82af4541e74eeb059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 16 Aug 2018 16:03:56 +0200 Subject: [PATCH 46/72] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3eb0941568a..b93de1c4de2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # DOLIBARR ERP & CRM -![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg) ![Downloads per day](https://img.shields.io/sourceforge/dm/dolibarr.svg) +![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg?branch=4.0) ![Downloads per day](https://img.shields.io/sourceforge/dm/dolibarr.svg) Dolibarr ERP & CRM is a modern software package to manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda, ...). From 2aa0956f15ffde4ca09f4ae0c693dc23379c8d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 16 Aug 2018 16:08:04 +0200 Subject: [PATCH 47/72] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b93de1c4de2..e89f2d46daa 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # DOLIBARR ERP & CRM -![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg?branch=4.0) ![Downloads per day](https://img.shields.io/sourceforge/dm/dolibarr.svg) +![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/4.0.svg) ![Downloads per day](https://img.shields.io/sourceforge/dm/dolibarr.svg) Dolibarr ERP & CRM is a modern software package to manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda, ...). From 3523c2b3d2461fec5e223696b26e87a64e9b56fe Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Aug 2018 13:09:06 +0200 Subject: [PATCH 48/72] Update project.class.php --- htdocs/projet/class/project.class.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 4413e9b3361..ebc887ccbb6 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -712,21 +712,22 @@ class Project extends CommonObject } /** - * Reoder tasks to delete children tasks first + * Delete tasks with no children first, then task with children recursively * - * @param array $arr Array of tasks + * @param int <0 if KO, 1 if OK */ function deleteTasks($user) { $countTasks = count($this->lines); $deleted = false; - if ($countTasks){ + if ($countTasks) + { foreach($this->lines as $task) { - if($task->hasChildren() <= 0) { + if ($task->hasChildren() <= 0) { // If there is no children (or error to detect them) $deleted = true; $ret = $task->delete($user); - if ($ret < 1) + if ($ret <= 0) { $this->errors[] = $this->db->lasterror(); return -1; @@ -735,7 +736,7 @@ class Project extends CommonObject } } $this->getLinesArray($user); - if($deleted && count($this->lines) < $countTasks) + if ($deleted && count($this->lines) < $countTasks) { if (count($this->lines)) $this->deleteTasks($this->lines); } From 91bfa4be6cb9022f7474cb53cc8518feeff6c4f1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Aug 2018 13:10:20 +0200 Subject: [PATCH 49/72] Update project.class.php --- htdocs/projet/class/project.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index ebc887ccbb6..59a8db62dab 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -714,14 +714,15 @@ class Project extends CommonObject /** * Delete tasks with no children first, then task with children recursively * - * @param int <0 if KO, 1 if OK + * @param User $user User + * @return int <0 if KO, 1 if OK */ function deleteTasks($user) { $countTasks = count($this->lines); $deleted = false; if ($countTasks) - { + { foreach($this->lines as $task) { if ($task->hasChildren() <= 0) { // If there is no children (or error to detect them) From b1a3238c94f1c5b37a0c888819226d5ae326e35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 21 Aug 2018 14:22:29 +0200 Subject: [PATCH 50/72] Build badge for 5.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 64faedeb8b6..46216642e49 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # DOLIBARR ERP & CRM -![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg) ![Downloads per day](https://img.shields.io/sourceforge/dm/dolibarr.svg) +![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/5.0.svg) ![Downloads per day](https://img.shields.io/sourceforge/dm/dolibarr.svg) Dolibarr ERP & CRM is a modern software package to manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda, ...). From 53e476483c0e47d37dbf3c1e55e8b119c3215695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 28 Aug 2018 09:38:24 +0200 Subject: [PATCH 51/72] Build Badge for 6.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fbbbdddf665..56ae0038be3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # DOLIBARR ERP & CRM -![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg) ![Downloads per day](https://img.shields.io/sourceforge/dm/dolibarr.svg) +![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/6.0.svg) ![Downloads per day](https://img.shields.io/sourceforge/dm/dolibarr.svg) Dolibarr ERP & CRM is a modern software package to manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda, ...). From 61a57e619f41a555d5a6af01ab6fc1f53b461855 Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 28 Aug 2018 16:54:04 +0200 Subject: [PATCH 52/72] FIX : $fk_account is always empty, must be $soc->fk_account --- htdocs/comm/propal/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 980121836ae..2fdaadd1d59 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1451,7 +1451,7 @@ if ($action == 'create') // Bank Account if (! empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL) && ! empty($conf->banque->enabled)) { print '' . $langs->trans('BankAccount') . ''; - $form->select_comptes($fk_account, 'fk_account', 0, '', 1); + $form->select_comptes($soc->fk_account, 'fk_account', 0, '', 1); print ''; } From 24be0b7305800c776ce09770e6df81d95dd0d978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Aug 2018 13:08:52 +0200 Subject: [PATCH 53/72] Update viewimage.php code may have rich content (qrcode, datamatrix,...) --- htdocs/viewimage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php index 3f7ddbcd1cb..1db05467a66 100644 --- a/htdocs/viewimage.php +++ b/htdocs/viewimage.php @@ -136,7 +136,7 @@ if (preg_match('/\.\./',$fullpath_original_file) || preg_match('/[<>|]/',$fullpa if ($modulepart == 'barcode') { $generator=GETPOST("generator","alpha"); - $code=GETPOST("code",'alpha'); + $code=GETPOST("code",'none'); $encoding=GETPOST("encoding","alpha"); $readable=GETPOST("readable",'alpha')?GETPOST("readable","alpha"):"Y"; From f8fef6107555ac6ad45976da8222a658357fb235 Mon Sep 17 00:00:00 2001 From: atm-greg Date: Thu, 30 Aug 2018 09:19:44 +0200 Subject: [PATCH 54/72] remove useless db begin --- htdocs/product/class/product.class.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 0b40f815816..f33029d368a 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4456,8 +4456,6 @@ class Product extends CommonObject $langs->load('products'); - $this->db->begin(); - $label_type = 'label'; if ($type == 'short') From 53caac13a962a7b2b32615e9b0eda6b8e0afec9c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Sep 2018 13:57:51 +0200 Subject: [PATCH 55/72] Test phpunit --- test/phpunit/AdherentTest.php | 4 +++- test/phpunit/AdminLibTest.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/test/phpunit/AdherentTest.php b/test/phpunit/AdherentTest.php index 34ec0a80917..864f9b757fb 100644 --- a/test/phpunit/AdherentTest.php +++ b/test/phpunit/AdherentTest.php @@ -61,7 +61,9 @@ class AdherentTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/AdminLibTest.php b/test/phpunit/AdminLibTest.php index 5cf34e969b1..cc83eefe84e 100644 --- a/test/phpunit/AdminLibTest.php +++ b/test/phpunit/AdminLibTest.php @@ -59,7 +59,9 @@ class AdminLibTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; From a69c3caf2c6a5a579312abf21a9ce922f1a5d017 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Sep 2018 14:10:06 +0200 Subject: [PATCH 56/72] Prepare compatibility with phpunit 6.1 --- test/phpunit/AdherentTest.php | 6 +- test/phpunit/AdminLibTest.php | 12 ++-- test/phpunit/BankAccountTest.php | 4 +- test/phpunit/BonPrelevementTest.php | 2 + test/phpunit/BuildDocTest.php | 4 +- test/phpunit/CMailFileTest.php | 6 +- test/phpunit/CategorieTest.php | 4 +- test/phpunit/ChargeSocialesTest.php | 20 ++++--- test/phpunit/CommandeFournisseurTest.php | 4 +- test/phpunit/CommandeTest.php | 4 +- test/phpunit/CommonObjectTest.php | 4 +- test/phpunit/CompanyBankAccountTest.php | 2 + test/phpunit/ContactTest.php | 4 +- test/phpunit/ContratTest.php | 2 + test/phpunit/CoreTest.php | 12 ++-- test/phpunit/DateLibTest.php | 32 ++++++----- test/phpunit/DateLibTzFranceTest.php | 2 + test/phpunit/DiscountTest.php | 2 + test/phpunit/EntrepotTest.php | 2 + test/phpunit/ExportTest.php | 2 + test/phpunit/FactureFournisseurTest.php | 2 + test/phpunit/FactureRecTest.php | 2 + test/phpunit/FactureTest.php | 4 +- test/phpunit/FactureTestRounding.php | 2 + test/phpunit/FichinterTest.php | 2 + test/phpunit/FilesLibTest.php | 6 +- test/phpunit/FormAdminTest.php | 2 + test/phpunit/Functions2LibTest.php | 4 +- test/phpunit/FunctionsLibTest.php | 16 +++--- test/phpunit/HolidayTest.php | 8 ++- test/phpunit/ImagesLibTest.php | 2 + test/phpunit/ImportTest.php | 2 + test/phpunit/JsonLibTest.php | 10 ++-- test/phpunit/LangTest.php | 2 + test/phpunit/MarginsLibTest.php | 6 +- test/phpunit/ModulesTest.php | 2 + test/phpunit/MouvementStockTest.php | 2 + test/phpunit/NumberingModulesTest.php | 6 +- test/phpunit/PaypalTest.php | 6 +- test/phpunit/PdfDocTest.php | 2 + test/phpunit/PgsqlTest.php | 6 +- test/phpunit/PricesTest.php | 8 ++- test/phpunit/ProductTest.php | 4 +- test/phpunit/ProjectTest.php | 2 + test/phpunit/PropalTest.php | 2 + test/phpunit/RestAPIUserTest.php | 22 ++++---- test/phpunit/ScriptsTest.php | 2 + test/phpunit/SecurityTest.php | 2 + test/phpunit/SocieteTest.php | 4 +- test/phpunit/SqlTest.php | 18 +++--- test/phpunit/UserGroupTest.php | 18 +++--- test/phpunit/UserTest.php | 4 +- test/phpunit/WebservicesInvoicesTest.php | 36 ++++++------ test/phpunit/WebservicesOrdersTest.php | 4 +- test/phpunit/WebservicesOtherTest.php | 4 +- test/phpunit/WebservicesProductsTest.php | 4 +- test/phpunit/WebservicesThirdpartyTest.php | 66 +++++++++++----------- test/phpunit/WebservicesUserTest.php | 4 +- test/phpunit/XCalLibTest.php | 4 +- 59 files changed, 275 insertions(+), 157 deletions(-) diff --git a/test/phpunit/AdherentTest.php b/test/phpunit/AdherentTest.php index 42b4ff7cf7f..316f74a7cc0 100644 --- a/test/phpunit/AdherentTest.php +++ b/test/phpunit/AdherentTest.php @@ -61,7 +61,9 @@ class AdherentTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; @@ -79,7 +81,7 @@ class AdherentTest extends PHPUnit_Framework_TestCase global $conf,$user,$langs,$db; $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. - if (! empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { + if (! empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { print "\n".__METHOD__." Company must be setup to have name-firstname in order 'Firstname Lastname'\n"; die(); } diff --git a/test/phpunit/AdminLibTest.php b/test/phpunit/AdminLibTest.php index d7f3d17a583..937ede95f3b 100644 --- a/test/phpunit/AdminLibTest.php +++ b/test/phpunit/AdminLibTest.php @@ -59,7 +59,9 @@ class AdminLibTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; @@ -142,21 +144,21 @@ class AdminLibTest extends PHPUnit_Framework_TestCase return $result; } - + /** * testEnableModule - * + * * @return void */ public function testEnableModule() { global $conf, $db, $langs, $user; - + require_once dirname(__FILE__).'/../../htdocs/core/modules/modExpenseReport.class.php'; print "Enable module modExpenseReport"; $moduledescriptor=new modExpenseReport($db); $moduledescriptor->init(); $conf->setValues($db); } - + } diff --git a/test/phpunit/BankAccountTest.php b/test/phpunit/BankAccountTest.php index a212ff0317a..f6c135158d5 100644 --- a/test/phpunit/BankAccountTest.php +++ b/test/phpunit/BankAccountTest.php @@ -61,7 +61,9 @@ class BankAccountTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/BonPrelevementTest.php b/test/phpunit/BonPrelevementTest.php index 0124b25e6c6..de0c3be3416 100644 --- a/test/phpunit/BonPrelevementTest.php +++ b/test/phpunit/BonPrelevementTest.php @@ -62,6 +62,8 @@ class BonPrelevementTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/BuildDocTest.php b/test/phpunit/BuildDocTest.php index 25b7bd15c03..1c8ac48c868 100644 --- a/test/phpunit/BuildDocTest.php +++ b/test/phpunit/BuildDocTest.php @@ -89,7 +89,9 @@ class BuildDocTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/CMailFileTest.php b/test/phpunit/CMailFileTest.php index 092d2e1f41c..ddc69676170 100755 --- a/test/phpunit/CMailFileTest.php +++ b/test/phpunit/CMailFileTest.php @@ -59,7 +59,9 @@ class CMailFileTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; @@ -103,7 +105,7 @@ class CMailFileTest extends PHPUnit_Framework_TestCase $db=$this->savdb; $conf->global->MAIN_DISABLE_ALL_MAILS=1; // If I comment/remove this lien, unit test still works alone but failed when ran from AllTest. Don't know why. - + print __METHOD__."\n"; } /** diff --git a/test/phpunit/CategorieTest.php b/test/phpunit/CategorieTest.php index 574a8d793f9..394267d40e1 100644 --- a/test/phpunit/CategorieTest.php +++ b/test/phpunit/CategorieTest.php @@ -60,7 +60,9 @@ class CategorieTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/ChargeSocialesTest.php b/test/phpunit/ChargeSocialesTest.php index 0836036afa5..8f06564eb1c 100644 --- a/test/phpunit/ChargeSocialesTest.php +++ b/test/phpunit/ChargeSocialesTest.php @@ -60,6 +60,8 @@ class ChargeSocialesTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; @@ -117,7 +119,7 @@ class ChargeSocialesTest extends PHPUnit_Framework_TestCase /** * testChargeSocialesCreate - * + * * @return void */ public function testChargeSocialesCreate() @@ -139,10 +141,10 @@ class ChargeSocialesTest extends PHPUnit_Framework_TestCase /** * testChargeSocialesFetch - * + * * @param int $id Id of social contribution * @return void - * + * * @depends testChargeSocialesCreate * The depends says test is run only if previous is ok */ @@ -164,10 +166,10 @@ class ChargeSocialesTest extends PHPUnit_Framework_TestCase /** * testChargeSocialesValid - * + * * @param Object $localobject Social contribution * @return void - * + * * @depends testChargeSocialesFetch * The depends says test is run only if previous is ok */ @@ -188,10 +190,10 @@ class ChargeSocialesTest extends PHPUnit_Framework_TestCase /** * testChargeSocialesOther - * + * * @param Object $localobject Social contribution * @return void - * + * * @depends testChargeSocialesValid * The depends says test is run only if previous is ok */ @@ -216,10 +218,10 @@ class ChargeSocialesTest extends PHPUnit_Framework_TestCase /** * testChargeSocialesDelete - * + * * @param int $id Social contribution * @return void - * + * * @depends testChargeSocialesOther * The depends says test is run only if previous is ok */ diff --git a/test/phpunit/CommandeFournisseurTest.php b/test/phpunit/CommandeFournisseurTest.php index 03880a56eca..61dcce7f06c 100644 --- a/test/phpunit/CommandeFournisseurTest.php +++ b/test/phpunit/CommandeFournisseurTest.php @@ -61,7 +61,9 @@ class CommandeFournisseurTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/CommandeTest.php b/test/phpunit/CommandeTest.php index aaba882cc87..73d0977d7fd 100644 --- a/test/phpunit/CommandeTest.php +++ b/test/phpunit/CommandeTest.php @@ -59,7 +59,9 @@ class CommandeTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/CommonObjectTest.php b/test/phpunit/CommonObjectTest.php index 18f96034fd1..09200a15b91 100644 --- a/test/phpunit/CommonObjectTest.php +++ b/test/phpunit/CommonObjectTest.php @@ -60,7 +60,9 @@ class CommonObjectTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/CompanyBankAccountTest.php b/test/phpunit/CompanyBankAccountTest.php index 95ea937a017..5c72dca72a0 100644 --- a/test/phpunit/CompanyBankAccountTest.php +++ b/test/phpunit/CompanyBankAccountTest.php @@ -60,6 +60,8 @@ class CompanyBankAccountTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/ContactTest.php b/test/phpunit/ContactTest.php index cb0f37875b3..b943020efea 100755 --- a/test/phpunit/ContactTest.php +++ b/test/phpunit/ContactTest.php @@ -68,6 +68,8 @@ class ContactTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; @@ -207,7 +209,7 @@ class ContactTest extends PHPUnit_Framework_TestCase $localobject->email='newemail@newemail.com'; $localobject->jabberid='New im id'; $localobject->default_lang='es_ES'; - + $result=$localobject->update($localobject->id,$user); print __METHOD__." id=".$localobject->id." result=".$result."\n"; $this->assertLessThan($result, 0, 'Contact::update error'); diff --git a/test/phpunit/ContratTest.php b/test/phpunit/ContratTest.php index 5adf002c885..7e7dfb64922 100644 --- a/test/phpunit/ContratTest.php +++ b/test/phpunit/ContratTest.php @@ -60,6 +60,8 @@ class ContratTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/CoreTest.php b/test/phpunit/CoreTest.php index 3a158260e96..43f74c840fe 100644 --- a/test/phpunit/CoreTest.php +++ b/test/phpunit/CoreTest.php @@ -62,7 +62,9 @@ class CoreTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; @@ -290,22 +292,22 @@ class CoreTest extends PHPUnit_Framework_TestCase } // Run tests - + $_SERVER["PHP_SELF"]='/DIR WITH SPACE/htdocs/admin/index.php?mainmenu=home&leftmenu=setup&username=weservices'; $result=test_sql_and_script_inject($_SERVER["PHP_SELF"], 2); $expectedresult=0; $this->assertEquals($expectedresult, $result, 'Error on test_sql_and_script_inject 1a'); - + $_SERVER["PHP_SELF"]='/DIR WITH SPACE/htdocs/admin/index.php?mainmenu=home&leftmenu=setup&username=weservices;badaction'; $result=test_sql_and_script_inject($_SERVER["PHP_SELF"], 2); $expectedresult=1; $this->assertEquals($expectedresult, $result, 'Error on test_sql_and_script_inject 1b'); - + $_GET['aaa']=""; $result=test_sql_and_script_inject($_GET['aaa'], 0); $expectedresult=1; $this->assertEquals($expectedresult, $result, 'Error on test_sql_and_script_inject 2'); - + $_POST['bbb']=""; $result=test_sql_and_script_inject($_POST['bbb'], 2); $expectedresult=1; diff --git a/test/phpunit/DateLibTest.php b/test/phpunit/DateLibTest.php index 02d85164d79..734465d0853 100644 --- a/test/phpunit/DateLibTest.php +++ b/test/phpunit/DateLibTest.php @@ -60,6 +60,8 @@ class DateLibTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; @@ -179,32 +181,32 @@ class DateLibTest extends PHPUnit_Framework_TestCase $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; - + // With same hours - Tuesday/Wednesday jan 2013 $date1=dol_mktime(0, 0, 0, 1, 1, 2013); $date2=dol_mktime(0, 0, 0, 1, 2, 2013); - + $result=num_public_holiday($date1,$date2,'FR',1); print __METHOD__." result=".$result."\n"; $this->assertEquals(1,$result,'NumPublicHoliday for Tuesday/Wednesday jan 2013 for FR'); // 1 closed days - + $result=num_public_holiday($date1,$date2,'XX',1); print __METHOD__." result=".$result."\n"; $this->assertEquals(0,$result,'NumPublicHoliday for Tuesday/Wednesday jan 2013 for XX'); // no closed days (country unknown) - + // With same hours - Friday/Sunday jan 2013 $date1=dol_mktime(0, 0, 0, 1, 4, 2013); $date2=dol_mktime(0, 0, 0, 1, 6, 2013); - + $result=num_public_holiday($date1,$date2,'FR',1); print __METHOD__." result=".$result."\n"; - $this->assertEquals(2,$result,'NumPublicHoliday for FR'); // 1 opened day, 2 closed days - + $this->assertEquals(2,$result,'NumPublicHoliday for FR'); // 1 opened day, 2 closed days + $result=num_public_holiday($date1,$date2,'XX',1); print __METHOD__." result=".$result."\n"; $this->assertEquals(2,$result,'NumPublicHoliday for XX'); // 1 opened day, 2 closed days (even if country unknown) } - + /** * testNumOpenDay * @@ -217,32 +219,32 @@ class DateLibTest extends PHPUnit_Framework_TestCase $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; - + // With same hours - Tuesday/Wednesday jan 2013 $date1=dol_mktime(0, 0, 0, 1, 1, 2013); $date2=dol_mktime(0, 0, 0, 1, 2, 2013); - + $result=num_open_day($date1,$date2,0,1,0,'FR'); print __METHOD__." result=".$result."\n"; $this->assertEquals(1,$result,'NumOpenDay Tuesday/Wednesday jan 2013 for FR'); // 1 opened days - + $result=num_open_day($date1,$date2,0,1,0,'XX'); print __METHOD__." result=".$result."\n"; $this->assertEquals(2,$result,'NumOpenDay Tuesday/Wednesday jan 2013 for XX'); // 2 opened days (country unknown) - + // With same hours - Friday/Sunday jan 2013 $date1=dol_mktime(0, 0, 0, 1, 4, 2013); $date2=dol_mktime(0, 0, 0, 1, 6, 2013); - + $result=num_open_day($date1,$date2,0,1,0,'FR'); print __METHOD__." result=".$result."\n"; $this->assertEquals(1,$result,'NumOpenDay for FR'); // 1 opened day, 2 closed - + $result=num_open_day($date1,$date2,'XX',1); print __METHOD__." result=".$result."\n"; $this->assertEquals(1,$result,'NumOpenDay for XX'); // 1 opened day, 2 closes (even if country unknown) } - + /** * testConvertTime2Seconds * diff --git a/test/phpunit/DateLibTzFranceTest.php b/test/phpunit/DateLibTzFranceTest.php index 668af000204..b41688c153f 100644 --- a/test/phpunit/DateLibTzFranceTest.php +++ b/test/phpunit/DateLibTzFranceTest.php @@ -60,6 +60,8 @@ class DateLibTzFranceTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/DiscountTest.php b/test/phpunit/DiscountTest.php index cf4d5033597..724a97e6f3e 100644 --- a/test/phpunit/DiscountTest.php +++ b/test/phpunit/DiscountTest.php @@ -60,6 +60,8 @@ class DiscountTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/EntrepotTest.php b/test/phpunit/EntrepotTest.php index d3d7c300308..6f27685faa7 100644 --- a/test/phpunit/EntrepotTest.php +++ b/test/phpunit/EntrepotTest.php @@ -60,6 +60,8 @@ class EntrepotTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/ExportTest.php b/test/phpunit/ExportTest.php index 7c14b0ccd64..af1c1e95a26 100644 --- a/test/phpunit/ExportTest.php +++ b/test/phpunit/ExportTest.php @@ -64,6 +64,8 @@ class ExportTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/FactureFournisseurTest.php b/test/phpunit/FactureFournisseurTest.php index 199d397f50d..b91092f294e 100644 --- a/test/phpunit/FactureFournisseurTest.php +++ b/test/phpunit/FactureFournisseurTest.php @@ -60,6 +60,8 @@ class FactureFournisseurTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/FactureRecTest.php b/test/phpunit/FactureRecTest.php index f7f857fe317..07d728eb0ec 100644 --- a/test/phpunit/FactureRecTest.php +++ b/test/phpunit/FactureRecTest.php @@ -61,6 +61,8 @@ class FactureRecTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/FactureTest.php b/test/phpunit/FactureTest.php index 142a5284989..678992ed77c 100644 --- a/test/phpunit/FactureTest.php +++ b/test/phpunit/FactureTest.php @@ -59,7 +59,9 @@ class FactureTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/FactureTestRounding.php b/test/phpunit/FactureTestRounding.php index 5fe0df4e5d0..4ed76d900bf 100644 --- a/test/phpunit/FactureTestRounding.php +++ b/test/phpunit/FactureTestRounding.php @@ -60,6 +60,8 @@ class FactureTestRounding extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/FichinterTest.php b/test/phpunit/FichinterTest.php index baa72b7020a..4d6e1224498 100644 --- a/test/phpunit/FichinterTest.php +++ b/test/phpunit/FichinterTest.php @@ -60,6 +60,8 @@ class FichinterTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/FilesLibTest.php b/test/phpunit/FilesLibTest.php index f9000006b46..8e4cc4b009b 100644 --- a/test/phpunit/FilesLibTest.php +++ b/test/phpunit/FilesLibTest.php @@ -61,6 +61,8 @@ class FilesLibTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; @@ -399,7 +401,7 @@ class FilesLibTest extends PHPUnit_Framework_TestCase print __METHOD__." result=".join(',',$result)."\n"; $this->assertEquals(0,count($result)); } - + /** * testDolDirList * @@ -411,7 +413,7 @@ class FilesLibTest extends PHPUnit_Framework_TestCase public function testDolDirList() { global $conf,$user,$langs,$db; - + // Scan dir to guaruante we on't have library jquery twice (we accept exception of duplicte into ckeditor because all dir is removed for debian package, so there is no duplicate). $founddirs=dol_dir_list(DOL_DOCUMENT_ROOT.'/includes/', 'files', 1, '^jquery\.js', array('ckeditor')); print __METHOD__." count(founddirs)=".count($founddirs)."\n"; diff --git a/test/phpunit/FormAdminTest.php b/test/phpunit/FormAdminTest.php index 30c96600210..876e733b56d 100644 --- a/test/phpunit/FormAdminTest.php +++ b/test/phpunit/FormAdminTest.php @@ -60,6 +60,8 @@ class FormAdminTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/Functions2LibTest.php b/test/phpunit/Functions2LibTest.php index 470a570bf6e..87b2eaefe58 100644 --- a/test/phpunit/Functions2LibTest.php +++ b/test/phpunit/Functions2LibTest.php @@ -63,7 +63,9 @@ class Functions2LibTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index ca06655c845..4da3beb48ee 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -63,7 +63,9 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; @@ -130,21 +132,21 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase /*$tmp=dol_buildpath('/google/oauth2callback.php', 0); var_dump($tmp); */ - + /*$tmp=dol_buildpath('/google/oauth2callback.php', 1); var_dump($tmp); */ - + $result=dol_buildpath('/google/oauth2callback.php', 2); print __METHOD__." result=".$result."\n"; $this->assertStringStartsWith('http', $result); - + $result=dol_buildpath('/google/oauth2callback.php', 3); print __METHOD__." result=".$result."\n"; $this->assertStringStartsWith('http', $result); } - - + + /** * testGetBrowserInfo * @@ -999,5 +1001,5 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase return true; } - + } diff --git a/test/phpunit/HolidayTest.php b/test/phpunit/HolidayTest.php index a04646a8a14..1239cff2f92 100644 --- a/test/phpunit/HolidayTest.php +++ b/test/phpunit/HolidayTest.php @@ -62,6 +62,8 @@ class HolidayTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; @@ -201,11 +203,11 @@ class HolidayTest extends PHPUnit_Framework_TestCase $localobject->email='newemail@newemail.com'; $localobject->jabberid='New im id'; $localobject->default_lang='es_ES'; - + $result=$localobject->update($localobject->id,$user); print __METHOD__." id=".$localobject->id." result=".$result."\n"; $this->assertLessThan($result, 0, 'Holiday::update error'); - + $result=$localobject->update_note($localobject->note_private,'_private'); print __METHOD__." id=".$localobject->id." result=".$result."\n"; $this->assertLessThan($result, 0, 'Holiday::update_note (private) error'); @@ -213,7 +215,7 @@ class HolidayTest extends PHPUnit_Framework_TestCase $result=$localobject->update_note($localobject->note_public, '_public'); print __METHOD__." id=".$localobject->id." result=".$result."\n"; $this->assertLessThan($result, 0, 'Holiday::update_note (public) error'); - + $newobject=new Holiday($this->savdb); $result=$newobject->fetch($localobject->id); diff --git a/test/phpunit/ImagesLibTest.php b/test/phpunit/ImagesLibTest.php index 41c7005e25d..cc4e6bd7462 100644 --- a/test/phpunit/ImagesLibTest.php +++ b/test/phpunit/ImagesLibTest.php @@ -61,6 +61,8 @@ class ImagesLibTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/ImportTest.php b/test/phpunit/ImportTest.php index 067b06910c9..0e80b6384e8 100644 --- a/test/phpunit/ImportTest.php +++ b/test/phpunit/ImportTest.php @@ -62,6 +62,8 @@ class ImportTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/JsonLibTest.php b/test/phpunit/JsonLibTest.php index 66999e31c65..cd63ed2f221 100644 --- a/test/phpunit/JsonLibTest.php +++ b/test/phpunit/JsonLibTest.php @@ -62,7 +62,9 @@ class JsonLibTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; @@ -134,7 +136,7 @@ class JsonLibTest extends PHPUnit_Framework_TestCase // Do a test with an array starting with 0 $arraytotest=array(0=>array('key'=>1,'value'=>'PRODREF','label'=>'Product ref with é and special chars \\ \' "')); $arrayencodedexpected='[{"key":1,"value":"PRODREF","label":"Product ref with \u00e9 and special chars \\\\ \' \""}]'; - + $encoded=json_encode($arraytotest); $this->assertEquals($arrayencodedexpected,$encoded); $decoded=json_decode($encoded,true); @@ -148,7 +150,7 @@ class JsonLibTest extends PHPUnit_Framework_TestCase // Same test but array start with 2 instead of 0 $arraytotest=array(2=>array('key'=>1,'value'=>'PRODREF','label'=>'Product ref with é and special chars \\ \' "')); $arrayencodedexpected='{"2":{"key":1,"value":"PRODREF","label":"Product ref with \u00e9 and special chars \\\\ \' \""}}'; - + $encoded=json_encode($arraytotest); $this->assertEquals($arrayencodedexpected,$encoded); $decoded=json_decode($encoded,true); @@ -158,7 +160,7 @@ class JsonLibTest extends PHPUnit_Framework_TestCase $this->assertEquals($arrayencodedexpected,$encoded); $decoded=dol_json_decode($encoded,true); $this->assertEquals($arraytotest,$decoded,'test for dol_json_xxx'); - + // Test with object $now=gmmktime(12,0,0,1,1,1970); $objecttotest=new stdClass(); diff --git a/test/phpunit/LangTest.php b/test/phpunit/LangTest.php index 4487568c1d6..61a34b37271 100644 --- a/test/phpunit/LangTest.php +++ b/test/phpunit/LangTest.php @@ -72,6 +72,8 @@ class LangTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/MarginsLibTest.php b/test/phpunit/MarginsLibTest.php index 7c2e8f68ef6..ae06128925c 100644 --- a/test/phpunit/MarginsLibTest.php +++ b/test/phpunit/MarginsLibTest.php @@ -60,6 +60,8 @@ class MarginsLibTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; @@ -136,7 +138,7 @@ class MarginsLibTest extends PHPUnit_Framework_TestCase $this->assertEquals(25,$result[1]); print __METHOD__." result[2]=".$result[2]."\n"; $this->assertEquals(20,$result[2]); - + $result=getMarginInfos(10, 10, 19.6, 0, 0, 0, 8); var_dump($result); print __METHOD__." result[0]=".$result[0]."\n"; @@ -145,7 +147,7 @@ class MarginsLibTest extends PHPUnit_Framework_TestCase $this->assertEquals(12.5,$result[1]); print __METHOD__." result[2]=".$result[2]."\n"; $this->assertEquals(1/9*100,$result[2]); - + return 0; } diff --git a/test/phpunit/ModulesTest.php b/test/phpunit/ModulesTest.php index e769ce9dd51..46b2fb4ee91 100755 --- a/test/phpunit/ModulesTest.php +++ b/test/phpunit/ModulesTest.php @@ -59,6 +59,8 @@ class ModulesTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/MouvementStockTest.php b/test/phpunit/MouvementStockTest.php index 826b55851e2..2779b3011d6 100644 --- a/test/phpunit/MouvementStockTest.php +++ b/test/phpunit/MouvementStockTest.php @@ -62,6 +62,8 @@ class MouvementStockTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/NumberingModulesTest.php b/test/phpunit/NumberingModulesTest.php index b29cd03b2c9..26302e19ea9 100644 --- a/test/phpunit/NumberingModulesTest.php +++ b/test/phpunit/NumberingModulesTest.php @@ -59,6 +59,8 @@ class NumberingModulesTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; @@ -75,7 +77,7 @@ class NumberingModulesTest extends PHPUnit_Framework_TestCase public static function setUpBeforeClass() { global $conf,$user,$langs,$db; - + $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. print __METHOD__."\n"; @@ -138,7 +140,7 @@ class NumberingModulesTest extends PHPUnit_Framework_TestCase $conf->global->FACTURE_MERCURE_MASK_CREDIT='{yyyy}-{0000}'; $conf->global->FACTURE_MERCURE_MASK_INVOICE='{yyyy}-{0000}'; $conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED=0; - + $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1915); // we use year 1915 to be sure to not have existing invoice for this year diff --git a/test/phpunit/PaypalTest.php b/test/phpunit/PaypalTest.php index fb48279cd66..59c28be2177 100644 --- a/test/phpunit/PaypalTest.php +++ b/test/phpunit/PaypalTest.php @@ -61,6 +61,8 @@ class PaypalTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; @@ -135,9 +137,9 @@ class PaypalTest extends PHPUnit_Framework_TestCase $urltotest=getPaypalPaymentUrl(1,'free'); print "urltotest=".$urltotest."\n"; - + $result=getURLContent($urltotest, 'GET'); - + print __METHOD__." result=".$result."\n"; $this->assertLessThanOrEqual($result, 0); diff --git a/test/phpunit/PdfDocTest.php b/test/phpunit/PdfDocTest.php index 13cb1b59ae3..0cf37b48762 100644 --- a/test/phpunit/PdfDocTest.php +++ b/test/phpunit/PdfDocTest.php @@ -63,6 +63,8 @@ class PdfDocTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/PgsqlTest.php b/test/phpunit/PgsqlTest.php index 05efcaeb30b..8347bc32905 100644 --- a/test/phpunit/PgsqlTest.php +++ b/test/phpunit/PgsqlTest.php @@ -62,6 +62,8 @@ class PgsqlTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; @@ -167,13 +169,13 @@ class PgsqlTest extends PHPUnit_Framework_TestCase $result=DoliDBPgsql::convertSQLFromMysql($sql); print __METHOD__." result=".$result."\n"; $this->assertEquals($result, "SELECT a.b, STRING_AGG(a.c, ',') FROM table GROUP BY a.b", 'Test GROUP_CONCAT (without SEPARATOR)'); - + // Test GROUP_CONCAT (with SEPARATOR) $sql="SELECT a.b, GROUP_CONCAT(a.c SEPARATOR ',') FROM table GROUP BY a.b"; $result=DoliDBPgsql::convertSQLFromMysql($sql); print __METHOD__." result=".$result."\n"; $this->assertEquals($result, "SELECT a.b, STRING_AGG(a.c, ',') FROM table GROUP BY a.b", 'Test GROUP_CONCAT (with SEPARATOR)'); - + return $result; } } diff --git a/test/phpunit/PricesTest.php b/test/phpunit/PricesTest.php index aee698c1a6e..9a89f8339b4 100755 --- a/test/phpunit/PricesTest.php +++ b/test/phpunit/PricesTest.php @@ -67,7 +67,9 @@ class PricesTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; @@ -160,8 +162,8 @@ class PricesTest extends PHPUnit_Framework_TestCase print __METHOD__." result1=".join(', ',$result1)."\n"; // result[0,1,2,3,4,5,6,7,8] (total_ht, total_vat, total_ttc, pu_ht, pu_tva, pu_ttc, total_ht_without_discount, total_vat_without_discount, total_ttc_without_discount) $this->assertEquals(array(17.12, 1.71, 18.83, 8.56, 0.856, 9.416, 17.12, 1.71, 18.83, 0, 0, 0, 0, 0, 0, 0, 18.7, 1.87, 20.56),$result1,'Test1 FR'); - - + + /* * Country Spain */ diff --git a/test/phpunit/ProductTest.php b/test/phpunit/ProductTest.php index 199aace802c..f9d3390c693 100644 --- a/test/phpunit/ProductTest.php +++ b/test/phpunit/ProductTest.php @@ -60,7 +60,9 @@ class ProductTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/ProjectTest.php b/test/phpunit/ProjectTest.php index c2f5d5b8161..ea7cf01c328 100644 --- a/test/phpunit/ProjectTest.php +++ b/test/phpunit/ProjectTest.php @@ -61,6 +61,8 @@ class ProjectTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/PropalTest.php b/test/phpunit/PropalTest.php index 707673e0d0f..23b07c25a26 100644 --- a/test/phpunit/PropalTest.php +++ b/test/phpunit/PropalTest.php @@ -60,6 +60,8 @@ class PropalTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/RestAPIUserTest.php b/test/phpunit/RestAPIUserTest.php index 189c17a0bd3..d25d0f1bc52 100644 --- a/test/phpunit/RestAPIUserTest.php +++ b/test/phpunit/RestAPIUserTest.php @@ -64,7 +64,9 @@ class RestAPIUserTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; @@ -106,7 +108,7 @@ class RestAPIUserTest extends PHPUnit_Framework_TestCase $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; - + $this->api_url=DOL_MAIN_URL_ROOT.'/api/index.php'; $login='admin'; @@ -149,7 +151,7 @@ class RestAPIUserTest extends PHPUnit_Framework_TestCase $url = $this->api_url.'/user/123456789?api_key='.$this->api_key; //$addheaders=array('Content-Type: application/json'); - + print __METHOD__." Request url=".$url."\n"; $result=getURLContent($url, 'GET', '', 1, array()); //print __METHOD__." Result for unexisting user: ".var_export($result, true)."\n"; @@ -158,7 +160,7 @@ class RestAPIUserTest extends PHPUnit_Framework_TestCase $object=json_decode($result['content'], true); $this->assertNotNull($object, "Parsing of json result must no be null"); $this->assertEquals(404, $object['error']['code']); - + $url = $this->api_url.'/user/1?api_key='.$this->api_key; print __METHOD__." Request url=".$url."\n"; @@ -172,18 +174,18 @@ class RestAPIUserTest extends PHPUnit_Framework_TestCase } public function testRestCreateUser() { - + // attemp to create without mandatory fields : $url = $this->api_url.'/user?api_key='.$this->api_key; $addheaders=array('Content-Type: application/json'); - + $bodyobj = array( "lastname"=>"testRestUser", "password"=>"testRestPassword", "email"=>"test@restuser.com" ); $body = json_encode($bodyobj); - + print __METHOD__." Request url=".$url."\n"; $result=getURLContent($url, 'POST', $body, 1, $addheaders); //print __METHOD__." Result for creating incomplete user".var_export($result, true)."\n"; @@ -207,17 +209,17 @@ class RestAPIUserTest extends PHPUnit_Framework_TestCase print __METHOD__." Result code for creating user ".var_export($result, true)."\n"; print __METHOD__." curl_error_no: ".$result['curl_error_no']."\n"; $this->assertEquals($result['curl_error_no'],''); - $object=json_decode($result['content'], true); + $object=json_decode($result['content'], true); $this->assertNotNull($object, "Parsing of json result must no be null"); $this->assertGreaterThan(0, $object['id'], $object['error']['code'].' '.$object['error']['message']); - + // attempt to create duplicated user print __METHOD__." Request url=".$url."\n"; $result=getURLContent($url, 'POST', $body, 1, $addheaders); //print __METHOD__." Result for creating duplicate user".var_export($result, true)."\n"; print __METHOD__." curl_error_no: ".$result['curl_error_no']."\n"; $this->assertEquals($result['curl_error_no'],''); - $object=json_decode($result['content'], true); + $object=json_decode($result['content'], true); $this->assertNotNull($object, "Parsing of json result must no be null"); $this->assertEquals(500, $object['error']['code'], $object['error']['code'].' '.$object['error']['message']); } diff --git a/test/phpunit/ScriptsTest.php b/test/phpunit/ScriptsTest.php index b7916c39d9f..0c49567a4a4 100644 --- a/test/phpunit/ScriptsTest.php +++ b/test/phpunit/ScriptsTest.php @@ -72,6 +72,8 @@ class ScriptsTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 00714e7bfab..2796ecb2c32 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -72,6 +72,8 @@ class SecurityTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; diff --git a/test/phpunit/SocieteTest.php b/test/phpunit/SocieteTest.php index 24b868b743e..5f1ed299cdc 100755 --- a/test/phpunit/SocieteTest.php +++ b/test/phpunit/SocieteTest.php @@ -60,7 +60,9 @@ class SocieteTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/SqlTest.php b/test/phpunit/SqlTest.php index 0a9acc50220..f2e3729fbe4 100644 --- a/test/phpunit/SqlTest.php +++ b/test/phpunit/SqlTest.php @@ -72,7 +72,9 @@ class SqlTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; @@ -143,16 +145,16 @@ class SqlTest extends PHPUnit_Framework_TestCase $listofsqldir = array(DOL_DOCUMENT_ROOT.'/install/mysql/tables', DOL_DOCUMENT_ROOT.'/install/mysql/migration'); - foreach ($listofsqldir as $dir) + foreach ($listofsqldir as $dir) { print 'Process dir '.$dir."\n"; $filesarray = scandir($dir); - - foreach($filesarray as $key => $file) + + foreach($filesarray as $key => $file) { if (! preg_match('/\.sql$/',$file)) continue; - + print 'Check sql file '.$file."\n"; $filecontent=file_get_contents($dir.'/'.$file); @@ -167,7 +169,7 @@ class SqlTest extends PHPUnit_Framework_TestCase $result=strpos($filecontent,'ON DELETE CASCADE'); print __METHOD__." Result for checking we don't have 'ON DELETE CASCADE' = ".$result."\n"; $this->assertTrue($result===false, 'Found ON DELETE CASCADE into '.$file.'. Bad.'); - + if ($dir == DOL_DOCUMENT_ROOT.'/install/mysql/migration') { // Test for migration files only @@ -176,9 +178,9 @@ class SqlTest extends PHPUnit_Framework_TestCase else { if (preg_match('/\.key\.sql$/',$file)) - { + { // Test for files key files only - + } else { diff --git a/test/phpunit/UserGroupTest.php b/test/phpunit/UserGroupTest.php index d41eefcbd39..b1e9b3bb43f 100644 --- a/test/phpunit/UserGroupTest.php +++ b/test/phpunit/UserGroupTest.php @@ -59,7 +59,9 @@ class UserGroupTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; @@ -117,7 +119,7 @@ class UserGroupTest extends PHPUnit_Framework_TestCase /** * testUserGroupCreate - * + * * @return void */ public function testUserGroupCreate() @@ -139,7 +141,7 @@ class UserGroupTest extends PHPUnit_Framework_TestCase /** * testUserGroupFetch - * + * * @param int $id Id of group * @return void * @depends testUserGroupCreate @@ -163,7 +165,7 @@ class UserGroupTest extends PHPUnit_Framework_TestCase /** * testUserGroupUpdate - * + * * @param Object $localobject Group * @return void * @depends testUserGroupFetch @@ -187,7 +189,7 @@ class UserGroupTest extends PHPUnit_Framework_TestCase /** * testUserGroupAddRight - * + * * @param Object $localobject Object to show * @return void * @depends testUserGroupUpdate @@ -210,7 +212,7 @@ class UserGroupTest extends PHPUnit_Framework_TestCase /** * testUserGroupDelRight - * + * * @param Object $localobject Object * @return void * @depends testUserGroupAddRight @@ -233,7 +235,7 @@ class UserGroupTest extends PHPUnit_Framework_TestCase /** * testUserGroupOther - * + * * @param Object $localobject Object * @return void * @depends testUserGroupDelRight @@ -261,7 +263,7 @@ class UserGroupTest extends PHPUnit_Framework_TestCase /** * testUserGroupDelete - * + * * @param int $id Id of object * @return void * @depends testUserGroupOther diff --git a/test/phpunit/UserTest.php b/test/phpunit/UserTest.php index 4e0c0ba58ca..912dd6f382b 100644 --- a/test/phpunit/UserTest.php +++ b/test/phpunit/UserTest.php @@ -59,7 +59,9 @@ class UserTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/WebservicesInvoicesTest.php b/test/phpunit/WebservicesInvoicesTest.php index ce3275bb58e..6e2ae6fbda1 100644 --- a/test/phpunit/WebservicesInvoicesTest.php +++ b/test/phpunit/WebservicesInvoicesTest.php @@ -55,9 +55,9 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase protected $savdb; protected $soapclient; protected $socid; - + protected $ns = 'http://www.dolibarr.org/ns/'; - + /** * Constructor * We save global variables into local variables @@ -66,6 +66,8 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase */ function __construct() { + parent::__construct(); + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; @@ -73,8 +75,8 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase $this->savlangs=$langs; $this->savdb=$db; $WS_DOL_URL = DOL_MAIN_URL_ROOT.'/webservices/server_invoice.php'; - - + + // Set the WebService URL print __METHOD__." create nusoap_client for URL=".$WS_DOL_URL."\n"; $this->soapclient = new nusoap_client($WS_DOL_URL); @@ -83,7 +85,7 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase $this->soapclient->soap_defencoding='UTF-8'; $this->soapclient->decodeUTF8(false); } - + // create third_parties, needed to test an invoice $societe=new Societe($db); $societe->ref=''; @@ -95,11 +97,11 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase $societe->date_creation=$now; $societe->tva_assuj=0; $societe->particulier=0; - + $societe->create($user); - + $this->socid = $societe->id; - + print __METHOD__." societe created id=".$societe->id."\n"; print __METHOD__." db->type=".$db->type." user->id=".$user->id; @@ -135,9 +137,9 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; - + print __METHOD__."\n"; - + } /** @@ -171,7 +173,7 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase $societe->fetch('', '', 'ref-phpunit'); print __METHOD__." societe loaded id=".$societe->id."\n"; */ - + $body = array ( "id" => NULL, "ref" => NULL, @@ -252,13 +254,13 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase return $result; } - + /** * testWSInvoicesGetInvoiceByRefExt - * + * * Retrieve an invoice using ref_ext * @depends testWSInvoicesCreateInvoice - * + * * @param array $result Invoice created by create method * @return array Invoice */ @@ -308,13 +310,13 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase return $result; } - + /** * testWSInvoicesUpdateInvoiceByRefExt - * + * * Update an invoice using ref_ext * @depends testWSInvoicesCreateInvoice - * + * * @param array $result invoice created by create method * @return array Invoice */ diff --git a/test/phpunit/WebservicesOrdersTest.php b/test/phpunit/WebservicesOrdersTest.php index 06ead4f4873..d9c718c399a 100644 --- a/test/phpunit/WebservicesOrdersTest.php +++ b/test/phpunit/WebservicesOrdersTest.php @@ -61,7 +61,9 @@ class WebservicesOrdersTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/WebservicesOtherTest.php b/test/phpunit/WebservicesOtherTest.php index d04fc6b9b9c..d31d4ed9cc0 100644 --- a/test/phpunit/WebservicesOtherTest.php +++ b/test/phpunit/WebservicesOtherTest.php @@ -61,7 +61,9 @@ class WebservicesOtherTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/WebservicesProductsTest.php b/test/phpunit/WebservicesProductsTest.php index fecc58a65e1..e9cdee38b8a 100644 --- a/test/phpunit/WebservicesProductsTest.php +++ b/test/phpunit/WebservicesProductsTest.php @@ -68,7 +68,9 @@ class WebservicesProductsTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/WebservicesThirdpartyTest.php b/test/phpunit/WebservicesThirdpartyTest.php index 2888c432e73..7bfd171436a 100644 --- a/test/phpunit/WebservicesThirdpartyTest.php +++ b/test/phpunit/WebservicesThirdpartyTest.php @@ -53,12 +53,12 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase protected $savlangs; protected $savdb; protected $soapclient; - + private $_WS_DOL_URL; private $_ns='http://www.dolibarr.org/ns/'; - - - + + + /** * Constructor @@ -68,15 +68,17 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; $this->savlangs=$langs; $this->savdb=$db; - + $this->_WS_DOL_URL = DOL_MAIN_URL_ROOT.'/webservices/server_thirdparty.php'; - + // Set the WebService URL print __METHOD__." create nusoap_client for URL=".$this->_WS_DOL_URL."\n"; $this->soapclient = new nusoap_client($this->_WS_DOL_URL); @@ -146,10 +148,10 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; - + $WS_METHOD = 'createThirdParty'; - - + + // Call the WebService method and store its result in $result. $authentication=array( 'dolibarrkey'=>$conf->global->WEBSERVICES_KEY, @@ -157,7 +159,7 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase 'login'=>'admin', 'password'=>'admin', 'entity'=>''); - + $body = array ( "id" => NULL, "ref" => "name", @@ -195,7 +197,7 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase "vat_used" => "", "vat_number" => "" ); - + // Test URL $result=''; $parameters = array('authentication'=>$authentication, 'thirdparty'=>$body); @@ -215,20 +217,20 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase print $this->soapclient->response; print "\n"; } - + print __METHOD__." result=".$result['result']['result_code']."\n"; $this->assertEquals('OK',$result['result']['result_code']); - $this->assertEquals('name',$result['ref']); - + $this->assertEquals('name',$result['ref']); + return $result; } /** * testWSThirdpartygetThirdPartyById - * + * * Use id to retrieve thirdparty * @depends testWSThirdpartycreateThirdParty - * + * * @param array $result thirdparty created by create method * @return array thirpdarty updated */ @@ -278,18 +280,18 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase $this->assertEquals('0', $result['thirdparty']['status']); $this->assertEquals('1', $result['thirdparty']['client']); $this->assertEquals('0', $result['thirdparty']['supplier']); - - + + return $result; } - + /** * testWSThirdpartygetThirdPartyByRefExt * * Use ref_ext to retrieve thirdparty * * @depends testWSThirdpartycreateThirdParty - * + * * @param array $result thirdparty created by create method * @return array thirdparty */ @@ -301,9 +303,9 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase $langs=$this->savlangs; $db=$this->savdb; $id = $result['id']; - + $WS_METHOD = 'getThirdParty'; - + // Call the WebService method and store its result in $result. $authentication=array( 'dolibarrkey'=>$conf->global->WEBSERVICES_KEY, @@ -311,7 +313,7 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase 'login'=>'admin', 'password'=>'admin', 'entity'=>''); - + // Test URL $result=''; $parameters = array('authentication'=>$authentication, 'id'=>'', 'ref'=>'', 'ref_ext'=>'12'); @@ -332,7 +334,7 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase print $this->soapclient->response; print "\n"; } - + print __METHOD__." result=".$result['result']['result_code']."\n"; $this->assertEquals('OK',$result['result']['result_code']); $this->assertEquals($id, $result['thirdparty']['id']); @@ -341,11 +343,11 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase $this->assertEquals('0', $result['thirdparty']['status']); $this->assertEquals('1', $result['thirdparty']['client']); $this->assertEquals('0', $result['thirdparty']['supplier']); - - + + return $result; } - + /** * testWSThirdpartydeleteThirdParty * @@ -362,9 +364,9 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase $langs=$this->savlangs; $db=$this->savdb; $id = $result['id']; - + $WS_METHOD = 'deleteThirdParty'; - + // Call the WebService method and store its result in $result. $authentication=array( 'dolibarrkey'=>$conf->global->WEBSERVICES_KEY, @@ -372,7 +374,7 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase 'login'=>'admin', 'password'=>'admin', 'entity'=>''); - + $result=''; $parameters = array('authentication'=>$authentication, 'id'=>$id, 'ref'=>'', 'ref_ext'=>''); print __METHOD__." call method ".$WS_METHOD."\n"; @@ -393,7 +395,7 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase print __METHOD__." result=".$result['result']['result_code']."\n"; $this->assertEquals('OK',$result['result']['result_code']); - + return $result; } diff --git a/test/phpunit/WebservicesUserTest.php b/test/phpunit/WebservicesUserTest.php index 9be97167104..b4cc865bf5c 100644 --- a/test/phpunit/WebservicesUserTest.php +++ b/test/phpunit/WebservicesUserTest.php @@ -61,7 +61,9 @@ class WebservicesUserTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; diff --git a/test/phpunit/XCalLibTest.php b/test/phpunit/XCalLibTest.php index 3bbf3469b17..932f68aa18d 100644 --- a/test/phpunit/XCalLibTest.php +++ b/test/phpunit/XCalLibTest.php @@ -59,7 +59,9 @@ class XCalLibTest extends PHPUnit_Framework_TestCase */ function __construct() { - //$this->sharedFixture + parent::__construct(); + + //$this->sharedFixture global $conf,$user,$langs,$db; $this->savconf=$conf; $this->savuser=$user; From df721a5fbcd7e4ea04160d1779670f0b864dc07f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Sep 2018 14:18:04 +0200 Subject: [PATCH 57/72] Only min and max php version --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index bac020e13c5..4c7a714eba1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -63,6 +63,14 @@ matrix: - php: nightly # We exclude some combinations not usefull to save Travis CPU exclude: + - php: '5.4' + env: DB=mysql + - php: '5.5' + env: DB=mysql + - php: '5.6' + env: DB=mysql + - php: '7.0' + env: DB=mysql - php: '5.4' env: DB=postgresql - php: '5.5' From 5bab9d59b29f4f7bcd5a580064fe137cd0c6b562 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Sep 2018 14:19:23 +0200 Subject: [PATCH 58/72] Fix var_dump --- test/phpunit/MarginsLibTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/test/phpunit/MarginsLibTest.php b/test/phpunit/MarginsLibTest.php index ae06128925c..21c07f7c04a 100644 --- a/test/phpunit/MarginsLibTest.php +++ b/test/phpunit/MarginsLibTest.php @@ -140,7 +140,6 @@ class MarginsLibTest extends PHPUnit_Framework_TestCase $this->assertEquals(20,$result[2]); $result=getMarginInfos(10, 10, 19.6, 0, 0, 0, 8); - var_dump($result); print __METHOD__." result[0]=".$result[0]."\n"; $this->assertEquals(8,$result[0]); print __METHOD__." result[1]=".$result[1]."\n"; From e0b272941fcfa5f4941b60a5a421193d8502b081 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Sep 2018 15:25:27 +0200 Subject: [PATCH 59/72] Fix mariadb --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4c7a714eba1..22593b1eb08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,13 +64,13 @@ matrix: # We exclude some combinations not usefull to save Travis CPU exclude: - php: '5.4' - env: DB=mysql + env: DB=mariadb - php: '5.5' - env: DB=mysql + env: DB=mariadb - php: '5.6' - env: DB=mysql + env: DB=mariadb - php: '7.0' - env: DB=mysql + env: DB=mariadb - php: '5.4' env: DB=postgresql - php: '5.5' From e285b42a185c4394b123832c377b9eeb7d995c64 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio Date: Mon, 3 Sep 2018 17:55:24 +0200 Subject: [PATCH 60/72] FIX: PDF address: handle when contact thirdparty different from document thirdparty --- htdocs/core/lib/pdf.lib.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 234c0cc7e34..b47bfbc79e6 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -432,8 +432,15 @@ function pdf_build_address($outputlangs,$sourcecompany,$targetcompany='',$target if (!empty($targetcontact->address)) { $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset(dol_format_address($targetcontact))."\n"; - }else { - $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset(dol_format_address($targetcompany))."\n"; + } else { + $companytouse = $targetcompany; + + if($targetcontact->socid > 0 && $targetcontact->socid != $targetcompany->id) { // Contact thirdparty different from document thirdparty + $targetcontact->fetch_thirparty(); + $companytouse = $targetcontact->thirdparty; + } + + $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset(dol_format_address($companytouse))."\n"; } // Country if (!empty($targetcontact->country_code) && $targetcontact->country_code != $sourcecompany->country_code) { From 252335318fcaaf03a9543f81d6083625090c878c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Sep 2018 09:57:01 +0200 Subject: [PATCH 61/72] Update pdf.lib.php --- htdocs/core/lib/pdf.lib.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index b47bfbc79e6..66caf2ea23a 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -433,14 +433,16 @@ function pdf_build_address($outputlangs,$sourcecompany,$targetcompany='',$target if (!empty($targetcontact->address)) { $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset(dol_format_address($targetcontact))."\n"; } else { - $companytouse = $targetcompany; + $companytouseforaddress = $targetcompany; - if($targetcontact->socid > 0 && $targetcontact->socid != $targetcompany->id) { // Contact thirdparty different from document thirdparty + // Contact on a thirdparty that is a different thirdparty than the thirdparty of object + if ($targetcontact->socid > 0 && $targetcontact->socid != $targetcompany->id) + { $targetcontact->fetch_thirparty(); - $companytouse = $targetcontact->thirdparty; + $companytouseforaddress = $targetcontact->thirdparty; } - $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset(dol_format_address($companytouse))."\n"; + $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset(dol_format_address($companytouseforaddress))."\n"; } // Country if (!empty($targetcontact->country_code) && $targetcontact->country_code != $sourcecompany->country_code) { From e4afd4af0084c6d0599f58fd44154ffa45665e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 4 Sep 2018 22:05:06 +0200 Subject: [PATCH 62/72] Create index.html --- htdocs/product/dynamic_price/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 htdocs/product/dynamic_price/index.html diff --git a/htdocs/product/dynamic_price/index.html b/htdocs/product/dynamic_price/index.html new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/htdocs/product/dynamic_price/index.html @@ -0,0 +1 @@ + From 2015268b7e0e0fb66311cd153cefddaa51657d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 4 Sep 2018 22:06:24 +0200 Subject: [PATCH 63/72] Create index.html --- htdocs/product/dynamic_price/class/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 htdocs/product/dynamic_price/class/index.html diff --git a/htdocs/product/dynamic_price/class/index.html b/htdocs/product/dynamic_price/class/index.html new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/htdocs/product/dynamic_price/class/index.html @@ -0,0 +1 @@ + From c94689e9a972e431de79965d223af5c0c416f5f2 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Wed, 12 Sep 2018 09:21:23 +0200 Subject: [PATCH 64/72] FIX remain to pay for credit note was wrong on invoice list --- htdocs/compta/facture/list.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 859889966eb..1fbdfcf380a 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -1014,6 +1014,9 @@ if ($resql) $facturestatic->ref=$obj->ref; $facturestatic->type=$obj->type; $facturestatic->statut=$obj->fk_statut; + $facturestatic->total_ttc=$obj->total_ttc; + $facturestatic->paye=$obj->paye; + $facturestatic->fk_soc=$obj->fk_soc; $facturestatic->date_lim_reglement=$db->jdate($obj->datelimite); $facturestatic->note_public=$obj->note_public; $facturestatic->note_private=$obj->note_private; @@ -1022,7 +1025,13 @@ if ($resql) $totalcreditnotes = $facturestatic->getSumCreditNotesUsed(); $totaldeposits = $facturestatic->getSumDepositsUsed(); $totalpay = $paiement + $totalcreditnotes + $totaldeposits; - $remaintopay = $obj->total_ttc - $totalpay; + $remaintopay = $facturestatic->total_ttc - $totalpay; + if($facturestatic->type == Facture::TYPE_CREDIT_NOTE && $obj->paye == 1) { + $discount = new DiscountAbsolute($db); + $remaincreditnote = $discount->getAvailableDiscounts($obj->fk_soc, '', 'rc.fk_facture_source='.$facturestatic->id); + $remaintopay = -$remaincreditnote; + $totalpay = $facturestatic->total_ttc - $remaintopay; + } print ''; if (! empty($arrayfields['f.facnumber']['checked'])) From 7838b75ec9dba723f6f0f11ce97f4b180efb6001 Mon Sep 17 00:00:00 2001 From: gauthier Date: Thu, 13 Sep 2018 16:11:42 +0200 Subject: [PATCH 65/72] FIX : wrong var name --- htdocs/fourn/commande/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 7a1d80daa28..e4f79f6ac88 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -401,7 +401,7 @@ if (empty($reshook)) $localtax2_tx, $idprod, $productsupplier->product_fourn_price_id, - $productsupplier->fourn_ref, + $productsupplier->ref_supplier, $remise_percent, 'HT', $pu_ttc, From cdbb79a26c579fcf694965a54eb5f3dcb46022ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 19 Sep 2018 09:26:56 +0200 Subject: [PATCH 66/72] correct typo in multicurrency doc pdf --- .gitignore | 1 + htdocs/core/modules/commande/doc/pdf_einstein.modules.php | 6 +++--- htdocs/core/modules/facture/doc/pdf_crabe.modules.php | 6 +++--- htdocs/core/modules/propale/doc/pdf_azur.modules.php | 6 +++--- .../modules/supplier_invoice/pdf/pdf_canelle.modules.php | 6 +++--- .../modules/supplier_order/pdf/pdf_muscadet.modules.php | 6 +++--- 6 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 1efe4f4bb82..a0fbe7489df 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ dolibarr_install.log upgrade.log doxygen_warnings.log /.project +/.vscode .DS_Store .idea *.iml diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php index 9fecdc277b5..9dc2b770222 100644 --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php @@ -7,6 +7,7 @@ * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2015 Marcos García * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018 Frédéric France * * 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 @@ -856,7 +857,7 @@ class pdf_einstein extends ModelePDFCommandes $pdf->SetXY($col1x, $tab2_top + 0); $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1); - $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); + $total_ht = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); $pdf->SetXY($col2x, $tab2_top + 0); $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (! empty($object->remise)?$object->remise:0), 0, $outputlangs), 0, 'R', 1); @@ -1307,7 +1308,7 @@ class pdf_einstein extends ModelePDFCommandes { $top_shift = $pdf->getY() - $current_y; } - + if ($showaddress) { // Sender properties @@ -1421,4 +1422,3 @@ class pdf_einstein extends ModelePDFCommandes } } - diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 88a47095b8c..804eb8885db 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -8,6 +8,7 @@ * Copyright (C) 2012-2014 Raphaël Doursenaud * Copyright (C) 2015 Marcos García * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018 Frédéric France * * 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 @@ -1054,7 +1055,7 @@ class pdf_crabe extends ModelePDFFactures $pdf->SetXY($col1x, $tab2_top + 0); $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1); - $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); + $total_ht = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); $pdf->SetXY($col2x, $tab2_top + 0); $pdf->MultiCell($largcol2, $tab2_hl, price($sign * ($total_ht + (! empty($object->remise)?$object->remise:0)), 0, $outputlangs), 0, 'R', 1); @@ -1679,7 +1680,7 @@ class pdf_crabe extends ModelePDFFactures { $top_shift = $pdf->getY() - $current_y; } - + if ($showaddress) { // Sender properties @@ -1788,4 +1789,3 @@ class pdf_crabe extends ModelePDFFactures } } - diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index 03d0db86d8f..17b99fb8b36 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -7,6 +7,7 @@ * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2015 Marcos García * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018 Frédéric France * * 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 @@ -1004,7 +1005,7 @@ class pdf_azur extends ModelePDFPropales $pdf->SetXY($col1x, $tab2_top + 0); $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1); - $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); + $total_ht = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); $pdf->SetXY($col2x, $tab2_top + 0); $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (! empty($object->remise)?$object->remise:0), 0, $outputlangs), 0, 'R', 1); @@ -1493,7 +1494,7 @@ class pdf_azur extends ModelePDFPropales { $top_shift = $pdf->getY() - $current_y; } - + if ($showaddress) { // Sender properties @@ -1636,4 +1637,3 @@ class pdf_azur extends ModelePDFPropales return ($tab_hl*7); } } - diff --git a/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php b/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php index 11951e90207..9cfc1be320b 100644 --- a/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php +++ b/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php @@ -2,6 +2,7 @@ /* Copyright (C) 2010-2011 Juanjo Menent * Copyright (C) 2010-2014 Laurent Destailleur * Copyright (C) 2015 Marcos García + * Copyright (C) 2018 Frédéric France * * 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 @@ -598,7 +599,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices $pdf->SetXY($col1x, $tab2_top + 0); $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1); - $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); + $total_ht = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); $pdf->SetXY($col2x, $tab2_top + 0); $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + $object->remise), 0, 'R', 1); @@ -1094,7 +1095,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices $object->fetch_user($arrayidcontact[0]); $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n"; } - + $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty); // Show sender @@ -1192,4 +1193,3 @@ class pdf_canelle extends ModelePDFSuppliersInvoices } } - diff --git a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php index 196d1f0c6a2..23a06264778 100644 --- a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php +++ b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php @@ -5,6 +5,7 @@ * Copyright (C) 2010-2014 Juanjo Menent * Copyright (C) 2015 Marcos García * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018 Frédéric France * * 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 @@ -695,7 +696,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders $pdf->SetXY($col1x, $tab2_top + 0); $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1); - $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); + $total_ht = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); $pdf->SetXY($col2x, $tab2_top + 0); $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (! empty($object->remise)?$object->remise:0)), 0, 'R', 1); @@ -1144,7 +1145,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders $object->fetch_user($arrayidcontact[0]); $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n"; } - + $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty); // Show sender @@ -1242,4 +1243,3 @@ class pdf_muscadet extends ModelePDFSuppliersOrders } } - From d62118dca83ca6f57758deabf3cbb82c759cddbc Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 19 Sep 2018 14:53:56 +0200 Subject: [PATCH 67/72] FIX : langs fr --- htdocs/langs/fr_FR/agenda.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index dbbf3513041..5efd3959e6e 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -108,7 +108,7 @@ MyAvailability=Ma disponibilité ActionType=Type événement DateActionBegin=Date début événément CloneAction=Cloner l'événement -ConfirmCloneEvent=Êtes-vous sûr de vouloir cloner cette facture %s ? +ConfirmCloneEvent=Êtes-vous sûr de vouloir cloner l'événement %s ? RepeatEvent=Répétez événement EveryWeek=Chaque semaine EveryMonth=Chaque mois From 12690666e2cbe0ccb4b961bd00e6120b348badf7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 24 Sep 2018 10:03:08 +0200 Subject: [PATCH 68/72] Missing trans --- htdocs/langs/en_US/admin.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index f932ec05959..6f2a8a951b5 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1705,6 +1705,7 @@ BaseCurrency=Reference currency of the company (go into setup of company to chan WarningNoteModuleInvoiceForFrenchLaw=This module %s is compliant with french laws (Loi Finance 2016). WarningNoteModulePOSForFrenchLaw=This module %s is compliant with french laws (Loi Finance 2016) because module Non Reversible Logs is automatically activated. WarningInstallationMayBecomeNotCompliantWithLaw=You try to install the module %s that is an external module. Activating an external module means you trust the publisher of the module and you are sure that this module does not alterate negatively the behavior of your application and is compliant with laws of your country (%s). If the module bring a non legal feature, you become responsible for the use of a non legal software. +NothingToSetup=There is no specific setup to do for this module. ##### Resource #### ResourceSetup=Configuration du module Resource UseSearchToSelectResource=Use a search form to choose a resource (rather than a drop-down list). From d15c52db3b8e9614e868e02ed96761ffc8017611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 25 Sep 2018 08:16:05 +0200 Subject: [PATCH 69/72] Update rssparser.class.php --- htdocs/core/class/rssparser.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/rssparser.class.php b/htdocs/core/class/rssparser.class.php index 56e338b7eb8..1417b9a0e29 100644 --- a/htdocs/core/class/rssparser.class.php +++ b/htdocs/core/class/rssparser.class.php @@ -742,7 +742,7 @@ function xml2php($xml) } //Let see if the new child is not in the array - if($tab==false && in_array($key,array_keys($array))) + if($tab === false && in_array($key,array_keys($array))) { //If this element is already in the array we will create an indexed array $tmp = $array[$key]; @@ -751,7 +751,7 @@ function xml2php($xml) $array[$key][] = $child; $tab = true; } - elseif($tab == true) + elseif($tab === true) { //Add an element in an existing array $array[$key][] = $child; From 92a3faeaf76df2b31e2fdc2302e3d33e0aa05abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 26 Sep 2018 10:13:14 +0200 Subject: [PATCH 70/72] add try catch for swiftmailer --- htdocs/core/class/CMailFile.class.php | 36 +++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 8313894f68c..9bd17a9670a 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -407,18 +407,44 @@ class CMailFile // TODO if (! empty($moreinheader)) ... // Give the message a subject - $this->message->setSubject($this->encodetorfc2822($subject)); + try { + $this->message->setSubject($this->encodetorfc2822($subject)); + } catch (Exception $e) { + $this->error = $e->getMessage(); + } // Set the From address with an associative array //$this->message->setFrom(array('john@doe.com' => 'John Doe')); - if (! empty($from)) $this->message->setFrom($this->getArrayAddress($from)); + if (! empty($from)) { + try { + $result = $this->message->setFrom($this->getArrayAddress($from)); + } catch (Exception $e) { + $this->error = $e->getMessage(); + } + } // Set the To addresses with an associative array - if (! empty($to)) $this->message->setTo($this->getArrayAddress($to)); + if (! empty($to)) { + try { + $result = $this->message->setTo($this->getArrayAddress($to)); + } catch (Exception $e) { + $this->error = $e->getMessage(); + } + } - if (! empty($from)) $this->message->SetReplyTo($this->getArrayAddress($from)); + if (! empty($from)) { + try { + $result = $this->message->SetReplyTo($this->getArrayAddress($from)); + } catch (Exception $e) { + $this->error = $e->getMessage(); + } + } - $this->message->setCharSet($conf->file->character_set_client); + try { + $result = $this->message->setCharSet($conf->file->character_set_client); + } catch (Exception $e) { + $this->error = $e->getMessage(); + } if (! empty($this->html)) { From 1bac3a0ccfc4ce81a76eca8b3734b0d22d8f14ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 26 Sep 2018 10:37:20 +0200 Subject: [PATCH 71/72] swiftmailer is doing encodetorfc2822 --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 9bd17a9670a..bb38563837a 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -408,7 +408,7 @@ class CMailFile // Give the message a subject try { - $this->message->setSubject($this->encodetorfc2822($subject)); + $this->message->setSubject($subject); } catch (Exception $e) { $this->error = $e->getMessage(); } From af93fc74846f500b26c96a34b1b3729e0598ef19 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio Date: Wed, 26 Sep 2018 17:19:06 +0200 Subject: [PATCH 72/72] FIX: showOptionals: column mismatches --- htdocs/core/class/commonobject.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index e9498d52d7d..47fabb6e2dc 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4524,7 +4524,7 @@ abstract class CommonObject { if (is_array($params) && count($params)>0) { if (array_key_exists('colspan',$params)) { - $colspan=$params['colspan']; + $colspan=$params['colspan'] - 1; } }else { $colspan='3'; @@ -4581,6 +4581,12 @@ abstract class CommonObject if($extrafields->attribute_required[$key]) $label = ''.$label.''; + if(! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) + { + $out .= ' '; + $colspan--; + } + $out .= ''.$langs->trans($label).''; $html_id = !empty($this->id) ? $this->element.'_extras_'.$key.'_'.$this->id : ''; $out .='';